xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_halinit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2016 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _RTL8821CS_HALINIT_C_
16 
17 #include <drv_types.h>		/* PADAPTER, basic_types.h and etc. */
18 #include <hal_data.h>		/* HAL_DATA_TYPE */
19 #include "../rtl8821c.h"		/* rtl8821c_mac_init(), rtl8821c_phy_init() and etc. */
20 #include "../../hal_halmac.h"	/* rtw_halmac_get_oqt_size*/
21 
22 /*
23 #define HALMAC_NORMAL_HPQ_PGNUM_8821C	16
24 #define HALMAC_NORMAL_NPQ_PGNUM_8821C	16
25 #define HALMAC_NORMAL_LPQ_PGNUM_8821C	16
26 #define HALMAC_NORMAL_EXPQ_PGNUM_8821C	14
27 #define HALMAC_NORMAL_GAP_PGNUM_8821C	1
28 
29 	case HALMAC_TRX_MODE_NORMAL:
30 	pHalmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO] = HALMAC_DMA_MAPPING_NORMAL;
31 	pHalmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI] = HALMAC_DMA_MAPPING_NORMAL;
32 	pHalmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE] = HALMAC_DMA_MAPPING_LOW;
33 	pHalmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK] = HALMAC_DMA_MAPPING_LOW;
34 	pHalmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG] = HALMAC_DMA_MAPPING_EXTRA;
35 	pHalmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] = HALMAC_DMA_MAPPING_HIGH;
36 
37 */
38 
rtl8821cs_init_xmit_info(_adapter * adapter)39 static void rtl8821cs_init_xmit_info(_adapter *adapter)
40 {
41 	PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter);
42 	u32 page_size;
43 
44 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
45 
46 	hal_data->tx_high_page = rtw_read16(adapter, REG_FIFOPAGE_INFO_1) & 0xFFF;
47 	hal_data->tx_low_page = rtw_read16(adapter, REG_FIFOPAGE_INFO_2) & 0xFFF;
48 	hal_data->tx_normal_page = rtw_read16(adapter, REG_FIFOPAGE_INFO_3) & 0xFFF;
49 	hal_data->tx_extra_page = rtw_read16(adapter, REG_FIFOPAGE_INFO_4) & 0xFFF;
50 	hal_data->tx_pub_page = rtw_read16(adapter, REG_FIFOPAGE_INFO_5) & 0xFFF;
51 
52 #ifdef DBG_DUMP_RQPN
53 	{
54 	u32 tx_fifo_size;
55 
56 	rtw_halmac_get_tx_fifo_size(adapter_to_dvobj(adapter), &tx_fifo_size);
57 	RTW_INFO("%s => High Pages:%d, LOW Pages:%d, Normal Pages:%d, Extra Pages:%d, Pub Pages:%d, Total Pages:%d\n"
58 		 , __func__
59 		 , hal_data->tx_high_page
60 		 , hal_data->tx_low_page
61 		 , hal_data->tx_normal_page
62 		 , hal_data->tx_extra_page
63 		 , hal_data->tx_pub_page
64 		 , (tx_fifo_size / page_size));
65 	}
66 #endif
67 
68 	hal_data->max_xmit_page = PageNum(MAX_XMITBUF_SZ, page_size);
69 
70 	if (adapter->registrypriv.wifi_spec) {
71 		/*HALMAC_TRX_MODE_WMM - VO - HQ , VI - NQ , BE - LQ , BK - NQ , MG - HQ , HI -HQ*/
72 		hal_data->max_xmit_page_vo = hal_data->tx_high_page + hal_data->tx_pub_page;
73 		hal_data->max_xmit_page_vi = (hal_data->tx_normal_page + hal_data->tx_pub_page) >> 1;
74 		hal_data->max_xmit_page_be = hal_data->tx_low_page + hal_data->tx_pub_page;
75 		hal_data->max_xmit_page_bk = (hal_data->tx_normal_page + hal_data->tx_pub_page) >> 1;
76 	} else {
77 		/*HALMAC_TRX_MODE_NORMAL - VO - NQ , VI - NQ , BE - LQ , BK - LQ , MG - EXQ , HI -HQ*/
78 		#ifdef XMIT_BUF_SIZE
79 		hal_data->max_xmit_size_vovi = ((hal_data->tx_normal_page + hal_data->tx_pub_page) >> 1) * page_size;
80 		hal_data->max_xmit_size_bebk = ((hal_data->tx_low_page + hal_data->tx_pub_page) >> 1) * page_size;
81 		#endif
82 
83 		hal_data->max_xmit_page_vo = (hal_data->tx_normal_page + hal_data->tx_pub_page) >> 1;
84 		hal_data->max_xmit_page_vi = (hal_data->tx_normal_page + hal_data->tx_pub_page) >> 1;
85 		hal_data->max_xmit_page_be = (hal_data->tx_low_page + hal_data->tx_pub_page) >> 1;
86 		hal_data->max_xmit_page_bk = (hal_data->tx_low_page + hal_data->tx_pub_page) >> 1;
87 	}
88 
89 #ifdef DBG_DUMP_RQPN
90 	#ifdef XMIT_BUF_SIZE
91 	RTW_INFO("%s => max_xmit_size_vovi:%d, max_xmit_size_bebk:%d\n", __func__, hal_data->max_xmit_size_vovi, hal_data->max_xmit_size_bebk);
92 	#endif
93 
94 	RTW_INFO("%s => VO max_xmit_page:%d, VI max_xmit_page:%d\n", __func__, hal_data->max_xmit_page_vo, hal_data->max_xmit_page_vi);
95 	RTW_INFO("%s => BE max_xmit_page:%d, BK max_xmit_page:%d\n", __func__, hal_data->max_xmit_page_be, hal_data->max_xmit_page_bk);
96 #endif
97 
98 	if (rtw_halmac_get_oqt_size(adapter_to_dvobj(adapter), &hal_data->max_oqt_size)) {
99 		RTW_WARN("%s: Fail to get Max OQT size! use default max-size : 32\n", __func__);
100 		hal_data->max_oqt_size = 32;
101 	}
102 }
103 
104 #ifdef CONFIG_FWLPS_IN_IPS
rtl8821cs_fw_ips_init(_adapter * padapter)105 u8 rtl8821cs_fw_ips_init(_adapter *padapter)
106 {
107 	struct sreset_priv *psrtpriv = &GET_HAL_DATA(padapter)->srestpriv;
108 	struct debug_priv *pdbgpriv = &adapter_to_dvobj(padapter)->drv_dbg;
109 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
110 
111 	if (pwrctl->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE
112 		&& GET_HAL_DATA(padapter)->bFWReady == _TRUE && pwrctl->pre_ips_type == 0) {
113 		systime start_time;
114 		u8 cpwm_orig, cpwm_now, rpwm;
115 		u8 bMacPwrCtrlOn = _TRUE;
116 
117 		RTW_INFO("%s: Leaving FW_IPS\n", __func__);
118 
119 		/* for polling cpwm */
120 		cpwm_orig = 0;
121 		rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
122 
123 		/* set rpwm */
124 		rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &rpwm);
125 		rpwm += 0x80;
126 		rpwm |= PS_ACK;
127 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
128 
129 
130 		RTW_INFO("%s: write rpwm=%02x\n", __func__, rpwm);
131 
132 		pwrctl->tog = (rpwm + 0x80) & 0x80;
133 
134 		/* do polling cpwm */
135 		start_time = rtw_get_current_time();
136 		do {
137 
138 			rtw_mdelay_os(1);
139 
140 			rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
141 			if ((cpwm_orig ^ cpwm_now) & 0x80) {
142 				#ifdef DBG_CHECK_FW_PS_STATE
143 				RTW_INFO("%s: polling cpwm ok when leaving IPS in FWLPS state, cpwm_orig=%02x, cpwm_now=%02x, 0x100=0x%x\n"
144 					, __func__, cpwm_orig, cpwm_now, rtw_read8(padapter, REG_CR));
145 				#endif /* DBG_CHECK_FW_PS_STATE */
146 				break;
147 			}
148 
149 			if (rtw_get_passing_time_ms(start_time) > 100) {
150 				RTW_INFO("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __func__);
151 				break;
152 			}
153 		} while (1);
154 
155 		rtl8821c_set_FwPwrModeInIPS_cmd(padapter, 0);
156 
157 		rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
158 
159 		#ifdef DBG_CHECK_FW_PS_STATE
160 		if (rtw_fw_ps_state(padapter) == _FAIL) {
161 			RTW_INFO("after hal init, fw ps state in 32k\n");
162 			pdbgpriv->dbg_ips_drvopen_fail_cnt++;
163 		}
164 		#endif /* DBG_CHECK_FW_PS_STATE */
165 		return _SUCCESS;
166 	}
167 	return _FAIL;
168 }
169 
rtl8821cs_fw_ips_deinit(_adapter * padapter)170 u8 rtl8821cs_fw_ips_deinit(_adapter *padapter)
171 {
172 	struct sreset_priv *psrtpriv =  &GET_HAL_DATA(padapter)->srestpriv;
173 	struct debug_priv *pdbgpriv = &adapter_to_dvobj(padapter)->drv_dbg;
174 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
175 
176 	if (pwrctl->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE
177 		&& GET_HAL_DATA(padapter)->bFWReady == _TRUE && padapter->netif_up == _TRUE) {
178 		int cnt = 0;
179 		u8 val8 = 0, rpwm;
180 
181 		RTW_INFO("%s: issue H2C to FW when entering IPS\n", __func__);
182 
183 		rtl8821c_set_FwPwrModeInIPS_cmd(padapter, 0x1);
184 		/* poll 0x1cc to make sure H2C command already finished by FW; MAC_0x1cc=0 means H2C done by FW. */
185 		do {
186 			val8 = rtw_read8(padapter, REG_HMETFR);
187 			cnt++;
188 			RTW_INFO("%s  polling REG_HMETFR=0x%x, cnt=%d\n", __func__, val8, cnt);
189 			rtw_mdelay_os(10);
190 		} while (cnt < 100 && (val8 != 0));
191 
192 		/* H2C done, enter 32k */
193 		if (val8 == 0) {
194 			/* set rpwm to enter 32k */
195 			rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &rpwm);
196 			rpwm += 0x80;
197 			rpwm |= BIT_SYS_CLK_8821C;
198 			rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
199 			RTW_INFO("%s: write rpwm=%02x\n", __func__, rpwm);
200 			pwrctl->tog = (val8 + 0x80) & 0x80;
201 
202 			cnt = val8 = 0;
203 			do {
204 				val8 = rtw_read8(padapter, REG_CR);
205 				cnt++;
206 				RTW_INFO("%s  polling 0x100=0x%x, cnt=%d\n", __func__, val8, cnt);
207 				rtw_mdelay_os(10);
208 			} while (cnt < 100 && (val8 != 0xEA));
209 
210 			#ifdef DBG_CHECK_FW_PS_STATE
211 			if (val8 != 0xEA)
212 				RTW_INFO("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n"
213 					, rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
214 					, rtw_read32(padapter, 0x1c8), rtw_read32(padapter, REG_HMETFR));
215 			#endif /* DBG_CHECK_FW_PS_STATE */
216 		} else {
217 			RTW_INFO("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n"
218 				, rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
219 				, rtw_read32(padapter, 0x1c8), rtw_read32(padapter, REG_HMETFR));
220 		}
221 
222 		RTW_INFO("polling done when entering IPS, check result : 0x100=0x%x, cnt=%d, MAC_1cc=0x%02x\n"
223 			, rtw_read8(padapter, REG_CR), cnt, rtw_read8(padapter, REG_HMETFR));
224 
225 		pwrctl->pre_ips_type = 0;
226 
227 		return _SUCCESS;
228 	}
229 
230 	pdbgpriv->dbg_carddisable_cnt++;
231 	pwrctl->pre_ips_type = 1;
232 
233 	return _FAIL;
234 
235 }
236 #endif /*CONFIG_FWLPS_IN_IPS*/
237 
238 #define MAX_AMPDU_NUMBER		0x1212 /*MAX AMPDU Number = 18*/
rtl8821cs_ampdu_num_cfg(_adapter * adapter)239 static void rtl8821cs_ampdu_num_cfg(_adapter *adapter)
240 {
241 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
242 	PSDIO_DATA psdio_data = &dvobj->intf_data;
243 	u16 ampdu_num = MAX_AMPDU_NUMBER;
244 
245 	if (psdio_data->clock < RTW_SDIO_CLK_80M)
246 		ampdu_num = 0x1F1F;
247 
248 	rtw_write16(adapter, REG_PROT_MODE_CTRL_8821C + 2, ampdu_num);
249 }
250 
rtl8821cs_init_misc(_adapter * adapter)251 static void rtl8821cs_init_misc(_adapter *adapter)
252 {
253 	#ifdef DBG_DL_FW_MEM
254 	rtw_write8(adapter, 0xf6, 0x01);
255 	rtw_write8(adapter, 0x3a, 0x28);
256 	#endif
257 
258 	#ifdef CONFIG_BT_WAKE_HST_OPEN_DRAIN
259 	/*PAD Type control select for GPIO14 (DEV_WAKE_HST) in USB or SDIO interface
260 	0: Push-Pull , 1: Open-Drain*/
261 	rtw_write32(adapter, REG_WL_BT_PWR_CTRL,
262 		rtw_read32(adapter, REG_WL_BT_PWR_CTRL) | BIT_DEVWAKE_PAD_TYPE_SEL);
263 	#endif
264 
265 	rtl8821cs_ampdu_num_cfg(adapter);
266 }
267 
rtl8821cs_hal_init(PADAPTER adapter)268 u32 rtl8821cs_hal_init(PADAPTER adapter)
269 {
270 #ifdef CONFIG_FWLPS_IN_IPS
271 	if (_SUCCESS == rtl8821cs_fw_ips_init(adapter))
272 		return _SUCCESS;
273 #endif
274 	if (_FALSE == rtl8821c_hal_init(adapter))
275 		return _FAIL;
276 
277 	rtl8821cs_init_xmit_info(adapter);
278 	rtl8821cs_init_misc(adapter);
279 
280 	return _SUCCESS;
281 }
rtl8821cs_hal_deinit(PADAPTER adapter)282 u32 rtl8821cs_hal_deinit(PADAPTER adapter)
283 {
284 #ifdef CONFIG_FWLPS_IN_IPS
285 	if (_SUCCESS == rtl8821cs_fw_ips_deinit(adapter))
286 		return _SUCCESS;
287 #endif
288 
289 	return rtl8821c_hal_deinit(adapter);
290 }
291 
rtl8821cs_init_default_value(PADAPTER adapter)292 void rtl8821cs_init_default_value(PADAPTER adapter)
293 {
294 	PHAL_DATA_TYPE hal;
295 
296 
297 	hal = GET_HAL_DATA(adapter);
298 
299 	rtl8821c_init_default_value(adapter);
300 
301 	/* interface related variable */
302 	hal->SdioRxFIFOCnt = 0;
303 }
304