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