1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <common/debug.h> 8*91f16700Schasinglulu #include <lib/mmio.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include "emmc_config.h" 11*91f16700Schasinglulu #include "emmc_def.h" 12*91f16700Schasinglulu #include "emmc_hal.h" 13*91f16700Schasinglulu #include "emmc_registers.h" 14*91f16700Schasinglulu #include "emmc_std.h" 15*91f16700Schasinglulu #include "micro_delay.h" 16*91f16700Schasinglulu #include "rcar_def.h" 17*91f16700Schasinglulu 18*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode); 19*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_card_init(void); 20*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_high_speed(void); 21*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_bus_width(uint32_t width); 22*91f16700Schasinglulu static uint32_t emmc_set_timeout_register_value(uint32_t freq); 23*91f16700Schasinglulu static void set_sd_clk(uint32_t clkDiv); 24*91f16700Schasinglulu static uint32_t emmc_calc_tran_speed(uint32_t *freq); 25*91f16700Schasinglulu static void emmc_get_partition_access(void); 26*91f16700Schasinglulu static void emmc_set_bootpartition(void); 27*91f16700Schasinglulu 28*91f16700Schasinglulu static void emmc_set_bootpartition(void) 29*91f16700Schasinglulu { 30*91f16700Schasinglulu uint32_t reg; 31*91f16700Schasinglulu 32*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 33*91f16700Schasinglulu if (reg == PRR_PRODUCT_M3_CUT10) { 34*91f16700Schasinglulu mmc_drv_obj.boot_partition_en = 35*91f16700Schasinglulu (EMMC_PARTITION_ID) ((mmc_drv_obj.ext_csd_data[179] & 36*91f16700Schasinglulu EMMC_BOOT_PARTITION_EN_MASK) >> 37*91f16700Schasinglulu EMMC_BOOT_PARTITION_EN_SHIFT); 38*91f16700Schasinglulu } else if ((reg == PRR_PRODUCT_H3_CUT20) 39*91f16700Schasinglulu || (reg == PRR_PRODUCT_M3_CUT11)) { 40*91f16700Schasinglulu mmc_drv_obj.boot_partition_en = mmc_drv_obj.partition_access; 41*91f16700Schasinglulu } else { 42*91f16700Schasinglulu if ((mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION) != 43*91f16700Schasinglulu 0U) { 44*91f16700Schasinglulu mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_2; 45*91f16700Schasinglulu } else { 46*91f16700Schasinglulu mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_1; 47*91f16700Schasinglulu } 48*91f16700Schasinglulu } 49*91f16700Schasinglulu } 50*91f16700Schasinglulu 51*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_card_init(void) 52*91f16700Schasinglulu { 53*91f16700Schasinglulu int32_t retry; 54*91f16700Schasinglulu uint32_t freq = MMC_400KHZ; /* 390KHz */ 55*91f16700Schasinglulu EMMC_ERROR_CODE result; 56*91f16700Schasinglulu uint32_t result_calc; 57*91f16700Schasinglulu 58*91f16700Schasinglulu /* state check */ 59*91f16700Schasinglulu if ((mmc_drv_obj.initialize != TRUE) 60*91f16700Schasinglulu || (mmc_drv_obj.card_power_enable != TRUE) 61*91f16700Schasinglulu || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) 62*91f16700Schasinglulu ) { 63*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_STATE); 64*91f16700Schasinglulu return EMMC_ERR_STATE; 65*91f16700Schasinglulu } 66*91f16700Schasinglulu 67*91f16700Schasinglulu /* clock on (force change) */ 68*91f16700Schasinglulu mmc_drv_obj.current_freq = 0; 69*91f16700Schasinglulu mmc_drv_obj.max_freq = MMC_20MHZ; 70*91f16700Schasinglulu result = emmc_set_request_mmc_clock(&freq); 71*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 72*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 73*91f16700Schasinglulu return EMMC_ERR; 74*91f16700Schasinglulu } 75*91f16700Schasinglulu 76*91f16700Schasinglulu rcar_micro_delay(1000U); /* wait 1ms */ 77*91f16700Schasinglulu 78*91f16700Schasinglulu /* Get current access partition */ 79*91f16700Schasinglulu emmc_get_partition_access(); 80*91f16700Schasinglulu 81*91f16700Schasinglulu /* CMD0, arg=0x00000000 */ 82*91f16700Schasinglulu result = emmc_send_idle_cmd(0x00000000); 83*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 84*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 85*91f16700Schasinglulu return result; 86*91f16700Schasinglulu } 87*91f16700Schasinglulu 88*91f16700Schasinglulu rcar_micro_delay(200U); /* wait 74clock 390kHz(189.74us) */ 89*91f16700Schasinglulu 90*91f16700Schasinglulu /* CMD1 */ 91*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD1_SEND_OP_COND, EMMC_HOST_OCR_VALUE); 92*91f16700Schasinglulu for (retry = 300; retry > 0; retry--) { 93*91f16700Schasinglulu result = 94*91f16700Schasinglulu emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 95*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 96*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 97*91f16700Schasinglulu return result; 98*91f16700Schasinglulu } 99*91f16700Schasinglulu 100*91f16700Schasinglulu if ((mmc_drv_obj.r3_ocr & EMMC_OCR_STATUS_BIT) != 0) { 101*91f16700Schasinglulu break; /* card is ready. exit loop */ 102*91f16700Schasinglulu } 103*91f16700Schasinglulu rcar_micro_delay(1000U); /* wait 1ms */ 104*91f16700Schasinglulu } 105*91f16700Schasinglulu 106*91f16700Schasinglulu if (retry == 0) { 107*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_TIMEOUT); 108*91f16700Schasinglulu return EMMC_ERR_TIMEOUT; 109*91f16700Schasinglulu } 110*91f16700Schasinglulu 111*91f16700Schasinglulu switch (mmc_drv_obj.r3_ocr & EMMC_OCR_ACCESS_MODE_MASK) { 112*91f16700Schasinglulu case EMMC_OCR_ACCESS_MODE_SECT: 113*91f16700Schasinglulu mmc_drv_obj.access_mode = TRUE; /* sector mode */ 114*91f16700Schasinglulu break; 115*91f16700Schasinglulu default: 116*91f16700Schasinglulu /* unknown value */ 117*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR); 118*91f16700Schasinglulu return EMMC_ERR; 119*91f16700Schasinglulu } 120*91f16700Schasinglulu 121*91f16700Schasinglulu /* CMD2 */ 122*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD2_ALL_SEND_CID_MMC, 0x00000000); 123*91f16700Schasinglulu mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.cid_data[0]); /* use CID special buffer */ 124*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 125*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 126*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 127*91f16700Schasinglulu return result; 128*91f16700Schasinglulu } 129*91f16700Schasinglulu 130*91f16700Schasinglulu /* CMD3 */ 131*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD3_SET_RELATIVE_ADDR, EMMC_RCA << 16); 132*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 133*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 134*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 135*91f16700Schasinglulu return result; 136*91f16700Schasinglulu } 137*91f16700Schasinglulu 138*91f16700Schasinglulu /* CMD9 (CSD) */ 139*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD9_SEND_CSD, EMMC_RCA << 16); 140*91f16700Schasinglulu mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.csd_data[0]); /* use CSD special buffer */ 141*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 142*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 143*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 144*91f16700Schasinglulu return result; 145*91f16700Schasinglulu } 146*91f16700Schasinglulu 147*91f16700Schasinglulu /* card version check */ 148*91f16700Schasinglulu if (EMMC_CSD_SPEC_VARS() < 4) { 149*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, 150*91f16700Schasinglulu EMMC_ERR_ILLEGAL_CARD); 151*91f16700Schasinglulu return EMMC_ERR_ILLEGAL_CARD; 152*91f16700Schasinglulu } 153*91f16700Schasinglulu 154*91f16700Schasinglulu /* CMD7 (select card) */ 155*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD7_SELECT_CARD, EMMC_RCA << 16); 156*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 157*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 158*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 159*91f16700Schasinglulu return result; 160*91f16700Schasinglulu } 161*91f16700Schasinglulu 162*91f16700Schasinglulu mmc_drv_obj.selected = TRUE; 163*91f16700Schasinglulu 164*91f16700Schasinglulu /* 165*91f16700Schasinglulu * card speed check 166*91f16700Schasinglulu * Card spec is calculated from TRAN_SPEED(CSD) 167*91f16700Schasinglulu */ 168*91f16700Schasinglulu result_calc = emmc_calc_tran_speed(&freq); 169*91f16700Schasinglulu if (result_calc == 0) { 170*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, 171*91f16700Schasinglulu EMMC_ERR_ILLEGAL_CARD); 172*91f16700Schasinglulu return EMMC_ERR_ILLEGAL_CARD; 173*91f16700Schasinglulu } 174*91f16700Schasinglulu mmc_drv_obj.max_freq = freq; /* max frequency (card spec) */ 175*91f16700Schasinglulu 176*91f16700Schasinglulu result = emmc_set_request_mmc_clock(&freq); 177*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 178*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 179*91f16700Schasinglulu return EMMC_ERR; 180*91f16700Schasinglulu } 181*91f16700Schasinglulu 182*91f16700Schasinglulu /* set read/write timeout */ 183*91f16700Schasinglulu mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq); 184*91f16700Schasinglulu SETR_32(SD_OPTION, 185*91f16700Schasinglulu ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | 186*91f16700Schasinglulu mmc_drv_obj.data_timeout)); 187*91f16700Schasinglulu 188*91f16700Schasinglulu /* SET_BLOCKLEN(512byte) */ 189*91f16700Schasinglulu /* CMD16 */ 190*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD16_SET_BLOCKLEN, EMMC_BLOCK_LENGTH); 191*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 192*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 193*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 194*91f16700Schasinglulu return result; 195*91f16700Schasinglulu } 196*91f16700Schasinglulu 197*91f16700Schasinglulu /* Transfer Data Length */ 198*91f16700Schasinglulu SETR_32(SD_SIZE, EMMC_BLOCK_LENGTH); 199*91f16700Schasinglulu 200*91f16700Schasinglulu /* CMD8 (EXT_CSD) */ 201*91f16700Schasinglulu emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, 202*91f16700Schasinglulu (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), 203*91f16700Schasinglulu EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, 204*91f16700Schasinglulu HAL_MEMCARD_NOT_DMA); 205*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 206*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 207*91f16700Schasinglulu /* 208*91f16700Schasinglulu * CMD12 is not send. 209*91f16700Schasinglulu * If BUS initialization is failed, user must be execute Bus initialization again. 210*91f16700Schasinglulu * Bus initialization is start CMD0(soft reset command). 211*91f16700Schasinglulu */ 212*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 213*91f16700Schasinglulu return result; 214*91f16700Schasinglulu } 215*91f16700Schasinglulu 216*91f16700Schasinglulu /* Set boot partition */ 217*91f16700Schasinglulu emmc_set_bootpartition(); 218*91f16700Schasinglulu 219*91f16700Schasinglulu return EMMC_SUCCESS; 220*91f16700Schasinglulu } 221*91f16700Schasinglulu 222*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_high_speed(void) 223*91f16700Schasinglulu { 224*91f16700Schasinglulu uint32_t freq; /* High speed mode clock frequency */ 225*91f16700Schasinglulu EMMC_ERROR_CODE result; 226*91f16700Schasinglulu uint8_t cardType; 227*91f16700Schasinglulu 228*91f16700Schasinglulu /* state check */ 229*91f16700Schasinglulu if (mmc_drv_obj.selected != TRUE) { 230*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_HIGH_SPEED, EMMC_ERR_STATE); 231*91f16700Schasinglulu return EMMC_ERR_STATE; 232*91f16700Schasinglulu } 233*91f16700Schasinglulu 234*91f16700Schasinglulu /* max frequency */ 235*91f16700Schasinglulu cardType = (uint8_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_CARD_TYPE]; 236*91f16700Schasinglulu if ((cardType & EMMC_EXT_CSD_CARD_TYPE_52MHZ) != 0) 237*91f16700Schasinglulu freq = MMC_52MHZ; 238*91f16700Schasinglulu else if ((cardType & EMMC_EXT_CSD_CARD_TYPE_26MHZ) != 0) 239*91f16700Schasinglulu freq = MMC_26MHZ; 240*91f16700Schasinglulu else 241*91f16700Schasinglulu freq = MMC_20MHZ; 242*91f16700Schasinglulu 243*91f16700Schasinglulu /* Hi-Speed-mode selection */ 244*91f16700Schasinglulu if ((freq == MMC_52MHZ) || (freq == MMC_26MHZ)) { 245*91f16700Schasinglulu /* CMD6 */ 246*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING); 247*91f16700Schasinglulu result = 248*91f16700Schasinglulu emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 249*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 250*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); 251*91f16700Schasinglulu return result; 252*91f16700Schasinglulu } 253*91f16700Schasinglulu 254*91f16700Schasinglulu mmc_drv_obj.hs_timing = TIMING_HIGH_SPEED; /* High-Speed */ 255*91f16700Schasinglulu } 256*91f16700Schasinglulu 257*91f16700Schasinglulu /* set mmc clock */ 258*91f16700Schasinglulu mmc_drv_obj.max_freq = freq; 259*91f16700Schasinglulu result = emmc_set_request_mmc_clock(&freq); 260*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 261*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); 262*91f16700Schasinglulu return EMMC_ERR; 263*91f16700Schasinglulu } 264*91f16700Schasinglulu 265*91f16700Schasinglulu /* set read/write timeout */ 266*91f16700Schasinglulu mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq); 267*91f16700Schasinglulu SETR_32(SD_OPTION, 268*91f16700Schasinglulu ((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) | 269*91f16700Schasinglulu mmc_drv_obj.data_timeout)); 270*91f16700Schasinglulu 271*91f16700Schasinglulu /* CMD13 */ 272*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); 273*91f16700Schasinglulu result = 274*91f16700Schasinglulu emmc_exec_cmd(EMMC_R1_ERROR_MASK_WITHOUT_CRC, mmc_drv_obj.response); 275*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 276*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); 277*91f16700Schasinglulu return result; 278*91f16700Schasinglulu } 279*91f16700Schasinglulu 280*91f16700Schasinglulu return EMMC_SUCCESS; 281*91f16700Schasinglulu } 282*91f16700Schasinglulu 283*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode) 284*91f16700Schasinglulu { 285*91f16700Schasinglulu uint32_t value; 286*91f16700Schasinglulu 287*91f16700Schasinglulu /* busy check */ 288*91f16700Schasinglulu if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) { 289*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, 290*91f16700Schasinglulu EMMC_ERR_CARD_BUSY); 291*91f16700Schasinglulu return EMMC_ERR; 292*91f16700Schasinglulu } 293*91f16700Schasinglulu 294*91f16700Schasinglulu if (mode == TRUE) { 295*91f16700Schasinglulu /* clock ON */ 296*91f16700Schasinglulu value = 297*91f16700Schasinglulu ((GETR_32(SD_CLK_CTRL) | MMC_SD_CLK_START) & 298*91f16700Schasinglulu SD_CLK_WRITE_MASK); 299*91f16700Schasinglulu SETR_32(SD_CLK_CTRL, value); /* on */ 300*91f16700Schasinglulu mmc_drv_obj.clock_enable = TRUE; 301*91f16700Schasinglulu } else { 302*91f16700Schasinglulu /* clock OFF */ 303*91f16700Schasinglulu value = 304*91f16700Schasinglulu ((GETR_32(SD_CLK_CTRL) & MMC_SD_CLK_STOP) & 305*91f16700Schasinglulu SD_CLK_WRITE_MASK); 306*91f16700Schasinglulu SETR_32(SD_CLK_CTRL, value); /* off */ 307*91f16700Schasinglulu mmc_drv_obj.clock_enable = FALSE; 308*91f16700Schasinglulu } 309*91f16700Schasinglulu 310*91f16700Schasinglulu return EMMC_SUCCESS; 311*91f16700Schasinglulu } 312*91f16700Schasinglulu 313*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_bus_width(uint32_t width) 314*91f16700Schasinglulu { 315*91f16700Schasinglulu EMMC_ERROR_CODE result = EMMC_ERR; 316*91f16700Schasinglulu 317*91f16700Schasinglulu /* parameter check */ 318*91f16700Schasinglulu if ((width != 8) && (width != 4) && (width != 1)) { 319*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_PARAM); 320*91f16700Schasinglulu return EMMC_ERR_PARAM; 321*91f16700Schasinglulu } 322*91f16700Schasinglulu 323*91f16700Schasinglulu /* state check */ 324*91f16700Schasinglulu if (mmc_drv_obj.selected != TRUE) { 325*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_STATE); 326*91f16700Schasinglulu return EMMC_ERR_STATE; 327*91f16700Schasinglulu } 328*91f16700Schasinglulu 329*91f16700Schasinglulu /* 2 = 8bit, 1 = 4bit, 0 =1bit */ 330*91f16700Schasinglulu mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); 331*91f16700Schasinglulu 332*91f16700Schasinglulu /* CMD6 */ 333*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD6_SWITCH, 334*91f16700Schasinglulu (EMMC_SWITCH_BUS_WIDTH_1 | 335*91f16700Schasinglulu (mmc_drv_obj.bus_width << 8))); 336*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 337*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 338*91f16700Schasinglulu /* occurred error */ 339*91f16700Schasinglulu mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; 340*91f16700Schasinglulu goto EXIT; 341*91f16700Schasinglulu } 342*91f16700Schasinglulu 343*91f16700Schasinglulu switch (mmc_drv_obj.bus_width) { 344*91f16700Schasinglulu case HAL_MEMCARD_DATA_WIDTH_1_BIT: 345*91f16700Schasinglulu SETR_32(SD_OPTION, 346*91f16700Schasinglulu ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT15)); 347*91f16700Schasinglulu break; 348*91f16700Schasinglulu case HAL_MEMCARD_DATA_WIDTH_4_BIT: 349*91f16700Schasinglulu SETR_32(SD_OPTION, (GETR_32(SD_OPTION) & ~(BIT15 | BIT13))); 350*91f16700Schasinglulu break; 351*91f16700Schasinglulu case HAL_MEMCARD_DATA_WIDTH_8_BIT: 352*91f16700Schasinglulu SETR_32(SD_OPTION, 353*91f16700Schasinglulu ((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT13)); 354*91f16700Schasinglulu break; 355*91f16700Schasinglulu default: 356*91f16700Schasinglulu goto EXIT; 357*91f16700Schasinglulu } 358*91f16700Schasinglulu 359*91f16700Schasinglulu /* CMD13 */ 360*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); 361*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 362*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 363*91f16700Schasinglulu goto EXIT; 364*91f16700Schasinglulu } 365*91f16700Schasinglulu 366*91f16700Schasinglulu /* CMD8 (EXT_CSD) */ 367*91f16700Schasinglulu emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, 368*91f16700Schasinglulu (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), 369*91f16700Schasinglulu EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, 370*91f16700Schasinglulu HAL_MEMCARD_NOT_DMA); 371*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 372*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 373*91f16700Schasinglulu goto EXIT; 374*91f16700Schasinglulu } 375*91f16700Schasinglulu 376*91f16700Schasinglulu return EMMC_SUCCESS; 377*91f16700Schasinglulu 378*91f16700Schasinglulu EXIT: 379*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result); 380*91f16700Schasinglulu ERROR("BL2: emmc bus_width error end\n"); 381*91f16700Schasinglulu return result; 382*91f16700Schasinglulu } 383*91f16700Schasinglulu 384*91f16700Schasinglulu EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id) 385*91f16700Schasinglulu { 386*91f16700Schasinglulu EMMC_ERROR_CODE result; 387*91f16700Schasinglulu uint32_t arg; 388*91f16700Schasinglulu uint32_t partition_config; 389*91f16700Schasinglulu 390*91f16700Schasinglulu /* state check */ 391*91f16700Schasinglulu if (mmc_drv_obj.mount != TRUE) { 392*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_STATE); 393*91f16700Schasinglulu return EMMC_ERR_STATE; 394*91f16700Schasinglulu } 395*91f16700Schasinglulu 396*91f16700Schasinglulu /* id = PARTITION_ACCESS(Bit[2:0]) */ 397*91f16700Schasinglulu if ((id & ~PARTITION_ID_MASK) != 0) { 398*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_PARAM); 399*91f16700Schasinglulu return EMMC_ERR_PARAM; 400*91f16700Schasinglulu } 401*91f16700Schasinglulu 402*91f16700Schasinglulu /* EXT_CSD[179] value */ 403*91f16700Schasinglulu partition_config = 404*91f16700Schasinglulu (uint32_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_PARTITION_CONFIG]; 405*91f16700Schasinglulu if ((partition_config & PARTITION_ID_MASK) == id) { 406*91f16700Schasinglulu result = EMMC_SUCCESS; 407*91f16700Schasinglulu } else { 408*91f16700Schasinglulu 409*91f16700Schasinglulu partition_config = 410*91f16700Schasinglulu (uint32_t) ((partition_config & ~PARTITION_ID_MASK) | id); 411*91f16700Schasinglulu arg = EMMC_SWITCH_PARTITION_CONFIG | (partition_config << 8); 412*91f16700Schasinglulu 413*91f16700Schasinglulu result = emmc_set_ext_csd(arg); 414*91f16700Schasinglulu } 415*91f16700Schasinglulu 416*91f16700Schasinglulu return result; 417*91f16700Schasinglulu } 418*91f16700Schasinglulu 419*91f16700Schasinglulu static void set_sd_clk(uint32_t clkDiv) 420*91f16700Schasinglulu { 421*91f16700Schasinglulu uint32_t dataL; 422*91f16700Schasinglulu 423*91f16700Schasinglulu dataL = (GETR_32(SD_CLK_CTRL) & (~SD_CLK_CTRL_CLKDIV_MASK)); 424*91f16700Schasinglulu 425*91f16700Schasinglulu switch (clkDiv) { 426*91f16700Schasinglulu case 1: 427*91f16700Schasinglulu dataL |= 0x000000FFU; 428*91f16700Schasinglulu break; /* 1/1 */ 429*91f16700Schasinglulu case 2: 430*91f16700Schasinglulu dataL |= 0x00000000U; 431*91f16700Schasinglulu break; /* 1/2 */ 432*91f16700Schasinglulu case 4: 433*91f16700Schasinglulu dataL |= 0x00000001U; 434*91f16700Schasinglulu break; /* 1/4 */ 435*91f16700Schasinglulu case 8: 436*91f16700Schasinglulu dataL |= 0x00000002U; 437*91f16700Schasinglulu break; /* 1/8 */ 438*91f16700Schasinglulu case 16: 439*91f16700Schasinglulu dataL |= 0x00000004U; 440*91f16700Schasinglulu break; /* 1/16 */ 441*91f16700Schasinglulu case 32: 442*91f16700Schasinglulu dataL |= 0x00000008U; 443*91f16700Schasinglulu break; /* 1/32 */ 444*91f16700Schasinglulu case 64: 445*91f16700Schasinglulu dataL |= 0x00000010U; 446*91f16700Schasinglulu break; /* 1/64 */ 447*91f16700Schasinglulu case 128: 448*91f16700Schasinglulu dataL |= 0x00000020U; 449*91f16700Schasinglulu break; /* 1/128 */ 450*91f16700Schasinglulu case 256: 451*91f16700Schasinglulu dataL |= 0x00000040U; 452*91f16700Schasinglulu break; /* 1/256 */ 453*91f16700Schasinglulu case 512: 454*91f16700Schasinglulu dataL |= 0x00000080U; 455*91f16700Schasinglulu break; /* 1/512 */ 456*91f16700Schasinglulu } 457*91f16700Schasinglulu 458*91f16700Schasinglulu SETR_32(SD_CLK_CTRL, dataL); 459*91f16700Schasinglulu mmc_drv_obj.current_freq = (uint32_t) clkDiv; 460*91f16700Schasinglulu } 461*91f16700Schasinglulu 462*91f16700Schasinglulu static void emmc_get_partition_access(void) 463*91f16700Schasinglulu { 464*91f16700Schasinglulu uint32_t reg; 465*91f16700Schasinglulu EMMC_ERROR_CODE result; 466*91f16700Schasinglulu 467*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 468*91f16700Schasinglulu if ((reg == PRR_PRODUCT_H3_CUT20) || (reg == PRR_PRODUCT_M3_CUT11)) { 469*91f16700Schasinglulu SETR_32(SD_OPTION, 0x000060EEU); /* 8 bits width */ 470*91f16700Schasinglulu /* CMD8 (EXT_CSD) */ 471*91f16700Schasinglulu emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U, 472*91f16700Schasinglulu (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), 473*91f16700Schasinglulu EMMC_MAX_EXT_CSD_LENGTH, 474*91f16700Schasinglulu HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA); 475*91f16700Schasinglulu mmc_drv_obj.get_partition_access_flag = TRUE; 476*91f16700Schasinglulu result = 477*91f16700Schasinglulu emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 478*91f16700Schasinglulu mmc_drv_obj.get_partition_access_flag = FALSE; 479*91f16700Schasinglulu if (result == EMMC_SUCCESS) { 480*91f16700Schasinglulu mmc_drv_obj.partition_access = 481*91f16700Schasinglulu (EMMC_PARTITION_ID) (mmc_drv_obj.ext_csd_data[179] 482*91f16700Schasinglulu & PARTITION_ID_MASK); 483*91f16700Schasinglulu } else if (result == EMMC_ERR_CMD_TIMEOUT) { 484*91f16700Schasinglulu mmc_drv_obj.partition_access = PARTITION_ID_BOOT_1; 485*91f16700Schasinglulu } else { 486*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_GET_PERTITION_ACCESS, 487*91f16700Schasinglulu result); 488*91f16700Schasinglulu panic(); 489*91f16700Schasinglulu } 490*91f16700Schasinglulu SETR_32(SD_OPTION, 0x0000C0EEU); /* Initialize */ 491*91f16700Schasinglulu } 492*91f16700Schasinglulu } 493*91f16700Schasinglulu 494*91f16700Schasinglulu static uint32_t emmc_calc_tran_speed(uint32_t *freq) 495*91f16700Schasinglulu { 496*91f16700Schasinglulu const uint32_t unit[8] = { 10000U, 100000U, 1000000U, 10000000U, 497*91f16700Schasinglulu 0U, 0U, 0U, 0U }; /* frequency unit (1/10) */ 498*91f16700Schasinglulu const uint32_t mult[16] = { 0U, 10U, 12U, 13U, 15U, 20U, 26U, 30U, 35U, 499*91f16700Schasinglulu 40U, 45U, 52U, 55U, 60U, 70U, 80U }; 500*91f16700Schasinglulu uint32_t tran_speed = EMMC_CSD_TRAN_SPEED(); 501*91f16700Schasinglulu uint32_t max_freq; 502*91f16700Schasinglulu uint32_t result; 503*91f16700Schasinglulu 504*91f16700Schasinglulu /* 505*91f16700Schasinglulu * tran_speed = 0x32 506*91f16700Schasinglulu * unit[tran_speed&0x7] = uint[0x2] = 1000000 507*91f16700Schasinglulu * mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26 508*91f16700Schasinglulu * 1000000 * 26 = 26000000 (26MHz) 509*91f16700Schasinglulu */ 510*91f16700Schasinglulu 511*91f16700Schasinglulu result = 1; 512*91f16700Schasinglulu max_freq = 513*91f16700Schasinglulu unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] * 514*91f16700Schasinglulu mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >> 515*91f16700Schasinglulu EMMC_TRANSPEED_MULT_SHIFT]; 516*91f16700Schasinglulu 517*91f16700Schasinglulu if (max_freq == 0) { 518*91f16700Schasinglulu result = 0; 519*91f16700Schasinglulu } else if (max_freq >= MMC_FREQ_52MHZ) { 520*91f16700Schasinglulu *freq = MMC_52MHZ; 521*91f16700Schasinglulu } else if (max_freq >= MMC_FREQ_26MHZ) { 522*91f16700Schasinglulu *freq = MMC_26MHZ; 523*91f16700Schasinglulu } else if (max_freq >= MMC_FREQ_20MHZ) { 524*91f16700Schasinglulu *freq = MMC_20MHZ; 525*91f16700Schasinglulu } else { 526*91f16700Schasinglulu *freq = MMC_400KHZ; 527*91f16700Schasinglulu } 528*91f16700Schasinglulu 529*91f16700Schasinglulu return result; 530*91f16700Schasinglulu } 531*91f16700Schasinglulu 532*91f16700Schasinglulu static uint32_t emmc_set_timeout_register_value(uint32_t freq) 533*91f16700Schasinglulu { 534*91f16700Schasinglulu uint32_t timeout_cnt; /* SD_OPTION - Timeout Counter */ 535*91f16700Schasinglulu 536*91f16700Schasinglulu switch (freq) { 537*91f16700Schasinglulu case 1U: 538*91f16700Schasinglulu timeout_cnt = 0xE0U; 539*91f16700Schasinglulu break; /* SDCLK * 2^27 */ 540*91f16700Schasinglulu case 2U: 541*91f16700Schasinglulu timeout_cnt = 0xE0U; 542*91f16700Schasinglulu break; /* SDCLK * 2^27 */ 543*91f16700Schasinglulu case 4U: 544*91f16700Schasinglulu timeout_cnt = 0xD0U; 545*91f16700Schasinglulu break; /* SDCLK * 2^26 */ 546*91f16700Schasinglulu case 8U: 547*91f16700Schasinglulu timeout_cnt = 0xC0U; 548*91f16700Schasinglulu break; /* SDCLK * 2^25 */ 549*91f16700Schasinglulu case 16U: 550*91f16700Schasinglulu timeout_cnt = 0xB0U; 551*91f16700Schasinglulu break; /* SDCLK * 2^24 */ 552*91f16700Schasinglulu case 32U: 553*91f16700Schasinglulu timeout_cnt = 0xA0U; 554*91f16700Schasinglulu break; /* SDCLK * 2^23 */ 555*91f16700Schasinglulu case 64U: 556*91f16700Schasinglulu timeout_cnt = 0x90U; 557*91f16700Schasinglulu break; /* SDCLK * 2^22 */ 558*91f16700Schasinglulu case 128U: 559*91f16700Schasinglulu timeout_cnt = 0x80U; 560*91f16700Schasinglulu break; /* SDCLK * 2^21 */ 561*91f16700Schasinglulu case 256U: 562*91f16700Schasinglulu timeout_cnt = 0x70U; 563*91f16700Schasinglulu break; /* SDCLK * 2^20 */ 564*91f16700Schasinglulu case 512U: 565*91f16700Schasinglulu timeout_cnt = 0x70U; 566*91f16700Schasinglulu break; /* SDCLK * 2^20 */ 567*91f16700Schasinglulu default: 568*91f16700Schasinglulu timeout_cnt = 0xE0U; 569*91f16700Schasinglulu break; /* SDCLK * 2^27 */ 570*91f16700Schasinglulu } 571*91f16700Schasinglulu 572*91f16700Schasinglulu return timeout_cnt; 573*91f16700Schasinglulu } 574*91f16700Schasinglulu 575*91f16700Schasinglulu EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg) 576*91f16700Schasinglulu { 577*91f16700Schasinglulu EMMC_ERROR_CODE result; 578*91f16700Schasinglulu 579*91f16700Schasinglulu /* CMD6 */ 580*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD6_SWITCH, arg); 581*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 582*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 583*91f16700Schasinglulu return result; 584*91f16700Schasinglulu } 585*91f16700Schasinglulu 586*91f16700Schasinglulu /* CMD13 */ 587*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16); 588*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 589*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 590*91f16700Schasinglulu return result; 591*91f16700Schasinglulu } 592*91f16700Schasinglulu 593*91f16700Schasinglulu /* CMD8 (EXT_CSD) */ 594*91f16700Schasinglulu emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000, 595*91f16700Schasinglulu (uint32_t *) (&mmc_drv_obj.ext_csd_data[0]), 596*91f16700Schasinglulu EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ, 597*91f16700Schasinglulu HAL_MEMCARD_NOT_DMA); 598*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 599*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 600*91f16700Schasinglulu return result; 601*91f16700Schasinglulu } 602*91f16700Schasinglulu return EMMC_SUCCESS; 603*91f16700Schasinglulu } 604*91f16700Schasinglulu 605*91f16700Schasinglulu EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq) 606*91f16700Schasinglulu { 607*91f16700Schasinglulu /* parameter check */ 608*91f16700Schasinglulu if (freq == NULL) { 609*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_PARAM); 610*91f16700Schasinglulu return EMMC_ERR_PARAM; 611*91f16700Schasinglulu } 612*91f16700Schasinglulu 613*91f16700Schasinglulu /* state check */ 614*91f16700Schasinglulu if ((mmc_drv_obj.initialize != TRUE) 615*91f16700Schasinglulu || (mmc_drv_obj.card_power_enable != TRUE)) { 616*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_STATE); 617*91f16700Schasinglulu return EMMC_ERR_STATE; 618*91f16700Schasinglulu } 619*91f16700Schasinglulu 620*91f16700Schasinglulu /* clock is already running in the desired frequency. */ 621*91f16700Schasinglulu if ((mmc_drv_obj.clock_enable == TRUE) 622*91f16700Schasinglulu && (mmc_drv_obj.current_freq == *freq)) { 623*91f16700Schasinglulu return EMMC_SUCCESS; 624*91f16700Schasinglulu } 625*91f16700Schasinglulu 626*91f16700Schasinglulu /* busy check */ 627*91f16700Schasinglulu if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) { 628*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, 629*91f16700Schasinglulu EMMC_ERR_CARD_BUSY); 630*91f16700Schasinglulu return EMMC_ERR; 631*91f16700Schasinglulu } 632*91f16700Schasinglulu 633*91f16700Schasinglulu set_sd_clk(*freq); 634*91f16700Schasinglulu mmc_drv_obj.clock_enable = FALSE; 635*91f16700Schasinglulu 636*91f16700Schasinglulu return emmc_clock_ctrl(TRUE); /* clock on */ 637*91f16700Schasinglulu } 638*91f16700Schasinglulu 639*91f16700Schasinglulu EMMC_ERROR_CODE rcar_emmc_mount(void) 640*91f16700Schasinglulu { 641*91f16700Schasinglulu EMMC_ERROR_CODE result; 642*91f16700Schasinglulu 643*91f16700Schasinglulu /* state check */ 644*91f16700Schasinglulu if ((mmc_drv_obj.initialize != TRUE) 645*91f16700Schasinglulu || (mmc_drv_obj.card_power_enable != TRUE) 646*91f16700Schasinglulu || ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) 647*91f16700Schasinglulu ) { 648*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_MOUNT, EMMC_ERR_STATE); 649*91f16700Schasinglulu return EMMC_ERR_STATE; 650*91f16700Schasinglulu } 651*91f16700Schasinglulu 652*91f16700Schasinglulu /* initialize card (IDLE state --> Transfer state) */ 653*91f16700Schasinglulu result = emmc_card_init(); 654*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 655*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT); 656*91f16700Schasinglulu if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { 657*91f16700Schasinglulu /* nothing to do. */ 658*91f16700Schasinglulu } 659*91f16700Schasinglulu return result; 660*91f16700Schasinglulu } 661*91f16700Schasinglulu 662*91f16700Schasinglulu /* Switching high speed mode */ 663*91f16700Schasinglulu result = emmc_high_speed(); 664*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 665*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED); 666*91f16700Schasinglulu if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { 667*91f16700Schasinglulu /* nothing to do. */ 668*91f16700Schasinglulu } 669*91f16700Schasinglulu return result; 670*91f16700Schasinglulu } 671*91f16700Schasinglulu 672*91f16700Schasinglulu /* Changing the data bus width */ 673*91f16700Schasinglulu result = emmc_bus_width(8); 674*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 675*91f16700Schasinglulu emmc_write_error_info_func_no(EMMC_FUNCNO_BUS_WIDTH); 676*91f16700Schasinglulu if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) { 677*91f16700Schasinglulu /* nothing to do. */ 678*91f16700Schasinglulu } 679*91f16700Schasinglulu return result; 680*91f16700Schasinglulu } 681*91f16700Schasinglulu 682*91f16700Schasinglulu /* mount complete */ 683*91f16700Schasinglulu mmc_drv_obj.mount = TRUE; 684*91f16700Schasinglulu 685*91f16700Schasinglulu return EMMC_SUCCESS; 686*91f16700Schasinglulu } 687