--- c743d096d2c89bd2a9ca3c3d5f94ae14f343a043 +++ 69809aa85aa1a2e1c8132eaa8b92597ec3978915 @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh_sdmmc.c 347640 2012-07-27 11:53:21Z $ + * $Id: bcmsdh_sdmmc.c 362913 2012-10-15 11:26:11Z $ */ #include @@ -62,12 +62,13 @@ extern int sdio_reset_comm(struct mmc_ca extern PBCMSDH_SDMMC_INSTANCE gInstance; -uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -#if defined(SDIO_F2_BLKSIZE) -uint sd_f2_blocksize = SDIO_F2_BLKSIZE; -#else -uint sd_f2_blocksize = 512; /* Default blocksize */ +#define DEFAULT_SDIO_F2_BLKSIZE 512 +#ifndef CUSTOM_SDIO_F2_BLKSIZE +#define CUSTOM_SDIO_F2_BLKSIZE DEFAULT_SDIO_F2_BLKSIZE #endif + +uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ +uint sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE; uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ uint sd_power = 1; /* Default to SD Slot powered ON */ @@ -81,6 +82,7 @@ DHD_PM_RESUME_WAIT_INIT(sdioh_request_pa DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); #define DMA_ALIGN_MASK 0x03 +#define MMC_SDIO_ABORT_RETRY_LIMIT 5 int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data); @@ -523,7 +525,7 @@ sdioh_iovar_op(sdioh_info_t *si, const c /* Now set it */ si->client_block_size[func] = blksize; -#if defined(CUSTOMER_HW4) && defined(DYNAMIC_F2_BLKSIZE_OF_PROPTXSTATUS) +#if defined(CUSTOMER_HW4) && defined(USE_DYNAMIC_F2_BLKSIZE) if (gInstance == NULL || gInstance->func[func] == NULL) { sd_err(("%s: SDIO Device not present\n", __FUNCTION__)); bcmerror = BCME_NORESOURCE; @@ -536,7 +538,7 @@ sdioh_iovar_op(sdioh_info_t *si, const c blksize)); } sdio_release_host(gInstance->func[func]); -#endif /* CUSTOMER_HW4 && DYNAMIC_F2_BLKSIZE_OF_PROPTXSTATUS */ +#endif /* CUSTOMER_HW4 && USE_DYNAMIC_F2_BLKSIZE */ break; } @@ -792,7 +794,9 @@ extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) { int err_ret; - +#if defined(MMC_SDIO_ABORT) + int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT; +#endif sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr)); DHD_PM_RESUME_WAIT(sdioh_request_byte_wait); @@ -826,16 +830,24 @@ sdioh_request_byte(sdioh_info_t *sd, uin #if defined(MMC_SDIO_ABORT) /* to allow abort command through F1 */ else if (regaddr == SDIOD_CCCR_IOABORT) { - if (gInstance->func[func]) { - sdio_claim_host(gInstance->func[func]); - /* - * this sdio_f0_writeb() can be replaced with another api - * depending upon MMC driver change. - * As of this time, this is temporaray one - */ - sdio_writeb(gInstance->func[func], - *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); + /* Because of SDIO3.0 host issue on Manta, + * sometimes the abort fails. + * Retrying again will fix this issue. + */ + while (sdio_abort_retry--) { + if (gInstance->func[func]) { + sdio_claim_host(gInstance->func[func]); + /* + * this sdio_f0_writeb() can be replaced with + * another api depending upon MMC driver change. + * As of this time, this is temporaray one + */ + sdio_writeb(gInstance->func[func], + *byte, regaddr, &err_ret); + sdio_release_host(gInstance->func[func]); + } + if (!err_ret) + break; } } #endif /* MMC_SDIO_ABORT */ @@ -884,6 +896,9 @@ sdioh_request_word(sdioh_info_t *sd, uin uint32 *word, uint nbytes) { int err_ret = SDIOH_API_RC_FAIL; +#if defined(MMC_SDIO_ABORT) + int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT; +#endif if (func == 0) { sd_err(("%s: Only CMD52 allowed to F0.\n", __FUNCTION__)); @@ -898,7 +913,7 @@ sdioh_request_word(sdioh_info_t *sd, uin /* Claim host controller */ sdio_claim_host(gInstance->func[func]); - if(rw) { /* CMD52 Write */ + if(rw) { /* CMD53 Write */ if (nbytes == 4) { sdio_writel(gInstance->func[func], *word, addr, &err_ret); } else if (nbytes == 2) { @@ -920,8 +935,29 @@ sdioh_request_word(sdioh_info_t *sd, uin sdio_release_host(gInstance->func[func]); if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x", +#if defined(MMC_SDIO_ABORT) + /* Any error on CMD53 transaction should abort that function using function 0. */ + while (sdio_abort_retry--) { + if (gInstance->func[0]) { + sdio_claim_host(gInstance->func[0]); + /* + * this sdio_f0_writeb() can be replaced with another api + * depending upon MMC driver change. + * As of this time, this is temporaray one + */ + sdio_writeb(gInstance->func[0], + func, SDIOD_CCCR_IOABORT, &err_ret); + sdio_release_host(gInstance->func[0]); + } + if (!err_ret) + break; + } + if (err_ret) +#endif /* MMC_SDIO_ABORT */ + { + sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x\n", rw ? "Write" : "Read", err_ret)); + } } return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); @@ -937,6 +973,7 @@ sdioh_request_packet(sdioh_info_t *sd, u void *pnext, *pprev; uint ttl_len, dma_len, lft_len, xfred_len, pkt_len; uint blk_num; + int blk_size; struct mmc_request mmc_req; struct mmc_command mmc_cmd; struct mmc_data mmc_dat; @@ -952,12 +989,13 @@ sdioh_request_packet(sdioh_info_t *sd, u for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) ttl_len += PKTLEN(sd->osh, pnext); - if (!sd->use_rxchain || ttl_len <= sd->client_block_size[func]) { + blk_size = sd->client_block_size[func]; + if (!sd->use_rxchain || ttl_len <= blk_size) { blk_num = 0; dma_len = 0; } else { - blk_num = ttl_len / sd->client_block_size[func]; - dma_len = blk_num * sd->client_block_size[func]; + blk_num = ttl_len / blk_size; + dma_len = blk_num * blk_size; } lft_len = ttl_len - dma_len; @@ -998,7 +1036,7 @@ sdioh_request_packet(sdioh_info_t *sd, u mmc_dat.sg = sd->sg_list; mmc_dat.sg_len = SGCount; - mmc_dat.blksz = sd->client_block_size[func]; + mmc_dat.blksz = blk_size; mmc_dat.blocks = blk_num; mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; @@ -1054,13 +1092,13 @@ sdioh_request_packet(sdioh_info_t *sd, u */ if (write == 0 || pkt_len < 32) pkt_len = (pkt_len + 3) & 0xFFFFFFFC; - else if (pkt_len % DHD_SDALIGN) - pkt_len += DHD_SDALIGN - (pkt_len % DHD_SDALIGN); + else if (pkt_len % blk_size) + pkt_len += blk_size - (pkt_len % blk_size); -#if defined(CUSTOMER_HW4) && defined(DYNAMIC_F2_BLKSIZE_OF_PROPTXSTATUS) +#if defined(CUSTOMER_HW4) && defined(USE_DYNAMIC_F2_BLKSIZE) if (write && pkt_len > 64 && (pkt_len % 64) == 32) pkt_len += 32; -#endif /* CUSTOMER_HW4 && DYNAMIC_F2_BLKSIZE_OF_PROPTXSTATUS */ +#endif /* CUSTOMER_HW4 && USE_DYNAMIC_F2_BLKSIZE */ #ifdef CONFIG_MMC_MSM7X00A if ((pkt_len % 64) == 32) { sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__));