329-v5.0-0004-brcmfmac-add-support-for-CYW43012-SDIO-chipset.patch 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. From 35cb51b2162a1a7c5cd977f92595e60ab14d3b22 Mon Sep 17 00:00:00 2001
  2. From: Chi-Hsien Lin <[email protected]>
  3. Date: Wed, 21 Nov 2018 07:53:47 +0000
  4. Subject: [PATCH] brcmfmac: add support for CYW43012 SDIO chipset
  5. CYW43012 is a 1x1 802.11a/b/g/n Dual-Band HT20, 256-QAM/Turbo QAM. It
  6. is an Ultra Low Power WLAN+BT combo chip.
  7. Reviewed-by: Arend van Spriel <[email protected]>
  8. Signed-off-by: Chi-Hsien Lin <[email protected]>
  9. Signed-off-by: Praveen Babu C <[email protected]>
  10. Signed-off-by: Kalle Valo <[email protected]>
  11. ---
  12. .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
  13. .../broadcom/brcm80211/brcmfmac/chip.c | 14 +++-
  14. .../broadcom/brcm80211/brcmfmac/sdio.c | 74 ++++++++++++++++---
  15. .../broadcom/brcm80211/include/brcm_hw_ids.h | 1 +
  16. include/linux/mmc/sdio_ids.h | 1 +
  17. 5 files changed, 78 insertions(+), 13 deletions(-)
  18. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
  19. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
  20. @@ -972,6 +972,7 @@ static const struct sdio_device_id brcmf
  21. BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
  22. BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
  23. BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_4373),
  24. + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43012),
  25. { /* end: all zeroes */ }
  26. };
  27. MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
  28. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
  29. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
  30. @@ -165,6 +165,7 @@ struct sbconfig {
  31. #define SRCI_LSS_MASK 0x00f00000
  32. #define SRCI_LSS_SHIFT 20
  33. #define SRCI_SRNB_MASK 0xf0
  34. +#define SRCI_SRNB_MASK_EXT 0x100
  35. #define SRCI_SRNB_SHIFT 4
  36. #define SRCI_SRBSZ_MASK 0xf
  37. #define SRCI_SRBSZ_SHIFT 0
  38. @@ -592,7 +593,13 @@ static void brcmf_chip_socram_ramsize(st
  39. if (lss != 0)
  40. *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
  41. } else {
  42. - nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  43. + /* length of SRAM Banks increased for corerev greater than 23 */
  44. + if (sr->pub.rev >= 23) {
  45. + nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT))
  46. + >> SRCI_SRNB_SHIFT;
  47. + } else {
  48. + nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  49. + }
  50. for (i = 0; i < nb; i++) {
  51. retent = brcmf_chip_socram_banksize(sr, i, &banksize);
  52. *ramsize += banksize;
  53. @@ -1356,6 +1363,11 @@ bool brcmf_chip_sr_capable(struct brcmf_
  54. addr = CORE_CC_REG(base, sr_control1);
  55. reg = chip->ops->read32(chip->ctx, addr);
  56. return reg != 0;
  57. + case CY_CC_43012_CHIP_ID:
  58. + addr = CORE_CC_REG(pmu->base, retention_ctl);
  59. + reg = chip->ops->read32(chip->ctx, addr);
  60. + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
  61. + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
  62. default:
  63. addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
  64. reg = chip->ops->read32(chip->ctx, addr);
  65. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
  66. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
  67. @@ -624,6 +624,7 @@ BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"
  68. BRCMF_FW_DEF(4354, "brcmfmac4354-sdio");
  69. BRCMF_FW_DEF(4356, "brcmfmac4356-sdio");
  70. BRCMF_FW_DEF(4373, "brcmfmac4373-sdio");
  71. +BRCMF_FW_DEF(43012, "brcmfmac43012-sdio");
  72. static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
  73. BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
  74. @@ -643,7 +644,8 @@ static const struct brcmf_firmware_mappi
  75. BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455),
  76. BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
  77. BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
  78. - BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373)
  79. + BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
  80. + BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
  81. };
  82. static void pkt_align(struct sk_buff *p, int len, int align)
  83. @@ -677,6 +679,14 @@ brcmf_sdio_kso_control(struct brcmf_sdio
  84. /* 1st KSO write goes to AOS wake up core if device is asleep */
  85. brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
  86. + /* In case of 43012 chip, the chip could go down immediately after
  87. + * KSO bit is cleared. So the further reads of KSO register could
  88. + * fail. Thereby just bailing out immediately after clearing KSO
  89. + * bit, to avoid polling of KSO bit.
  90. + */
  91. + if (!on && bus->ci->chip == CY_CC_43012_CHIP_ID)
  92. + return err;
  93. +
  94. if (on) {
  95. /* device WAKEUP through KSO:
  96. * write bit 0 & read back until
  97. @@ -2402,6 +2412,14 @@ static int brcmf_sdio_tx_ctrlframe(struc
  98. return ret;
  99. }
  100. +static bool brcmf_chip_is_ulp(struct brcmf_chip *ci)
  101. +{
  102. + if (ci->chip == CY_CC_43012_CHIP_ID)
  103. + return true;
  104. + else
  105. + return false;
  106. +}
  107. +
  108. static void brcmf_sdio_bus_stop(struct device *dev)
  109. {
  110. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  111. @@ -2409,7 +2427,7 @@ static void brcmf_sdio_bus_stop(struct d
  112. struct brcmf_sdio *bus = sdiodev->bus;
  113. struct brcmf_core *core = bus->sdio_core;
  114. u32 local_hostintmask;
  115. - u8 saveclk;
  116. + u8 saveclk, bpreq;
  117. int err;
  118. brcmf_dbg(TRACE, "Enter\n");
  119. @@ -2436,9 +2454,14 @@ static void brcmf_sdio_bus_stop(struct d
  120. /* Force backplane clocks to assure F2 interrupt propagates */
  121. saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  122. &err);
  123. - if (!err)
  124. - brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  125. - (saveclk | SBSDIO_FORCE_HT), &err);
  126. + if (!err) {
  127. + bpreq = saveclk;
  128. + bpreq |= brcmf_chip_is_ulp(bus->ci) ?
  129. + SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
  130. + brcmf_sdiod_writeb(sdiodev,
  131. + SBSDIO_FUNC1_CHIPCLKCSR,
  132. + bpreq, &err);
  133. + }
  134. if (err)
  135. brcmf_err("Failed to force clock for F2: err %d\n",
  136. err);
  137. @@ -3328,20 +3351,45 @@ err:
  138. return bcmerror;
  139. }
  140. +static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
  141. +{
  142. + if (bus->ci->chip == CY_CC_43012_CHIP_ID)
  143. + return true;
  144. + else
  145. + return false;
  146. +}
  147. +
  148. static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
  149. {
  150. int err = 0;
  151. u8 val;
  152. + u8 wakeupctrl;
  153. + u8 cardcap;
  154. + u8 chipclkcsr;
  155. brcmf_dbg(TRACE, "Enter\n");
  156. + if (brcmf_chip_is_ulp(bus->ci)) {
  157. + wakeupctrl = SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT;
  158. + chipclkcsr = SBSDIO_HT_AVAIL_REQ;
  159. + } else {
  160. + wakeupctrl = SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
  161. + chipclkcsr = SBSDIO_FORCE_HT;
  162. + }
  163. +
  164. + if (brcmf_sdio_aos_no_decode(bus)) {
  165. + cardcap = SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC;
  166. + } else {
  167. + cardcap = (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
  168. + SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT);
  169. + }
  170. +
  171. val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
  172. if (err) {
  173. brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n");
  174. return;
  175. }
  176. -
  177. - val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
  178. + val |= 1 << wakeupctrl;
  179. brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
  180. if (err) {
  181. brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n");
  182. @@ -3350,8 +3398,7 @@ static void brcmf_sdio_sr_init(struct br
  183. /* Add CMD14 Support */
  184. brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
  185. - (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
  186. - SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
  187. + cardcap,
  188. &err);
  189. if (err) {
  190. brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n");
  191. @@ -3359,7 +3406,7 @@ static void brcmf_sdio_sr_init(struct br
  192. }
  193. brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  194. - SBSDIO_FORCE_HT, &err);
  195. + chipclkcsr, &err);
  196. if (err) {
  197. brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n");
  198. return;
  199. @@ -4051,7 +4098,7 @@ static void brcmf_sdio_firmware_callback
  200. const struct firmware *code;
  201. void *nvram;
  202. u32 nvram_len;
  203. - u8 saveclk;
  204. + u8 saveclk, bpreq;
  205. u8 devctl;
  206. brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
  207. @@ -4085,8 +4132,11 @@ static void brcmf_sdio_firmware_callback
  208. /* Force clocks on backplane to be sure F2 interrupt propagates */
  209. saveclk = brcmf_sdiod_readb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, &err);
  210. if (!err) {
  211. + bpreq = saveclk;
  212. + bpreq |= brcmf_chip_is_ulp(bus->ci) ?
  213. + SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
  214. brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR,
  215. - (saveclk | SBSDIO_FORCE_HT), &err);
  216. + bpreq, &err);
  217. }
  218. if (err) {
  219. brcmf_err("Failed to force clock for F2: err %d\n", err);
  220. --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
  221. +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
  222. @@ -60,6 +60,7 @@
  223. #define BRCM_CC_43664_CHIP_ID 43664
  224. #define BRCM_CC_4371_CHIP_ID 0x4371
  225. #define CY_CC_4373_CHIP_ID 0x4373
  226. +#define CY_CC_43012_CHIP_ID 43012
  227. /* USB Device IDs */
  228. #define BRCM_USB_43143_DEVICE_ID 0xbd1e
  229. --- a/include/linux/mmc/sdio_ids.h
  230. +++ b/include/linux/mmc/sdio_ids.h
  231. @@ -42,6 +42,7 @@
  232. #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
  233. #define SDIO_DEVICE_ID_BROADCOM_4356 0x4356
  234. #define SDIO_DEVICE_ID_CYPRESS_4373 0x4373
  235. +#define SDIO_DEVICE_ID_CYPRESS_43012 43012
  236. #define SDIO_VENDOR_ID_INTEL 0x0089
  237. #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402