sdio_chip.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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 <linux/ssb/ssb_regs.h>
  21. #include <linux/bcma/bcma.h>
  22. #include <chipcommon.h>
  23. #include <brcm_hw_ids.h>
  24. #include <brcmu_wifi.h>
  25. #include <brcmu_utils.h>
  26. #include <soc.h>
  27. #include "dhd.h"
  28. #include "dhd_dbg.h"
  29. #include "sdio_host.h"
  30. #include "sdio_chip.h"
  31. /* chip core base & ramsize */
  32. /* bcm4329 */
  33. /* SDIO device core, ID 0x829 */
  34. #define BCM4329_CORE_BUS_BASE 0x18011000
  35. /* internal memory core, ID 0x80e */
  36. #define BCM4329_CORE_SOCRAM_BASE 0x18003000
  37. /* ARM Cortex M3 core, ID 0x82a */
  38. #define BCM4329_CORE_ARM_BASE 0x18002000
  39. #define BCM4329_RAMSIZE 0x48000
  40. #define SBCOREREV(sbidh) \
  41. ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
  42. ((sbidh) & SSB_IDHIGH_RCLO))
  43. #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
  44. /* SDIO Pad drive strength to select value mappings */
  45. struct sdiod_drive_str {
  46. u8 strength; /* Pad Drive Strength in mA */
  47. u8 sel; /* Chip-specific select value */
  48. };
  49. /* SDIO Drive Strength to sel value table for PMU Rev 1 */
  50. static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
  51. {
  52. 4, 0x2}, {
  53. 2, 0x3}, {
  54. 1, 0x0}, {
  55. 0, 0x0}
  56. };
  57. /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
  58. static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
  59. {
  60. 12, 0x7}, {
  61. 10, 0x6}, {
  62. 8, 0x5}, {
  63. 6, 0x4}, {
  64. 4, 0x2}, {
  65. 2, 0x1}, {
  66. 0, 0x0}
  67. };
  68. /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
  69. static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
  70. {
  71. 32, 0x7}, {
  72. 26, 0x6}, {
  73. 22, 0x5}, {
  74. 16, 0x4}, {
  75. 12, 0x3}, {
  76. 8, 0x2}, {
  77. 4, 0x1}, {
  78. 0, 0x0}
  79. };
  80. u8
  81. brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
  82. {
  83. u8 idx;
  84. for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
  85. if (coreid == ci->c_inf[idx].id)
  86. return idx;
  87. return BRCMF_MAX_CORENUM;
  88. }
  89. static u32
  90. brcmf_sdio_chip_corerev(struct brcmf_sdio_dev *sdiodev,
  91. u32 corebase)
  92. {
  93. u32 regdata;
  94. regdata = brcmf_sdcard_reg_read(sdiodev,
  95. CORE_SB(corebase, sbidhigh), 4);
  96. return SBCOREREV(regdata);
  97. }
  98. bool
  99. brcmf_sdio_chip_iscoreup(struct brcmf_sdio_dev *sdiodev,
  100. u32 corebase)
  101. {
  102. u32 regdata;
  103. regdata = brcmf_sdcard_reg_read(sdiodev,
  104. CORE_SB(corebase, sbtmstatelow), 4);
  105. regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
  106. SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
  107. return (SSB_TMSLOW_CLOCK == regdata);
  108. }
  109. void
  110. brcmf_sdio_chip_coredisable(struct brcmf_sdio_dev *sdiodev, u32 corebase)
  111. {
  112. u32 regdata;
  113. regdata = brcmf_sdcard_reg_read(sdiodev,
  114. CORE_SB(corebase, sbtmstatelow), 4);
  115. if (regdata & SSB_TMSLOW_RESET)
  116. return;
  117. regdata = brcmf_sdcard_reg_read(sdiodev,
  118. CORE_SB(corebase, sbtmstatelow), 4);
  119. if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
  120. /*
  121. * set target reject and spin until busy is clear
  122. * (preserve core-specific bits)
  123. */
  124. regdata = brcmf_sdcard_reg_read(sdiodev,
  125. CORE_SB(corebase, sbtmstatelow), 4);
  126. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
  127. 4, regdata | SSB_TMSLOW_REJECT);
  128. regdata = brcmf_sdcard_reg_read(sdiodev,
  129. CORE_SB(corebase, sbtmstatelow), 4);
  130. udelay(1);
  131. SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
  132. CORE_SB(corebase, sbtmstatehigh), 4) &
  133. SSB_TMSHIGH_BUSY), 100000);
  134. regdata = brcmf_sdcard_reg_read(sdiodev,
  135. CORE_SB(corebase, sbtmstatehigh), 4);
  136. if (regdata & SSB_TMSHIGH_BUSY)
  137. brcmf_dbg(ERROR, "core state still busy\n");
  138. regdata = brcmf_sdcard_reg_read(sdiodev,
  139. CORE_SB(corebase, sbidlow), 4);
  140. if (regdata & SSB_IDLOW_INITIATOR) {
  141. regdata = brcmf_sdcard_reg_read(sdiodev,
  142. CORE_SB(corebase, sbimstate), 4) |
  143. SSB_IMSTATE_REJECT;
  144. brcmf_sdcard_reg_write(sdiodev,
  145. CORE_SB(corebase, sbimstate), 4,
  146. regdata);
  147. regdata = brcmf_sdcard_reg_read(sdiodev,
  148. CORE_SB(corebase, sbimstate), 4);
  149. udelay(1);
  150. SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
  151. CORE_SB(corebase, sbimstate), 4) &
  152. SSB_IMSTATE_BUSY), 100000);
  153. }
  154. /* set reset and reject while enabling the clocks */
  155. brcmf_sdcard_reg_write(sdiodev,
  156. CORE_SB(corebase, sbtmstatelow), 4,
  157. (SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  158. SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
  159. regdata = brcmf_sdcard_reg_read(sdiodev,
  160. CORE_SB(corebase, sbtmstatelow), 4);
  161. udelay(10);
  162. /* clear the initiator reject bit */
  163. regdata = brcmf_sdcard_reg_read(sdiodev,
  164. CORE_SB(corebase, sbidlow), 4);
  165. if (regdata & SSB_IDLOW_INITIATOR) {
  166. regdata = brcmf_sdcard_reg_read(sdiodev,
  167. CORE_SB(corebase, sbimstate), 4) &
  168. ~SSB_IMSTATE_REJECT;
  169. brcmf_sdcard_reg_write(sdiodev,
  170. CORE_SB(corebase, sbimstate), 4,
  171. regdata);
  172. }
  173. }
  174. /* leave reset and reject asserted */
  175. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
  176. (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
  177. udelay(1);
  178. }
  179. void
  180. brcmf_sdio_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase)
  181. {
  182. u32 regdata;
  183. /*
  184. * Must do the disable sequence first to work for
  185. * arbitrary current core state.
  186. */
  187. brcmf_sdio_chip_coredisable(sdiodev, corebase);
  188. /*
  189. * Now do the initialization sequence.
  190. * set reset while enabling the clock and
  191. * forcing them on throughout the core
  192. */
  193. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
  194. SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET);
  195. udelay(1);
  196. regdata = brcmf_sdcard_reg_read(sdiodev,
  197. CORE_SB(corebase, sbtmstatehigh), 4);
  198. if (regdata & SSB_TMSHIGH_SERR)
  199. brcmf_sdcard_reg_write(sdiodev,
  200. CORE_SB(corebase, sbtmstatehigh), 4, 0);
  201. regdata = brcmf_sdcard_reg_read(sdiodev,
  202. CORE_SB(corebase, sbimstate), 4);
  203. if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
  204. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4,
  205. regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO));
  206. /* clear reset and allow it to propagate throughout the core */
  207. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
  208. SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
  209. udelay(1);
  210. /* leave clock enabled */
  211. brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
  212. 4, SSB_TMSLOW_CLOCK);
  213. udelay(1);
  214. }
  215. static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
  216. struct chip_info *ci, u32 regs)
  217. {
  218. u32 regdata;
  219. /*
  220. * Get CC core rev
  221. * Chipid is assume to be at offset 0 from regs arg
  222. * For different chiptypes or old sdio hosts w/o chipcommon,
  223. * other ways of recognition should be added here.
  224. */
  225. ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
  226. ci->c_inf[0].base = regs;
  227. regdata = brcmf_sdcard_reg_read(sdiodev,
  228. CORE_CC_REG(ci->c_inf[0].base, chipid), 4);
  229. ci->chip = regdata & CID_ID_MASK;
  230. ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  231. brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
  232. /* Address of cores for new chips should be added here */
  233. switch (ci->chip) {
  234. case BCM4329_CHIP_ID:
  235. ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  236. ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
  237. ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  238. ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
  239. ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  240. ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
  241. ci->ramsize = BCM4329_RAMSIZE;
  242. break;
  243. default:
  244. brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
  245. return -ENODEV;
  246. }
  247. return 0;
  248. }
  249. static int
  250. brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
  251. {
  252. int err = 0;
  253. u8 clkval, clkset;
  254. /* Try forcing SDIO core to do ALPAvail request only */
  255. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  256. brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
  257. SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  258. if (err) {
  259. brcmf_dbg(ERROR, "error writing for HT off\n");
  260. return err;
  261. }
  262. /* If register supported, wait for ALPAvail and then force ALP */
  263. /* This may take up to 15 milliseconds */
  264. clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
  265. SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  266. if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  267. brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  268. clkset, clkval);
  269. return -EACCES;
  270. }
  271. SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
  272. SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  273. !SBSDIO_ALPAV(clkval)),
  274. PMU_MAX_TRANSITION_DLY);
  275. if (!SBSDIO_ALPAV(clkval)) {
  276. brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
  277. clkval);
  278. return -EBUSY;
  279. }
  280. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  281. brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
  282. SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  283. udelay(65);
  284. /* Also, disable the extra SDIO pull-ups */
  285. brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
  286. SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  287. return 0;
  288. }
  289. static void
  290. brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
  291. struct chip_info *ci)
  292. {
  293. u32 regdata;
  294. u8 idx;
  295. /* get chipcommon rev */
  296. ci->c_inf[0].rev =
  297. brcmf_sdio_chip_corerev(sdiodev, ci->c_inf[0].base);
  298. /* get chipcommon capabilites */
  299. ci->c_inf[0].caps =
  300. brcmf_sdcard_reg_read(sdiodev,
  301. CORE_CC_REG(ci->c_inf[0].base, capabilities), 4);
  302. /* get pmu caps & rev */
  303. if (ci->c_inf[0].caps & CC_CAP_PMU) {
  304. ci->pmucaps = brcmf_sdcard_reg_read(sdiodev,
  305. CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4);
  306. ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
  307. }
  308. ci->c_inf[1].rev = brcmf_sdio_chip_corerev(sdiodev, ci->c_inf[1].base);
  309. regdata = brcmf_sdcard_reg_read(sdiodev,
  310. CORE_SB(ci->c_inf[1].base, sbidhigh), 4);
  311. ci->c_inf[1].id = (regdata & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
  312. brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
  313. ci->c_inf[0].rev, ci->pmurev,
  314. ci->c_inf[1].rev, ci->c_inf[1].id);
  315. /*
  316. * Make sure any on-chip ARM is off (in case strapping is wrong),
  317. * or downloaded code was already running.
  318. */
  319. idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  320. brcmf_sdio_chip_coredisable(sdiodev, ci->c_inf[idx].base);
  321. }
  322. int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  323. struct chip_info **ci_ptr, u32 regs)
  324. {
  325. int ret;
  326. struct chip_info *ci;
  327. brcmf_dbg(TRACE, "Enter\n");
  328. /* alloc chip_info_t */
  329. ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
  330. if (!ci)
  331. return -ENOMEM;
  332. ret = brcmf_sdio_chip_buscoreprep(sdiodev);
  333. if (ret != 0)
  334. goto err;
  335. ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
  336. if (ret != 0)
  337. goto err;
  338. brcmf_sdio_chip_buscoresetup(sdiodev, ci);
  339. brcmf_sdcard_reg_write(sdiodev,
  340. CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0);
  341. brcmf_sdcard_reg_write(sdiodev,
  342. CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0);
  343. *ci_ptr = ci;
  344. return 0;
  345. err:
  346. kfree(ci);
  347. return ret;
  348. }
  349. void
  350. brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
  351. {
  352. brcmf_dbg(TRACE, "Enter\n");
  353. kfree(*ci_ptr);
  354. *ci_ptr = NULL;
  355. }
  356. static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
  357. {
  358. const char *fmt;
  359. fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
  360. snprintf(buf, len, fmt, chipid);
  361. return buf;
  362. }
  363. void
  364. brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  365. struct chip_info *ci, u32 drivestrength)
  366. {
  367. struct sdiod_drive_str *str_tab = NULL;
  368. u32 str_mask = 0;
  369. u32 str_shift = 0;
  370. char chn[8];
  371. if (!(ci->c_inf[0].caps & CC_CAP_PMU))
  372. return;
  373. switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
  374. case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
  375. str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
  376. str_mask = 0x30000000;
  377. str_shift = 28;
  378. break;
  379. case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
  380. case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
  381. str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
  382. str_mask = 0x00003800;
  383. str_shift = 11;
  384. break;
  385. case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
  386. str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
  387. str_mask = 0x00003800;
  388. str_shift = 11;
  389. break;
  390. default:
  391. brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
  392. brcmf_sdio_chip_name(ci->chip, chn, 8),
  393. ci->chiprev, ci->pmurev);
  394. break;
  395. }
  396. if (str_tab != NULL) {
  397. u32 drivestrength_sel = 0;
  398. u32 cc_data_temp;
  399. int i;
  400. for (i = 0; str_tab[i].strength != 0; i++) {
  401. if (drivestrength >= str_tab[i].strength) {
  402. drivestrength_sel = str_tab[i].sel;
  403. break;
  404. }
  405. }
  406. brcmf_sdcard_reg_write(sdiodev,
  407. CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
  408. 4, 1);
  409. cc_data_temp = brcmf_sdcard_reg_read(sdiodev,
  410. CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4);
  411. cc_data_temp &= ~str_mask;
  412. drivestrength_sel <<= str_shift;
  413. cc_data_temp |= drivestrength_sel;
  414. brcmf_sdcard_reg_write(sdiodev,
  415. CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
  416. 4, cc_data_temp);
  417. brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
  418. drivestrength, cc_data_temp);
  419. }
  420. }