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 /* */ 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