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