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