1*bffde63dSSheetal Tigadoli /* 2*bffde63dSSheetal Tigadoli * Copyright (c) 2016 - 2020, Broadcom 3*bffde63dSSheetal Tigadoli * 4*bffde63dSSheetal Tigadoli * SPDX-License-Identifier: BSD-3-Clause 5*bffde63dSSheetal Tigadoli */ 6*bffde63dSSheetal Tigadoli 7*bffde63dSSheetal Tigadoli #include <stdlib.h> 8*bffde63dSSheetal Tigadoli #include <string.h> 9*bffde63dSSheetal Tigadoli #include <stddef.h> 10*bffde63dSSheetal Tigadoli 11*bffde63dSSheetal Tigadoli #include <arch_helpers.h> 12*bffde63dSSheetal Tigadoli #include <lib/mmio.h> 13*bffde63dSSheetal Tigadoli 14*bffde63dSSheetal Tigadoli #include "bcm_emmc.h" 15*bffde63dSSheetal Tigadoli #include "emmc_chal_types.h" 16*bffde63dSSheetal Tigadoli #include "emmc_csl_sdprot.h" 17*bffde63dSSheetal Tigadoli #include "emmc_chal_sd.h" 18*bffde63dSSheetal Tigadoli #include "emmc_csl_sdcmd.h" 19*bffde63dSSheetal Tigadoli #include "emmc_csl_sd.h" 20*bffde63dSSheetal Tigadoli #include "emmc_pboot_hal_memory_drv.h" 21*bffde63dSSheetal Tigadoli 22*bffde63dSSheetal Tigadoli #define SD_CARD_BUSY 0x80000000 23*bffde63dSSheetal Tigadoli #define SD_CARD_RETRY_LIMIT 1000 24*bffde63dSSheetal Tigadoli #define SD_CARD_HIGH_SPEED_PS 13 25*bffde63dSSheetal Tigadoli #define SD_CHK_HIGH_SPEED_MODE 0x00FFFFF1 26*bffde63dSSheetal Tigadoli #define SD_SET_HIGH_SPEED_MODE 0x80FFFFF1 27*bffde63dSSheetal Tigadoli #define SD_MMC_ENABLE_HIGH_SPEED 0x03b90100 //0x03b90103 28*bffde63dSSheetal Tigadoli #define SD_MMC_8BIT_MODE 0x03b70200 29*bffde63dSSheetal Tigadoli #define SD_MMC_4BIT_MODE 0x03b70100 30*bffde63dSSheetal Tigadoli #define SD_MMC_1BIT_MODE 0x03b70000 31*bffde63dSSheetal Tigadoli 32*bffde63dSSheetal Tigadoli #define SD_MMC_BOOT_8BIT_MODE 0x03b10200 33*bffde63dSSheetal Tigadoli #define SD_MMC_BOOT_4BIT_MODE 0x03b10100 34*bffde63dSSheetal Tigadoli #define SD_MMC_BOOT_1BIT_MODE 0x03b10000 35*bffde63dSSheetal Tigadoli #define SDIO_HW_EMMC_EXT_CSD_BOOT_CNF 0X03B30000 36*bffde63dSSheetal Tigadoli 37*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE 38*bffde63dSSheetal Tigadoli /* 39*bffde63dSSheetal Tigadoli * Cache size mirrors the size of the global eMMC temp buffer 40*bffde63dSSheetal Tigadoli * which is used for non-image body reads such as headers, ToC etc. 41*bffde63dSSheetal Tigadoli */ 42*bffde63dSSheetal Tigadoli #define CACHE_SIZE ((EMMC_BLOCK_SIZE) * 2) 43*bffde63dSSheetal Tigadoli #define PARTITION_BLOCK_ADDR ((PLAT_FIP_ATTEMPT_OFFSET)/(EMMC_BLOCK_SIZE)) 44*bffde63dSSheetal Tigadoli 45*bffde63dSSheetal Tigadoli static uint32_t cached_partition_block; 46*bffde63dSSheetal Tigadoli static uint8_t cached_block[CACHE_SIZE]; 47*bffde63dSSheetal Tigadoli #endif 48*bffde63dSSheetal Tigadoli 49*bffde63dSSheetal Tigadoli static int set_card_data_width(struct sd_handle *handle, int width); 50*bffde63dSSheetal Tigadoli static int abort_err(struct sd_handle *handle); 51*bffde63dSSheetal Tigadoli static int err_recovery(struct sd_handle *handle, uint32_t errors); 52*bffde63dSSheetal Tigadoli static int xfer_data(struct sd_handle *handle, uint32_t mode, uint32_t addr, 53*bffde63dSSheetal Tigadoli uint32_t length, uint8_t *base); 54*bffde63dSSheetal Tigadoli 55*bffde63dSSheetal Tigadoli int set_boot_config(struct sd_handle *handle, uint32_t config) 56*bffde63dSSheetal Tigadoli { 57*bffde63dSSheetal Tigadoli return mmc_cmd6(handle, SDIO_HW_EMMC_EXT_CSD_BOOT_CNF | config); 58*bffde63dSSheetal Tigadoli } 59*bffde63dSSheetal Tigadoli 60*bffde63dSSheetal Tigadoli void process_csd_mmc_speed(struct sd_handle *handle, uint32_t csd_mmc_speed) 61*bffde63dSSheetal Tigadoli { 62*bffde63dSSheetal Tigadoli uint32_t div_ctrl_setting; 63*bffde63dSSheetal Tigadoli 64*bffde63dSSheetal Tigadoli /* CSD field TRAN_SPEED: 65*bffde63dSSheetal Tigadoli * Bits [2:0] 0 = 100 KHz 66*bffde63dSSheetal Tigadoli * 1 = 1 MHz 67*bffde63dSSheetal Tigadoli * 2 = 10 MHz 68*bffde63dSSheetal Tigadoli * 3 = 100 MHz 69*bffde63dSSheetal Tigadoli * 4...7 Reserved. 70*bffde63dSSheetal Tigadoli * Bits [6:3] 0 = Reserved 71*bffde63dSSheetal Tigadoli * 1 = 1.0 72*bffde63dSSheetal Tigadoli * 2 = 1.2 73*bffde63dSSheetal Tigadoli * 3 = 1.3 74*bffde63dSSheetal Tigadoli * 4 = 1.5 75*bffde63dSSheetal Tigadoli * 5 = 2.0 76*bffde63dSSheetal Tigadoli * 6 = 2.6 77*bffde63dSSheetal Tigadoli * 7 = 3.0 78*bffde63dSSheetal Tigadoli * 8 = 3.5 79*bffde63dSSheetal Tigadoli * 9 = 4.0 80*bffde63dSSheetal Tigadoli * A = 4.5 81*bffde63dSSheetal Tigadoli * B = 5.2 82*bffde63dSSheetal Tigadoli * C = 5.5 83*bffde63dSSheetal Tigadoli * D = 6.0 84*bffde63dSSheetal Tigadoli * E = 7.0 85*bffde63dSSheetal Tigadoli * F = 8.0 86*bffde63dSSheetal Tigadoli * For cards supporting version 4.0, 4.1, and 4.2 of the standard, 87*bffde63dSSheetal Tigadoli * the value shall be 20 MHz (0x2A). 88*bffde63dSSheetal Tigadoli * For cards supporting version 4.3 , the value shall be 26 MHz (0x32) 89*bffde63dSSheetal Tigadoli */ 90*bffde63dSSheetal Tigadoli 91*bffde63dSSheetal Tigadoli switch (csd_mmc_speed & 0x7F) { 92*bffde63dSSheetal Tigadoli case 0x2A: 93*bffde63dSSheetal Tigadoli EMMC_TRACE("Speeding up eMMC clock to 20MHz\n"); 94*bffde63dSSheetal Tigadoli div_ctrl_setting = 95*bffde63dSSheetal Tigadoli chal_sd_freq_2_div_ctrl_setting(20 * 1000 * 1000); 96*bffde63dSSheetal Tigadoli break; 97*bffde63dSSheetal Tigadoli case 0x32: 98*bffde63dSSheetal Tigadoli EMMC_TRACE("Speeding up eMMC clock to 26MHz\n"); 99*bffde63dSSheetal Tigadoli div_ctrl_setting = 100*bffde63dSSheetal Tigadoli chal_sd_freq_2_div_ctrl_setting(26 * 1000 * 1000); 101*bffde63dSSheetal Tigadoli break; 102*bffde63dSSheetal Tigadoli default: 103*bffde63dSSheetal Tigadoli /* Unknown */ 104*bffde63dSSheetal Tigadoli return; 105*bffde63dSSheetal Tigadoli } 106*bffde63dSSheetal Tigadoli 107*bffde63dSSheetal Tigadoli chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 0); 108*bffde63dSSheetal Tigadoli 109*bffde63dSSheetal Tigadoli chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 1); 110*bffde63dSSheetal Tigadoli 111*bffde63dSSheetal Tigadoli SD_US_DELAY(1000); 112*bffde63dSSheetal Tigadoli } 113*bffde63dSSheetal Tigadoli 114*bffde63dSSheetal Tigadoli 115*bffde63dSSheetal Tigadoli /* 116*bffde63dSSheetal Tigadoli * The function changes SD/SDIO/MMC card data width if 117*bffde63dSSheetal Tigadoli * the card support configurable data width. The host controller 118*bffde63dSSheetal Tigadoli * and the card has to be in the same bus data width. 119*bffde63dSSheetal Tigadoli */ 120*bffde63dSSheetal Tigadoli int set_card_data_width(struct sd_handle *handle, int width) 121*bffde63dSSheetal Tigadoli { 122*bffde63dSSheetal Tigadoli uint32_t data_width = 0; 123*bffde63dSSheetal Tigadoli int is_valid_arg = 1; 124*bffde63dSSheetal Tigadoli int rc = SD_FAIL; 125*bffde63dSSheetal Tigadoli char *bitwidth_str = " "; 126*bffde63dSSheetal Tigadoli char *result_str = "failed"; 127*bffde63dSSheetal Tigadoli 128*bffde63dSSheetal Tigadoli switch (width) { 129*bffde63dSSheetal Tigadoli #ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT 130*bffde63dSSheetal Tigadoli case SD_BUS_DATA_WIDTH_8BIT: 131*bffde63dSSheetal Tigadoli data_width = SD_MMC_8BIT_MODE; 132*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 133*bffde63dSSheetal Tigadoli bitwidth_str = "8_BIT"; 134*bffde63dSSheetal Tigadoli #endif 135*bffde63dSSheetal Tigadoli break; 136*bffde63dSSheetal Tigadoli #endif 137*bffde63dSSheetal Tigadoli case SD_BUS_DATA_WIDTH_4BIT: 138*bffde63dSSheetal Tigadoli data_width = SD_MMC_4BIT_MODE; 139*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 140*bffde63dSSheetal Tigadoli bitwidth_str = "4_BIT"; 141*bffde63dSSheetal Tigadoli #endif 142*bffde63dSSheetal Tigadoli break; 143*bffde63dSSheetal Tigadoli 144*bffde63dSSheetal Tigadoli case SD_BUS_DATA_WIDTH_1BIT: 145*bffde63dSSheetal Tigadoli data_width = SD_MMC_1BIT_MODE; 146*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 147*bffde63dSSheetal Tigadoli bitwidth_str = "1_BIT"; 148*bffde63dSSheetal Tigadoli #endif 149*bffde63dSSheetal Tigadoli break; 150*bffde63dSSheetal Tigadoli 151*bffde63dSSheetal Tigadoli default: 152*bffde63dSSheetal Tigadoli is_valid_arg = 0; 153*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 154*bffde63dSSheetal Tigadoli bitwidth_str = "unknown"; 155*bffde63dSSheetal Tigadoli #endif 156*bffde63dSSheetal Tigadoli break; 157*bffde63dSSheetal Tigadoli } 158*bffde63dSSheetal Tigadoli 159*bffde63dSSheetal Tigadoli if (is_valid_arg) { 160*bffde63dSSheetal Tigadoli rc = mmc_cmd6(handle, data_width); 161*bffde63dSSheetal Tigadoli if (rc == SD_OK) { 162*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 163*bffde63dSSheetal Tigadoli result_str = "succeeded"; 164*bffde63dSSheetal Tigadoli #endif 165*bffde63dSSheetal Tigadoli chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, 166*bffde63dSSheetal Tigadoli width); 167*bffde63dSSheetal Tigadoli } else { 168*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 169*bffde63dSSheetal Tigadoli result_str = "failed"; 170*bffde63dSSheetal Tigadoli #endif 171*bffde63dSSheetal Tigadoli } 172*bffde63dSSheetal Tigadoli } else { 173*bffde63dSSheetal Tigadoli rc = SD_FAIL; 174*bffde63dSSheetal Tigadoli #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 175*bffde63dSSheetal Tigadoli result_str = "ignored"; 176*bffde63dSSheetal Tigadoli #endif 177*bffde63dSSheetal Tigadoli } 178*bffde63dSSheetal Tigadoli 179*bffde63dSSheetal Tigadoli VERBOSE("SDIO Data Width(%s) %s.\n", bitwidth_str, result_str); 180*bffde63dSSheetal Tigadoli 181*bffde63dSSheetal Tigadoli return rc; 182*bffde63dSSheetal Tigadoli } 183*bffde63dSSheetal Tigadoli 184*bffde63dSSheetal Tigadoli 185*bffde63dSSheetal Tigadoli /* 186*bffde63dSSheetal Tigadoli * Error handling routine. Does abort data 187*bffde63dSSheetal Tigadoli * transmission if error is found. 188*bffde63dSSheetal Tigadoli */ 189*bffde63dSSheetal Tigadoli static int abort_err(struct sd_handle *handle) 190*bffde63dSSheetal Tigadoli { 191*bffde63dSSheetal Tigadoli uint32_t present, options, event, rel = 0; 192*bffde63dSSheetal Tigadoli struct sd_resp cmdRsp; 193*bffde63dSSheetal Tigadoli 194*bffde63dSSheetal Tigadoli handle->device->ctrl.argReg = 0; 195*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdIndex = SD_CMD_STOP_TRANSMISSION; 196*bffde63dSSheetal Tigadoli 197*bffde63dSSheetal Tigadoli options = (SD_CMD_STOP_TRANSMISSION << 24) | 198*bffde63dSSheetal Tigadoli (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) | 199*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_CMD_CRC_EN_MASK | 200*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_CMD_CCHK_EN_MASK; 201*bffde63dSSheetal Tigadoli 202*bffde63dSSheetal Tigadoli chal_sd_send_cmd((CHAL_HANDLE *) handle->device, 203*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdIndex, 204*bffde63dSSheetal Tigadoli handle->device->ctrl.argReg, options); 205*bffde63dSSheetal Tigadoli 206*bffde63dSSheetal Tigadoli event = wait_for_event(handle, 207*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_CMDDONE_MASK | 208*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 209*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry); 210*bffde63dSSheetal Tigadoli 211*bffde63dSSheetal Tigadoli if (event & SD_CMD_ERROR_INT) { 212*bffde63dSSheetal Tigadoli rel = SD_ERROR_NON_RECOVERABLE; 213*bffde63dSSheetal Tigadoli } else { 214*bffde63dSSheetal Tigadoli if (event & SD_DAT_TIMEOUT) { 215*bffde63dSSheetal Tigadoli return SD_ERROR_NON_RECOVERABLE; 216*bffde63dSSheetal Tigadoli } 217*bffde63dSSheetal Tigadoli 218*bffde63dSSheetal Tigadoli chal_sd_get_response((CHAL_HANDLE *) handle->device, 219*bffde63dSSheetal Tigadoli (uint32_t *)&cmdRsp); 220*bffde63dSSheetal Tigadoli 221*bffde63dSSheetal Tigadoli process_cmd_response(handle, handle->device->ctrl.cmdIndex, 222*bffde63dSSheetal Tigadoli cmdRsp.data.r2.rsp1, cmdRsp.data.r2.rsp2, 223*bffde63dSSheetal Tigadoli cmdRsp.data.r2.rsp3, cmdRsp.data.r2.rsp4, 224*bffde63dSSheetal Tigadoli &cmdRsp); 225*bffde63dSSheetal Tigadoli 226*bffde63dSSheetal Tigadoli SD_US_DELAY(2000); 227*bffde63dSSheetal Tigadoli 228*bffde63dSSheetal Tigadoli present = 229*bffde63dSSheetal Tigadoli chal_sd_get_present_status((CHAL_HANDLE *) handle->device); 230*bffde63dSSheetal Tigadoli 231*bffde63dSSheetal Tigadoli if ((present & 0x00F00000) == 0x00F00000) 232*bffde63dSSheetal Tigadoli rel = SD_ERROR_RECOVERABLE; 233*bffde63dSSheetal Tigadoli else 234*bffde63dSSheetal Tigadoli rel = SD_ERROR_NON_RECOVERABLE; 235*bffde63dSSheetal Tigadoli } 236*bffde63dSSheetal Tigadoli 237*bffde63dSSheetal Tigadoli return rel; 238*bffde63dSSheetal Tigadoli } 239*bffde63dSSheetal Tigadoli 240*bffde63dSSheetal Tigadoli 241*bffde63dSSheetal Tigadoli /* 242*bffde63dSSheetal Tigadoli * The function handles real data transmission on both DMA and 243*bffde63dSSheetal Tigadoli * none DMA mode, In None DMA mode the data transfer starts 244*bffde63dSSheetal Tigadoli * when the command is sent to the card, data has to be written 245*bffde63dSSheetal Tigadoli * into the host contollers buffer at this time one block 246*bffde63dSSheetal Tigadoli * at a time. 247*bffde63dSSheetal Tigadoli * In DMA mode, the real data transfer is done by the DMA engine 248*bffde63dSSheetal Tigadoli * and this functions just waits for the data transfer to complete. 249*bffde63dSSheetal Tigadoli * 250*bffde63dSSheetal Tigadoli */ 251*bffde63dSSheetal Tigadoli int process_data_xfer(struct sd_handle *handle, uint8_t *buffer, uint32_t addr, 252*bffde63dSSheetal Tigadoli uint32_t length, int dir) 253*bffde63dSSheetal Tigadoli { 254*bffde63dSSheetal Tigadoli if (dir == SD_XFER_HOST_TO_CARD) { 255*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE 256*bffde63dSSheetal Tigadoli if (handle->device->cfg.dma == SD_DMA_OFF) { 257*bffde63dSSheetal Tigadoli /* 258*bffde63dSSheetal Tigadoli * In NON DMA mode, the real data xfer starts from here 259*bffde63dSSheetal Tigadoli */ 260*bffde63dSSheetal Tigadoli if (write_buffer(handle, length, buffer)) 261*bffde63dSSheetal Tigadoli return SD_WRITE_ERROR; 262*bffde63dSSheetal Tigadoli } else { 263*bffde63dSSheetal Tigadoli wait_for_event(handle, 264*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_TXDONE_MASK | 265*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 266*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry); 267*bffde63dSSheetal Tigadoli 268*bffde63dSSheetal Tigadoli if (handle->device->ctrl.cmdStatus == SD_OK) 269*bffde63dSSheetal Tigadoli return SD_OK; 270*bffde63dSSheetal Tigadoli 271*bffde63dSSheetal Tigadoli check_error(handle, handle->device->ctrl.cmdStatus); 272*bffde63dSSheetal Tigadoli return SD_WRITE_ERROR; 273*bffde63dSSheetal Tigadoli } 274*bffde63dSSheetal Tigadoli #else 275*bffde63dSSheetal Tigadoli return SD_WRITE_ERROR; 276*bffde63dSSheetal Tigadoli #endif 277*bffde63dSSheetal Tigadoli } else { /* SD_XFER_CARD_TO_HOST */ 278*bffde63dSSheetal Tigadoli 279*bffde63dSSheetal Tigadoli if (handle->device->cfg.dma == SD_DMA_OFF) { 280*bffde63dSSheetal Tigadoli /* In NON DMA mode, the real data 281*bffde63dSSheetal Tigadoli * transfer starts from here 282*bffde63dSSheetal Tigadoli */ 283*bffde63dSSheetal Tigadoli if (read_buffer(handle, length, buffer)) 284*bffde63dSSheetal Tigadoli return SD_READ_ERROR; 285*bffde63dSSheetal Tigadoli 286*bffde63dSSheetal Tigadoli } else { /* for DMA mode */ 287*bffde63dSSheetal Tigadoli 288*bffde63dSSheetal Tigadoli /* 289*bffde63dSSheetal Tigadoli * once the data transmission is done 290*bffde63dSSheetal Tigadoli * copy data to the host buffer. 291*bffde63dSSheetal Tigadoli */ 292*bffde63dSSheetal Tigadoli wait_for_event(handle, 293*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_TXDONE_MASK | 294*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 295*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry); 296*bffde63dSSheetal Tigadoli 297*bffde63dSSheetal Tigadoli if (handle->device->ctrl.cmdStatus == SD_OK) 298*bffde63dSSheetal Tigadoli return SD_OK; 299*bffde63dSSheetal Tigadoli 300*bffde63dSSheetal Tigadoli check_error(handle, handle->device->ctrl.cmdStatus); 301*bffde63dSSheetal Tigadoli return SD_READ_ERROR; 302*bffde63dSSheetal Tigadoli } 303*bffde63dSSheetal Tigadoli } 304*bffde63dSSheetal Tigadoli return SD_OK; 305*bffde63dSSheetal Tigadoli } 306*bffde63dSSheetal Tigadoli 307*bffde63dSSheetal Tigadoli 308*bffde63dSSheetal Tigadoli /* 309*bffde63dSSheetal Tigadoli * The function sets block size for the next SD/SDIO/MMC 310*bffde63dSSheetal Tigadoli * card read/write command. 311*bffde63dSSheetal Tigadoli */ 312*bffde63dSSheetal Tigadoli int select_blk_sz(struct sd_handle *handle, uint16_t size) 313*bffde63dSSheetal Tigadoli { 314*bffde63dSSheetal Tigadoli return sd_cmd16(handle, size); 315*bffde63dSSheetal Tigadoli } 316*bffde63dSSheetal Tigadoli 317*bffde63dSSheetal Tigadoli 318*bffde63dSSheetal Tigadoli /* 319*bffde63dSSheetal Tigadoli * The function initalizes the SD/SDIO/MMC/CEATA and detects 320*bffde63dSSheetal Tigadoli * the card according to the flag of detection. 321*bffde63dSSheetal Tigadoli * Once this function is called, the card is put into ready state 322*bffde63dSSheetal Tigadoli * so application can do data transfer to and from the card. 323*bffde63dSSheetal Tigadoli */ 324*bffde63dSSheetal Tigadoli int init_card(struct sd_handle *handle, int detection) 325*bffde63dSSheetal Tigadoli { 326*bffde63dSSheetal Tigadoli /* 327*bffde63dSSheetal Tigadoli * After Reset, eMMC comes up in 1 Bit Data Width by default. 328*bffde63dSSheetal Tigadoli * Set host side to match. 329*bffde63dSSheetal Tigadoli */ 330*bffde63dSSheetal Tigadoli chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, 331*bffde63dSSheetal Tigadoli SD_BUS_DATA_WIDTH_1BIT); 332*bffde63dSSheetal Tigadoli 333*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE 334*bffde63dSSheetal Tigadoli cached_partition_block = 0; 335*bffde63dSSheetal Tigadoli #endif 336*bffde63dSSheetal Tigadoli handle->device->ctrl.present = 0; /* init card present to be no card */ 337*bffde63dSSheetal Tigadoli 338*bffde63dSSheetal Tigadoli init_mmc_card(handle); 339*bffde63dSSheetal Tigadoli 340*bffde63dSSheetal Tigadoli handle->device->ctrl.present = 1; /* card is detected */ 341*bffde63dSSheetal Tigadoli 342*bffde63dSSheetal Tigadoli /* switch the data width back */ 343*bffde63dSSheetal Tigadoli if (handle->card->type != SD_CARD_MMC) 344*bffde63dSSheetal Tigadoli return SD_FAIL; 345*bffde63dSSheetal Tigadoli 346*bffde63dSSheetal Tigadoli /* 347*bffde63dSSheetal Tigadoli * Dynamically set Data Width to highest supported value. 348*bffde63dSSheetal Tigadoli * Try different data width settings (highest to lowest). 349*bffde63dSSheetal Tigadoli * Verify each setting by reading EXT_CSD and comparing 350*bffde63dSSheetal Tigadoli * against the EXT_CSD contents previously read in call to 351*bffde63dSSheetal Tigadoli * init_mmc_card() earlier. Stop at first verified data width 352*bffde63dSSheetal Tigadoli * setting. 353*bffde63dSSheetal Tigadoli */ 354*bffde63dSSheetal Tigadoli { 355*bffde63dSSheetal Tigadoli #define EXT_CSD_PROPERTIES_SECTION_START_INDEX 192 356*bffde63dSSheetal Tigadoli #define EXT_CSD_PROPERTIES_SECTION_END_INDEX 511 357*bffde63dSSheetal Tigadoli uint8_t buffer[EXT_CSD_SIZE]; 358*bffde63dSSheetal Tigadoli #ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT 359*bffde63dSSheetal Tigadoli /* Try 8 Bit Data Width */ 360*bffde63dSSheetal Tigadoli chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, 361*bffde63dSSheetal Tigadoli SD_BUS_DATA_WIDTH_8BIT); 362*bffde63dSSheetal Tigadoli if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_8BIT)) && 363*bffde63dSSheetal Tigadoli (!mmc_cmd8(handle, buffer)) && 364*bffde63dSSheetal Tigadoli (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX], 365*bffde63dSSheetal Tigadoli &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]), 366*bffde63dSSheetal Tigadoli EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1))) 367*bffde63dSSheetal Tigadoli 368*bffde63dSSheetal Tigadoli return SD_OK; 369*bffde63dSSheetal Tigadoli #endif 370*bffde63dSSheetal Tigadoli /* Fall back to 4 Bit Data Width */ 371*bffde63dSSheetal Tigadoli chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, 372*bffde63dSSheetal Tigadoli SD_BUS_DATA_WIDTH_4BIT); 373*bffde63dSSheetal Tigadoli if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_4BIT)) && 374*bffde63dSSheetal Tigadoli (!mmc_cmd8(handle, buffer)) && 375*bffde63dSSheetal Tigadoli (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX], 376*bffde63dSSheetal Tigadoli &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]), 377*bffde63dSSheetal Tigadoli EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1))) 378*bffde63dSSheetal Tigadoli 379*bffde63dSSheetal Tigadoli return SD_OK; 380*bffde63dSSheetal Tigadoli 381*bffde63dSSheetal Tigadoli /* Fall back to 1 Bit Data Width */ 382*bffde63dSSheetal Tigadoli chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, 383*bffde63dSSheetal Tigadoli SD_BUS_DATA_WIDTH_1BIT); 384*bffde63dSSheetal Tigadoli /* Just use 1 Bit Data Width then. */ 385*bffde63dSSheetal Tigadoli if (!set_card_data_width(handle, SD_BUS_DATA_WIDTH_1BIT)) 386*bffde63dSSheetal Tigadoli return SD_OK; 387*bffde63dSSheetal Tigadoli 388*bffde63dSSheetal Tigadoli } 389*bffde63dSSheetal Tigadoli return SD_CARD_INIT_ERROR; 390*bffde63dSSheetal Tigadoli } 391*bffde63dSSheetal Tigadoli 392*bffde63dSSheetal Tigadoli 393*bffde63dSSheetal Tigadoli /* 394*bffde63dSSheetal Tigadoli * The function handles MMC/CEATA card initalization. 395*bffde63dSSheetal Tigadoli */ 396*bffde63dSSheetal Tigadoli int init_mmc_card(struct sd_handle *handle) 397*bffde63dSSheetal Tigadoli { 398*bffde63dSSheetal Tigadoli uint32_t ocr = 0, newOcr, rc, limit = 0; 399*bffde63dSSheetal Tigadoli uint32_t cmd1_option = 0x40300000; 400*bffde63dSSheetal Tigadoli uint32_t sec_count; 401*bffde63dSSheetal Tigadoli 402*bffde63dSSheetal Tigadoli handle->card->type = SD_CARD_MMC; 403*bffde63dSSheetal Tigadoli 404*bffde63dSSheetal Tigadoli do { 405*bffde63dSSheetal Tigadoli SD_US_DELAY(1000); 406*bffde63dSSheetal Tigadoli newOcr = 0; 407*bffde63dSSheetal Tigadoli ocr = 0; 408*bffde63dSSheetal Tigadoli rc = sd_cmd1(handle, cmd1_option, &newOcr); 409*bffde63dSSheetal Tigadoli limit++; 410*bffde63dSSheetal Tigadoli 411*bffde63dSSheetal Tigadoli if (rc == SD_OK) 412*bffde63dSSheetal Tigadoli ocr = newOcr; 413*bffde63dSSheetal Tigadoli 414*bffde63dSSheetal Tigadoli } while (((ocr & SD_CARD_BUSY) == 0) && (limit < SD_CARD_RETRY_LIMIT)); 415*bffde63dSSheetal Tigadoli 416*bffde63dSSheetal Tigadoli if (limit >= SD_CARD_RETRY_LIMIT) { 417*bffde63dSSheetal Tigadoli handle->card->type = SD_CARD_UNKNOWN; 418*bffde63dSSheetal Tigadoli EMMC_TRACE("CMD1 Timeout: Device is not ready\n"); 419*bffde63dSSheetal Tigadoli return SD_CARD_UNKNOWN; 420*bffde63dSSheetal Tigadoli } 421*bffde63dSSheetal Tigadoli 422*bffde63dSSheetal Tigadoli /* Save the ocr register */ 423*bffde63dSSheetal Tigadoli handle->device->ctrl.ocr = ocr; 424*bffde63dSSheetal Tigadoli 425*bffde63dSSheetal Tigadoli /* Ready State */ 426*bffde63dSSheetal Tigadoli rc = sd_cmd2(handle); 427*bffde63dSSheetal Tigadoli if (rc != SD_OK) { 428*bffde63dSSheetal Tigadoli handle->card->type = SD_CARD_UNKNOWN; 429*bffde63dSSheetal Tigadoli return SD_CARD_UNKNOWN; 430*bffde63dSSheetal Tigadoli } 431*bffde63dSSheetal Tigadoli 432*bffde63dSSheetal Tigadoli rc = sd_cmd3(handle); 433*bffde63dSSheetal Tigadoli if (rc != SD_OK) { 434*bffde63dSSheetal Tigadoli handle->card->type = SD_CARD_UNKNOWN; 435*bffde63dSSheetal Tigadoli return SD_CARD_UNKNOWN; 436*bffde63dSSheetal Tigadoli } 437*bffde63dSSheetal Tigadoli /* read CSD */ 438*bffde63dSSheetal Tigadoli rc = sd_cmd9(handle, &emmc_global_vars_ptr->cardData); 439*bffde63dSSheetal Tigadoli if (rc != SD_OK) { 440*bffde63dSSheetal Tigadoli handle->card->type = SD_CARD_UNKNOWN; 441*bffde63dSSheetal Tigadoli return SD_CARD_UNKNOWN; 442*bffde63dSSheetal Tigadoli } 443*bffde63dSSheetal Tigadoli 444*bffde63dSSheetal Tigadoli /* Increase clock frequency according to what the card advertises */ 445*bffde63dSSheetal Tigadoli EMMC_TRACE("From CSD... cardData.csd.mmc.speed = 0x%X\n", 446*bffde63dSSheetal Tigadoli emmc_global_vars_ptr->cardData.csd.mmc.speed); 447*bffde63dSSheetal Tigadoli process_csd_mmc_speed(handle, 448*bffde63dSSheetal Tigadoli emmc_global_vars_ptr->cardData.csd.mmc.speed); 449*bffde63dSSheetal Tigadoli 450*bffde63dSSheetal Tigadoli /* goto transfer mode */ 451*bffde63dSSheetal Tigadoli rc = sd_cmd7(handle, handle->device->ctrl.rca); 452*bffde63dSSheetal Tigadoli if (rc != SD_OK) { 453*bffde63dSSheetal Tigadoli handle->card->type = SD_CARD_UNKNOWN; 454*bffde63dSSheetal Tigadoli return SD_CARD_UNKNOWN; 455*bffde63dSSheetal Tigadoli } 456*bffde63dSSheetal Tigadoli 457*bffde63dSSheetal Tigadoli rc = mmc_cmd8(handle, emmc_global_buf_ptr->u.Ext_CSD_storage); 458*bffde63dSSheetal Tigadoli if (rc == SD_OK) { 459*bffde63dSSheetal Tigadoli /* calcul real capacity */ 460*bffde63dSSheetal Tigadoli sec_count = emmc_global_buf_ptr->u.Ext_CSD_storage[212] | 461*bffde63dSSheetal Tigadoli emmc_global_buf_ptr->u.Ext_CSD_storage[213] << 8 | 462*bffde63dSSheetal Tigadoli emmc_global_buf_ptr->u.Ext_CSD_storage[214] << 16 | 463*bffde63dSSheetal Tigadoli emmc_global_buf_ptr->u.Ext_CSD_storage[215] << 24; 464*bffde63dSSheetal Tigadoli 465*bffde63dSSheetal Tigadoli EMMC_TRACE("Device density = %ldMBytes\n", 466*bffde63dSSheetal Tigadoli handle->card->size / (1024 * 1024)); 467*bffde63dSSheetal Tigadoli 468*bffde63dSSheetal Tigadoli if (sec_count > 0) { 469*bffde63dSSheetal Tigadoli handle->card->size = (uint64_t)sec_count * 512; 470*bffde63dSSheetal Tigadoli 471*bffde63dSSheetal Tigadoli EMMC_TRACE("Updated Device density = %ldMBytes\n", 472*bffde63dSSheetal Tigadoli handle->card->size / (1024 * 1024)); 473*bffde63dSSheetal Tigadoli } 474*bffde63dSSheetal Tigadoli 475*bffde63dSSheetal Tigadoli if (sec_count > (2u * 1024 * 1024 * 1024) / 512) { 476*bffde63dSSheetal Tigadoli handle->device->ctrl.ocr |= SD_CARD_HIGH_CAPACITY; 477*bffde63dSSheetal Tigadoli handle->device->cfg.blockSize = 512; 478*bffde63dSSheetal Tigadoli } 479*bffde63dSSheetal Tigadoli 480*bffde63dSSheetal Tigadoli if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) 481*bffde63dSSheetal Tigadoli EMMC_TRACE("Sector addressing\n"); 482*bffde63dSSheetal Tigadoli else 483*bffde63dSSheetal Tigadoli EMMC_TRACE("Byte addressing\n"); 484*bffde63dSSheetal Tigadoli 485*bffde63dSSheetal Tigadoli EMMC_TRACE("Ext_CSD_storage[162]: 0x%02X Ext_CSD_storage[179]: 0x%02X\n", 486*bffde63dSSheetal Tigadoli emmc_global_buf_ptr->u.Ext_CSD_storage[162], 487*bffde63dSSheetal Tigadoli emmc_global_buf_ptr->u.Ext_CSD_storage[179]); 488*bffde63dSSheetal Tigadoli } 489*bffde63dSSheetal Tigadoli 490*bffde63dSSheetal Tigadoli return handle->card->type; 491*bffde63dSSheetal Tigadoli } 492*bffde63dSSheetal Tigadoli 493*bffde63dSSheetal Tigadoli 494*bffde63dSSheetal Tigadoli /* 495*bffde63dSSheetal Tigadoli * The function send reset command to the card. 496*bffde63dSSheetal Tigadoli * The card will be in ready status after the reset. 497*bffde63dSSheetal Tigadoli */ 498*bffde63dSSheetal Tigadoli int reset_card(struct sd_handle *handle) 499*bffde63dSSheetal Tigadoli { 500*bffde63dSSheetal Tigadoli int res = SD_OK; 501*bffde63dSSheetal Tigadoli 502*bffde63dSSheetal Tigadoli /* on reset, card's RCA should return to 0 */ 503*bffde63dSSheetal Tigadoli handle->device->ctrl.rca = 0; 504*bffde63dSSheetal Tigadoli 505*bffde63dSSheetal Tigadoli res = sd_cmd0(handle); 506*bffde63dSSheetal Tigadoli 507*bffde63dSSheetal Tigadoli if (res != SD_OK) 508*bffde63dSSheetal Tigadoli return SD_RESET_ERROR; 509*bffde63dSSheetal Tigadoli 510*bffde63dSSheetal Tigadoli return res; 511*bffde63dSSheetal Tigadoli } 512*bffde63dSSheetal Tigadoli 513*bffde63dSSheetal Tigadoli 514*bffde63dSSheetal Tigadoli /* 515*bffde63dSSheetal Tigadoli * The function sends command to the card and starts 516*bffde63dSSheetal Tigadoli * data transmission. 517*bffde63dSSheetal Tigadoli */ 518*bffde63dSSheetal Tigadoli static int xfer_data(struct sd_handle *handle, 519*bffde63dSSheetal Tigadoli uint32_t mode, 520*bffde63dSSheetal Tigadoli uint32_t addr, uint32_t length, uint8_t *base) 521*bffde63dSSheetal Tigadoli { 522*bffde63dSSheetal Tigadoli int rc = SD_OK; 523*bffde63dSSheetal Tigadoli 524*bffde63dSSheetal Tigadoli VERBOSE("XFER: dest: 0x%llx, addr: 0x%x, size: 0x%x bytes\n", 525*bffde63dSSheetal Tigadoli (uint64_t)base, addr, length); 526*bffde63dSSheetal Tigadoli 527*bffde63dSSheetal Tigadoli if ((length / handle->device->cfg.blockSize) > 1) { 528*bffde63dSSheetal Tigadoli if (mode == SD_OP_READ) { 529*bffde63dSSheetal Tigadoli inv_dcache_range((uintptr_t)base, (uint64_t)length); 530*bffde63dSSheetal Tigadoli rc = sd_cmd18(handle, addr, length, base); 531*bffde63dSSheetal Tigadoli } else { 532*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE 533*bffde63dSSheetal Tigadoli flush_dcache_range((uintptr_t)base, (uint64_t)length); 534*bffde63dSSheetal Tigadoli rc = sd_cmd25(handle, addr, length, base); 535*bffde63dSSheetal Tigadoli #else 536*bffde63dSSheetal Tigadoli rc = SD_DATA_XFER_ERROR; 537*bffde63dSSheetal Tigadoli #endif 538*bffde63dSSheetal Tigadoli } 539*bffde63dSSheetal Tigadoli } else { 540*bffde63dSSheetal Tigadoli if (mode == SD_OP_READ) { 541*bffde63dSSheetal Tigadoli inv_dcache_range((uintptr_t)base, (uint64_t)length); 542*bffde63dSSheetal Tigadoli rc = sd_cmd17(handle, addr, 543*bffde63dSSheetal Tigadoli handle->device->cfg.blockSize, base); 544*bffde63dSSheetal Tigadoli } else { 545*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE 546*bffde63dSSheetal Tigadoli flush_dcache_range((uintptr_t)base, (uint64_t)length); 547*bffde63dSSheetal Tigadoli rc = sd_cmd24(handle, addr, 548*bffde63dSSheetal Tigadoli handle->device->cfg.blockSize, base); 549*bffde63dSSheetal Tigadoli #else 550*bffde63dSSheetal Tigadoli rc = SD_DATA_XFER_ERROR; 551*bffde63dSSheetal Tigadoli #endif 552*bffde63dSSheetal Tigadoli } 553*bffde63dSSheetal Tigadoli } 554*bffde63dSSheetal Tigadoli 555*bffde63dSSheetal Tigadoli if (rc != SD_OK) 556*bffde63dSSheetal Tigadoli return SD_DATA_XFER_ERROR; 557*bffde63dSSheetal Tigadoli 558*bffde63dSSheetal Tigadoli return SD_OK; 559*bffde63dSSheetal Tigadoli } 560*bffde63dSSheetal Tigadoli 561*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE 562*bffde63dSSheetal Tigadoli int erase_card(struct sd_handle *handle, uint32_t addr, uint32_t blocks) 563*bffde63dSSheetal Tigadoli { 564*bffde63dSSheetal Tigadoli uint32_t end_addr; 565*bffde63dSSheetal Tigadoli 566*bffde63dSSheetal Tigadoli INFO("ERASE: addr: 0x%x, num of sectors: 0x%x\n", addr, blocks); 567*bffde63dSSheetal Tigadoli 568*bffde63dSSheetal Tigadoli if (sd_cmd35(handle, addr) != SD_OK) 569*bffde63dSSheetal Tigadoli return SD_FAIL; 570*bffde63dSSheetal Tigadoli 571*bffde63dSSheetal Tigadoli end_addr = addr + blocks - 1; 572*bffde63dSSheetal Tigadoli if (sd_cmd36(handle, end_addr) != SD_OK) 573*bffde63dSSheetal Tigadoli return SD_FAIL; 574*bffde63dSSheetal Tigadoli 575*bffde63dSSheetal Tigadoli if (sd_cmd38(handle) != SD_OK) 576*bffde63dSSheetal Tigadoli return SD_FAIL; 577*bffde63dSSheetal Tigadoli 578*bffde63dSSheetal Tigadoli return SD_OK; 579*bffde63dSSheetal Tigadoli } 580*bffde63dSSheetal Tigadoli #endif 581*bffde63dSSheetal Tigadoli 582*bffde63dSSheetal Tigadoli /* 583*bffde63dSSheetal Tigadoli * The function reads block data from a card. 584*bffde63dSSheetal Tigadoli */ 585*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE 586*bffde63dSSheetal Tigadoli int read_block(struct sd_handle *handle, 587*bffde63dSSheetal Tigadoli uint8_t *dst, uint32_t addr, uint32_t len) 588*bffde63dSSheetal Tigadoli { 589*bffde63dSSheetal Tigadoli int rel = SD_OK; 590*bffde63dSSheetal Tigadoli 591*bffde63dSSheetal Tigadoli /* 592*bffde63dSSheetal Tigadoli * Avoid doing repeated reads of the partition block 593*bffde63dSSheetal Tigadoli * by caching. 594*bffde63dSSheetal Tigadoli */ 595*bffde63dSSheetal Tigadoli if (cached_partition_block && 596*bffde63dSSheetal Tigadoli addr == PARTITION_BLOCK_ADDR && 597*bffde63dSSheetal Tigadoli len == CACHE_SIZE) { 598*bffde63dSSheetal Tigadoli memcpy(dst, cached_block, len); 599*bffde63dSSheetal Tigadoli } else { 600*bffde63dSSheetal Tigadoli rel = xfer_data(handle, SD_OP_READ, addr, len, dst); 601*bffde63dSSheetal Tigadoli 602*bffde63dSSheetal Tigadoli if (len == CACHE_SIZE && addr == PARTITION_BLOCK_ADDR) { 603*bffde63dSSheetal Tigadoli cached_partition_block = 1; 604*bffde63dSSheetal Tigadoli memcpy(cached_block, dst, len); 605*bffde63dSSheetal Tigadoli } 606*bffde63dSSheetal Tigadoli } 607*bffde63dSSheetal Tigadoli 608*bffde63dSSheetal Tigadoli return rel; 609*bffde63dSSheetal Tigadoli } 610*bffde63dSSheetal Tigadoli #else 611*bffde63dSSheetal Tigadoli int read_block(struct sd_handle *handle, 612*bffde63dSSheetal Tigadoli uint8_t *dst, uint32_t addr, uint32_t len) 613*bffde63dSSheetal Tigadoli { 614*bffde63dSSheetal Tigadoli return xfer_data(handle, SD_OP_READ, addr, len, dst); 615*bffde63dSSheetal Tigadoli } 616*bffde63dSSheetal Tigadoli #endif 617*bffde63dSSheetal Tigadoli 618*bffde63dSSheetal Tigadoli #ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE 619*bffde63dSSheetal Tigadoli 620*bffde63dSSheetal Tigadoli /* 621*bffde63dSSheetal Tigadoli * The function writes block data to a card. 622*bffde63dSSheetal Tigadoli */ 623*bffde63dSSheetal Tigadoli int write_block(struct sd_handle *handle, 624*bffde63dSSheetal Tigadoli uint8_t *src, uint32_t addr, uint32_t len) 625*bffde63dSSheetal Tigadoli { 626*bffde63dSSheetal Tigadoli int rel = SD_OK; 627*bffde63dSSheetal Tigadoli 628*bffde63dSSheetal Tigadoli /* 629*bffde63dSSheetal Tigadoli * Current HC has problem to get response of cmd16 after cmd12, 630*bffde63dSSheetal Tigadoli * the delay is necessary to sure the next cmd16 will not be timed out. 631*bffde63dSSheetal Tigadoli * The delay has to be at least 4 ms. 632*bffde63dSSheetal Tigadoli * The code removed cmd16 and use cmd13 to get card status before 633*bffde63dSSheetal Tigadoli * sending cmd18 or cmd25 to make sure the card is ready and thus 634*bffde63dSSheetal Tigadoli * no need to have delay here. 635*bffde63dSSheetal Tigadoli */ 636*bffde63dSSheetal Tigadoli 637*bffde63dSSheetal Tigadoli rel = xfer_data(handle, SD_OP_WRITE, addr, len, src); 638*bffde63dSSheetal Tigadoli 639*bffde63dSSheetal Tigadoli EMMC_TRACE("wr_blk addr:0x%08X src:0x%08X len:0x%08X result:%d\n", 640*bffde63dSSheetal Tigadoli addr, src, len, rel); 641*bffde63dSSheetal Tigadoli 642*bffde63dSSheetal Tigadoli return rel; 643*bffde63dSSheetal Tigadoli } 644*bffde63dSSheetal Tigadoli 645*bffde63dSSheetal Tigadoli 646*bffde63dSSheetal Tigadoli /* 647*bffde63dSSheetal Tigadoli * The function is called to write one block data directly to 648*bffde63dSSheetal Tigadoli * a card's data buffer. 649*bffde63dSSheetal Tigadoli * it is used in Non-DMA mode for card data transmission. 650*bffde63dSSheetal Tigadoli */ 651*bffde63dSSheetal Tigadoli int write_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data) 652*bffde63dSSheetal Tigadoli { 653*bffde63dSSheetal Tigadoli uint32_t rem, blockSize, event; 654*bffde63dSSheetal Tigadoli uint8_t *pData = data; 655*bffde63dSSheetal Tigadoli 656*bffde63dSSheetal Tigadoli blockSize = handle->device->cfg.blockSize; 657*bffde63dSSheetal Tigadoli rem = length; 658*bffde63dSSheetal Tigadoli 659*bffde63dSSheetal Tigadoli if (rem == 0) 660*bffde63dSSheetal Tigadoli return SD_OK; 661*bffde63dSSheetal Tigadoli 662*bffde63dSSheetal Tigadoli while (rem > 0) { 663*bffde63dSSheetal Tigadoli 664*bffde63dSSheetal Tigadoli event = wait_for_event(handle, 665*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_BWRDY_MASK | 666*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 667*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry); 668*bffde63dSSheetal Tigadoli 669*bffde63dSSheetal Tigadoli if (handle->device->ctrl.cmdStatus) { 670*bffde63dSSheetal Tigadoli check_error(handle, handle->device->ctrl.cmdStatus); 671*bffde63dSSheetal Tigadoli return SD_WRITE_ERROR; 672*bffde63dSSheetal Tigadoli } 673*bffde63dSSheetal Tigadoli 674*bffde63dSSheetal Tigadoli if (rem >= blockSize) 675*bffde63dSSheetal Tigadoli chal_sd_write_buffer((CHAL_HANDLE *) handle->device, 676*bffde63dSSheetal Tigadoli blockSize, pData); 677*bffde63dSSheetal Tigadoli else 678*bffde63dSSheetal Tigadoli chal_sd_write_buffer((CHAL_HANDLE *) handle->device, 679*bffde63dSSheetal Tigadoli rem, pData); 680*bffde63dSSheetal Tigadoli 681*bffde63dSSheetal Tigadoli if (rem > blockSize) { 682*bffde63dSSheetal Tigadoli rem -= blockSize; 683*bffde63dSSheetal Tigadoli pData += blockSize; 684*bffde63dSSheetal Tigadoli } else { 685*bffde63dSSheetal Tigadoli pData += rem; 686*bffde63dSSheetal Tigadoli rem = 0; 687*bffde63dSSheetal Tigadoli } 688*bffde63dSSheetal Tigadoli } 689*bffde63dSSheetal Tigadoli 690*bffde63dSSheetal Tigadoli if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) != 691*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_TXDONE_MASK) { 692*bffde63dSSheetal Tigadoli event = wait_for_event(handle, 693*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_TXDONE_MASK | 694*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 695*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry); 696*bffde63dSSheetal Tigadoli 697*bffde63dSSheetal Tigadoli if (handle->device->ctrl.cmdStatus != SD_OK) { 698*bffde63dSSheetal Tigadoli check_error(handle, handle->device->ctrl.cmdStatus); 699*bffde63dSSheetal Tigadoli return SD_WRITE_ERROR; 700*bffde63dSSheetal Tigadoli } 701*bffde63dSSheetal Tigadoli } else { 702*bffde63dSSheetal Tigadoli handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK; 703*bffde63dSSheetal Tigadoli } 704*bffde63dSSheetal Tigadoli 705*bffde63dSSheetal Tigadoli return SD_OK; 706*bffde63dSSheetal Tigadoli } 707*bffde63dSSheetal Tigadoli #endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */ 708*bffde63dSSheetal Tigadoli 709*bffde63dSSheetal Tigadoli 710*bffde63dSSheetal Tigadoli /* 711*bffde63dSSheetal Tigadoli * The function is called to read maximal one block data 712*bffde63dSSheetal Tigadoli * directly from a card 713*bffde63dSSheetal Tigadoli * It is used in Non-DMA mode for card data transmission. 714*bffde63dSSheetal Tigadoli */ 715*bffde63dSSheetal Tigadoli int read_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data) 716*bffde63dSSheetal Tigadoli { 717*bffde63dSSheetal Tigadoli uint32_t rem, blockSize, event = 0; 718*bffde63dSSheetal Tigadoli uint8_t *pData = data; 719*bffde63dSSheetal Tigadoli 720*bffde63dSSheetal Tigadoli blockSize = handle->device->cfg.blockSize; 721*bffde63dSSheetal Tigadoli rem = length; 722*bffde63dSSheetal Tigadoli 723*bffde63dSSheetal Tigadoli if (rem == 0) 724*bffde63dSSheetal Tigadoli return SD_OK; 725*bffde63dSSheetal Tigadoli 726*bffde63dSSheetal Tigadoli while (rem > 0) { 727*bffde63dSSheetal Tigadoli event = wait_for_event(handle, 728*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_BRRDY_MASK | 729*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 730*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry); 731*bffde63dSSheetal Tigadoli 732*bffde63dSSheetal Tigadoli if (handle->device->ctrl.cmdStatus) { 733*bffde63dSSheetal Tigadoli check_error(handle, handle->device->ctrl.cmdStatus); 734*bffde63dSSheetal Tigadoli return SD_READ_ERROR; 735*bffde63dSSheetal Tigadoli } 736*bffde63dSSheetal Tigadoli 737*bffde63dSSheetal Tigadoli if (rem >= blockSize) 738*bffde63dSSheetal Tigadoli chal_sd_read_buffer((CHAL_HANDLE *) handle->device, 739*bffde63dSSheetal Tigadoli blockSize, pData); 740*bffde63dSSheetal Tigadoli else 741*bffde63dSSheetal Tigadoli chal_sd_read_buffer((CHAL_HANDLE *) handle->device, rem, 742*bffde63dSSheetal Tigadoli pData); 743*bffde63dSSheetal Tigadoli 744*bffde63dSSheetal Tigadoli if (rem > blockSize) { 745*bffde63dSSheetal Tigadoli rem -= blockSize; 746*bffde63dSSheetal Tigadoli pData += blockSize; 747*bffde63dSSheetal Tigadoli } else { 748*bffde63dSSheetal Tigadoli pData += rem; 749*bffde63dSSheetal Tigadoli rem = 0; 750*bffde63dSSheetal Tigadoli } 751*bffde63dSSheetal Tigadoli } 752*bffde63dSSheetal Tigadoli 753*bffde63dSSheetal Tigadoli /* In case, there are extra data in the SD FIFO, just dump them. */ 754*bffde63dSSheetal Tigadoli chal_sd_dump_fifo((CHAL_HANDLE *) handle->device); 755*bffde63dSSheetal Tigadoli 756*bffde63dSSheetal Tigadoli if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) != 757*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_TXDONE_MASK) { 758*bffde63dSSheetal Tigadoli event = wait_for_event(handle, SD4_EMMC_TOP_INTR_TXDONE_MASK, 759*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry); 760*bffde63dSSheetal Tigadoli 761*bffde63dSSheetal Tigadoli if (handle->device->ctrl.cmdStatus) { 762*bffde63dSSheetal Tigadoli check_error(handle, handle->device->ctrl.cmdStatus); 763*bffde63dSSheetal Tigadoli return SD_READ_ERROR; 764*bffde63dSSheetal Tigadoli } 765*bffde63dSSheetal Tigadoli } else { 766*bffde63dSSheetal Tigadoli handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK; 767*bffde63dSSheetal Tigadoli } 768*bffde63dSSheetal Tigadoli 769*bffde63dSSheetal Tigadoli return SD_OK; 770*bffde63dSSheetal Tigadoli } 771*bffde63dSSheetal Tigadoli 772*bffde63dSSheetal Tigadoli 773*bffde63dSSheetal Tigadoli /* 774*bffde63dSSheetal Tigadoli * Error handling routine. 775*bffde63dSSheetal Tigadoli * The function just reset the DAT 776*bffde63dSSheetal Tigadoli * and CMD line if an error occures during data transmission. 777*bffde63dSSheetal Tigadoli */ 778*bffde63dSSheetal Tigadoli int check_error(struct sd_handle *handle, uint32_t ints) 779*bffde63dSSheetal Tigadoli { 780*bffde63dSSheetal Tigadoli uint32_t rel; 781*bffde63dSSheetal Tigadoli 782*bffde63dSSheetal Tigadoli chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, 783*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 0); 784*bffde63dSSheetal Tigadoli 785*bffde63dSSheetal Tigadoli if (ints & SD4_EMMC_TOP_INTR_CMDERROR_MASK) { 786*bffde63dSSheetal Tigadoli 787*bffde63dSSheetal Tigadoli chal_sd_reset_line((CHAL_HANDLE *) handle->device, 788*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_CTRL1_CMDRST_MASK); 789*bffde63dSSheetal Tigadoli rel = abort_err(handle); 790*bffde63dSSheetal Tigadoli 791*bffde63dSSheetal Tigadoli chal_sd_reset_line((CHAL_HANDLE *) handle->device, 792*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_CTRL1_DATRST_MASK); 793*bffde63dSSheetal Tigadoli chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, 794*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 1); 795*bffde63dSSheetal Tigadoli 796*bffde63dSSheetal Tigadoli return (rel == SD_ERROR_NON_RECOVERABLE) ? 797*bffde63dSSheetal Tigadoli SD_ERROR_NON_RECOVERABLE : SD_ERROR_RECOVERABLE; 798*bffde63dSSheetal Tigadoli } else { 799*bffde63dSSheetal Tigadoli rel = err_recovery(handle, ints); 800*bffde63dSSheetal Tigadoli } 801*bffde63dSSheetal Tigadoli 802*bffde63dSSheetal Tigadoli chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, 803*bffde63dSSheetal Tigadoli SD_ERR_INTERRUPTS, 1); 804*bffde63dSSheetal Tigadoli 805*bffde63dSSheetal Tigadoli return rel; 806*bffde63dSSheetal Tigadoli } 807*bffde63dSSheetal Tigadoli 808*bffde63dSSheetal Tigadoli 809*bffde63dSSheetal Tigadoli /* 810*bffde63dSSheetal Tigadoli * Error recovery routine. 811*bffde63dSSheetal Tigadoli * Try to recover from the error. 812*bffde63dSSheetal Tigadoli */ 813*bffde63dSSheetal Tigadoli static int err_recovery(struct sd_handle *handle, uint32_t errors) 814*bffde63dSSheetal Tigadoli { 815*bffde63dSSheetal Tigadoli uint32_t rel = 0; 816*bffde63dSSheetal Tigadoli 817*bffde63dSSheetal Tigadoli /* 818*bffde63dSSheetal Tigadoli * In case of timeout error, the cmd line and data line maybe 819*bffde63dSSheetal Tigadoli * still active or stuck at atcitve so it is needed to reset 820*bffde63dSSheetal Tigadoli * either data line or cmd line to make sure a new cmd can be sent. 821*bffde63dSSheetal Tigadoli */ 822*bffde63dSSheetal Tigadoli 823*bffde63dSSheetal Tigadoli if (errors & SD_CMD_ERROR_INT) 824*bffde63dSSheetal Tigadoli chal_sd_reset_line((CHAL_HANDLE *) handle->device, 825*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_CTRL1_CMDRST_MASK); 826*bffde63dSSheetal Tigadoli 827*bffde63dSSheetal Tigadoli if (errors & SD_DAT_ERROR_INT) 828*bffde63dSSheetal Tigadoli chal_sd_reset_line((CHAL_HANDLE *) handle->device, 829*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_CTRL1_DATRST_MASK); 830*bffde63dSSheetal Tigadoli 831*bffde63dSSheetal Tigadoli /* Abort transaction by sending out stop command */ 832*bffde63dSSheetal Tigadoli if ((handle->device->ctrl.cmdIndex == 18) || 833*bffde63dSSheetal Tigadoli (handle->device->ctrl.cmdIndex == 25)) 834*bffde63dSSheetal Tigadoli rel = abort_err(handle); 835*bffde63dSSheetal Tigadoli 836*bffde63dSSheetal Tigadoli return rel; 837*bffde63dSSheetal Tigadoli } 838*bffde63dSSheetal Tigadoli 839*bffde63dSSheetal Tigadoli 840*bffde63dSSheetal Tigadoli /* 841*bffde63dSSheetal Tigadoli * The function is called to read one block data directly from a card. 842*bffde63dSSheetal Tigadoli * It is used in Non-DMA mode for card data transmission. 843*bffde63dSSheetal Tigadoli */ 844*bffde63dSSheetal Tigadoli int process_cmd_response(struct sd_handle *handle, 845*bffde63dSSheetal Tigadoli uint32_t cmdIndex, 846*bffde63dSSheetal Tigadoli uint32_t rsp0, 847*bffde63dSSheetal Tigadoli uint32_t rsp1, 848*bffde63dSSheetal Tigadoli uint32_t rsp2, uint32_t rsp3, struct sd_resp *resp) 849*bffde63dSSheetal Tigadoli { 850*bffde63dSSheetal Tigadoli int result = SD_OK; 851*bffde63dSSheetal Tigadoli 852*bffde63dSSheetal Tigadoli /* R6 */ 853*bffde63dSSheetal Tigadoli uint32_t rca = (rsp0 >> 16) & 0xffff; 854*bffde63dSSheetal Tigadoli uint32_t cardStatus = rsp0; 855*bffde63dSSheetal Tigadoli 856*bffde63dSSheetal Tigadoli /* R4 */ 857*bffde63dSSheetal Tigadoli uint32_t cBit = (rsp0 >> 31) & 0x1; 858*bffde63dSSheetal Tigadoli uint32_t funcs = (rsp0 >> 28) & 0x7; 859*bffde63dSSheetal Tigadoli uint32_t memPresent = (rsp0 >> 27) & 0x1; 860*bffde63dSSheetal Tigadoli 861*bffde63dSSheetal Tigadoli resp->r1 = 0x3f; 862*bffde63dSSheetal Tigadoli resp->cardStatus = cardStatus; 863*bffde63dSSheetal Tigadoli 864*bffde63dSSheetal Tigadoli if (cmdIndex == SD_CMD_IO_SEND_OP_COND) { 865*bffde63dSSheetal Tigadoli resp->data.r4.cardReady = cBit; 866*bffde63dSSheetal Tigadoli resp->data.r4.funcs = funcs; 867*bffde63dSSheetal Tigadoli resp->data.r4.memPresent = memPresent; 868*bffde63dSSheetal Tigadoli resp->data.r4.ocr = cardStatus; 869*bffde63dSSheetal Tigadoli } 870*bffde63dSSheetal Tigadoli 871*bffde63dSSheetal Tigadoli if (cmdIndex == SD_CMD_MMC_SET_RCA) { 872*bffde63dSSheetal Tigadoli resp->data.r6.rca = rca; 873*bffde63dSSheetal Tigadoli resp->data.r6.cardStatus = cardStatus & 0xFFFF; 874*bffde63dSSheetal Tigadoli } 875*bffde63dSSheetal Tigadoli 876*bffde63dSSheetal Tigadoli if (cmdIndex == SD_CMD_SELECT_DESELECT_CARD) { 877*bffde63dSSheetal Tigadoli resp->data.r7.rca = rca; 878*bffde63dSSheetal Tigadoli } 879*bffde63dSSheetal Tigadoli 880*bffde63dSSheetal Tigadoli if (cmdIndex == SD_CMD_IO_RW_DIRECT) { 881*bffde63dSSheetal Tigadoli if (((rsp0 >> 16) & 0xffff) != 0) 882*bffde63dSSheetal Tigadoli result = SD_CMD_ERR_INVALID_RESPONSE; 883*bffde63dSSheetal Tigadoli 884*bffde63dSSheetal Tigadoli resp->data.r5.data = rsp0 & 0xff; 885*bffde63dSSheetal Tigadoli } 886*bffde63dSSheetal Tigadoli 887*bffde63dSSheetal Tigadoli if (cmdIndex == SD_CMD_IO_RW_EXTENDED) { 888*bffde63dSSheetal Tigadoli if (((rsp0 >> 16) & 0xffff) != 0) 889*bffde63dSSheetal Tigadoli result = SD_CMD_ERR_INVALID_RESPONSE; 890*bffde63dSSheetal Tigadoli 891*bffde63dSSheetal Tigadoli resp->data.r5.data = rsp0 & 0xff; 892*bffde63dSSheetal Tigadoli } 893*bffde63dSSheetal Tigadoli 894*bffde63dSSheetal Tigadoli if (cmdIndex == SD_ACMD_SD_SEND_OP_COND || 895*bffde63dSSheetal Tigadoli cmdIndex == SD_CMD_SEND_OPCOND) 896*bffde63dSSheetal Tigadoli resp->data.r3.ocr = cardStatus; 897*bffde63dSSheetal Tigadoli 898*bffde63dSSheetal Tigadoli if (cmdIndex == SD_CMD_SEND_CSD || 899*bffde63dSSheetal Tigadoli cmdIndex == SD_CMD_SEND_CID || 900*bffde63dSSheetal Tigadoli cmdIndex == SD_CMD_ALL_SEND_CID) { 901*bffde63dSSheetal Tigadoli resp->data.r2.rsp4 = rsp3; 902*bffde63dSSheetal Tigadoli resp->data.r2.rsp3 = rsp2; 903*bffde63dSSheetal Tigadoli resp->data.r2.rsp2 = rsp1; 904*bffde63dSSheetal Tigadoli resp->data.r2.rsp1 = rsp0; 905*bffde63dSSheetal Tigadoli } 906*bffde63dSSheetal Tigadoli 907*bffde63dSSheetal Tigadoli if ((cmdIndex == SD_CMD_READ_EXT_CSD) && 908*bffde63dSSheetal Tigadoli (handle->card->type == SD_CARD_SD)) { 909*bffde63dSSheetal Tigadoli if ((resp->cardStatus & 0xAA) != 0xAA) { 910*bffde63dSSheetal Tigadoli result = SD_CMD_ERR_INVALID_RESPONSE; 911*bffde63dSSheetal Tigadoli } 912*bffde63dSSheetal Tigadoli } 913*bffde63dSSheetal Tigadoli 914*bffde63dSSheetal Tigadoli return result; 915*bffde63dSSheetal Tigadoli } 916*bffde63dSSheetal Tigadoli 917*bffde63dSSheetal Tigadoli 918*bffde63dSSheetal Tigadoli /* 919*bffde63dSSheetal Tigadoli * The function sets DMA buffer and data length, process 920*bffde63dSSheetal Tigadoli * block size and the number of blocks to be transferred. 921*bffde63dSSheetal Tigadoli * It returns the DMA buffer address. 922*bffde63dSSheetal Tigadoli * It copies dma data from user buffer to the DMA buffer 923*bffde63dSSheetal Tigadoli * if the operation is to write data to the SD card. 924*bffde63dSSheetal Tigadoli */ 925*bffde63dSSheetal Tigadoli void data_xfer_setup(struct sd_handle *handle, uint8_t *data, uint32_t length, 926*bffde63dSSheetal Tigadoli int dir) 927*bffde63dSSheetal Tigadoli { 928*bffde63dSSheetal Tigadoli chal_sd_setup_xfer((CHAL_HANDLE *)handle->device, data, length, dir); 929*bffde63dSSheetal Tigadoli } 930*bffde63dSSheetal Tigadoli 931*bffde63dSSheetal Tigadoli 932*bffde63dSSheetal Tigadoli /* 933*bffde63dSSheetal Tigadoli * The function does soft reset the host SD controller. After 934*bffde63dSSheetal Tigadoli * the function call all host controller's register are reset 935*bffde63dSSheetal Tigadoli * to default vallue; 936*bffde63dSSheetal Tigadoli * 937*bffde63dSSheetal Tigadoli * Note This function only resets the host controller it does not 938*bffde63dSSheetal Tigadoli * reset the controller's handler. 939*bffde63dSSheetal Tigadoli */ 940*bffde63dSSheetal Tigadoli int reset_host_ctrl(struct sd_handle *handle) 941*bffde63dSSheetal Tigadoli { 942*bffde63dSSheetal Tigadoli chal_sd_stop(); 943*bffde63dSSheetal Tigadoli 944*bffde63dSSheetal Tigadoli return SD_OK; 945*bffde63dSSheetal Tigadoli } 946*bffde63dSSheetal Tigadoli 947*bffde63dSSheetal Tigadoli static void pstate_log(struct sd_handle *handle) 948*bffde63dSSheetal Tigadoli { 949*bffde63dSSheetal Tigadoli ERROR("PSTATE: 0x%x\n", mmio_read_32 950*bffde63dSSheetal Tigadoli (handle->device->ctrl.sdRegBaseAddr + 951*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_PSTATE_SD4_OFFSET)); 952*bffde63dSSheetal Tigadoli ERROR("ERRSTAT: 0x%x\n", mmio_read_32 953*bffde63dSSheetal Tigadoli (handle->device->ctrl.sdRegBaseAddr + 954*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_ERRSTAT_OFFSET)); 955*bffde63dSSheetal Tigadoli } 956*bffde63dSSheetal Tigadoli 957*bffde63dSSheetal Tigadoli /* 958*bffde63dSSheetal Tigadoli * The function waits for one or a group of interrupts specified 959*bffde63dSSheetal Tigadoli * by mask. The function returns if any one the interrupt status 960*bffde63dSSheetal Tigadoli * is set. If interrupt mode is not enabled then it will poll 961*bffde63dSSheetal Tigadoli * the interrupt status register until a interrupt status is set 962*bffde63dSSheetal Tigadoli * an error interrupt happens. If interrupt mode is enabled then 963*bffde63dSSheetal Tigadoli * this function should be called after the interrupt 964*bffde63dSSheetal Tigadoli * is received by ISR routine. 965*bffde63dSSheetal Tigadoli */ 966*bffde63dSSheetal Tigadoli uint32_t wait_for_event(struct sd_handle *handle, 967*bffde63dSSheetal Tigadoli uint32_t mask, uint32_t retry) 968*bffde63dSSheetal Tigadoli { 969*bffde63dSSheetal Tigadoli uint32_t regval, cmd12, time = 0; 970*bffde63dSSheetal Tigadoli 971*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdStatus = 0; /* no error */ 972*bffde63dSSheetal Tigadoli EMMC_TRACE("%s %d mask:0x%x timeout:%d irq_status:0x%x\n", 973*bffde63dSSheetal Tigadoli __func__, __LINE__, mask, retry, 974*bffde63dSSheetal Tigadoli chal_sd_get_irq_status((CHAL_HANDLE *)handle->device)); 975*bffde63dSSheetal Tigadoli 976*bffde63dSSheetal Tigadoli /* Polling mode */ 977*bffde63dSSheetal Tigadoli do { 978*bffde63dSSheetal Tigadoli regval = chal_sd_get_irq_status((CHAL_HANDLE *)handle->device); 979*bffde63dSSheetal Tigadoli 980*bffde63dSSheetal Tigadoli if (regval & SD4_EMMC_TOP_INTR_DMAIRQ_MASK) { 981*bffde63dSSheetal Tigadoli chal_sd_set_dma_addr((CHAL_HANDLE *)handle->device, 982*bffde63dSSheetal Tigadoli (uintptr_t) 983*bffde63dSSheetal Tigadoli chal_sd_get_dma_addr((CHAL_HANDLE *) 984*bffde63dSSheetal Tigadoli handle->device)); 985*bffde63dSSheetal Tigadoli chal_sd_clear_irq((CHAL_HANDLE *)handle->device, 986*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_DMAIRQ_MASK); 987*bffde63dSSheetal Tigadoli } 988*bffde63dSSheetal Tigadoli 989*bffde63dSSheetal Tigadoli if (time++ > retry) { 990*bffde63dSSheetal Tigadoli ERROR("EMMC: No response (cmd%d) after %dus.\n", 991*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdIndex, 992*bffde63dSSheetal Tigadoli time * EMMC_WFE_RETRY_DELAY_US); 993*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdStatus = SD_CMD_MISSING; 994*bffde63dSSheetal Tigadoli pstate_log(handle); 995*bffde63dSSheetal Tigadoli ERROR("EMMC: INT[0x%x]\n", regval); 996*bffde63dSSheetal Tigadoli break; 997*bffde63dSSheetal Tigadoli } 998*bffde63dSSheetal Tigadoli 999*bffde63dSSheetal Tigadoli if (regval & SD4_EMMC_TOP_INTR_CTOERR_MASK) { 1000*bffde63dSSheetal Tigadoli ERROR("EMMC: Cmd%d timeout INT[0x%x]\n", 1001*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdIndex, regval); 1002*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdStatus = 1003*bffde63dSSheetal Tigadoli SD4_EMMC_TOP_INTR_CTOERR_MASK; 1004*bffde63dSSheetal Tigadoli pstate_log(handle); 1005*bffde63dSSheetal Tigadoli break; 1006*bffde63dSSheetal Tigadoli } 1007*bffde63dSSheetal Tigadoli if (regval & SD_CMD_ERROR_FLAGS) { 1008*bffde63dSSheetal Tigadoli ERROR("EMMC: Cmd%d error INT[0x%x]\n", 1009*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdIndex, regval); 1010*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdStatus = SD_CMD_ERROR_FLAGS; 1011*bffde63dSSheetal Tigadoli pstate_log(handle); 1012*bffde63dSSheetal Tigadoli break; 1013*bffde63dSSheetal Tigadoli } 1014*bffde63dSSheetal Tigadoli 1015*bffde63dSSheetal Tigadoli cmd12 = chal_sd_get_atuo12_error((CHAL_HANDLE *)handle->device); 1016*bffde63dSSheetal Tigadoli if (cmd12) { 1017*bffde63dSSheetal Tigadoli ERROR("EMMC: Cmd%d auto cmd12 err:0x%x\n", 1018*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdIndex, cmd12); 1019*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdStatus = cmd12; 1020*bffde63dSSheetal Tigadoli pstate_log(handle); 1021*bffde63dSSheetal Tigadoli break; 1022*bffde63dSSheetal Tigadoli } 1023*bffde63dSSheetal Tigadoli 1024*bffde63dSSheetal Tigadoli if (SD_DATA_ERROR_FLAGS & regval) { 1025*bffde63dSSheetal Tigadoli ERROR("EMMC: Data for cmd%d error, INT[0x%x]\n", 1026*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdIndex, regval); 1027*bffde63dSSheetal Tigadoli handle->device->ctrl.cmdStatus = 1028*bffde63dSSheetal Tigadoli (SD_DATA_ERROR_FLAGS & regval); 1029*bffde63dSSheetal Tigadoli pstate_log(handle); 1030*bffde63dSSheetal Tigadoli break; 1031*bffde63dSSheetal Tigadoli } 1032*bffde63dSSheetal Tigadoli 1033*bffde63dSSheetal Tigadoli if ((regval & mask) == 0) 1034*bffde63dSSheetal Tigadoli udelay(EMMC_WFE_RETRY_DELAY_US); 1035*bffde63dSSheetal Tigadoli 1036*bffde63dSSheetal Tigadoli } while ((regval & mask) == 0); 1037*bffde63dSSheetal Tigadoli 1038*bffde63dSSheetal Tigadoli /* clear the interrupt since it is processed */ 1039*bffde63dSSheetal Tigadoli chal_sd_clear_irq((CHAL_HANDLE *)handle->device, (regval & mask)); 1040*bffde63dSSheetal Tigadoli 1041*bffde63dSSheetal Tigadoli return (regval & mask); 1042*bffde63dSSheetal Tigadoli } 1043*bffde63dSSheetal Tigadoli 1044*bffde63dSSheetal Tigadoli int32_t set_config(struct sd_handle *handle, uint32_t speed, uint32_t retry, 1045*bffde63dSSheetal Tigadoli uint32_t dma, uint32_t dmaBound, uint32_t blkSize, 1046*bffde63dSSheetal Tigadoli uint32_t wfe_retry) 1047*bffde63dSSheetal Tigadoli { 1048*bffde63dSSheetal Tigadoli int32_t rel = 0; 1049*bffde63dSSheetal Tigadoli 1050*bffde63dSSheetal Tigadoli if (handle == NULL) 1051*bffde63dSSheetal Tigadoli return SD_FAIL; 1052*bffde63dSSheetal Tigadoli 1053*bffde63dSSheetal Tigadoli handle->device->cfg.wfe_retry = wfe_retry; 1054*bffde63dSSheetal Tigadoli 1055*bffde63dSSheetal Tigadoli rel = chal_sd_config((CHAL_HANDLE *)handle->device, speed, retry, 1056*bffde63dSSheetal Tigadoli dmaBound, blkSize, dma); 1057*bffde63dSSheetal Tigadoli return rel; 1058*bffde63dSSheetal Tigadoli 1059*bffde63dSSheetal Tigadoli } 1060*bffde63dSSheetal Tigadoli 1061*bffde63dSSheetal Tigadoli int mmc_cmd1(struct sd_handle *handle) 1062*bffde63dSSheetal Tigadoli { 1063*bffde63dSSheetal Tigadoli uint32_t newOcr, res; 1064*bffde63dSSheetal Tigadoli uint32_t cmd1_option = MMC_OCR_OP_VOLT | MMC_OCR_SECTOR_ACCESS_MODE; 1065*bffde63dSSheetal Tigadoli 1066*bffde63dSSheetal Tigadoli /* 1067*bffde63dSSheetal Tigadoli * After Reset, eMMC comes up in 1 Bit Data Width by default. 1068*bffde63dSSheetal Tigadoli * Set host side to match. 1069*bffde63dSSheetal Tigadoli */ 1070*bffde63dSSheetal Tigadoli chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, 1071*bffde63dSSheetal Tigadoli SD_BUS_DATA_WIDTH_1BIT); 1072*bffde63dSSheetal Tigadoli 1073*bffde63dSSheetal Tigadoli #ifdef USE_EMMC_FIP_TOC_CACHE 1074*bffde63dSSheetal Tigadoli cached_partition_block = 0; 1075*bffde63dSSheetal Tigadoli #endif 1076*bffde63dSSheetal Tigadoli handle->device->ctrl.present = 0; /* init card present to be no card */ 1077*bffde63dSSheetal Tigadoli 1078*bffde63dSSheetal Tigadoli handle->card->type = SD_CARD_MMC; 1079*bffde63dSSheetal Tigadoli 1080*bffde63dSSheetal Tigadoli res = sd_cmd1(handle, cmd1_option, &newOcr); 1081*bffde63dSSheetal Tigadoli 1082*bffde63dSSheetal Tigadoli if (res != SD_OK) { 1083*bffde63dSSheetal Tigadoli EMMC_TRACE("CMD1 Timeout: Device is not ready\n"); 1084*bffde63dSSheetal Tigadoli res = SD_CARD_UNKNOWN; 1085*bffde63dSSheetal Tigadoli } 1086*bffde63dSSheetal Tigadoli return res; 1087*bffde63dSSheetal Tigadoli } 1088