HalPwrSeqCmd.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 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. /*++
  16. Copyright (c) Realtek Semiconductor Corp. All rights reserved.
  17. Module Name:
  18. HalPwrSeqCmd.c
  19. Abstract:
  20. Implement HW Power sequence configuration CMD handling routine for Realtek devices.
  21. Major Change History:
  22. When Who What
  23. ---------- --------------- -------------------------------
  24. 2011-10-26 Lucas Modify to be compatible with SD4-CE driver.
  25. 2011-07-07 Roger Create.
  26. --*/
  27. #include <HalPwrSeqCmd.h>
  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. PADAPTER padapter,
  39. u8 CutVersion,
  40. u8 FabVersion,
  41. u8 InterfaceType,
  42. WLAN_PWR_CFG PwrSeqCmd[])
  43. {
  44. WLAN_PWR_CFG PwrCfgCmd = {0};
  45. u8 bPollingBit = _FALSE;
  46. u8 bHWICSupport = _FALSE;
  47. u32 AryIdx = 0;
  48. u8 value = 0;
  49. u32 offset = 0;
  50. u8 flag = 0;
  51. u32 pollingCount = 0; /* polling autoload done. */
  52. u32 maxPollingCnt = 5000;
  53. do {
  54. PwrCfgCmd = PwrSeqCmd[AryIdx];
  55. /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
  56. if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
  57. (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
  58. (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) {
  59. switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
  60. case PWR_CMD_READ:
  61. break;
  62. case PWR_CMD_WRITE:
  63. offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
  64. #ifdef CONFIG_SDIO_HCI
  65. /* */
  66. /* <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
  67. /* 2011.07.07. */
  68. /* */
  69. if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
  70. /* Read Back SDIO Local value */
  71. value = SdioLocalCmd52Read1Byte(padapter, offset);
  72. value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
  73. value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));
  74. /* Write Back SDIO Local value */
  75. SdioLocalCmd52Write1Byte(padapter, offset, value);
  76. } else
  77. #endif
  78. {
  79. #ifdef CONFIG_GSPI_HCI
  80. if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
  81. offset = SPI_LOCAL_OFFSET | offset;
  82. #endif
  83. /* Read the value from system register */
  84. value = rtw_read8(padapter, offset);
  85. value = value & (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
  86. value = value | (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));
  87. /* Write the value back to sytem register */
  88. rtw_write8(padapter, offset, value);
  89. }
  90. break;
  91. case PWR_CMD_POLLING:
  92. bPollingBit = _FALSE;
  93. offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
  94. rtw_hal_get_hwreg(padapter, HW_VAR_PWR_CMD, &bHWICSupport);
  95. if (bHWICSupport && offset == 0x06) {
  96. flag = 0;
  97. maxPollingCnt = 100000;
  98. } else
  99. maxPollingCnt = 5000;
  100. #ifdef CONFIG_GSPI_HCI
  101. if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
  102. offset = SPI_LOCAL_OFFSET | offset;
  103. #endif
  104. do {
  105. #ifdef CONFIG_SDIO_HCI
  106. if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
  107. value = SdioLocalCmd52Read1Byte(padapter, offset);
  108. else
  109. #endif
  110. value = rtw_read8(padapter, offset);
  111. value = value & GET_PWR_CFG_MASK(PwrCfgCmd);
  112. if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)))
  113. bPollingBit = _TRUE;
  114. else
  115. rtw_udelay_os(10);
  116. if (pollingCount++ > maxPollingCnt) {
  117. RTW_ERR("HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value);
  118. /* For PCIE + USB package poll power bit timeout issue only modify 8821AE and 8723BE */
  119. if (bHWICSupport && offset == 0x06 && flag == 0) {
  120. RTW_ERR("[WARNING] PCIE polling(0x%X) timeout(%d), Toggle 0x04[3] and try again.\n", offset, maxPollingCnt);
  121. if (IS_HARDWARE_TYPE_8723DE(padapter))
  122. PlatformEFIOWrite1Byte(padapter, 0x40, (PlatformEFIORead1Byte(padapter, 0x40)) & (~BIT3));
  123. PlatformEFIOWrite1Byte(padapter, 0x04, PlatformEFIORead1Byte(padapter, 0x04) | BIT3);
  124. PlatformEFIOWrite1Byte(padapter, 0x04, PlatformEFIORead1Byte(padapter, 0x04) & ~BIT3);
  125. if (IS_HARDWARE_TYPE_8723DE(padapter))
  126. PlatformEFIOWrite1Byte(padapter, 0x40, PlatformEFIORead1Byte(padapter, 0x40)|BIT3);
  127. /* Retry Polling Process one more time */
  128. pollingCount = 0;
  129. flag = 1;
  130. } else {
  131. return _FALSE;
  132. }
  133. }
  134. } while (!bPollingBit);
  135. break;
  136. case PWR_CMD_DELAY:
  137. if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
  138. rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd));
  139. else
  140. rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd) * 1000);
  141. break;
  142. case PWR_CMD_END:
  143. /* When this command is parsed, end the process */
  144. return _TRUE;
  145. break;
  146. default:
  147. break;
  148. }
  149. }
  150. AryIdx++;/* Add Array Index */
  151. } while (1);
  152. return _TRUE;
  153. }