bcmspibrcm.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801
  1. /*
  2. * Broadcom BCMSDH to gSPI Protocol Conversion Layer
  3. *
  4. * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
  5. *
  6. * Copyright (C) 1999-2020, Broadcom Corporation
  7. *
  8. * Unless you and Broadcom execute a separate written software license
  9. * agreement governing use of this software, this software is licensed to you
  10. * under the terms of the GNU General Public License version 2 (the "GPL"),
  11. * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  12. * following added to such license:
  13. *
  14. * As a special exception, the copyright holders of this software give you
  15. * permission to link this software with independent modules, and to copy and
  16. * distribute the resulting executable under terms of your choice, provided that
  17. * you also meet, for each linked independent module, the terms and conditions of
  18. * the license of that module. An independent module is a module which is not
  19. * derived from this software. The special exception does not apply to any
  20. * modifications of the software.
  21. *
  22. * Notwithstanding the above, under no circumstances may you combine this
  23. * software in any way with any other Broadcom software provided under a license
  24. * other than the GPL, without Broadcom's express prior written consent.
  25. *
  26. *
  27. * <<Broadcom-WL-IPTag/Open:>>
  28. *
  29. * $Id: bcmspibrcm.c 700323 2017-05-18 16:12:11Z $
  30. */
  31. #define HSMODE
  32. #include <typedefs.h>
  33. #include <bcmdevs.h>
  34. #include <bcmendian.h>
  35. #include <bcmutils.h>
  36. #include <osl.h>
  37. #include <hndsoc.h>
  38. #include <siutils.h>
  39. #include <sbchipc.h>
  40. #include <sbsdio.h> /* SDIO device core hardware definitions. */
  41. #include <spid.h>
  42. #include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
  43. #include <sdiovar.h> /* ioctl/iovars */
  44. #include <sdio.h> /* SDIO Device and Protocol Specs */
  45. #include <pcicfg.h>
  46. #include <bcmspibrcm.h>
  47. #ifdef BCMSPI_ANDROID
  48. extern void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen);
  49. #else
  50. #include <bcmspi.h>
  51. #endif /* BCMSPI_ANDROID */
  52. /* these are for the older cores... for newer cores we have control for each of them */
  53. #define F0_RESPONSE_DELAY 16
  54. #define F1_RESPONSE_DELAY 16
  55. #define F2_RESPONSE_DELAY F0_RESPONSE_DELAY
  56. #define GSPI_F0_RESP_DELAY 0
  57. #define GSPI_F1_RESP_DELAY F1_RESPONSE_DELAY
  58. #define GSPI_F2_RESP_DELAY 0
  59. #define GSPI_F3_RESP_DELAY 0
  60. #define CMDLEN 4
  61. /* Globals */
  62. #if defined(DHD_DEBUG)
  63. uint sd_msglevel = SDH_ERROR_VAL;
  64. #else
  65. uint sd_msglevel = 0;
  66. #endif // endif
  67. uint sd_hiok = FALSE; /* Use hi-speed mode if available? */
  68. uint sd_sdmode = SDIOH_MODE_SPI; /* Use SD4 mode by default */
  69. uint sd_f2_blocksize = 64; /* Default blocksize */
  70. uint sd_divisor = 2;
  71. uint sd_power = 1; /* Default to SD Slot powered ON */
  72. uint sd_clock = 1; /* Default to SD Clock turned ON */
  73. uint sd_crc = 0; /* Default to SPI CRC Check turned OFF */
  74. uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */
  75. uint8 spi_outbuf[SPI_MAX_PKT_LEN];
  76. uint8 spi_inbuf[SPI_MAX_PKT_LEN];
  77. /* 128bytes buffer is enough to clear data-not-available and program response-delay F0 bits
  78. * assuming we will not exceed F0 response delay > 100 bytes at 48MHz.
  79. */
  80. #define BUF2_PKT_LEN 128
  81. uint8 spi_outbuf2[BUF2_PKT_LEN];
  82. uint8 spi_inbuf2[BUF2_PKT_LEN];
  83. #ifdef BCMSPI_ANDROID
  84. uint *dhd_spi_lockcount = NULL;
  85. #endif /* BCMSPI_ANDROID */
  86. #if !(defined(SPI_PIO_RW_BIGENDIAN) && defined(SPI_PIO_32BIT_RW))
  87. #define SPISWAP_WD4(x) bcmswap32(x);
  88. #define SPISWAP_WD2(x) (bcmswap16(x & 0xffff)) | \
  89. (bcmswap16((x & 0xffff0000) >> 16) << 16);
  90. #else
  91. #define SPISWAP_WD4(x) x;
  92. #define SPISWAP_WD2(x) bcmswap32by16(x);
  93. #endif // endif
  94. /* Prototypes */
  95. static bool bcmspi_test_card(sdioh_info_t *sd);
  96. static bool bcmspi_host_device_init_adapt(sdioh_info_t *sd);
  97. static int bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode);
  98. static int bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg,
  99. uint32 *data, uint32 datalen);
  100. static int bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr,
  101. int regsize, uint32 *data);
  102. static int bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr,
  103. int regsize, uint32 data);
  104. static int bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr,
  105. uint8 *data);
  106. static int bcmspi_driver_init(sdioh_info_t *sd);
  107. static int bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo,
  108. uint32 addr, int nbytes, uint32 *data);
  109. static int bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize,
  110. uint32 *data);
  111. static void bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer);
  112. static int bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg);
  113. /*
  114. * Public entry points & extern's
  115. */
  116. extern sdioh_info_t *
  117. sdioh_attach(osl_t *osh, void *bar0, uint irq)
  118. {
  119. sdioh_info_t *sd;
  120. sd_trace(("%s\n", __FUNCTION__));
  121. if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) {
  122. sd_err(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh)));
  123. return NULL;
  124. }
  125. bzero((char *)sd, sizeof(sdioh_info_t));
  126. sd->osh = osh;
  127. if (spi_osinit(sd) != 0) {
  128. sd_err(("%s: spi_osinit() failed\n", __FUNCTION__));
  129. MFREE(sd->osh, sd, sizeof(sdioh_info_t));
  130. return NULL;
  131. }
  132. #ifndef BCMSPI_ANDROID
  133. sd->bar0 = bar0;
  134. #endif /* !BCMSPI_ANDROID */
  135. sd->irq = irq;
  136. #ifndef BCMSPI_ANDROID
  137. sd->intr_handler = NULL;
  138. sd->intr_handler_arg = NULL;
  139. sd->intr_handler_valid = FALSE;
  140. #endif /* !BCMSPI_ANDROID */
  141. /* Set defaults */
  142. sd->use_client_ints = TRUE;
  143. sd->sd_use_dma = FALSE; /* DMA Not supported */
  144. /* Spi device default is 16bit mode, change to 4 when device is changed to 32bit
  145. * mode
  146. */
  147. sd->wordlen = 2;
  148. #ifdef BCMSPI_ANDROID
  149. dhd_spi_lockcount = &sd->lockcount;
  150. #endif /* BCMSPI_ANDROID */
  151. #ifndef BCMSPI_ANDROID
  152. if (!spi_hw_attach(sd)) {
  153. sd_err(("%s: spi_hw_attach() failed\n", __FUNCTION__));
  154. spi_osfree(sd);
  155. MFREE(sd->osh, sd, sizeof(sdioh_info_t));
  156. return (NULL);
  157. }
  158. #endif /* !BCMSPI_ANDROID */
  159. if (bcmspi_driver_init(sd) != SUCCESS) {
  160. sd_err(("%s: bcmspi_driver_init() failed()\n", __FUNCTION__));
  161. #ifndef BCMSPI_ANDROID
  162. spi_hw_detach(sd);
  163. #endif /* !BCMSPI_ANDROID */
  164. spi_osfree(sd);
  165. MFREE(sd->osh, sd, sizeof(sdioh_info_t));
  166. return (NULL);
  167. }
  168. if (spi_register_irq(sd, irq) != SUCCESS) {
  169. sd_err(("%s: spi_register_irq() failed for irq = %d\n", __FUNCTION__, irq));
  170. #ifndef BCMSPI_ANDROID
  171. spi_hw_detach(sd);
  172. #endif /* !BCMSPI_ANDROID */
  173. spi_osfree(sd);
  174. MFREE(sd->osh, sd, sizeof(sdioh_info_t));
  175. return (NULL);
  176. }
  177. sd_trace(("%s: Done\n", __FUNCTION__));
  178. return sd;
  179. }
  180. extern SDIOH_API_RC
  181. sdioh_detach(osl_t *osh, sdioh_info_t *sd)
  182. {
  183. sd_trace(("%s\n", __FUNCTION__));
  184. if (sd) {
  185. sd_err(("%s: detaching from hardware\n", __FUNCTION__));
  186. spi_free_irq(sd->irq, sd);
  187. #ifndef BCMSPI_ANDROID
  188. spi_hw_detach(sd);
  189. #endif /* !BCMSPI_ANDROID */
  190. spi_osfree(sd);
  191. #ifdef BCMSPI_ANDROID
  192. dhd_spi_lockcount = NULL;
  193. #endif /* !BCMSPI_ANDROID */
  194. MFREE(sd->osh, sd, sizeof(sdioh_info_t));
  195. }
  196. return SDIOH_API_RC_SUCCESS;
  197. }
  198. /* Configure callback to client when we recieve client interrupt */
  199. extern SDIOH_API_RC
  200. sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
  201. {
  202. sd_trace(("%s: Entering\n", __FUNCTION__));
  203. #if !defined(OOB_INTR_ONLY)
  204. sd->intr_handler = fn;
  205. sd->intr_handler_arg = argh;
  206. sd->intr_handler_valid = TRUE;
  207. #endif /* !defined(OOB_INTR_ONLY) */
  208. return SDIOH_API_RC_SUCCESS;
  209. }
  210. extern SDIOH_API_RC
  211. sdioh_interrupt_deregister(sdioh_info_t *sd)
  212. {
  213. sd_trace(("%s: Entering\n", __FUNCTION__));
  214. #if !defined(OOB_INTR_ONLY)
  215. sd->intr_handler_valid = FALSE;
  216. sd->intr_handler = NULL;
  217. sd->intr_handler_arg = NULL;
  218. #endif /* !defined(OOB_INTR_ONLY) */
  219. return SDIOH_API_RC_SUCCESS;
  220. }
  221. extern SDIOH_API_RC
  222. sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
  223. {
  224. #ifndef BCMSPI_ANDROID
  225. sd_trace(("%s: Entering\n", __FUNCTION__));
  226. *onoff = sd->client_intr_enabled;
  227. #endif /* !BCMSPI_ANDROID */
  228. return SDIOH_API_RC_SUCCESS;
  229. }
  230. #if defined(DHD_DEBUG)
  231. extern bool
  232. sdioh_interrupt_pending(sdioh_info_t *sd)
  233. {
  234. return 0;
  235. }
  236. #endif // endif
  237. /* Provide dstatus bits of spi-transaction for dhd layers. */
  238. extern uint32
  239. sdioh_get_dstatus(sdioh_info_t *sd)
  240. {
  241. return sd->card_dstatus;
  242. }
  243. extern void
  244. sdioh_chipinfo(sdioh_info_t *sd, uint32 chip, uint32 chiprev)
  245. {
  246. sd->chip = chip;
  247. sd->chiprev = chiprev;
  248. }
  249. extern void
  250. sdioh_dwordmode(sdioh_info_t *sd, bool set)
  251. {
  252. uint8 reg = 0;
  253. int status;
  254. if ((status = sdioh_request_byte(sd, SDIOH_READ, SPI_FUNC_0, SPID_STATUS_ENABLE, &reg)) !=
  255. SUCCESS) {
  256. sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__));
  257. return;
  258. }
  259. if (set) {
  260. reg |= DWORD_PKT_LEN_EN;
  261. sd->dwordmode = TRUE;
  262. sd->client_block_size[SPI_FUNC_2] = 4096; /* h2spi's limit is 4KB, we support 8KB */
  263. } else {
  264. reg &= ~DWORD_PKT_LEN_EN;
  265. sd->dwordmode = FALSE;
  266. sd->client_block_size[SPI_FUNC_2] = 2048;
  267. }
  268. if ((status = sdioh_request_byte(sd, SDIOH_WRITE, SPI_FUNC_0, SPID_STATUS_ENABLE, &reg)) !=
  269. SUCCESS) {
  270. sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__));
  271. return;
  272. }
  273. }
  274. uint
  275. sdioh_query_iofnum(sdioh_info_t *sd)
  276. {
  277. return sd->num_funcs;
  278. }
  279. /* IOVar table */
  280. enum {
  281. IOV_MSGLEVEL = 1,
  282. IOV_BLOCKMODE,
  283. IOV_BLOCKSIZE,
  284. IOV_DMA,
  285. IOV_USEINTS,
  286. IOV_NUMINTS,
  287. IOV_NUMLOCALINTS,
  288. IOV_HOSTREG,
  289. IOV_DEVREG,
  290. IOV_DIVISOR,
  291. IOV_SDMODE,
  292. IOV_HISPEED,
  293. IOV_HCIREGS,
  294. IOV_POWER,
  295. IOV_CLOCK,
  296. IOV_SPIERRSTATS,
  297. IOV_RESP_DELAY_ALL
  298. };
  299. const bcm_iovar_t sdioh_iovars[] = {
  300. {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 },
  301. {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */
  302. {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 },
  303. {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 },
  304. {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 },
  305. {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 },
  306. {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
  307. {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
  308. {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 },
  309. {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 },
  310. {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 },
  311. {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100},
  312. {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0},
  313. {"spi_errstats", IOV_SPIERRSTATS, 0, IOVT_BUFFER, sizeof(struct spierrstats_t) },
  314. {"spi_respdelay", IOV_RESP_DELAY_ALL, 0, IOVT_BOOL, 0 },
  315. {NULL, 0, 0, 0, 0 }
  316. };
  317. int
  318. sdioh_iovar_op(sdioh_info_t *si, const char *name,
  319. void *params, int plen, void *arg, int len, bool set)
  320. {
  321. const bcm_iovar_t *vi = NULL;
  322. int bcmerror = 0;
  323. int val_size;
  324. int32 int_val = 0;
  325. bool bool_val;
  326. uint32 actionid;
  327. /*
  328. sdioh_regs_t *regs;
  329. */
  330. ASSERT(name);
  331. ASSERT(len >= 0);
  332. /* Get must have return space; Set does not take qualifiers */
  333. ASSERT(set || (arg && len));
  334. ASSERT(!set || (!params && !plen));
  335. sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name));
  336. if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) {
  337. bcmerror = BCME_UNSUPPORTED;
  338. goto exit;
  339. }
  340. if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0)
  341. goto exit;
  342. /* Set up params so get and set can share the convenience variables */
  343. if (params == NULL) {
  344. params = arg;
  345. plen = len;
  346. }
  347. if (vi->type == IOVT_VOID)
  348. val_size = 0;
  349. else if (vi->type == IOVT_BUFFER)
  350. val_size = len;
  351. else
  352. val_size = sizeof(int);
  353. if (plen >= (int)sizeof(int_val))
  354. bcopy(params, &int_val, sizeof(int_val));
  355. bool_val = (int_val != 0) ? TRUE : FALSE;
  356. actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
  357. switch (actionid) {
  358. case IOV_GVAL(IOV_MSGLEVEL):
  359. int_val = (int32)sd_msglevel;
  360. bcopy(&int_val, arg, val_size);
  361. break;
  362. case IOV_SVAL(IOV_MSGLEVEL):
  363. sd_msglevel = int_val;
  364. break;
  365. case IOV_GVAL(IOV_BLOCKSIZE):
  366. if ((uint32)int_val > si->num_funcs) {
  367. bcmerror = BCME_BADARG;
  368. break;
  369. }
  370. int_val = (int32)si->client_block_size[int_val];
  371. bcopy(&int_val, arg, val_size);
  372. break;
  373. case IOV_GVAL(IOV_DMA):
  374. int_val = (int32)si->sd_use_dma;
  375. bcopy(&int_val, arg, val_size);
  376. break;
  377. case IOV_SVAL(IOV_DMA):
  378. si->sd_use_dma = (bool)int_val;
  379. break;
  380. case IOV_GVAL(IOV_USEINTS):
  381. int_val = (int32)si->use_client_ints;
  382. bcopy(&int_val, arg, val_size);
  383. break;
  384. case IOV_SVAL(IOV_USEINTS):
  385. break;
  386. case IOV_GVAL(IOV_DIVISOR):
  387. int_val = (uint32)sd_divisor;
  388. bcopy(&int_val, arg, val_size);
  389. break;
  390. #ifndef BCMSPI_ANDROID
  391. case IOV_SVAL(IOV_DIVISOR):
  392. sd_divisor = int_val;
  393. if (!spi_start_clock(si, (uint16)sd_divisor)) {
  394. sd_err(("%s: set clock failed\n", __FUNCTION__));
  395. bcmerror = BCME_ERROR;
  396. }
  397. break;
  398. #endif /* !BCMSPI_ANDROID */
  399. case IOV_GVAL(IOV_POWER):
  400. int_val = (uint32)sd_power;
  401. bcopy(&int_val, arg, val_size);
  402. break;
  403. case IOV_SVAL(IOV_POWER):
  404. sd_power = int_val;
  405. break;
  406. case IOV_GVAL(IOV_CLOCK):
  407. int_val = (uint32)sd_clock;
  408. bcopy(&int_val, arg, val_size);
  409. break;
  410. case IOV_SVAL(IOV_CLOCK):
  411. sd_clock = int_val;
  412. break;
  413. case IOV_GVAL(IOV_SDMODE):
  414. int_val = (uint32)sd_sdmode;
  415. bcopy(&int_val, arg, val_size);
  416. break;
  417. case IOV_SVAL(IOV_SDMODE):
  418. sd_sdmode = int_val;
  419. break;
  420. case IOV_GVAL(IOV_HISPEED):
  421. int_val = (uint32)sd_hiok;
  422. bcopy(&int_val, arg, val_size);
  423. break;
  424. case IOV_SVAL(IOV_HISPEED):
  425. sd_hiok = int_val;
  426. if (!bcmspi_set_highspeed_mode(si, (bool)sd_hiok)) {
  427. sd_err(("%s: Failed changing highspeed mode to %d.\n",
  428. __FUNCTION__, sd_hiok));
  429. bcmerror = BCME_ERROR;
  430. return ERROR;
  431. }
  432. break;
  433. case IOV_GVAL(IOV_NUMINTS):
  434. int_val = (int32)si->intrcount;
  435. bcopy(&int_val, arg, val_size);
  436. break;
  437. case IOV_GVAL(IOV_NUMLOCALINTS):
  438. int_val = (int32)si->local_intrcount;
  439. bcopy(&int_val, arg, val_size);
  440. break;
  441. case IOV_GVAL(IOV_DEVREG):
  442. {
  443. sdreg_t *sd_ptr = (sdreg_t *)params;
  444. uint8 data;
  445. if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
  446. bcmerror = BCME_SDIO_ERROR;
  447. break;
  448. }
  449. int_val = (int)data;
  450. bcopy(&int_val, arg, sizeof(int_val));
  451. break;
  452. }
  453. case IOV_SVAL(IOV_DEVREG):
  454. {
  455. sdreg_t *sd_ptr = (sdreg_t *)params;
  456. uint8 data = (uint8)sd_ptr->value;
  457. if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
  458. bcmerror = BCME_SDIO_ERROR;
  459. break;
  460. }
  461. break;
  462. }
  463. case IOV_GVAL(IOV_SPIERRSTATS):
  464. {
  465. bcopy(&si->spierrstats, arg, sizeof(struct spierrstats_t));
  466. break;
  467. }
  468. case IOV_SVAL(IOV_SPIERRSTATS):
  469. {
  470. bzero(&si->spierrstats, sizeof(struct spierrstats_t));
  471. break;
  472. }
  473. case IOV_GVAL(IOV_RESP_DELAY_ALL):
  474. int_val = (int32)si->resp_delay_all;
  475. bcopy(&int_val, arg, val_size);
  476. break;
  477. case IOV_SVAL(IOV_RESP_DELAY_ALL):
  478. si->resp_delay_all = (bool)int_val;
  479. int_val = STATUS_ENABLE|INTR_WITH_STATUS;
  480. if (si->resp_delay_all)
  481. int_val |= RESP_DELAY_ALL;
  482. else {
  483. if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_RESPONSE_DELAY, 1,
  484. F1_RESPONSE_DELAY) != SUCCESS) {
  485. sd_err(("%s: Unable to set response delay.\n", __FUNCTION__));
  486. bcmerror = BCME_SDIO_ERROR;
  487. break;
  488. }
  489. }
  490. if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_STATUS_ENABLE, 1, int_val)
  491. != SUCCESS) {
  492. sd_err(("%s: Unable to set response delay.\n", __FUNCTION__));
  493. bcmerror = BCME_SDIO_ERROR;
  494. break;
  495. }
  496. break;
  497. default:
  498. bcmerror = BCME_UNSUPPORTED;
  499. break;
  500. }
  501. exit:
  502. return bcmerror;
  503. }
  504. extern SDIOH_API_RC
  505. sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
  506. {
  507. SDIOH_API_RC status;
  508. /* No lock needed since sdioh_request_byte does locking */
  509. status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
  510. return status;
  511. }
  512. extern SDIOH_API_RC
  513. sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
  514. {
  515. /* No lock needed since sdioh_request_byte does locking */
  516. SDIOH_API_RC status;
  517. if ((fnc_num == SPI_FUNC_1) && (addr == SBSDIO_FUNC1_FRAMECTRL)) {
  518. uint8 dummy_data;
  519. status = sdioh_cfg_read(sd, fnc_num, addr, &dummy_data);
  520. if (status) {
  521. sd_err(("sdioh_cfg_read() failed.\n"));
  522. return status;
  523. }
  524. }
  525. status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
  526. return status;
  527. }
  528. extern SDIOH_API_RC
  529. sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
  530. {
  531. uint32 count;
  532. int offset;
  533. uint32 cis_byte;
  534. uint16 *cis = (uint16 *)cisd;
  535. uint bar0 = SI_ENUM_BASE(sd->sih);
  536. int status;
  537. uint8 data;
  538. sd_trace(("%s: Func %d\n", __FUNCTION__, func));
  539. spi_lock(sd);
  540. /* Set sb window address to 0x18000000 */
  541. data = (bar0 >> 8) & SBSDIO_SBADDRLOW_MASK;
  542. status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, &data);
  543. if (status == SUCCESS) {
  544. data = (bar0 >> 16) & SBSDIO_SBADDRMID_MASK;
  545. status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, &data);
  546. } else {
  547. sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__));
  548. spi_unlock(sd);
  549. return (BCME_ERROR);
  550. }
  551. if (status == SUCCESS) {
  552. data = (bar0 >> 24) & SBSDIO_SBADDRHIGH_MASK;
  553. status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, &data);
  554. } else {
  555. sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__));
  556. spi_unlock(sd);
  557. return (BCME_ERROR);
  558. }
  559. offset = CC_SROM_OTP; /* OTP offset in chipcommon. */
  560. for (count = 0; count < length/2; count++) {
  561. if (bcmspi_card_regread (sd, SDIO_FUNC_1, offset, 2, &cis_byte) < 0) {
  562. sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__));
  563. spi_unlock(sd);
  564. return (BCME_ERROR);
  565. }
  566. *cis = (uint16)cis_byte;
  567. cis++;
  568. offset += 2;
  569. }
  570. spi_unlock(sd);
  571. return (BCME_OK);
  572. }
  573. extern SDIOH_API_RC
  574. sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
  575. {
  576. int status;
  577. uint32 cmd_arg;
  578. uint32 dstatus;
  579. uint32 data = (uint32)(*byte);
  580. spi_lock(sd);
  581. cmd_arg = 0;
  582. cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
  583. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */
  584. cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
  585. cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, rw == SDIOH_READ ? 0 : 1);
  586. cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1);
  587. if (rw == SDIOH_READ) {
  588. sd_trace(("%s: RD cmd_arg=0x%x func=%d regaddr=0x%x\n",
  589. __FUNCTION__, cmd_arg, func, regaddr));
  590. } else {
  591. sd_trace(("%s: WR cmd_arg=0x%x func=%d regaddr=0x%x data=0x%x\n",
  592. __FUNCTION__, cmd_arg, func, regaddr, data));
  593. }
  594. if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, 1)) != SUCCESS) {
  595. spi_unlock(sd);
  596. return status;
  597. }
  598. if (rw == SDIOH_READ) {
  599. *byte = (uint8)data;
  600. sd_trace(("%s: RD result=0x%x\n", __FUNCTION__, *byte));
  601. }
  602. bcmspi_cmd_getdstatus(sd, &dstatus);
  603. if (dstatus)
  604. sd_trace(("dstatus=0x%x\n", dstatus));
  605. spi_unlock(sd);
  606. return SDIOH_API_RC_SUCCESS;
  607. }
  608. extern SDIOH_API_RC
  609. sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr,
  610. uint32 *word, uint nbytes)
  611. {
  612. int status;
  613. spi_lock(sd);
  614. if (rw == SDIOH_READ)
  615. status = bcmspi_card_regread(sd, func, addr, nbytes, word);
  616. else
  617. status = bcmspi_card_regwrite(sd, func, addr, nbytes, *word);
  618. spi_unlock(sd);
  619. return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
  620. }
  621. extern SDIOH_API_RC
  622. sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func,
  623. uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
  624. {
  625. int len;
  626. int buflen = (int)buflen_u;
  627. bool fifo = (fix_inc == SDIOH_DATA_FIX);
  628. spi_lock(sd);
  629. ASSERT(reg_width == 4);
  630. ASSERT(buflen_u < (1 << 30));
  631. ASSERT(sd->client_block_size[func]);
  632. sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n",
  633. __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W',
  634. buflen_u, sd->r_cnt, sd->t_cnt, pkt));
  635. /* Break buffer down into blocksize chunks. */
  636. while (buflen > 0) {
  637. len = MIN(sd->client_block_size[func], buflen);
  638. if (bcmspi_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) {
  639. sd_err(("%s: bcmspi_card_buf %s failed\n",
  640. __FUNCTION__, rw == SDIOH_READ ? "Read" : "Write"));
  641. spi_unlock(sd);
  642. return SDIOH_API_RC_FAIL;
  643. }
  644. buffer += len;
  645. buflen -= len;
  646. if (!fifo)
  647. addr += len;
  648. }
  649. spi_unlock(sd);
  650. return SDIOH_API_RC_SUCCESS;
  651. }
  652. /* This function allows write to gspi bus when another rd/wr function is deep down the call stack.
  653. * Its main aim is to have simpler spi writes rather than recursive writes.
  654. * e.g. When there is a need to program response delay on the fly after detecting the SPI-func
  655. * this call will allow to program the response delay.
  656. */
  657. static int
  658. bcmspi_card_byterewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 byte)
  659. {
  660. uint32 cmd_arg;
  661. uint32 datalen = 1;
  662. uint32 hostlen;
  663. cmd_arg = 0;
  664. cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1);
  665. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */
  666. cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
  667. cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
  668. cmd_arg = SFIELD(cmd_arg, SPI_LEN, datalen);
  669. sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
  670. /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen
  671. * according to the wordlen mode(16/32bit) the device is in.
  672. */
  673. ASSERT(sd->wordlen == 4 || sd->wordlen == 2);
  674. datalen = ROUNDUP(datalen, sd->wordlen);
  675. /* Start by copying command in the spi-outbuffer */
  676. if (sd->wordlen == 4) { /* 32bit spid */
  677. *(uint32 *)spi_outbuf2 = SPISWAP_WD4(cmd_arg);
  678. if (datalen & 0x3)
  679. datalen += (4 - (datalen & 0x3));
  680. } else if (sd->wordlen == 2) { /* 16bit spid */
  681. *(uint32 *)spi_outbuf2 = SPISWAP_WD2(cmd_arg);
  682. if (datalen & 0x1)
  683. datalen++;
  684. } else {
  685. sd_err(("%s: Host is %d bit spid, could not create SPI command.\n",
  686. __FUNCTION__, 8 * sd->wordlen));
  687. return ERROR;
  688. }
  689. /* for Write, put the data into the output buffer */
  690. if (datalen != 0) {
  691. if (sd->wordlen == 4) { /* 32bit spid */
  692. *(uint32 *)&spi_outbuf2[CMDLEN] = SPISWAP_WD4(byte);
  693. } else if (sd->wordlen == 2) { /* 16bit spid */
  694. *(uint32 *)&spi_outbuf2[CMDLEN] = SPISWAP_WD2(byte);
  695. }
  696. }
  697. /* +4 for cmd, +4 for dstatus */
  698. hostlen = datalen + 8;
  699. hostlen += (4 - (hostlen & 0x3));
  700. spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, hostlen);
  701. /* Last 4bytes are dstatus. Device is configured to return status bits. */
  702. if (sd->wordlen == 4) { /* 32bit spid */
  703. sd->card_dstatus = SPISWAP_WD4(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]);
  704. } else if (sd->wordlen == 2) { /* 16bit spid */
  705. sd->card_dstatus = SPISWAP_WD2(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]);
  706. } else {
  707. sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n",
  708. __FUNCTION__, 8 * sd->wordlen));
  709. return ERROR;
  710. }
  711. if (sd->card_dstatus)
  712. sd_trace(("dstatus after byte rewrite = 0x%x\n", sd->card_dstatus));
  713. return (BCME_OK);
  714. }
  715. /* Program the response delay corresponding to the spi function */
  716. static int
  717. bcmspi_prog_resp_delay(sdioh_info_t *sd, int func, uint8 resp_delay)
  718. {
  719. if (sd->resp_delay_all == FALSE)
  720. return (BCME_OK);
  721. if (sd->prev_fun == func)
  722. return (BCME_OK);
  723. if (F0_RESPONSE_DELAY == F1_RESPONSE_DELAY)
  724. return (BCME_OK);
  725. bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_RESPONSE_DELAY, resp_delay);
  726. /* Remember function for which to avoid reprogramming resp-delay in next iteration */
  727. sd->prev_fun = func;
  728. return (BCME_OK);
  729. }
  730. #define GSPI_RESYNC_PATTERN 0x0
  731. /* A resync pattern is a 32bit MOSI line with all zeros. Its a special command in gSPI.
  732. * It resets the spi-bkplane logic so that all F1 related ping-pong buffer logic is
  733. * synchronised and all queued resuests are cancelled.
  734. */
  735. static int
  736. bcmspi_resync_f1(sdioh_info_t *sd)
  737. {
  738. uint32 cmd_arg = GSPI_RESYNC_PATTERN, data = 0, datalen = 0;
  739. /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen
  740. * according to the wordlen mode(16/32bit) the device is in.
  741. */
  742. ASSERT(sd->wordlen == 4 || sd->wordlen == 2);
  743. datalen = ROUNDUP(datalen, sd->wordlen);
  744. /* Start by copying command in the spi-outbuffer */
  745. *(uint32 *)spi_outbuf2 = cmd_arg;
  746. /* for Write, put the data into the output buffer */
  747. *(uint32 *)&spi_outbuf2[CMDLEN] = data;
  748. /* +4 for cmd, +4 for dstatus */
  749. spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, datalen + 8);
  750. /* Last 4bytes are dstatus. Device is configured to return status bits. */
  751. if (sd->wordlen == 4) { /* 32bit spid */
  752. sd->card_dstatus = SPISWAP_WD4(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]);
  753. } else if (sd->wordlen == 2) { /* 16bit spid */
  754. sd->card_dstatus = SPISWAP_WD2(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]);
  755. } else {
  756. sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n",
  757. __FUNCTION__, 8 * sd->wordlen));
  758. return ERROR;
  759. }
  760. if (sd->card_dstatus)
  761. sd_trace(("dstatus after resync pattern write = 0x%x\n", sd->card_dstatus));
  762. return (BCME_OK);
  763. }
  764. uint32 dstatus_count = 0;
  765. static int
  766. bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg)
  767. {
  768. uint32 dstatus = sd->card_dstatus;
  769. struct spierrstats_t *spierrstats = &sd->spierrstats;
  770. int err = SUCCESS;
  771. sd_trace(("cmd = 0x%x, dstatus = 0x%x\n", cmd_arg, dstatus));
  772. /* Store dstatus of last few gSPI transactions */
  773. spierrstats->dstatus[dstatus_count % NUM_PREV_TRANSACTIONS] = dstatus;
  774. spierrstats->spicmd[dstatus_count % NUM_PREV_TRANSACTIONS] = cmd_arg;
  775. dstatus_count++;
  776. if (sd->card_init_done == FALSE)
  777. return err;
  778. if (dstatus & STATUS_DATA_NOT_AVAILABLE) {
  779. spierrstats->dna++;
  780. sd_trace(("Read data not available on F1 addr = 0x%x\n",
  781. GFIELD(cmd_arg, SPI_REG_ADDR)));
  782. /* Clear dna bit */
  783. bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, DATA_UNAVAILABLE);
  784. }
  785. if (dstatus & STATUS_UNDERFLOW) {
  786. spierrstats->rdunderflow++;
  787. sd_err(("FIFO underflow happened due to current F2 read command.\n"));
  788. }
  789. if (dstatus & STATUS_OVERFLOW) {
  790. spierrstats->wroverflow++;
  791. sd_err(("FIFO overflow happened due to current (F1/F2) write command.\n"));
  792. bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, F1_OVERFLOW);
  793. bcmspi_resync_f1(sd);
  794. sd_err(("Recovering from F1 FIFO overflow.\n"));
  795. }
  796. if (dstatus & STATUS_F2_INTR) {
  797. spierrstats->f2interrupt++;
  798. sd_trace(("Interrupt from F2. SW should clear corresponding IntStatus bits\n"));
  799. }
  800. if (dstatus & STATUS_F3_INTR) {
  801. spierrstats->f3interrupt++;
  802. sd_err(("Interrupt from F3. SW should clear corresponding IntStatus bits\n"));
  803. }
  804. if (dstatus & STATUS_HOST_CMD_DATA_ERR) {
  805. spierrstats->hostcmddataerr++;
  806. sd_err(("Error in CMD or Host data, detected by CRC/Checksum (optional)\n"));
  807. }
  808. if (dstatus & STATUS_F2_PKT_AVAILABLE) {
  809. spierrstats->f2pktavailable++;
  810. sd_trace(("Packet is available/ready in F2 TX FIFO\n"));
  811. sd_trace(("Packet length = %d\n", sd->dwordmode ?
  812. ((dstatus & STATUS_F2_PKT_LEN_MASK) >> (STATUS_F2_PKT_LEN_SHIFT - 2)) :
  813. ((dstatus & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT)));
  814. }
  815. if (dstatus & STATUS_F3_PKT_AVAILABLE) {
  816. spierrstats->f3pktavailable++;
  817. sd_err(("Packet is available/ready in F3 TX FIFO\n"));
  818. sd_err(("Packet length = %d\n",
  819. (dstatus & STATUS_F3_PKT_LEN_MASK) >> STATUS_F3_PKT_LEN_SHIFT));
  820. }
  821. return err;
  822. }
  823. extern int
  824. sdioh_abort(sdioh_info_t *sd, uint func)
  825. {
  826. return 0;
  827. }
  828. int
  829. sdioh_start(sdioh_info_t *sd, int stage)
  830. {
  831. return SUCCESS;
  832. }
  833. int
  834. sdioh_stop(sdioh_info_t *sd)
  835. {
  836. return SUCCESS;
  837. }
  838. int
  839. sdioh_waitlockfree(sdioh_info_t *sd)
  840. {
  841. return SUCCESS;
  842. }
  843. /*
  844. * Private/Static work routines
  845. */
  846. static int
  847. bcmspi_host_init(sdioh_info_t *sd)
  848. {
  849. /* Default power on mode */
  850. sd->sd_mode = SDIOH_MODE_SPI;
  851. sd->polled_mode = TRUE;
  852. sd->host_init_done = TRUE;
  853. sd->card_init_done = FALSE;
  854. sd->adapter_slot = 1;
  855. return (SUCCESS);
  856. }
  857. static int
  858. get_client_blocksize(sdioh_info_t *sd)
  859. {
  860. uint32 regdata[2];
  861. int status;
  862. /* Find F1/F2/F3 max packet size */
  863. if ((status = bcmspi_card_regread(sd, 0, SPID_F1_INFO_REG,
  864. 8, regdata)) != SUCCESS) {
  865. return status;
  866. }
  867. sd_trace(("pkt_size regdata[0] = 0x%x, regdata[1] = 0x%x\n",
  868. regdata[0], regdata[1]));
  869. sd->client_block_size[1] = (regdata[0] & F1_MAX_PKT_SIZE) >> 2;
  870. sd_trace(("Func1 blocksize = %d\n", sd->client_block_size[1]));
  871. ASSERT(sd->client_block_size[1] == BLOCK_SIZE_F1);
  872. sd->client_block_size[2] = ((regdata[0] >> 16) & F2_MAX_PKT_SIZE) >> 2;
  873. sd_trace(("Func2 blocksize = %d\n", sd->client_block_size[2]));
  874. ASSERT(sd->client_block_size[2] == BLOCK_SIZE_F2);
  875. sd->client_block_size[3] = (regdata[1] & F3_MAX_PKT_SIZE) >> 2;
  876. sd_trace(("Func3 blocksize = %d\n", sd->client_block_size[3]));
  877. ASSERT(sd->client_block_size[3] == BLOCK_SIZE_F3);
  878. return 0;
  879. }
  880. static int
  881. bcmspi_client_init(sdioh_info_t *sd)
  882. {
  883. uint32 status_en_reg = 0;
  884. sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot));
  885. #ifndef BCMSPI_ANDROID
  886. #ifdef HSMODE
  887. if (!spi_start_clock(sd, (uint16)sd_divisor)) {
  888. sd_err(("spi_start_clock failed\n"));
  889. return ERROR;
  890. }
  891. #else
  892. /* Start at ~400KHz clock rate for initialization */
  893. if (!spi_start_clock(sd, 128)) {
  894. sd_err(("spi_start_clock failed\n"));
  895. return ERROR;
  896. }
  897. #endif /* HSMODE */
  898. #endif /* !BCMSPI_ANDROID */
  899. if (!bcmspi_host_device_init_adapt(sd)) {
  900. sd_err(("bcmspi_host_device_init_adapt failed\n"));
  901. return ERROR;
  902. }
  903. if (!bcmspi_test_card(sd)) {
  904. sd_err(("bcmspi_test_card failed\n"));
  905. return ERROR;
  906. }
  907. sd->num_funcs = SPI_MAX_IOFUNCS;
  908. get_client_blocksize(sd);
  909. /* Apply resync pattern cmd with all zeros to reset spi-bkplane F1 logic */
  910. bcmspi_resync_f1(sd);
  911. sd->dwordmode = FALSE;
  912. bcmspi_card_regread(sd, 0, SPID_STATUS_ENABLE, 1, &status_en_reg);
  913. sd_trace(("%s: Enabling interrupt with dstatus \n", __FUNCTION__));
  914. status_en_reg |= INTR_WITH_STATUS;
  915. if (bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_STATUS_ENABLE, 1,
  916. status_en_reg & 0xff) != SUCCESS) {
  917. sd_err(("%s: Unable to set response delay for all fun's.\n", __FUNCTION__));
  918. return ERROR;
  919. }
  920. #ifndef HSMODE
  921. #ifndef BCMSPI_ANDROID
  922. /* After configuring for High-Speed mode, set the desired clock rate. */
  923. if (!spi_start_clock(sd, 4)) {
  924. sd_err(("spi_start_clock failed\n"));
  925. return ERROR;
  926. }
  927. #endif /* !BCMSPI_ANDROID */
  928. #endif /* HSMODE */
  929. /* check to see if the response delay needs to be programmed properly */
  930. {
  931. uint32 f1_respdelay = 0;
  932. bcmspi_card_regread(sd, 0, SPID_RESP_DELAY_F1, 1, &f1_respdelay);
  933. if ((f1_respdelay == 0) || (f1_respdelay == 0xFF)) {
  934. /* older sdiodevice core and has no separte resp delay for each of */
  935. sd_err(("older corerev < 4 so use the same resp delay for all funcs\n"));
  936. sd->resp_delay_new = FALSE;
  937. }
  938. else {
  939. /* older sdiodevice core and has no separte resp delay for each of */
  940. int ret_val;
  941. sd->resp_delay_new = TRUE;
  942. sd_err(("new corerev >= 4 so set the resp delay for each of the funcs\n"));
  943. sd_trace(("resp delay for funcs f0(%d), f1(%d), f2(%d), f3(%d)\n",
  944. GSPI_F0_RESP_DELAY, GSPI_F1_RESP_DELAY,
  945. GSPI_F2_RESP_DELAY, GSPI_F3_RESP_DELAY));
  946. ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F0, 1,
  947. GSPI_F0_RESP_DELAY);
  948. if (ret_val != SUCCESS) {
  949. sd_err(("%s: Unable to set response delay for F0\n", __FUNCTION__));
  950. return ERROR;
  951. }
  952. ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F1, 1,
  953. GSPI_F1_RESP_DELAY);
  954. if (ret_val != SUCCESS) {
  955. sd_err(("%s: Unable to set response delay for F1\n", __FUNCTION__));
  956. return ERROR;
  957. }
  958. ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F2, 1,
  959. GSPI_F2_RESP_DELAY);
  960. if (ret_val != SUCCESS) {
  961. sd_err(("%s: Unable to set response delay for F2\n", __FUNCTION__));
  962. return ERROR;
  963. }
  964. ret_val = bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_RESP_DELAY_F3, 1,
  965. GSPI_F3_RESP_DELAY);
  966. if (ret_val != SUCCESS) {
  967. sd_err(("%s: Unable to set response delay for F2\n", __FUNCTION__));
  968. return ERROR;
  969. }
  970. }
  971. }
  972. sd->card_init_done = TRUE;
  973. /* get the device rev to program the prop respdelays */
  974. return SUCCESS;
  975. }
  976. static int
  977. bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode)
  978. {
  979. uint32 regdata;
  980. int status;
  981. if ((status = bcmspi_card_regread(sd, 0, SPID_CONFIG,
  982. 4, &regdata)) != SUCCESS)
  983. return status;
  984. sd_trace(("In %s spih-ctrl = 0x%x \n", __FUNCTION__, regdata));
  985. if (hsmode == TRUE) {
  986. sd_trace(("Attempting to enable High-Speed mode.\n"));
  987. if (regdata & HIGH_SPEED_MODE) {
  988. sd_trace(("Device is already in High-Speed mode.\n"));
  989. return status;
  990. } else {
  991. regdata |= HIGH_SPEED_MODE;
  992. sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG));
  993. if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG,
  994. 4, regdata)) != SUCCESS) {
  995. return status;
  996. }
  997. }
  998. } else {
  999. sd_trace(("Attempting to disable High-Speed mode.\n"));
  1000. if (regdata & HIGH_SPEED_MODE) {
  1001. regdata &= ~HIGH_SPEED_MODE;
  1002. sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG));
  1003. if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG,
  1004. 4, regdata)) != SUCCESS)
  1005. return status;
  1006. }
  1007. else {
  1008. sd_trace(("Device is already in Low-Speed mode.\n"));
  1009. return status;
  1010. }
  1011. }
  1012. #ifndef BCMSPI_ANDROID
  1013. spi_controller_highspeed_mode(sd, hsmode);
  1014. #endif /* !BCMSPI_ANDROID */
  1015. return TRUE;
  1016. }
  1017. #define bcmspi_find_curr_mode(sd) { \
  1018. sd->wordlen = 2; \
  1019. status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, &regdata); \
  1020. regdata &= 0xff; \
  1021. if ((regdata == 0xad) || (regdata == 0x5b) || \
  1022. (regdata == 0x5d) || (regdata == 0x5a)) \
  1023. break; \
  1024. sd->wordlen = 4; \
  1025. status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, &regdata); \
  1026. regdata &= 0xff; \
  1027. if ((regdata == 0xad) || (regdata == 0x5b) || \
  1028. (regdata == 0x5d) || (regdata == 0x5a)) \
  1029. break; \
  1030. sd_trace(("Silicon testability issue: regdata = 0x%x." \
  1031. " Expected 0xad, 0x5a, 0x5b or 0x5d.\n", regdata)); \
  1032. OSL_DELAY(100000); \
  1033. }
  1034. #define INIT_ADAPT_LOOP 100
  1035. /* Adapt clock-phase-speed-bitwidth between host and device */
  1036. static bool
  1037. bcmspi_host_device_init_adapt(sdioh_info_t *sd)
  1038. {
  1039. uint32 wrregdata, regdata = 0;
  1040. int status;
  1041. int i;
  1042. /* Due to a silicon testability issue, the first command from the Host
  1043. * to the device will get corrupted (first bit will be lost). So the
  1044. * Host should poll the device with a safe read request. ie: The Host
  1045. * should try to read F0 addr 0x14 using the Fixed address mode
  1046. * (This will prevent a unintended write command to be detected by device)
  1047. */
  1048. for (i = 0; i < INIT_ADAPT_LOOP; i++) {
  1049. /* If device was not power-cycled it will stay in 32bit mode with
  1050. * response-delay-all bit set. Alternate the iteration so that
  1051. * read either with or without response-delay for F0 to succeed.
  1052. */
  1053. bcmspi_find_curr_mode(sd);
  1054. sd->resp_delay_all = (i & 0x1) ? TRUE : FALSE;
  1055. bcmspi_find_curr_mode(sd);
  1056. sd->dwordmode = TRUE;
  1057. bcmspi_find_curr_mode(sd);
  1058. sd->dwordmode = FALSE;
  1059. }
  1060. /* Bail out, device not detected */
  1061. if (i == INIT_ADAPT_LOOP)
  1062. return FALSE;
  1063. /* Softreset the spid logic */
  1064. if ((sd->dwordmode) || (sd->wordlen == 4)) {
  1065. bcmspi_card_regwrite(sd, 0, SPID_RESET_BP, 1, RESET_ON_WLAN_BP_RESET|RESET_SPI);
  1066. bcmspi_card_regread(sd, 0, SPID_RESET_BP, 1, &regdata);
  1067. sd_trace(("reset reg read = 0x%x\n", regdata));
  1068. sd_trace(("dwordmode = %d, wordlen = %d, resp_delay_all = %d\n", sd->dwordmode,
  1069. sd->wordlen, sd->resp_delay_all));
  1070. /* Restore default state after softreset */
  1071. sd->wordlen = 2;
  1072. sd->dwordmode = FALSE;
  1073. }
  1074. if (sd->wordlen == 4) {
  1075. if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) !=
  1076. SUCCESS)
  1077. return FALSE;
  1078. if (regdata == TEST_RO_DATA_32BIT_LE) {
  1079. sd_trace(("Spid is already in 32bit LE mode. Value read = 0x%x\n",
  1080. regdata));
  1081. sd_trace(("Spid power was left on.\n"));
  1082. } else {
  1083. sd_err(("Spid power was left on but signature read failed."
  1084. " Value read = 0x%x\n", regdata));
  1085. return FALSE;
  1086. }
  1087. } else {
  1088. sd->wordlen = 2;
  1089. #define CTRL_REG_DEFAULT 0x00010430 /* according to the host m/c */
  1090. wrregdata = (CTRL_REG_DEFAULT);
  1091. if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) != SUCCESS)
  1092. return FALSE;
  1093. sd_trace(("(we are still in 16bit mode) 32bit READ LE regdata = 0x%x\n", regdata));
  1094. #ifndef HSMODE
  1095. wrregdata |= (CLOCK_PHASE | CLOCK_POLARITY);
  1096. wrregdata &= ~HIGH_SPEED_MODE;
  1097. bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata);
  1098. #endif /* HSMODE */
  1099. for (i = 0; i < INIT_ADAPT_LOOP; i++) {
  1100. if ((regdata == 0xfdda7d5b) || (regdata == 0xfdda7d5a)) {
  1101. sd_trace(("0xfeedbead was leftshifted by 1-bit.\n"));
  1102. if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4,
  1103. &regdata)) != SUCCESS)
  1104. return FALSE;
  1105. }
  1106. OSL_DELAY(1000);
  1107. }
  1108. #if defined(CHANGE_SPI_INTR_POLARITY_ACTIVE_HIGH)
  1109. /* Change to host controller intr-polarity of active-high */
  1110. wrregdata |= INTR_POLARITY;
  1111. #else
  1112. /* Change to host controller intr-polarity of active-low */
  1113. wrregdata &= ~INTR_POLARITY;
  1114. #endif /* CHANGE_SPI_INTR_POLARITY_ACTIVE_HIGH */
  1115. sd_trace(("(we are still in 16bit mode) 32bit Write LE reg-ctrl-data = 0x%x\n",
  1116. wrregdata));
  1117. /* Change to 32bit mode */
  1118. wrregdata |= WORD_LENGTH_32;
  1119. bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata);
  1120. /* Change command/data packaging in 32bit LE mode */
  1121. sd->wordlen = 4;
  1122. if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) != SUCCESS)
  1123. return FALSE;
  1124. if (regdata == TEST_RO_DATA_32BIT_LE) {
  1125. sd_trace(("Read spid passed. Value read = 0x%x\n", regdata));
  1126. sd_trace(("Spid had power-on cycle OR spi was soft-resetted \n"));
  1127. } else {
  1128. sd_err(("Stale spid reg values read as it was kept powered. Value read ="
  1129. "0x%x\n", regdata));
  1130. return FALSE;
  1131. }
  1132. }
  1133. return TRUE;
  1134. }
  1135. static bool
  1136. bcmspi_test_card(sdioh_info_t *sd)
  1137. {
  1138. uint32 regdata;
  1139. int status;
  1140. if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) != SUCCESS)
  1141. return FALSE;
  1142. if (regdata == (TEST_RO_DATA_32BIT_LE))
  1143. sd_trace(("32bit LE regdata = 0x%x\n", regdata));
  1144. else {
  1145. sd_trace(("Incorrect 32bit LE regdata = 0x%x\n", regdata));
  1146. return FALSE;
  1147. }
  1148. #define RW_PATTERN1 0xA0A1A2A3
  1149. #define RW_PATTERN2 0x4B5B6B7B
  1150. regdata = RW_PATTERN1;
  1151. if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS)
  1152. return FALSE;
  1153. regdata = 0;
  1154. if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, &regdata)) != SUCCESS)
  1155. return FALSE;
  1156. if (regdata != RW_PATTERN1) {
  1157. sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n",
  1158. RW_PATTERN1, regdata));
  1159. return FALSE;
  1160. } else
  1161. sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata));
  1162. regdata = RW_PATTERN2;
  1163. if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS)
  1164. return FALSE;
  1165. regdata = 0;
  1166. if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, &regdata)) != SUCCESS)
  1167. return FALSE;
  1168. if (regdata != RW_PATTERN2) {
  1169. sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n",
  1170. RW_PATTERN2, regdata));
  1171. return FALSE;
  1172. } else
  1173. sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata));
  1174. return TRUE;
  1175. }
  1176. static int
  1177. bcmspi_driver_init(sdioh_info_t *sd)
  1178. {
  1179. sd_trace(("%s\n", __FUNCTION__));
  1180. if ((bcmspi_host_init(sd)) != SUCCESS) {
  1181. return ERROR;
  1182. }
  1183. if (bcmspi_client_init(sd) != SUCCESS) {
  1184. return ERROR;
  1185. }
  1186. return SUCCESS;
  1187. }
  1188. /* Read device reg */
  1189. static int
  1190. bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data)
  1191. {
  1192. int status;
  1193. uint32 cmd_arg, dstatus;
  1194. ASSERT(regsize);
  1195. if (func == 2)
  1196. sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n"));
  1197. cmd_arg = 0;
  1198. cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0);
  1199. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */
  1200. cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
  1201. cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
  1202. cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize);
  1203. sd_trace(("%s: RD cmd_arg=0x%x func=%d regaddr=0x%x regsize=%d\n",
  1204. __FUNCTION__, cmd_arg, func, regaddr, regsize));
  1205. if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize)) != SUCCESS)
  1206. return status;
  1207. bcmspi_cmd_getdstatus(sd, &dstatus);
  1208. if (dstatus)
  1209. sd_trace(("dstatus =0x%x\n", dstatus));
  1210. return SUCCESS;
  1211. }
  1212. static int
  1213. bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data)
  1214. {
  1215. int status;
  1216. uint32 cmd_arg;
  1217. uint32 dstatus;
  1218. ASSERT(regsize);
  1219. if (func == 2)
  1220. sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n"));
  1221. cmd_arg = 0;
  1222. cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0);
  1223. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0); /* Fixed access */
  1224. cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
  1225. cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
  1226. cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize);
  1227. sd_trace(("%s: RD cmd_arg=0x%x func=%d regaddr=0x%x regsize=%d\n",
  1228. __FUNCTION__, cmd_arg, func, regaddr, regsize));
  1229. if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize)) != SUCCESS)
  1230. return status;
  1231. sd_trace(("%s: RD result=0x%x\n", __FUNCTION__, *data));
  1232. bcmspi_cmd_getdstatus(sd, &dstatus);
  1233. sd_trace(("dstatus =0x%x\n", dstatus));
  1234. return SUCCESS;
  1235. }
  1236. /* write a device register */
  1237. static int
  1238. bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data)
  1239. {
  1240. int status;
  1241. uint32 cmd_arg, dstatus;
  1242. ASSERT(regsize);
  1243. cmd_arg = 0;
  1244. cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1);
  1245. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */
  1246. cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
  1247. cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
  1248. cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize);
  1249. sd_trace(("%s: WR cmd_arg=0x%x func=%d regaddr=0x%x regsize=%d data=0x%x\n",
  1250. __FUNCTION__, cmd_arg, func, regaddr, regsize, data));
  1251. if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, regsize)) != SUCCESS)
  1252. return status;
  1253. bcmspi_cmd_getdstatus(sd, &dstatus);
  1254. if (dstatus)
  1255. sd_trace(("dstatus=0x%x\n", dstatus));
  1256. return SUCCESS;
  1257. }
  1258. /* write a device register - 1 byte */
  1259. static int
  1260. bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 *byte)
  1261. {
  1262. int status;
  1263. uint32 cmd_arg;
  1264. uint32 dstatus;
  1265. uint32 data = (uint32)(*byte);
  1266. cmd_arg = 0;
  1267. cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
  1268. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1); /* Incremental access */
  1269. cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
  1270. cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1);
  1271. cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1);
  1272. sd_trace(("%s: WR cmd_arg=0x%x func=%d regaddr=0x%x data=0x%x\n",
  1273. __FUNCTION__, cmd_arg, func, regaddr, data));
  1274. if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, 1)) != SUCCESS)
  1275. return status;
  1276. bcmspi_cmd_getdstatus(sd, &dstatus);
  1277. if (dstatus)
  1278. sd_trace(("dstatus =0x%x\n", dstatus));
  1279. return SUCCESS;
  1280. }
  1281. void
  1282. bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer)
  1283. {
  1284. *dstatus_buffer = sd->card_dstatus;
  1285. }
  1286. /* 'data' is of type uint32 whereas other buffers are of type uint8 */
  1287. static int
  1288. bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg,
  1289. uint32 *data, uint32 datalen)
  1290. {
  1291. uint32 i, j;
  1292. uint8 resp_delay = 0;
  1293. int err = SUCCESS;
  1294. uint32 hostlen;
  1295. uint32 spilen = 0;
  1296. uint32 dstatus_idx = 0;
  1297. uint16 templen, buslen, len, *ptr = NULL;
  1298. sd_trace(("spi cmd = 0x%x\n", cmd_arg));
  1299. /* Set up and issue the SPI command. MSByte goes out on bus first. Increase datalen
  1300. * according to the wordlen mode(16/32bit) the device is in.
  1301. */
  1302. if (sd->wordlen == 4) { /* 32bit spid */
  1303. *(uint32 *)spi_outbuf = SPISWAP_WD4(cmd_arg);
  1304. if (datalen & 0x3)
  1305. datalen += (4 - (datalen & 0x3));
  1306. } else if (sd->wordlen == 2) { /* 16bit spid */
  1307. *(uint32 *)spi_outbuf = SPISWAP_WD2(cmd_arg);
  1308. if (datalen & 0x1)
  1309. datalen++;
  1310. if (datalen < 4)
  1311. datalen = ROUNDUP(datalen, 4);
  1312. } else {
  1313. sd_err(("Host is %d bit spid, could not create SPI command.\n",
  1314. 8 * sd->wordlen));
  1315. return ERROR;
  1316. }
  1317. /* for Write, put the data into the output buffer */
  1318. if (GFIELD(cmd_arg, SPI_RW_FLAG) == 1) {
  1319. /* We send len field of hw-header always a mod16 size, both from host and dongle */
  1320. if (datalen != 0) {
  1321. for (i = 0; i < datalen/4; i++) {
  1322. if (sd->wordlen == 4) { /* 32bit spid */
  1323. *(uint32 *)&spi_outbuf[i * 4 + CMDLEN] =
  1324. SPISWAP_WD4(data[i]);
  1325. } else if (sd->wordlen == 2) { /* 16bit spid */
  1326. *(uint32 *)&spi_outbuf[i * 4 + CMDLEN] =
  1327. SPISWAP_WD2(data[i]);
  1328. }
  1329. }
  1330. }
  1331. }
  1332. /* Append resp-delay number of bytes and clock them out for F0/1/2 reads. */
  1333. if ((GFIELD(cmd_arg, SPI_RW_FLAG) == 0)) {
  1334. int func = GFIELD(cmd_arg, SPI_FUNCTION);
  1335. switch (func) {
  1336. case 0:
  1337. if (sd->resp_delay_new)
  1338. resp_delay = GSPI_F0_RESP_DELAY;
  1339. else
  1340. resp_delay = sd->resp_delay_all ? F0_RESPONSE_DELAY : 0;
  1341. break;
  1342. case 1:
  1343. if (sd->resp_delay_new)
  1344. resp_delay = GSPI_F1_RESP_DELAY;
  1345. else
  1346. resp_delay = F1_RESPONSE_DELAY;
  1347. break;
  1348. case 2:
  1349. if (sd->resp_delay_new)
  1350. resp_delay = GSPI_F2_RESP_DELAY;
  1351. else
  1352. resp_delay = sd->resp_delay_all ? F2_RESPONSE_DELAY : 0;
  1353. break;
  1354. default:
  1355. ASSERT(0);
  1356. break;
  1357. }
  1358. /* Program response delay */
  1359. if (sd->resp_delay_new == FALSE)
  1360. bcmspi_prog_resp_delay(sd, func, resp_delay);
  1361. }
  1362. /* +4 for cmd and +4 for dstatus */
  1363. hostlen = datalen + 8 + resp_delay;
  1364. hostlen += dstatus_idx;
  1365. #ifdef BCMSPI_ANDROID
  1366. if (hostlen%4) {
  1367. sd_err(("Unaligned data len %d, hostlen %d\n",
  1368. datalen, hostlen));
  1369. #endif /* BCMSPI_ANDROID */
  1370. hostlen += (4 - (hostlen & 0x3));
  1371. #ifdef BCMSPI_ANDROID
  1372. }
  1373. #endif /* BCMSPI_ANDROID */
  1374. spi_sendrecv(sd, spi_outbuf, spi_inbuf, hostlen);
  1375. /* for Read, get the data into the input buffer */
  1376. if (datalen != 0) {
  1377. if (GFIELD(cmd_arg, SPI_RW_FLAG) == 0) { /* if read cmd */
  1378. for (j = 0; j < datalen/4; j++) {
  1379. if (sd->wordlen == 4) { /* 32bit spid */
  1380. data[j] = SPISWAP_WD4(*(uint32 *)&spi_inbuf[j * 4 +
  1381. CMDLEN + resp_delay]);
  1382. } else if (sd->wordlen == 2) { /* 16bit spid */
  1383. data[j] = SPISWAP_WD2(*(uint32 *)&spi_inbuf[j * 4 +
  1384. CMDLEN + resp_delay]);
  1385. }
  1386. }
  1387. }
  1388. }
  1389. dstatus_idx += (datalen + CMDLEN + resp_delay);
  1390. /* Last 4bytes are dstatus. Device is configured to return status bits. */
  1391. if (sd->wordlen == 4) { /* 32bit spid */
  1392. sd->card_dstatus = SPISWAP_WD4(*(uint32 *)&spi_inbuf[dstatus_idx]);
  1393. } else if (sd->wordlen == 2) { /* 16bit spid */
  1394. sd->card_dstatus = SPISWAP_WD2(*(uint32 *)&spi_inbuf[dstatus_idx]);
  1395. } else {
  1396. sd_err(("Host is %d bit machine, could not read SPI dstatus.\n",
  1397. 8 * sd->wordlen));
  1398. return ERROR;
  1399. }
  1400. if (sd->card_dstatus == 0xffffffff) {
  1401. sd_err(("looks like not a GSPI device or device is not powered.\n"));
  1402. }
  1403. err = bcmspi_update_stats(sd, cmd_arg);
  1404. return err;
  1405. }
  1406. static int
  1407. bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo,
  1408. uint32 addr, int nbytes, uint32 *data)
  1409. {
  1410. int status;
  1411. uint32 cmd_arg;
  1412. bool write = rw == SDIOH_READ ? 0 : 1;
  1413. uint retries = 0;
  1414. bool enable;
  1415. uint32 spilen;
  1416. cmd_arg = 0;
  1417. ASSERT(nbytes);
  1418. ASSERT(nbytes <= sd->client_block_size[func]);
  1419. if (write) sd->t_cnt++; else sd->r_cnt++;
  1420. if (func == 2) {
  1421. /* Frame len check limited by gSPI. */
  1422. if ((nbytes > 2000) && write) {
  1423. sd_trace((">2KB write: F2 wr of %d bytes\n", nbytes));
  1424. }
  1425. /* ASSERT(nbytes <= 2048); Fix bigger len gspi issue and uncomment. */
  1426. /* If F2 fifo on device is not ready to receive data, don't do F2 transfer */
  1427. if (write) {
  1428. uint32 dstatus;
  1429. /* check F2 ready with cached one */
  1430. bcmspi_cmd_getdstatus(sd, &dstatus);
  1431. if ((dstatus & STATUS_F2_RX_READY) == 0) {
  1432. retries = WAIT_F2RXFIFORDY;
  1433. enable = 0;
  1434. while (retries-- && !enable) {
  1435. OSL_DELAY(WAIT_F2RXFIFORDY_DELAY * 1000);
  1436. bcmspi_card_regread(sd, SPI_FUNC_0, SPID_STATUS_REG, 4,
  1437. &dstatus);
  1438. if (dstatus & STATUS_F2_RX_READY)
  1439. enable = TRUE;
  1440. }
  1441. if (!enable) {
  1442. struct spierrstats_t *spierrstats = &sd->spierrstats;
  1443. spierrstats->f2rxnotready++;
  1444. sd_err(("F2 FIFO is not ready to receive data.\n"));
  1445. return ERROR;
  1446. }
  1447. sd_trace(("No of retries on F2 ready %d\n",
  1448. (WAIT_F2RXFIFORDY - retries)));
  1449. }
  1450. }
  1451. }
  1452. /* F2 transfers happen on 0 addr */
  1453. addr = (func == 2) ? 0 : addr;
  1454. /* In pio mode buffer is read using fixed address fifo in func 1 */
  1455. if ((func == 1) && (fifo))
  1456. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0);
  1457. else
  1458. cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1);
  1459. cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
  1460. cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, addr);
  1461. cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, write);
  1462. spilen = sd->data_xfer_count = MIN(sd->client_block_size[func], nbytes);
  1463. if ((sd->dwordmode == TRUE) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) {
  1464. /* convert len to mod4 size */
  1465. spilen = spilen + ((spilen & 0x3) ? (4 - (spilen & 0x3)): 0);
  1466. cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2));
  1467. } else
  1468. cmd_arg = SFIELD(cmd_arg, SPI_LEN, spilen);
  1469. if ((func == 2) && (fifo == 1)) {
  1470. sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n",
  1471. __FUNCTION__, write ? "Wr" : "Rd", func, "INCR",
  1472. addr, nbytes, sd->r_cnt, sd->t_cnt));
  1473. }
  1474. sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
  1475. sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n",
  1476. __FUNCTION__, write ? "Wd" : "Rd", func, "INCR",
  1477. addr, nbytes, sd->r_cnt, sd->t_cnt));
  1478. if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, nbytes)) != SUCCESS) {
  1479. sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__,
  1480. (write ? "write" : "read")));
  1481. return status;
  1482. }
  1483. /* gSPI expects that hw-header-len is equal to spi-command-len */
  1484. if ((func == 2) && (rw == SDIOH_WRITE) && (sd->dwordmode == FALSE)) {
  1485. ASSERT((uint16)sd->data_xfer_count == (uint16)(*data & 0xffff));
  1486. ASSERT((uint16)sd->data_xfer_count == (uint16)(~((*data & 0xffff0000) >> 16)));
  1487. }
  1488. if ((nbytes > 2000) && !write) {
  1489. sd_trace((">2KB read: F2 rd of %d bytes\n", nbytes));
  1490. }
  1491. return SUCCESS;
  1492. }
  1493. /* Reset and re-initialize the device */
  1494. int
  1495. sdioh_sdio_reset(sdioh_info_t *si)
  1496. {
  1497. si->card_init_done = FALSE;
  1498. return bcmspi_client_init(si);
  1499. }
  1500. SDIOH_API_RC
  1501. sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio)
  1502. {
  1503. return SDIOH_API_RC_FAIL;
  1504. }
  1505. SDIOH_API_RC
  1506. sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab)
  1507. {
  1508. return SDIOH_API_RC_FAIL;
  1509. }
  1510. bool
  1511. sdioh_gpioin(sdioh_info_t *sd, uint32 gpio)
  1512. {
  1513. return FALSE;
  1514. }
  1515. SDIOH_API_RC
  1516. sdioh_gpio_init(sdioh_info_t *sd)
  1517. {
  1518. return SDIOH_API_RC_FAIL;
  1519. }