1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016 - 2020, Broadcom 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <string.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <emmc_api.h> 10*91f16700Schasinglulu #include <cmn_plat_util.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #define MAX_CMD_RETRY 10 13*91f16700Schasinglulu 14*91f16700Schasinglulu #if EMMC_USE_DMA 15*91f16700Schasinglulu #define USE_DMA 1 16*91f16700Schasinglulu #else 17*91f16700Schasinglulu #define USE_DMA 0 18*91f16700Schasinglulu #endif 19*91f16700Schasinglulu 20*91f16700Schasinglulu struct emmc_global_buffer emmc_global_buf; 21*91f16700Schasinglulu struct emmc_global_buffer *emmc_global_buf_ptr = &emmc_global_buf; 22*91f16700Schasinglulu 23*91f16700Schasinglulu struct emmc_global_vars emmc_global_vars; 24*91f16700Schasinglulu struct emmc_global_vars *emmc_global_vars_ptr = &emmc_global_vars; 25*91f16700Schasinglulu 26*91f16700Schasinglulu static struct sd_handle *sdio_gethandle(void); 27*91f16700Schasinglulu static uint32_t sdio_idle(struct sd_handle *p_sdhandle); 28*91f16700Schasinglulu 29*91f16700Schasinglulu static uint32_t sdio_read(struct sd_handle *p_sdhandle, 30*91f16700Schasinglulu uintptr_t mem_addr, 31*91f16700Schasinglulu uintptr_t storage_addr, 32*91f16700Schasinglulu size_t storage_size, 33*91f16700Schasinglulu size_t bytes_to_read); 34*91f16700Schasinglulu 35*91f16700Schasinglulu #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE 36*91f16700Schasinglulu static uint32_t sdio_write(struct sd_handle *p_sdhandle, 37*91f16700Schasinglulu uintptr_t mem_addr, 38*91f16700Schasinglulu uintptr_t data_addr, 39*91f16700Schasinglulu size_t bytes_to_write); 40*91f16700Schasinglulu #endif 41*91f16700Schasinglulu 42*91f16700Schasinglulu static struct sd_handle *sdio_init(void); 43*91f16700Schasinglulu static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle); 44*91f16700Schasinglulu 45*91f16700Schasinglulu static void init_globals(void) 46*91f16700Schasinglulu { 47*91f16700Schasinglulu memset((void *)emmc_global_buf_ptr, 0, sizeof(*emmc_global_buf_ptr)); 48*91f16700Schasinglulu memset((void *)emmc_global_vars_ptr, 0, sizeof(*emmc_global_vars_ptr)); 49*91f16700Schasinglulu } 50*91f16700Schasinglulu 51*91f16700Schasinglulu /* 52*91f16700Schasinglulu * This function is used to change partition 53*91f16700Schasinglulu */ 54*91f16700Schasinglulu uint32_t emmc_partition_select(uint32_t partition) 55*91f16700Schasinglulu { 56*91f16700Schasinglulu int rc; 57*91f16700Schasinglulu struct sd_handle *sd_handle = sdio_gethandle(); 58*91f16700Schasinglulu 59*91f16700Schasinglulu if (sd_handle->device == 0) { 60*91f16700Schasinglulu EMMC_TRACE("eMMC init is not done"); 61*91f16700Schasinglulu return 0; 62*91f16700Schasinglulu } 63*91f16700Schasinglulu 64*91f16700Schasinglulu switch (partition) { 65*91f16700Schasinglulu case EMMC_BOOT_PARTITION1: 66*91f16700Schasinglulu rc = set_boot_config(sd_handle, 67*91f16700Schasinglulu SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT1); 68*91f16700Schasinglulu EMMC_TRACE( 69*91f16700Schasinglulu "Change to Boot Partition 1 result:%d (0 means SD_OK)\n", 70*91f16700Schasinglulu rc); 71*91f16700Schasinglulu break; 72*91f16700Schasinglulu 73*91f16700Schasinglulu case EMMC_BOOT_PARTITION2: 74*91f16700Schasinglulu rc = set_boot_config(sd_handle, 75*91f16700Schasinglulu SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT2); 76*91f16700Schasinglulu EMMC_TRACE( 77*91f16700Schasinglulu "Change to Boot Partition 2 result:%d (0 means SD_OK)\n", 78*91f16700Schasinglulu rc); 79*91f16700Schasinglulu break; 80*91f16700Schasinglulu 81*91f16700Schasinglulu case EMMC_USE_CURRENT_PARTITION: 82*91f16700Schasinglulu rc = SD_OK; 83*91f16700Schasinglulu EMMC_TRACE("Stay on current partition"); 84*91f16700Schasinglulu break; 85*91f16700Schasinglulu 86*91f16700Schasinglulu case EMMC_USER_AREA: 87*91f16700Schasinglulu default: 88*91f16700Schasinglulu rc = set_boot_config(sd_handle, 89*91f16700Schasinglulu SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_USER); 90*91f16700Schasinglulu EMMC_TRACE("Change to User area result:%d (0 means SD_OK)\n", 91*91f16700Schasinglulu rc); 92*91f16700Schasinglulu break; 93*91f16700Schasinglulu 94*91f16700Schasinglulu } 95*91f16700Schasinglulu return (rc == SD_OK); 96*91f16700Schasinglulu } 97*91f16700Schasinglulu 98*91f16700Schasinglulu /* 99*91f16700Schasinglulu * Initialize emmc controller for eMMC 100*91f16700Schasinglulu * Returns 0 on fail condition 101*91f16700Schasinglulu */ 102*91f16700Schasinglulu uint32_t bcm_emmc_init(bool card_rdy_only) 103*91f16700Schasinglulu { 104*91f16700Schasinglulu struct sd_handle *p_sdhandle; 105*91f16700Schasinglulu uint32_t result = 0; 106*91f16700Schasinglulu 107*91f16700Schasinglulu EMMC_TRACE("Enter emmc_controller_init()\n"); 108*91f16700Schasinglulu 109*91f16700Schasinglulu /* If eMMC is already initialized, skip init */ 110*91f16700Schasinglulu if (emmc_global_vars_ptr->init_done) 111*91f16700Schasinglulu return 1; 112*91f16700Schasinglulu 113*91f16700Schasinglulu init_globals(); 114*91f16700Schasinglulu 115*91f16700Schasinglulu p_sdhandle = sdio_init(); 116*91f16700Schasinglulu 117*91f16700Schasinglulu if (p_sdhandle == NULL) { 118*91f16700Schasinglulu ERROR("eMMC init failed"); 119*91f16700Schasinglulu return result; 120*91f16700Schasinglulu } 121*91f16700Schasinglulu 122*91f16700Schasinglulu if (card_rdy_only) { 123*91f16700Schasinglulu /* Put the card in Ready state, Not complete init */ 124*91f16700Schasinglulu result = bcm_emmc_card_ready_state(p_sdhandle); 125*91f16700Schasinglulu return !result; 126*91f16700Schasinglulu } 127*91f16700Schasinglulu 128*91f16700Schasinglulu if (sdio_idle(p_sdhandle) == EMMC_BOOT_OK) { 129*91f16700Schasinglulu set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, USE_DMA, 130*91f16700Schasinglulu SD_DMA_BOUNDARY_256K, EMMC_BLOCK_SIZE, 131*91f16700Schasinglulu EMMC_WFE_RETRY); 132*91f16700Schasinglulu 133*91f16700Schasinglulu if (!select_blk_sz(p_sdhandle, 134*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize)) { 135*91f16700Schasinglulu emmc_global_vars_ptr->init_done = 1; 136*91f16700Schasinglulu result = 1; 137*91f16700Schasinglulu } else { 138*91f16700Schasinglulu ERROR("Select Block Size failed\n"); 139*91f16700Schasinglulu } 140*91f16700Schasinglulu } else { 141*91f16700Schasinglulu ERROR("eMMC init failed"); 142*91f16700Schasinglulu } 143*91f16700Schasinglulu 144*91f16700Schasinglulu /* Initialization is failed, so deinit HW setting */ 145*91f16700Schasinglulu if (result == 0) 146*91f16700Schasinglulu emmc_deinit(); 147*91f16700Schasinglulu 148*91f16700Schasinglulu return result; 149*91f16700Schasinglulu } 150*91f16700Schasinglulu 151*91f16700Schasinglulu /* 152*91f16700Schasinglulu * Function to de-init SDIO controller for eMMC 153*91f16700Schasinglulu */ 154*91f16700Schasinglulu void emmc_deinit(void) 155*91f16700Schasinglulu { 156*91f16700Schasinglulu emmc_global_vars_ptr->init_done = 0; 157*91f16700Schasinglulu emmc_global_vars_ptr->sdHandle.card = 0; 158*91f16700Schasinglulu emmc_global_vars_ptr->sdHandle.device = 0; 159*91f16700Schasinglulu } 160*91f16700Schasinglulu 161*91f16700Schasinglulu /* 162*91f16700Schasinglulu * Read eMMC memory 163*91f16700Schasinglulu * Returns read_size 164*91f16700Schasinglulu */ 165*91f16700Schasinglulu uint32_t emmc_read(uintptr_t mem_addr, uintptr_t storage_addr, 166*91f16700Schasinglulu size_t storage_size, size_t bytes_to_read) 167*91f16700Schasinglulu { 168*91f16700Schasinglulu struct sd_handle *sd_handle = sdio_gethandle(); 169*91f16700Schasinglulu 170*91f16700Schasinglulu if (sd_handle->device == 0) { 171*91f16700Schasinglulu EMMC_TRACE("eMMC init is not done"); 172*91f16700Schasinglulu return 0; 173*91f16700Schasinglulu } 174*91f16700Schasinglulu 175*91f16700Schasinglulu return sdio_read(sdio_gethandle(), mem_addr, storage_addr, 176*91f16700Schasinglulu storage_size, bytes_to_read); 177*91f16700Schasinglulu } 178*91f16700Schasinglulu 179*91f16700Schasinglulu #ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE 180*91f16700Schasinglulu #define EXT_CSD_ERASE_GRP_SIZE 224 181*91f16700Schasinglulu 182*91f16700Schasinglulu static int emmc_block_erase(uintptr_t mem_addr, size_t blocks) 183*91f16700Schasinglulu { 184*91f16700Schasinglulu struct sd_handle *sd_handle = sdio_gethandle(); 185*91f16700Schasinglulu 186*91f16700Schasinglulu if (sd_handle->device == 0) { 187*91f16700Schasinglulu ERROR("eMMC init is not done"); 188*91f16700Schasinglulu return -1; 189*91f16700Schasinglulu } 190*91f16700Schasinglulu 191*91f16700Schasinglulu return erase_card(sdio_gethandle(), mem_addr, blocks); 192*91f16700Schasinglulu } 193*91f16700Schasinglulu 194*91f16700Schasinglulu int emmc_erase(uintptr_t mem_addr, size_t num_of_blocks, uint32_t partition) 195*91f16700Schasinglulu { 196*91f16700Schasinglulu int err = 0; 197*91f16700Schasinglulu size_t block_count = 0, blocks = 0; 198*91f16700Schasinglulu size_t erase_group = 0; 199*91f16700Schasinglulu 200*91f16700Schasinglulu erase_group = 201*91f16700Schasinglulu emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_ERASE_GRP_SIZE]*1024; 202*91f16700Schasinglulu 203*91f16700Schasinglulu INFO("eMMC Erase Group Size=0x%lx\n", erase_group); 204*91f16700Schasinglulu 205*91f16700Schasinglulu emmc_partition_select(partition); 206*91f16700Schasinglulu 207*91f16700Schasinglulu while (block_count < num_of_blocks) { 208*91f16700Schasinglulu blocks = ((num_of_blocks - block_count) > erase_group) ? 209*91f16700Schasinglulu erase_group : (num_of_blocks - block_count); 210*91f16700Schasinglulu err = emmc_block_erase(mem_addr + block_count, blocks); 211*91f16700Schasinglulu if (err) 212*91f16700Schasinglulu break; 213*91f16700Schasinglulu 214*91f16700Schasinglulu block_count += blocks; 215*91f16700Schasinglulu } 216*91f16700Schasinglulu 217*91f16700Schasinglulu if (err == 0) 218*91f16700Schasinglulu INFO("eMMC Erase of partition %d successful\n", partition); 219*91f16700Schasinglulu else 220*91f16700Schasinglulu ERROR("eMMC Erase of partition %d Failed(%i)\n", partition, err); 221*91f16700Schasinglulu 222*91f16700Schasinglulu return err; 223*91f16700Schasinglulu } 224*91f16700Schasinglulu #endif 225*91f16700Schasinglulu 226*91f16700Schasinglulu #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE 227*91f16700Schasinglulu /* 228*91f16700Schasinglulu * Write to eMMC memory 229*91f16700Schasinglulu * Returns written_size 230*91f16700Schasinglulu */ 231*91f16700Schasinglulu uint32_t emmc_write(uintptr_t mem_addr, uintptr_t data_addr, 232*91f16700Schasinglulu size_t bytes_to_write) 233*91f16700Schasinglulu { 234*91f16700Schasinglulu struct sd_handle *sd_handle = sdio_gethandle(); 235*91f16700Schasinglulu 236*91f16700Schasinglulu if (sd_handle->device == 0) { 237*91f16700Schasinglulu EMMC_TRACE("eMMC init is not done"); 238*91f16700Schasinglulu return 0; 239*91f16700Schasinglulu } 240*91f16700Schasinglulu 241*91f16700Schasinglulu return sdio_write(sd_handle, mem_addr, data_addr, bytes_to_write); 242*91f16700Schasinglulu } 243*91f16700Schasinglulu #endif 244*91f16700Schasinglulu 245*91f16700Schasinglulu /* 246*91f16700Schasinglulu * Send SDIO Cmd 247*91f16700Schasinglulu * Return 0 for pass condition 248*91f16700Schasinglulu */ 249*91f16700Schasinglulu uint32_t send_sdio_cmd(uint32_t cmdIndex, uint32_t argument, 250*91f16700Schasinglulu uint32_t options, struct sd_resp *resp) 251*91f16700Schasinglulu { 252*91f16700Schasinglulu struct sd_handle *sd_handle = sdio_gethandle(); 253*91f16700Schasinglulu 254*91f16700Schasinglulu if (sd_handle->device == 0) { 255*91f16700Schasinglulu EMMC_TRACE("eMMC init is not done"); 256*91f16700Schasinglulu return 1; 257*91f16700Schasinglulu } 258*91f16700Schasinglulu 259*91f16700Schasinglulu return send_cmd(sd_handle, cmdIndex, argument, options, resp); 260*91f16700Schasinglulu } 261*91f16700Schasinglulu 262*91f16700Schasinglulu 263*91f16700Schasinglulu /* 264*91f16700Schasinglulu * This function return SDIO handle 265*91f16700Schasinglulu */ 266*91f16700Schasinglulu struct sd_handle *sdio_gethandle(void) 267*91f16700Schasinglulu { 268*91f16700Schasinglulu return &emmc_global_vars_ptr->sdHandle; 269*91f16700Schasinglulu } 270*91f16700Schasinglulu 271*91f16700Schasinglulu /* 272*91f16700Schasinglulu * Initialize SDIO controller 273*91f16700Schasinglulu */ 274*91f16700Schasinglulu struct sd_handle *sdio_init(void) 275*91f16700Schasinglulu { 276*91f16700Schasinglulu uint32_t SDIO_base; 277*91f16700Schasinglulu struct sd_handle *p_sdhandle = &emmc_global_vars_ptr->sdHandle; 278*91f16700Schasinglulu 279*91f16700Schasinglulu SDIO_base = EMMC_CTRL_REGS_BASE_ADDR; 280*91f16700Schasinglulu 281*91f16700Schasinglulu if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR) { 282*91f16700Schasinglulu EMMC_TRACE(" ---> for SDIO 0 Controller\n\n"); 283*91f16700Schasinglulu } 284*91f16700Schasinglulu 285*91f16700Schasinglulu memset(p_sdhandle, 0, sizeof(struct sd_handle)); 286*91f16700Schasinglulu 287*91f16700Schasinglulu p_sdhandle->device = &emmc_global_vars_ptr->sdDevice; 288*91f16700Schasinglulu p_sdhandle->card = &emmc_global_vars_ptr->sdCard; 289*91f16700Schasinglulu 290*91f16700Schasinglulu memset(p_sdhandle->device, 0, sizeof(struct sd_dev)); 291*91f16700Schasinglulu memset(p_sdhandle->card, 0, sizeof(struct sd_card_info)); 292*91f16700Schasinglulu 293*91f16700Schasinglulu if (chal_sd_start((CHAL_HANDLE *) p_sdhandle->device, 294*91f16700Schasinglulu SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK) { 295*91f16700Schasinglulu return NULL; 296*91f16700Schasinglulu } 297*91f16700Schasinglulu 298*91f16700Schasinglulu set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, SD_DMA_OFF, 299*91f16700Schasinglulu SD_DMA_BOUNDARY_4K, EMMC_BLOCK_SIZE, EMMC_WFE_RETRY); 300*91f16700Schasinglulu 301*91f16700Schasinglulu return &emmc_global_vars_ptr->sdHandle; 302*91f16700Schasinglulu } 303*91f16700Schasinglulu 304*91f16700Schasinglulu uint32_t sdio_idle(struct sd_handle *p_sdhandle) 305*91f16700Schasinglulu { 306*91f16700Schasinglulu reset_card(p_sdhandle); 307*91f16700Schasinglulu 308*91f16700Schasinglulu SD_US_DELAY(1000); 309*91f16700Schasinglulu 310*91f16700Schasinglulu if (init_card(p_sdhandle, SD_CARD_DETECT_MMC) != SD_OK) { 311*91f16700Schasinglulu reset_card(p_sdhandle); 312*91f16700Schasinglulu reset_host_ctrl(p_sdhandle); 313*91f16700Schasinglulu return EMMC_BOOT_NO_CARD; 314*91f16700Schasinglulu } 315*91f16700Schasinglulu 316*91f16700Schasinglulu return EMMC_BOOT_OK; 317*91f16700Schasinglulu } 318*91f16700Schasinglulu 319*91f16700Schasinglulu /* 320*91f16700Schasinglulu * This function read eMMC 321*91f16700Schasinglulu */ 322*91f16700Schasinglulu uint32_t sdio_read(struct sd_handle *p_sdhandle, 323*91f16700Schasinglulu uintptr_t mem_addr, 324*91f16700Schasinglulu uintptr_t storage_addr, 325*91f16700Schasinglulu size_t storage_size, size_t bytes_to_read) 326*91f16700Schasinglulu { 327*91f16700Schasinglulu uint32_t offset = 0, blockAddr, readLen = 0, rdCount; 328*91f16700Schasinglulu uint32_t remSize, manual_copy_size; 329*91f16700Schasinglulu uint8_t *outputBuf = (uint8_t *) storage_addr; 330*91f16700Schasinglulu const size_t blockSize = p_sdhandle->device->cfg.blockSize; 331*91f16700Schasinglulu 332*91f16700Schasinglulu VERBOSE("EMMC READ: dst=0x%lx, src=0x%lx, size=0x%lx\n", 333*91f16700Schasinglulu storage_addr, mem_addr, bytes_to_read); 334*91f16700Schasinglulu 335*91f16700Schasinglulu if (storage_size < bytes_to_read) { 336*91f16700Schasinglulu /* Don't have sufficient storage to complete the operation */ 337*91f16700Schasinglulu return 0; 338*91f16700Schasinglulu } 339*91f16700Schasinglulu 340*91f16700Schasinglulu /* Range check non high capacity memory */ 341*91f16700Schasinglulu if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) { 342*91f16700Schasinglulu if (mem_addr > 0x80000000) { 343*91f16700Schasinglulu return 0; 344*91f16700Schasinglulu } 345*91f16700Schasinglulu } 346*91f16700Schasinglulu 347*91f16700Schasinglulu /* High capacity card use block address mode */ 348*91f16700Schasinglulu if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { 349*91f16700Schasinglulu blockAddr = (uint32_t) (mem_addr / blockSize); 350*91f16700Schasinglulu offset = (uint32_t) (mem_addr - (blockAddr * blockSize)); 351*91f16700Schasinglulu } else { 352*91f16700Schasinglulu blockAddr = (uint32_t) (mem_addr / blockSize) * blockSize; 353*91f16700Schasinglulu offset = (uint32_t) (mem_addr - blockAddr); 354*91f16700Schasinglulu } 355*91f16700Schasinglulu 356*91f16700Schasinglulu remSize = bytes_to_read; 357*91f16700Schasinglulu 358*91f16700Schasinglulu rdCount = 0; 359*91f16700Schasinglulu 360*91f16700Schasinglulu /* Process first unaligned block of MAX_READ_LENGTH */ 361*91f16700Schasinglulu if (offset > 0) { 362*91f16700Schasinglulu if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, 363*91f16700Schasinglulu blockAddr, SD_MAX_READ_LENGTH)) { 364*91f16700Schasinglulu 365*91f16700Schasinglulu if (remSize < (blockSize - offset)) { 366*91f16700Schasinglulu rdCount += remSize; 367*91f16700Schasinglulu manual_copy_size = remSize; 368*91f16700Schasinglulu remSize = 0; /* read is done */ 369*91f16700Schasinglulu } else { 370*91f16700Schasinglulu remSize -= (blockSize - offset); 371*91f16700Schasinglulu rdCount += (blockSize - offset); 372*91f16700Schasinglulu manual_copy_size = blockSize - offset; 373*91f16700Schasinglulu } 374*91f16700Schasinglulu 375*91f16700Schasinglulu /* Check for overflow */ 376*91f16700Schasinglulu if (manual_copy_size > storage_size || 377*91f16700Schasinglulu (((uintptr_t)outputBuf + manual_copy_size) > 378*91f16700Schasinglulu (storage_addr + storage_size))) { 379*91f16700Schasinglulu ERROR("EMMC READ: Overflow 1\n"); 380*91f16700Schasinglulu return 0; 381*91f16700Schasinglulu } 382*91f16700Schasinglulu 383*91f16700Schasinglulu memcpy(outputBuf, 384*91f16700Schasinglulu (void *)((uintptr_t) 385*91f16700Schasinglulu (emmc_global_buf_ptr->u.tempbuf + offset)), 386*91f16700Schasinglulu manual_copy_size); 387*91f16700Schasinglulu 388*91f16700Schasinglulu /* Update Physical address */ 389*91f16700Schasinglulu outputBuf += manual_copy_size; 390*91f16700Schasinglulu 391*91f16700Schasinglulu if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { 392*91f16700Schasinglulu blockAddr++; 393*91f16700Schasinglulu } else { 394*91f16700Schasinglulu blockAddr += blockSize; 395*91f16700Schasinglulu } 396*91f16700Schasinglulu } else { 397*91f16700Schasinglulu return 0; 398*91f16700Schasinglulu } 399*91f16700Schasinglulu } 400*91f16700Schasinglulu 401*91f16700Schasinglulu while (remSize >= blockSize) { 402*91f16700Schasinglulu 403*91f16700Schasinglulu if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH) { 404*91f16700Schasinglulu readLen = SD_MAX_BLK_TRANSFER_LENGTH; 405*91f16700Schasinglulu } else { 406*91f16700Schasinglulu readLen = (remSize / blockSize) * blockSize; 407*91f16700Schasinglulu } 408*91f16700Schasinglulu 409*91f16700Schasinglulu /* Check for overflow */ 410*91f16700Schasinglulu if ((rdCount + readLen) > storage_size || 411*91f16700Schasinglulu (((uintptr_t) outputBuf + readLen) > 412*91f16700Schasinglulu (storage_addr + storage_size))) { 413*91f16700Schasinglulu ERROR("EMMC READ: Overflow\n"); 414*91f16700Schasinglulu return 0; 415*91f16700Schasinglulu } 416*91f16700Schasinglulu 417*91f16700Schasinglulu if (!read_block(p_sdhandle, outputBuf, blockAddr, readLen)) { 418*91f16700Schasinglulu if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { 419*91f16700Schasinglulu blockAddr += (readLen / blockSize); 420*91f16700Schasinglulu } else { 421*91f16700Schasinglulu blockAddr += readLen; 422*91f16700Schasinglulu } 423*91f16700Schasinglulu 424*91f16700Schasinglulu remSize -= readLen; 425*91f16700Schasinglulu rdCount += readLen; 426*91f16700Schasinglulu 427*91f16700Schasinglulu /* Update Physical address */ 428*91f16700Schasinglulu outputBuf += readLen; 429*91f16700Schasinglulu } else { 430*91f16700Schasinglulu return 0; 431*91f16700Schasinglulu } 432*91f16700Schasinglulu } 433*91f16700Schasinglulu 434*91f16700Schasinglulu /* process the last unaligned block reading */ 435*91f16700Schasinglulu if (remSize > 0) { 436*91f16700Schasinglulu if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, 437*91f16700Schasinglulu blockAddr, SD_MAX_READ_LENGTH)) { 438*91f16700Schasinglulu 439*91f16700Schasinglulu rdCount += remSize; 440*91f16700Schasinglulu /* Check for overflow */ 441*91f16700Schasinglulu if (rdCount > storage_size || 442*91f16700Schasinglulu (((uintptr_t) outputBuf + remSize) > 443*91f16700Schasinglulu (storage_addr + storage_size))) { 444*91f16700Schasinglulu ERROR("EMMC READ: Overflow\n"); 445*91f16700Schasinglulu return 0; 446*91f16700Schasinglulu } 447*91f16700Schasinglulu 448*91f16700Schasinglulu memcpy(outputBuf, 449*91f16700Schasinglulu emmc_global_buf_ptr->u.tempbuf, remSize); 450*91f16700Schasinglulu 451*91f16700Schasinglulu /* Update Physical address */ 452*91f16700Schasinglulu outputBuf += remSize; 453*91f16700Schasinglulu } else { 454*91f16700Schasinglulu rdCount = 0; 455*91f16700Schasinglulu } 456*91f16700Schasinglulu } 457*91f16700Schasinglulu 458*91f16700Schasinglulu return rdCount; 459*91f16700Schasinglulu } 460*91f16700Schasinglulu 461*91f16700Schasinglulu #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE 462*91f16700Schasinglulu static uint32_t sdio_write(struct sd_handle *p_sdhandle, uintptr_t mem_addr, 463*91f16700Schasinglulu uintptr_t data_addr, size_t bytes_to_write) 464*91f16700Schasinglulu { 465*91f16700Schasinglulu 466*91f16700Schasinglulu uint32_t offset, blockAddr, writeLen, wtCount = 0; 467*91f16700Schasinglulu uint32_t remSize, manual_copy_size = 0; 468*91f16700Schasinglulu 469*91f16700Schasinglulu uint8_t *inputBuf = (uint8_t *)data_addr; 470*91f16700Schasinglulu 471*91f16700Schasinglulu /* range check non high capacity memory */ 472*91f16700Schasinglulu if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) { 473*91f16700Schasinglulu if (mem_addr > 0x80000000) { 474*91f16700Schasinglulu return 0; 475*91f16700Schasinglulu } 476*91f16700Schasinglulu } 477*91f16700Schasinglulu 478*91f16700Schasinglulu /* the high capacity card use block address mode */ 479*91f16700Schasinglulu if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { 480*91f16700Schasinglulu blockAddr = 481*91f16700Schasinglulu (uint32_t)(mem_addr / p_sdhandle->device->cfg.blockSize); 482*91f16700Schasinglulu offset = 483*91f16700Schasinglulu (uint32_t)(mem_addr - 484*91f16700Schasinglulu blockAddr * p_sdhandle->device->cfg.blockSize); 485*91f16700Schasinglulu } else { 486*91f16700Schasinglulu blockAddr = 487*91f16700Schasinglulu ((uint32_t)mem_addr / p_sdhandle->device->cfg.blockSize) * 488*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize; 489*91f16700Schasinglulu offset = (uint32_t) mem_addr - blockAddr; 490*91f16700Schasinglulu } 491*91f16700Schasinglulu 492*91f16700Schasinglulu remSize = bytes_to_write; 493*91f16700Schasinglulu 494*91f16700Schasinglulu wtCount = 0; 495*91f16700Schasinglulu 496*91f16700Schasinglulu /* process first unaligned block */ 497*91f16700Schasinglulu if (offset > 0) { 498*91f16700Schasinglulu if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, 499*91f16700Schasinglulu blockAddr, p_sdhandle->device->cfg.blockSize)) { 500*91f16700Schasinglulu 501*91f16700Schasinglulu if (remSize < 502*91f16700Schasinglulu (p_sdhandle->device->cfg.blockSize - offset)) { 503*91f16700Schasinglulu manual_copy_size = remSize; 504*91f16700Schasinglulu } else { 505*91f16700Schasinglulu manual_copy_size = 506*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize - offset; 507*91f16700Schasinglulu } 508*91f16700Schasinglulu 509*91f16700Schasinglulu memcpy((void *)((uintptr_t) 510*91f16700Schasinglulu (emmc_global_buf_ptr->u.tempbuf + offset)), 511*91f16700Schasinglulu inputBuf, 512*91f16700Schasinglulu manual_copy_size); 513*91f16700Schasinglulu 514*91f16700Schasinglulu /* Update Physical address */ 515*91f16700Schasinglulu 516*91f16700Schasinglulu if (!write_block(p_sdhandle, 517*91f16700Schasinglulu emmc_global_buf_ptr->u.tempbuf, 518*91f16700Schasinglulu blockAddr, 519*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize)) { 520*91f16700Schasinglulu 521*91f16700Schasinglulu if (remSize < 522*91f16700Schasinglulu (p_sdhandle->device->cfg.blockSize - 523*91f16700Schasinglulu offset)) { 524*91f16700Schasinglulu wtCount += remSize; 525*91f16700Schasinglulu manual_copy_size = remSize; 526*91f16700Schasinglulu remSize = 0; /* read is done */ 527*91f16700Schasinglulu } else { 528*91f16700Schasinglulu remSize -= 529*91f16700Schasinglulu (p_sdhandle->device->cfg.blockSize - 530*91f16700Schasinglulu offset); 531*91f16700Schasinglulu wtCount += 532*91f16700Schasinglulu (p_sdhandle->device->cfg.blockSize - 533*91f16700Schasinglulu offset); 534*91f16700Schasinglulu manual_copy_size = 535*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize - 536*91f16700Schasinglulu offset; 537*91f16700Schasinglulu } 538*91f16700Schasinglulu 539*91f16700Schasinglulu inputBuf += manual_copy_size; 540*91f16700Schasinglulu 541*91f16700Schasinglulu if (p_sdhandle->device->ctrl.ocr & 542*91f16700Schasinglulu SD_CARD_HIGH_CAPACITY) { 543*91f16700Schasinglulu blockAddr++; 544*91f16700Schasinglulu } else { 545*91f16700Schasinglulu blockAddr += 546*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize; 547*91f16700Schasinglulu } 548*91f16700Schasinglulu } else 549*91f16700Schasinglulu return 0; 550*91f16700Schasinglulu } else { 551*91f16700Schasinglulu return 0; 552*91f16700Schasinglulu } 553*91f16700Schasinglulu } 554*91f16700Schasinglulu 555*91f16700Schasinglulu /* process block writing */ 556*91f16700Schasinglulu while (remSize >= p_sdhandle->device->cfg.blockSize) { 557*91f16700Schasinglulu if (remSize >= SD_MAX_READ_LENGTH) { 558*91f16700Schasinglulu writeLen = SD_MAX_READ_LENGTH; 559*91f16700Schasinglulu } else { 560*91f16700Schasinglulu writeLen = 561*91f16700Schasinglulu (remSize / p_sdhandle->device->cfg.blockSize) * 562*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize; 563*91f16700Schasinglulu } 564*91f16700Schasinglulu 565*91f16700Schasinglulu if (!write_block(p_sdhandle, inputBuf, blockAddr, writeLen)) { 566*91f16700Schasinglulu if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) 567*91f16700Schasinglulu blockAddr += 568*91f16700Schasinglulu (writeLen / 569*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize); 570*91f16700Schasinglulu else 571*91f16700Schasinglulu blockAddr += writeLen; 572*91f16700Schasinglulu 573*91f16700Schasinglulu remSize -= writeLen; 574*91f16700Schasinglulu wtCount += writeLen; 575*91f16700Schasinglulu inputBuf += writeLen; 576*91f16700Schasinglulu } else { 577*91f16700Schasinglulu return 0; 578*91f16700Schasinglulu } 579*91f16700Schasinglulu } 580*91f16700Schasinglulu 581*91f16700Schasinglulu /* process the last unaligned block reading */ 582*91f16700Schasinglulu if (remSize > 0) { 583*91f16700Schasinglulu if (!read_block(p_sdhandle, 584*91f16700Schasinglulu emmc_global_buf_ptr->u.tempbuf, 585*91f16700Schasinglulu blockAddr, p_sdhandle->device->cfg.blockSize)) { 586*91f16700Schasinglulu 587*91f16700Schasinglulu memcpy(emmc_global_buf_ptr->u.tempbuf, 588*91f16700Schasinglulu inputBuf, remSize); 589*91f16700Schasinglulu 590*91f16700Schasinglulu /* Update Physical address */ 591*91f16700Schasinglulu 592*91f16700Schasinglulu if (!write_block(p_sdhandle, 593*91f16700Schasinglulu emmc_global_buf_ptr->u.tempbuf, 594*91f16700Schasinglulu blockAddr, 595*91f16700Schasinglulu p_sdhandle->device->cfg.blockSize)) { 596*91f16700Schasinglulu wtCount += remSize; 597*91f16700Schasinglulu inputBuf += remSize; 598*91f16700Schasinglulu } else { 599*91f16700Schasinglulu return 0; 600*91f16700Schasinglulu } 601*91f16700Schasinglulu } else { 602*91f16700Schasinglulu wtCount = 0; 603*91f16700Schasinglulu } 604*91f16700Schasinglulu } 605*91f16700Schasinglulu 606*91f16700Schasinglulu return wtCount; 607*91f16700Schasinglulu } 608*91f16700Schasinglulu #endif 609*91f16700Schasinglulu 610*91f16700Schasinglulu /* 611*91f16700Schasinglulu * Function to put the card in Ready state by sending CMD0 and CMD1 612*91f16700Schasinglulu */ 613*91f16700Schasinglulu static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle) 614*91f16700Schasinglulu { 615*91f16700Schasinglulu int32_t result = 0; 616*91f16700Schasinglulu uint32_t argument = MMC_CMD_IDLE_RESET_ARG; /* Exit from Boot mode */ 617*91f16700Schasinglulu 618*91f16700Schasinglulu if (p_sdhandle) { 619*91f16700Schasinglulu send_sdio_cmd(SD_CMD_GO_IDLE_STATE, argument, 0, NULL); 620*91f16700Schasinglulu 621*91f16700Schasinglulu result = reset_card(p_sdhandle); 622*91f16700Schasinglulu if (result != SD_OK) { 623*91f16700Schasinglulu EMMC_TRACE("eMMC Reset error\n"); 624*91f16700Schasinglulu return SD_RESET_ERROR; 625*91f16700Schasinglulu } 626*91f16700Schasinglulu SD_US_DELAY(2000); 627*91f16700Schasinglulu result = mmc_cmd1(p_sdhandle); 628*91f16700Schasinglulu } 629*91f16700Schasinglulu 630*91f16700Schasinglulu return result; 631*91f16700Schasinglulu } 632