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 9*91f16700Schasinglulu #include "emmc_config.h" 10*91f16700Schasinglulu #include "emmc_def.h" 11*91f16700Schasinglulu #include "emmc_hal.h" 12*91f16700Schasinglulu #include "emmc_registers.h" 13*91f16700Schasinglulu #include "emmc_std.h" 14*91f16700Schasinglulu 15*91f16700Schasinglulu static const uint32_t cmd_reg_hw[EMMC_CMD_MAX + 1] = { 16*91f16700Schasinglulu 0x00000000, /* CMD0 */ 17*91f16700Schasinglulu 0x00000701, /* CMD1 */ 18*91f16700Schasinglulu 0x00000002, /* CMD2 */ 19*91f16700Schasinglulu 0x00000003, /* CMD3 */ 20*91f16700Schasinglulu 0x00000004, /* CMD4 */ 21*91f16700Schasinglulu 0x00000505, /* CMD5 */ 22*91f16700Schasinglulu 0x00000406, /* CMD6 */ 23*91f16700Schasinglulu 0x00000007, /* CMD7 */ 24*91f16700Schasinglulu 0x00001C08, /* CMD8 */ 25*91f16700Schasinglulu 0x00000009, /* CMD9 */ 26*91f16700Schasinglulu 0x0000000A, /* CMD10 */ 27*91f16700Schasinglulu 0x00000000, /* reserved */ 28*91f16700Schasinglulu 0x0000000C, /* CMD12 */ 29*91f16700Schasinglulu 0x0000000D, /* CMD13 */ 30*91f16700Schasinglulu 0x00001C0E, /* CMD14 */ 31*91f16700Schasinglulu 0x0000000F, /* CMD15 */ 32*91f16700Schasinglulu 0x00000010, /* CMD16 */ 33*91f16700Schasinglulu 0x00000011, /* CMD17 */ 34*91f16700Schasinglulu 0x00007C12, /* CMD18 */ 35*91f16700Schasinglulu 0x00000C13, /* CMD19 */ 36*91f16700Schasinglulu 0x00000000, 37*91f16700Schasinglulu 0x00001C15, /* CMD21 */ 38*91f16700Schasinglulu 0x00000000, 39*91f16700Schasinglulu 0x00000017, /* CMD23 */ 40*91f16700Schasinglulu 0x00000018, /* CMD24 */ 41*91f16700Schasinglulu 0x00006C19, /* CMD25 */ 42*91f16700Schasinglulu 0x00000C1A, /* CMD26 */ 43*91f16700Schasinglulu 0x0000001B, /* CMD27 */ 44*91f16700Schasinglulu 0x0000001C, /* CMD28 */ 45*91f16700Schasinglulu 0x0000001D, /* CMD29 */ 46*91f16700Schasinglulu 0x0000001E, /* CMD30 */ 47*91f16700Schasinglulu 0x00001C1F, /* CMD31 */ 48*91f16700Schasinglulu 0x00000000, 49*91f16700Schasinglulu 0x00000000, 50*91f16700Schasinglulu 0x00000000, 51*91f16700Schasinglulu 0x00000423, /* CMD35 */ 52*91f16700Schasinglulu 0x00000424, /* CMD36 */ 53*91f16700Schasinglulu 0x00000000, 54*91f16700Schasinglulu 0x00000026, /* CMD38 */ 55*91f16700Schasinglulu 0x00000427, /* CMD39 */ 56*91f16700Schasinglulu 0x00000428, /* CMD40(send cmd) */ 57*91f16700Schasinglulu 0x00000000, 58*91f16700Schasinglulu 0x0000002A, /* CMD42 */ 59*91f16700Schasinglulu 0x00000000, 60*91f16700Schasinglulu 0x00000000, 61*91f16700Schasinglulu 0x00000000, 62*91f16700Schasinglulu 0x00000000, 63*91f16700Schasinglulu 0x00000000, 64*91f16700Schasinglulu 0x00000000, 65*91f16700Schasinglulu 0x00000C31, 66*91f16700Schasinglulu 0x00000000, 67*91f16700Schasinglulu 0x00000000, 68*91f16700Schasinglulu 0x00000000, 69*91f16700Schasinglulu 0x00007C35, 70*91f16700Schasinglulu 0x00006C36, 71*91f16700Schasinglulu 0x00000037, /* CMD55 */ 72*91f16700Schasinglulu 0x00000038, /* CMD56(Read) */ 73*91f16700Schasinglulu 0x00000000, 74*91f16700Schasinglulu 0x00000000, 75*91f16700Schasinglulu 0x00000000, 76*91f16700Schasinglulu 0x00000000 77*91f16700Schasinglulu }; 78*91f16700Schasinglulu 79*91f16700Schasinglulu uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom) 80*91f16700Schasinglulu { 81*91f16700Schasinglulu uint32_t value; 82*91f16700Schasinglulu 83*91f16700Schasinglulu uint32_t index_top = (uint32_t) (15 - (top >> 3)); 84*91f16700Schasinglulu uint32_t index_bottom = (uint32_t) (15 - (bottom >> 3)); 85*91f16700Schasinglulu 86*91f16700Schasinglulu if (index_top == index_bottom) { 87*91f16700Schasinglulu value = data[index_top]; 88*91f16700Schasinglulu } else if ((index_top + 1) == index_bottom) { 89*91f16700Schasinglulu value = 90*91f16700Schasinglulu (uint32_t) ((data[index_top] << 8) | data[index_bottom]); 91*91f16700Schasinglulu } else if ((index_top + 2) == index_bottom) { 92*91f16700Schasinglulu value = 93*91f16700Schasinglulu (uint32_t) ((data[index_top] << 16) | 94*91f16700Schasinglulu (data[index_top + 1] << 8) | data[index_top + 95*91f16700Schasinglulu 2]); 96*91f16700Schasinglulu } else { 97*91f16700Schasinglulu value = 98*91f16700Schasinglulu (uint32_t) ((data[index_top] << 24) | 99*91f16700Schasinglulu (data[index_top + 1] << 16) | 100*91f16700Schasinglulu (data[index_top + 2] << 8) | 101*91f16700Schasinglulu data[index_top + 3]); 102*91f16700Schasinglulu } 103*91f16700Schasinglulu 104*91f16700Schasinglulu value = ((value >> (bottom & 0x07)) & ((1 << (top - bottom + 1)) - 1)); 105*91f16700Schasinglulu 106*91f16700Schasinglulu return value; 107*91f16700Schasinglulu } 108*91f16700Schasinglulu 109*91f16700Schasinglulu void emmc_write_error_info(uint16_t func_no, EMMC_ERROR_CODE error_code) 110*91f16700Schasinglulu { 111*91f16700Schasinglulu 112*91f16700Schasinglulu mmc_drv_obj.error_info.num = func_no; 113*91f16700Schasinglulu mmc_drv_obj.error_info.code = (uint16_t) error_code; 114*91f16700Schasinglulu 115*91f16700Schasinglulu ERROR("BL2: emmc err:func_no=0x%x code=0x%x\n", func_no, error_code); 116*91f16700Schasinglulu } 117*91f16700Schasinglulu 118*91f16700Schasinglulu void emmc_write_error_info_func_no(uint16_t func_no) 119*91f16700Schasinglulu { 120*91f16700Schasinglulu 121*91f16700Schasinglulu mmc_drv_obj.error_info.num = func_no; 122*91f16700Schasinglulu 123*91f16700Schasinglulu ERROR("BL2: emmc err:func_no=0x%x\n", func_no); 124*91f16700Schasinglulu } 125*91f16700Schasinglulu 126*91f16700Schasinglulu void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg) 127*91f16700Schasinglulu { 128*91f16700Schasinglulu /* command information */ 129*91f16700Schasinglulu mmc_drv_obj.cmd_info.cmd = cmd; 130*91f16700Schasinglulu mmc_drv_obj.cmd_info.arg = arg; 131*91f16700Schasinglulu mmc_drv_obj.cmd_info.dir = HAL_MEMCARD_READ; 132*91f16700Schasinglulu mmc_drv_obj.cmd_info.hw = 133*91f16700Schasinglulu cmd_reg_hw[cmd & HAL_MEMCARD_COMMAND_INDEX_MASK]; 134*91f16700Schasinglulu 135*91f16700Schasinglulu /* clear data transfer information */ 136*91f16700Schasinglulu mmc_drv_obj.trans_size = 0; 137*91f16700Schasinglulu mmc_drv_obj.remain_size = 0; 138*91f16700Schasinglulu mmc_drv_obj.buff_address_virtual = NULL; 139*91f16700Schasinglulu mmc_drv_obj.buff_address_physical = NULL; 140*91f16700Schasinglulu 141*91f16700Schasinglulu /* response information */ 142*91f16700Schasinglulu mmc_drv_obj.response_length = 6; 143*91f16700Schasinglulu 144*91f16700Schasinglulu switch (mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK) { 145*91f16700Schasinglulu case HAL_MEMCARD_RESPONSE_NONE: 146*91f16700Schasinglulu mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; 147*91f16700Schasinglulu mmc_drv_obj.response_length = 0; 148*91f16700Schasinglulu break; 149*91f16700Schasinglulu case HAL_MEMCARD_RESPONSE_R1: 150*91f16700Schasinglulu mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; 151*91f16700Schasinglulu break; 152*91f16700Schasinglulu case HAL_MEMCARD_RESPONSE_R1b: 153*91f16700Schasinglulu mmc_drv_obj.cmd_info.hw |= BIT10; /* bit10 = R1 busy bit */ 154*91f16700Schasinglulu mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; 155*91f16700Schasinglulu break; 156*91f16700Schasinglulu case HAL_MEMCARD_RESPONSE_R2: 157*91f16700Schasinglulu mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; 158*91f16700Schasinglulu mmc_drv_obj.response_length = 17; 159*91f16700Schasinglulu break; 160*91f16700Schasinglulu case HAL_MEMCARD_RESPONSE_R3: 161*91f16700Schasinglulu mmc_drv_obj.response = &mmc_drv_obj.r3_ocr; 162*91f16700Schasinglulu break; 163*91f16700Schasinglulu case HAL_MEMCARD_RESPONSE_R4: 164*91f16700Schasinglulu mmc_drv_obj.response = &mmc_drv_obj.r4_resp; 165*91f16700Schasinglulu break; 166*91f16700Schasinglulu case HAL_MEMCARD_RESPONSE_R5: 167*91f16700Schasinglulu mmc_drv_obj.response = &mmc_drv_obj.r5_resp; 168*91f16700Schasinglulu break; 169*91f16700Schasinglulu default: 170*91f16700Schasinglulu mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data; 171*91f16700Schasinglulu break; 172*91f16700Schasinglulu } 173*91f16700Schasinglulu } 174*91f16700Schasinglulu 175*91f16700Schasinglulu void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg, 176*91f16700Schasinglulu uint32_t *buff_address_virtual, 177*91f16700Schasinglulu uint32_t len, 178*91f16700Schasinglulu HAL_MEMCARD_OPERATION dir, 179*91f16700Schasinglulu HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode) 180*91f16700Schasinglulu { 181*91f16700Schasinglulu emmc_make_nontrans_cmd(cmd, arg); /* update common information */ 182*91f16700Schasinglulu 183*91f16700Schasinglulu /* for data transfer command */ 184*91f16700Schasinglulu mmc_drv_obj.cmd_info.dir = dir; 185*91f16700Schasinglulu mmc_drv_obj.buff_address_virtual = buff_address_virtual; 186*91f16700Schasinglulu mmc_drv_obj.buff_address_physical = buff_address_virtual; 187*91f16700Schasinglulu mmc_drv_obj.trans_size = len; 188*91f16700Schasinglulu mmc_drv_obj.remain_size = len; 189*91f16700Schasinglulu mmc_drv_obj.transfer_mode = transfer_mode; 190*91f16700Schasinglulu } 191*91f16700Schasinglulu 192*91f16700Schasinglulu EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg) 193*91f16700Schasinglulu { 194*91f16700Schasinglulu EMMC_ERROR_CODE result; 195*91f16700Schasinglulu uint32_t freq; 196*91f16700Schasinglulu 197*91f16700Schasinglulu /* initialize state */ 198*91f16700Schasinglulu mmc_drv_obj.mount = FALSE; 199*91f16700Schasinglulu mmc_drv_obj.selected = FALSE; 200*91f16700Schasinglulu mmc_drv_obj.during_transfer = FALSE; 201*91f16700Schasinglulu mmc_drv_obj.during_cmd_processing = FALSE; 202*91f16700Schasinglulu mmc_drv_obj.during_dma_transfer = FALSE; 203*91f16700Schasinglulu mmc_drv_obj.dma_error_flag = FALSE; 204*91f16700Schasinglulu mmc_drv_obj.force_terminate = FALSE; 205*91f16700Schasinglulu mmc_drv_obj.state_machine_blocking = FALSE; 206*91f16700Schasinglulu 207*91f16700Schasinglulu mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; 208*91f16700Schasinglulu mmc_drv_obj.max_freq = MMC_20MHZ; /* 20MHz */ 209*91f16700Schasinglulu mmc_drv_obj.current_state = EMMC_R1_STATE_IDLE; 210*91f16700Schasinglulu 211*91f16700Schasinglulu /* CMD0 (MMC clock is current frequency. if Data transfer mode, 20MHz or higher.) */ 212*91f16700Schasinglulu emmc_make_nontrans_cmd(CMD0_GO_IDLE_STATE, arg); /* CMD0 */ 213*91f16700Schasinglulu result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); 214*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 215*91f16700Schasinglulu return result; 216*91f16700Schasinglulu } 217*91f16700Schasinglulu 218*91f16700Schasinglulu /* change MMC clock(400KHz) */ 219*91f16700Schasinglulu freq = MMC_400KHZ; 220*91f16700Schasinglulu result = emmc_set_request_mmc_clock(&freq); 221*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 222*91f16700Schasinglulu return result; 223*91f16700Schasinglulu } 224*91f16700Schasinglulu 225*91f16700Schasinglulu return EMMC_SUCCESS; 226*91f16700Schasinglulu } 227