xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8822cs/hal/rtl8822c/sdio/rtl8822cs_halinit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2015 - 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 _RTL8822CS_HALINIT_C_
16 
17 #include <drv_types.h>		/* PADAPTER, basic_types.h and etc. */
18 #include <hal_data.h>		/* HAL_DATA_TYPE */
19 #include "../../hal_halmac.h"	/* rtw_halmac_query_tx_page_num() */
20 #include "../rtl8822c.h"	/* rtl8822c_hal_init(), rtl8822c_phy_init_haldm() and etc. */
21 
22 #ifdef CONFIG_FWLPS_IN_IPS
fw_ips_leave(struct _ADAPTER * a)23 static u8 fw_ips_leave(struct _ADAPTER *a)
24 {
25 	struct sreset_priv *psrtpriv = &GET_HAL_DATA(a)->srestpriv;
26 	struct debug_priv *pdbgpriv = &adapter_to_dvobj(a)->drv_dbg;
27 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(a);
28 	systime start_time;
29 	u8 cpwm_orig, cpwm_now, rpwm;
30 	u8 bMacPwrCtrlOn = _TRUE;
31 
32 
33 	if ((pwrctl->bips_processing == _FALSE)
34 	    || (psrtpriv->silent_reset_inprogress == _TRUE)
35 	    || (GET_HAL_DATA(a)->bFWReady == _FALSE)
36 	    || (pwrctl->pre_ips_type != 0))
37 		return _FAIL;
38 
39 	RTW_INFO("%s: Leaving FW_IPS\n", __func__);
40 
41 	/* for polling cpwm */
42 	cpwm_orig = 0;
43 	rtw_hal_get_hwreg(a, HW_VAR_CPWM, &cpwm_orig);
44 
45 	/* set rpwm */
46 #if 1
47 	rtw_hal_get_hwreg(a, HW_VAR_RPWM_TOG, &rpwm);
48 	rpwm += 0x80;
49 #else
50 	rpwm = pwrctl->tog;
51 #endif
52 	rpwm |= PS_ACK;
53 	rtw_hal_set_hwreg(a, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
54 	RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, rpwm);
55 
56 	pwrctl->tog = (rpwm + 0x80) & 0x80;
57 
58 	/* do polling cpwm */
59 	start_time = rtw_get_current_time();
60 	do {
61 		rtw_mdelay_os(1);
62 
63 		rtw_hal_get_hwreg(a, HW_VAR_CPWM, &cpwm_now);
64 		if ((cpwm_orig ^ cpwm_now) & 0x80) {
65 #ifdef DBG_CHECK_FW_PS_STATE
66 			RTW_INFO("%s: polling cpwm ok when leaving IPS in FWLPS state,"
67 				 " cost %d ms,"
68 				 " cpwm_orig=0x%02x, cpwm_now=0x%02x, 0x100=0x%x\n",
69 				 __FUNCTION__,
70 				 rtw_get_passing_time_ms(start_time),
71 				 cpwm_orig, cpwm_now, rtw_read8(a, REG_CR_8822C));
72 #endif /* DBG_CHECK_FW_PS_STATE */
73 			break;
74 		}
75 
76 		if (rtw_get_passing_time_ms(start_time) > 100) {
77 			RTW_ERR("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __FUNCTION__);
78 			break;
79 		}
80 	} while (1);
81 
82 	rtl8822c_set_FwPwrModeInIPS_cmd(a, 0);
83 
84 	rtw_hal_set_hwreg(a, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
85 
86 #ifdef DBG_CHECK_FW_PS_STATE
87 	if (rtw_fw_ps_state(a) == _FAIL) {
88 		RTW_INFO("after hal init, fw ps state in 32k\n");
89 		pdbgpriv->dbg_ips_drvopen_fail_cnt++;
90 	}
91 #endif /* DBG_CHECK_FW_PS_STATE */
92 
93 	return _SUCCESS;
94 }
95 
fw_ips_enter(struct _ADAPTER * a)96 static u8 fw_ips_enter(struct _ADAPTER *a)
97 {
98 	struct sreset_priv *psrtpriv = &GET_HAL_DATA(a)->srestpriv;
99 	struct debug_priv *pdbgpriv = &adapter_to_dvobj(a)->drv_dbg;
100 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(a);
101 	systime start_time;
102 	int cnt = 0;
103 	u8 val8 = 0, rpwm;
104 
105 
106 	if ((pwrctl->bips_processing == _FALSE)
107 	    || (psrtpriv->silent_reset_inprogress == _TRUE)
108 	    || (GET_HAL_DATA(a)->bFWReady == _FALSE)
109 	    || (a->netif_up == _FALSE)) {
110 		pdbgpriv->dbg_carddisable_cnt++;
111 		pwrctl->pre_ips_type = 1;
112 
113 		return _FAIL;
114 	}
115 
116 	RTW_INFO("%s: issue H2C to FW when entering IPS\n", __FUNCTION__);
117 	rtl8822c_set_FwPwrModeInIPS_cmd(a, 0x1);
118 
119 	/*
120 	 * poll 0x1cc to make sure H2C command already finished by FW;
121 	 * MAC_0x1cc=0 means H2C done by FW.
122 	 */
123 	start_time = rtw_get_current_time();
124 	do {
125 		rtw_mdelay_os(10);
126 		val8 = rtw_read8(a, REG_HMETFR_8822C);
127 		cnt++;
128 		if (!val8)
129 			break;
130 
131 		if (rtw_get_passing_time_ms(start_time) > 100) {
132 			RTW_ERR("%s: fail to wait H2C, REG_HMETFR=0x%x, cnt=%d\n",
133 				__FUNCTION__, val8, cnt);
134 #ifdef DBG_CHECK_FW_PS_STATE
135 			RTW_WARN("MAC_1C0=0x%08x, MAC_1C4=0x%08x, MAC_1C8=0x%08x, MAC_1CC=0x%08x\n",
136 				 rtw_read32(a, 0x1c0), rtw_read32(a, 0x1c4),
137 				 rtw_read32(a, 0x1c8), rtw_read32(a, REG_HMETFR_8822C));
138 #endif /* DBG_CHECK_FW_PS_STATE */
139 			goto exit;
140 		}
141 	} while (1);
142 
143 	/* H2C done, enter 32k */
144 	/* set rpwm to enter 32k */
145 #if 1
146 	rtw_hal_get_hwreg(a, HW_VAR_RPWM_TOG, &rpwm);
147 	rpwm += 0x80;
148 #else
149 	rpwm = pwrctl->tog;
150 #endif
151 	rpwm |= PS_STATE_S0;
152 	rtw_hal_set_hwreg(a, HW_VAR_SET_RPWM, &rpwm);
153 	RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, rpwm);
154 	pwrctl->tog = (rpwm + 0x80) & 0x80;
155 
156 	cnt = val8 = 0;
157 	start_time = rtw_get_current_time();
158 	do {
159 		val8 = rtw_read8(a, REG_CR_8822C);
160 		cnt++;
161 		RTW_INFO("%s: polling 0x100=0x%x, cnt=%d\n",
162 			 __FUNCTION__, val8, cnt);
163 		if (val8 == 0xEA) {
164 			RTW_INFO("%s: polling 0x100=0xEA, cnt=%d, cost %d ms\n",
165 				 __FUNCTION__, cnt,
166 				 rtw_get_passing_time_ms(start_time));
167 			break;
168 		}
169 
170 		if (rtw_get_passing_time_ms(start_time) > 100) {
171 			RTW_ERR("%s: polling polling 0x100=0xEA timeout! cnt=%d\n",
172 				__FUNCTION__, cnt);
173 #ifdef DBG_CHECK_FW_PS_STATE
174 			RTW_WARN("MAC_1C0=0x%08x, MAC_1C4=0x%08x, MAC_1C8=0x%08x, MAC_1CC=0x%08x\n",
175 				 rtw_read32(a, 0x1c0), rtw_read32(a, 0x1c4),
176 				 rtw_read32(a, 0x1c8), rtw_read32(a, REG_HMETFR_8822C));
177 #endif /* DBG_CHECK_FW_PS_STATE */
178 			break;
179 		}
180 
181 		rtw_mdelay_os(10);
182 	} while (1);
183 
184 exit:
185 	RTW_INFO("polling done when entering IPS, check result: 0x100=0x%02x, cnt=%d, MAC_1cc=0x%02x\n",
186 		 rtw_read8(a, REG_CR_8822C), cnt, rtw_read8(a, REG_HMETFR_8822C));
187 
188 	pwrctl->pre_ips_type = 0;
189 
190 	return _SUCCESS;
191 }
192 #endif /* CONFIG_FWLPS_IN_IPS */
193 
194 
rtl8822cs_init(PADAPTER adapter)195 u32 rtl8822cs_init(PADAPTER adapter)
196 {
197 	u8 ok = _TRUE;
198 	PHAL_DATA_TYPE hal;
199 
200 
201 	hal = GET_HAL_DATA(adapter);
202 
203 #ifdef CONFIG_FWLPS_IN_IPS
204 	if (fw_ips_leave(adapter) == _SUCCESS)
205 		return _SUCCESS;
206 #endif
207 	ok = rtl8822c_hal_init(adapter);
208 	if (_FALSE == ok)
209 		return _FAIL;
210 
211 	rtw_halmac_query_tx_page_num(adapter_to_dvobj(adapter));
212 
213 	rtl8822c_mac_verify(adapter);
214 
215 	rtl8822c_phy_init_haldm(adapter);
216 #ifdef CONFIG_BEAMFORMING
217 	rtl8822c_phy_bf_init(adapter);
218 #endif
219 
220 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
221 	/*HW /FW init*/
222 	rtw_hal_set_default_port_id_cmd(adapter, 0);
223 #endif
224 
225 #ifdef CONFIG_BT_COEXIST
226 	/* Init BT hw config. */
227 	if (hal->EEPROMBluetoothCoexist == _TRUE) {
228 		rtw_btcoex_HAL_Initialize(adapter, _FALSE);
229 		#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
230 		rtw_hal_set_wifi_btc_port_id_cmd(adapter);
231 		#endif
232 	} else
233 #endif /* CONFIG_BT_COEXIST */
234 		rtw_btcoex_wifionly_hw_config(adapter);
235 
236 	rtl8822c_init_misc(adapter);
237 
238 	return _SUCCESS;
239 }
240 
rtl8822cs_deinit(PADAPTER adapter)241 u32 rtl8822cs_deinit(PADAPTER adapter)
242 {
243 #ifdef CONFIG_FWLPS_IN_IPS
244 	if (fw_ips_enter(adapter) == _SUCCESS)
245 		return _SUCCESS;
246 #endif
247 
248 	return rtl8822c_deinit(adapter);
249 }
250 
rtl8822cs_init_default_value(PADAPTER adapter)251 void rtl8822cs_init_default_value(PADAPTER adapter)
252 {
253 	PHAL_DATA_TYPE hal;
254 
255 
256 	hal = GET_HAL_DATA(adapter);
257 
258 	rtl8822c_init_default_value(adapter);
259 
260 	/* interface related variable */
261 	hal->SdioRxFIFOCnt = 0;
262 }
263