1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 /*++
8 Copyright (c) Realtek Semiconductor Corp. All rights reserved.
9
10 Module Name:
11 HalPwrSeqCmd.c
12
13 Abstract:
14 Implement HW Power sequence configuration CMD handling routine for Realtek devices.
15
16 Major Change History:
17 When Who What
18 ---------- --------------- -------------------------------
19 2011-10-26 Lucas Modify to be compatible with SD4-CE driver.
20 2011-07-07 Roger Create.
21
22 --*/
23 #include <drv_types.h>
24 #include <rtw_debug.h>
25 #include <HalPwrSeqCmd.h>
26
27
28 /* */
29 /* Description: */
30 /* This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. */
31 /* */
32 /* Assumption: */
33 /* We should follow specific format which was released from HW SD. */
34 /* */
35 /* 2011.07.07, added by Roger. */
36 /* */
HalPwrSeqCmdParsing(struct adapter * padapter,u8 CutVersion,u8 FabVersion,u8 InterfaceType,WLAN_PWR_CFG PwrSeqCmd[])37 u8 HalPwrSeqCmdParsing(
38 struct adapter *padapter,
39 u8 CutVersion,
40 u8 FabVersion,
41 u8 InterfaceType,
42 WLAN_PWR_CFG PwrSeqCmd[]
43 )
44 {
45 WLAN_PWR_CFG PwrCfgCmd;
46 u8 bPollingBit = false;
47 u32 AryIdx = 0;
48 u8 value = 0;
49 u32 offset = 0;
50 u32 pollingCount = 0; /* polling autoload done. */
51 u32 maxPollingCnt = 5000;
52
53 do {
54 PwrCfgCmd = PwrSeqCmd[AryIdx];
55
56 RT_TRACE(
57 _module_hal_init_c_,
58 _drv_info_,
59 (
60 "HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n",
61 GET_PWR_CFG_OFFSET(PwrCfgCmd),
62 GET_PWR_CFG_CUT_MASK(PwrCfgCmd),
63 GET_PWR_CFG_FAB_MASK(PwrCfgCmd),
64 GET_PWR_CFG_INTF_MASK(PwrCfgCmd),
65 GET_PWR_CFG_BASE(PwrCfgCmd),
66 GET_PWR_CFG_CMD(PwrCfgCmd),
67 GET_PWR_CFG_MASK(PwrCfgCmd),
68 GET_PWR_CFG_VALUE(PwrCfgCmd)
69 )
70 );
71
72 /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
73 if (
74 (GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
75 (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
76 (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)
77 ) {
78 switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
79 case PWR_CMD_READ:
80 RT_TRACE(
81 _module_hal_init_c_,
82 _drv_info_,
83 ("HalPwrSeqCmdParsing: PWR_CMD_READ\n")
84 );
85 break;
86
87 case PWR_CMD_WRITE:
88 RT_TRACE(
89 _module_hal_init_c_,
90 _drv_info_,
91 ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n")
92 );
93 offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
94
95 /* */
96 /* <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
97 /* 2011.07.07. */
98 /* */
99 if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
100 /* Read Back SDIO Local value */
101 value = SdioLocalCmd52Read1Byte(padapter, offset);
102
103 value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
104 value |= (
105 GET_PWR_CFG_VALUE(PwrCfgCmd) &
106 GET_PWR_CFG_MASK(PwrCfgCmd)
107 );
108
109 /* Write Back SDIO Local value */
110 SdioLocalCmd52Write1Byte(padapter, offset, value);
111 } else {
112 /* Read the value from system register */
113 value = rtw_read8(padapter, offset);
114
115 value &= (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
116 value |= (
117 GET_PWR_CFG_VALUE(PwrCfgCmd)
118 &GET_PWR_CFG_MASK(PwrCfgCmd)
119 );
120
121 /* Write the value back to system register */
122 rtw_write8(padapter, offset, value);
123 }
124 break;
125
126 case PWR_CMD_POLLING:
127 RT_TRACE(
128 _module_hal_init_c_,
129 _drv_info_,
130 ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n")
131 );
132
133 bPollingBit = false;
134 offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
135 do {
136 if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
137 value = SdioLocalCmd52Read1Byte(padapter, offset);
138 else
139 value = rtw_read8(padapter, offset);
140
141 value = value&GET_PWR_CFG_MASK(PwrCfgCmd);
142 if (
143 value == (GET_PWR_CFG_VALUE(PwrCfgCmd) &
144 GET_PWR_CFG_MASK(PwrCfgCmd))
145 )
146 bPollingBit = true;
147 else
148 udelay(10);
149
150 if (pollingCount++ > maxPollingCnt) {
151 DBG_871X(
152 "Fail to polling Offset[%#x]=%02x\n",
153 offset,
154 value
155 );
156 return false;
157 }
158 } while (!bPollingBit);
159
160 break;
161
162 case PWR_CMD_DELAY:
163 RT_TRACE(
164 _module_hal_init_c_,
165 _drv_info_,
166 ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n")
167 );
168 if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
169 udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd));
170 else
171 udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
172 break;
173
174 case PWR_CMD_END:
175 /* When this command is parsed, end the process */
176 RT_TRACE(
177 _module_hal_init_c_,
178 _drv_info_,
179 ("HalPwrSeqCmdParsing: PWR_CMD_END\n")
180 );
181 return true;
182
183 default:
184 RT_TRACE(
185 _module_hal_init_c_,
186 _drv_err_,
187 ("HalPwrSeqCmdParsing: Unknown CMD!!\n")
188 );
189 break;
190 }
191 }
192
193 AryIdx++;/* Add Array Index */
194 } while (1);
195
196 return true;
197 }
198