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