sdio_chip.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * Copyright (c) 2011 Broadcom Corporation
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /* ***** SDIO interface chip backplane handle functions ***** */
  17. #include <linux/types.h>
  18. #include <linux/netdevice.h>
  19. #include <linux/mmc/card.h>
  20. #include <chipcommon.h>
  21. #include <brcm_hw_ids.h>
  22. #include <brcmu_wifi.h>
  23. #include <brcmu_utils.h>
  24. #include <soc.h>
  25. #include "dhd.h"
  26. #include "dhd_dbg.h"
  27. #include "sdio_host.h"
  28. #include "sdio_chip.h"
  29. /* chip core base & ramsize */
  30. /* bcm4329 */
  31. /* SDIO device core, ID 0x829 */
  32. #define BCM4329_CORE_BUS_BASE 0x18011000
  33. /* internal memory core, ID 0x80e */
  34. #define BCM4329_CORE_SOCRAM_BASE 0x18003000
  35. /* ARM Cortex M3 core, ID 0x82a */
  36. #define BCM4329_CORE_ARM_BASE 0x18002000
  37. #define BCM4329_RAMSIZE 0x48000
  38. /* SB regs */
  39. /* sbidhigh */
  40. #define SBIDH_RC_MASK 0x000f /* revision code */
  41. #define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
  42. #define SBIDH_RCE_SHIFT 8
  43. #define SBCOREREV(sbidh) \
  44. ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | \
  45. ((sbidh) & SBIDH_RC_MASK))
  46. #define SBIDH_CC_MASK 0x8ff0 /* core code */
  47. #define SBIDH_CC_SHIFT 4
  48. #define SBIDH_VC_MASK 0xffff0000 /* vendor code */
  49. #define SBIDH_VC_SHIFT 16
  50. static u32
  51. brcmf_sdio_chip_corerev(struct brcmf_sdio_dev *sdiodev,
  52. u32 corebase)
  53. {
  54. u32 regdata;
  55. regdata = brcmf_sdcard_reg_read(sdiodev,
  56. CORE_SB(corebase, sbidhigh), 4);
  57. return SBCOREREV(regdata);
  58. }
  59. bool
  60. brcmf_sdio_chip_iscoreup(struct brcmf_sdio_dev *sdiodev,
  61. u32 corebase)
  62. {
  63. u32 regdata;
  64. regdata = brcmf_sdcard_reg_read(sdiodev,
  65. CORE_SB(corebase, sbtmstatelow), 4);
  66. regdata &= (SBTML_RESET | SBTML_REJ_MASK |
  67. (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
  68. return ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) == regdata);
  69. }
  70. void
  71. brcmf_sdio_chip_coredisable(struct brcmf_sdio_dev *sdiodev, u32 corebase)
  72. {
  73. u32 regdata;
  74. regdata = brcmf_sdcard_reg_read(sdiodev,
  75. CORE_SB(corebase, sbtmstatelow), 4);
  76. if (regdata & SBTML_RESET)
  77. return;
  78. regdata = brcmf_sdcard_reg_read(sdiodev,
  79. CORE_SB(corebase, sbtmstatelow), 4);
  80. if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
  81. /*
  82. * set target reject and spin until busy is clear
  83. * (preserve core-specific bits)
  84. */
  85. regdata = brcmf_sdcard_reg_read(sdiodev,
  86. CORE_SB(corebase, sbtmstatelow), 4);
  87. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
  88. 4, regdata | SBTML_REJ);
  89. regdata = brcmf_sdcard_reg_read(sdiodev,
  90. CORE_SB(corebase, sbtmstatelow), 4);
  91. udelay(1);
  92. SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
  93. CORE_SB(corebase, sbtmstatehigh), 4) &
  94. SBTMH_BUSY), 100000);
  95. regdata = brcmf_sdcard_reg_read(sdiodev,
  96. CORE_SB(corebase, sbtmstatehigh), 4);
  97. if (regdata & SBTMH_BUSY)
  98. brcmf_dbg(ERROR, "core state still busy\n");
  99. regdata = brcmf_sdcard_reg_read(sdiodev,
  100. CORE_SB(corebase, sbidlow), 4);
  101. if (regdata & SBIDL_INIT) {
  102. regdata = brcmf_sdcard_reg_read(sdiodev,
  103. CORE_SB(corebase, sbimstate), 4) |
  104. SBIM_RJ;
  105. brcmf_sdcard_reg_write(sdiodev,
  106. CORE_SB(corebase, sbimstate), 4,
  107. regdata);
  108. regdata = brcmf_sdcard_reg_read(sdiodev,
  109. CORE_SB(corebase, sbimstate), 4);
  110. udelay(1);
  111. SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
  112. CORE_SB(corebase, sbimstate), 4) &
  113. SBIM_BY), 100000);
  114. }
  115. /* set reset and reject while enabling the clocks */
  116. brcmf_sdcard_reg_write(sdiodev,
  117. CORE_SB(corebase, sbtmstatelow), 4,
  118. (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
  119. SBTML_REJ | SBTML_RESET));
  120. regdata = brcmf_sdcard_reg_read(sdiodev,
  121. CORE_SB(corebase, sbtmstatelow), 4);
  122. udelay(10);
  123. /* clear the initiator reject bit */
  124. regdata = brcmf_sdcard_reg_read(sdiodev,
  125. CORE_SB(corebase, sbidlow), 4);
  126. if (regdata & SBIDL_INIT) {
  127. regdata = brcmf_sdcard_reg_read(sdiodev,
  128. CORE_SB(corebase, sbimstate), 4) &
  129. ~SBIM_RJ;
  130. brcmf_sdcard_reg_write(sdiodev,
  131. CORE_SB(corebase, sbimstate), 4,
  132. regdata);
  133. }
  134. }
  135. /* leave reset and reject asserted */
  136. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
  137. (SBTML_REJ | SBTML_RESET));
  138. udelay(1);
  139. }
  140. void
  141. brcmf_sdio_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase)
  142. {
  143. u32 regdata;
  144. /*
  145. * Must do the disable sequence first to work for
  146. * arbitrary current core state.
  147. */
  148. brcmf_sdio_chip_coredisable(sdiodev, corebase);
  149. /*
  150. * Now do the initialization sequence.
  151. * set reset while enabling the clock and
  152. * forcing them on throughout the core
  153. */
  154. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
  155. ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
  156. SBTML_RESET);
  157. udelay(1);
  158. regdata = brcmf_sdcard_reg_read(sdiodev,
  159. CORE_SB(corebase, sbtmstatehigh), 4);
  160. if (regdata & SBTMH_SERR)
  161. brcmf_sdcard_reg_write(sdiodev,
  162. CORE_SB(corebase, sbtmstatehigh), 4, 0);
  163. regdata = brcmf_sdcard_reg_read(sdiodev,
  164. CORE_SB(corebase, sbimstate), 4);
  165. if (regdata & (SBIM_IBE | SBIM_TO))
  166. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4,
  167. regdata & ~(SBIM_IBE | SBIM_TO));
  168. /* clear reset and allow it to propagate throughout the core */
  169. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
  170. (SICF_FGC << SBTML_SICF_SHIFT) |
  171. (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
  172. udelay(1);
  173. /* leave clock enabled */
  174. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
  175. (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
  176. udelay(1);
  177. }
  178. static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
  179. struct chip_info *ci, u32 regs)
  180. {
  181. u32 regdata;
  182. /*
  183. * Get CC core rev
  184. * Chipid is assume to be at offset 0 from regs arg
  185. * For different chiptypes or old sdio hosts w/o chipcommon,
  186. * other ways of recognition should be added here.
  187. */
  188. ci->cccorebase = regs;
  189. regdata = brcmf_sdcard_reg_read(sdiodev,
  190. CORE_CC_REG(ci->cccorebase, chipid), 4);
  191. ci->chip = regdata & CID_ID_MASK;
  192. ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  193. brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
  194. /* Address of cores for new chips should be added here */
  195. switch (ci->chip) {
  196. case BCM4329_CHIP_ID:
  197. ci->buscorebase = BCM4329_CORE_BUS_BASE;
  198. ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE;
  199. ci->armcorebase = BCM4329_CORE_ARM_BASE;
  200. ci->ramsize = BCM4329_RAMSIZE;
  201. break;
  202. default:
  203. brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
  204. return -ENODEV;
  205. }
  206. return 0;
  207. }
  208. static int
  209. brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
  210. {
  211. int err = 0;
  212. u8 clkval, clkset;
  213. /* Try forcing SDIO core to do ALPAvail request only */
  214. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  215. brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
  216. SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  217. if (err) {
  218. brcmf_dbg(ERROR, "error writing for HT off\n");
  219. return err;
  220. }
  221. /* If register supported, wait for ALPAvail and then force ALP */
  222. /* This may take up to 15 milliseconds */
  223. clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
  224. SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  225. if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  226. brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  227. clkset, clkval);
  228. return -EACCES;
  229. }
  230. SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
  231. SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  232. !SBSDIO_ALPAV(clkval)),
  233. PMU_MAX_TRANSITION_DLY);
  234. if (!SBSDIO_ALPAV(clkval)) {
  235. brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
  236. clkval);
  237. return -EBUSY;
  238. }
  239. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  240. brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
  241. SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  242. udelay(65);
  243. /* Also, disable the extra SDIO pull-ups */
  244. brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
  245. SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  246. return 0;
  247. }
  248. static void
  249. brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
  250. struct chip_info *ci)
  251. {
  252. u32 regdata;
  253. /* get chipcommon rev */
  254. ci->ccrev = brcmf_sdio_chip_corerev(sdiodev, ci->cccorebase);
  255. /* get chipcommon capabilites */
  256. ci->cccaps = brcmf_sdcard_reg_read(sdiodev,
  257. CORE_CC_REG(ci->cccorebase, capabilities), 4);
  258. /* get pmu caps & rev */
  259. if (ci->cccaps & CC_CAP_PMU) {
  260. ci->pmucaps = brcmf_sdcard_reg_read(sdiodev,
  261. CORE_CC_REG(ci->cccorebase, pmucapabilities), 4);
  262. ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
  263. }
  264. ci->buscorerev = brcmf_sdio_chip_corerev(sdiodev, ci->buscorebase);
  265. regdata = brcmf_sdcard_reg_read(sdiodev,
  266. CORE_SB(ci->buscorebase, sbidhigh), 4);
  267. ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
  268. brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
  269. ci->ccrev, ci->pmurev, ci->buscorerev, ci->buscoretype);
  270. /*
  271. * Make sure any on-chip ARM is off (in case strapping is wrong),
  272. * or downloaded code was already running.
  273. */
  274. brcmf_sdio_chip_coredisable(sdiodev, ci->armcorebase);
  275. }
  276. int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  277. struct chip_info **ci_ptr, u32 regs)
  278. {
  279. int ret;
  280. struct chip_info *ci;
  281. brcmf_dbg(TRACE, "Enter\n");
  282. /* alloc chip_info_t */
  283. ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
  284. if (!ci)
  285. return -ENOMEM;
  286. ret = brcmf_sdio_chip_buscoreprep(sdiodev);
  287. if (ret != 0)
  288. goto err;
  289. ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
  290. if (ret != 0)
  291. goto err;
  292. brcmf_sdio_chip_buscoresetup(sdiodev, ci);
  293. brcmf_sdcard_reg_write(sdiodev,
  294. CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0);
  295. brcmf_sdcard_reg_write(sdiodev,
  296. CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0);
  297. *ci_ptr = ci;
  298. return 0;
  299. err:
  300. kfree(ci);
  301. return ret;
  302. }