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 <stddef.h> 8*b28c29d0SBiju Das 9*b28c29d0SBiju Das #include <lib/mmio.h> 10*b28c29d0SBiju Das 11*b28c29d0SBiju Das #include "emmc_config.h" 12*b28c29d0SBiju Das #include "emmc_hal.h" 13*b28c29d0SBiju Das #include "emmc_std.h" 14*b28c29d0SBiju Das #include "emmc_registers.h" 15*b28c29d0SBiju Das #include "emmc_def.h" 16*b28c29d0SBiju Das #include "rcar_private.h" 17*b28c29d0SBiju Das 18*b28c29d0SBiju Das st_mmc_base mmc_drv_obj; 19*b28c29d0SBiju Das 20*b28c29d0SBiju Das EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode) 21*b28c29d0SBiju Das { 22*b28c29d0SBiju Das 23*b28c29d0SBiju Das if (mode == TRUE) { 24*b28c29d0SBiju Das /* power on (Vcc&Vccq is always power on) */ 25*b28c29d0SBiju Das mmc_drv_obj.card_power_enable = TRUE; 26*b28c29d0SBiju Das } else { 27*b28c29d0SBiju Das /* power off (Vcc&Vccq is always power on) */ 28*b28c29d0SBiju Das mmc_drv_obj.card_power_enable = FALSE; 29*b28c29d0SBiju Das mmc_drv_obj.mount = FALSE; 30*b28c29d0SBiju Das mmc_drv_obj.selected = FALSE; 31*b28c29d0SBiju Das } 32*b28c29d0SBiju Das 33*b28c29d0SBiju Das return EMMC_SUCCESS; 34*b28c29d0SBiju Das } 35*b28c29d0SBiju Das static inline void emmc_set_retry_count(uint32_t retry) 36*b28c29d0SBiju Das { 37*b28c29d0SBiju Das mmc_drv_obj.retries_after_fail = retry; 38*b28c29d0SBiju Das } 39*b28c29d0SBiju Das 40*b28c29d0SBiju Das static inline void emmc_set_data_timeout(uint32_t data_timeout) 41*b28c29d0SBiju Das { 42*b28c29d0SBiju Das mmc_drv_obj.data_timeout = data_timeout; 43*b28c29d0SBiju Das } 44*b28c29d0SBiju Das 45*b28c29d0SBiju Das static void emmc_memset(uint8_t *buff, uint8_t data, uint32_t cnt) 46*b28c29d0SBiju Das { 47*b28c29d0SBiju Das if (buff == NULL) { 48*b28c29d0SBiju Das return; 49*b28c29d0SBiju Das } 50*b28c29d0SBiju Das 51*b28c29d0SBiju Das while (cnt > 0) { 52*b28c29d0SBiju Das *buff++ = data; 53*b28c29d0SBiju Das cnt--; 54*b28c29d0SBiju Das } 55*b28c29d0SBiju Das } 56*b28c29d0SBiju Das 57*b28c29d0SBiju Das static void emmc_driver_config(void) 58*b28c29d0SBiju Das { 59*b28c29d0SBiju Das emmc_set_retry_count(EMMC_RETRY_COUNT); 60*b28c29d0SBiju Das emmc_set_data_timeout(EMMC_RW_DATA_TIMEOUT); 61*b28c29d0SBiju Das } 62*b28c29d0SBiju Das 63*b28c29d0SBiju Das static void emmc_drv_init(void) 64*b28c29d0SBiju Das { 65*b28c29d0SBiju Das emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base)); 66*b28c29d0SBiju Das mmc_drv_obj.card_present = HAL_MEMCARD_CARD_IS_IN; 67*b28c29d0SBiju Das mmc_drv_obj.data_timeout = EMMC_RW_DATA_TIMEOUT; 68*b28c29d0SBiju Das mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT; 69*b28c29d0SBiju Das } 70*b28c29d0SBiju Das 71*b28c29d0SBiju Das static EMMC_ERROR_CODE emmc_dev_finalize(void) 72*b28c29d0SBiju Das { 73*b28c29d0SBiju Das EMMC_ERROR_CODE result; 74*b28c29d0SBiju Das uint32_t dataL; 75*b28c29d0SBiju Das 76*b28c29d0SBiju Das /* 77*b28c29d0SBiju Das * MMC power off 78*b28c29d0SBiju Das * the power supply of eMMC device is always turning on. 79*b28c29d0SBiju Das * RST_n : Hi --> Low level. 80*b28c29d0SBiju Das */ 81*b28c29d0SBiju Das result = rcar_emmc_memcard_power(FALSE); 82*b28c29d0SBiju Das 83*b28c29d0SBiju Das /* host controller reset */ 84*b28c29d0SBiju Das SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */ 85*b28c29d0SBiju Das SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */ 86*b28c29d0SBiju Das SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ 87*b28c29d0SBiju Das SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ 88*b28c29d0SBiju Das SETR_32(SD_CLK_CTRL, 0x00000000U); /* MMC clock stop */ 89*b28c29d0SBiju Das 90*b28c29d0SBiju Das dataL = mmio_read_32(CPG_SMSTPCR3); 91*b28c29d0SBiju Das if ((dataL & CPG_MSTP_MMC) == 0U) { 92*b28c29d0SBiju Das dataL |= (CPG_MSTP_MMC); 93*b28c29d0SBiju Das mmio_write_32(CPG_CPGWPR, (~dataL)); 94*b28c29d0SBiju Das mmio_write_32(CPG_SMSTPCR3, dataL); 95*b28c29d0SBiju Das } 96*b28c29d0SBiju Das 97*b28c29d0SBiju Das return result; 98*b28c29d0SBiju Das } 99*b28c29d0SBiju Das 100*b28c29d0SBiju Das static EMMC_ERROR_CODE emmc_dev_init(void) 101*b28c29d0SBiju Das { 102*b28c29d0SBiju Das /* Enable clock supply to eMMC. */ 103*b28c29d0SBiju Das mstpcr_write(CPG_SMSTPCR3, CPG_MSTPSR3, CPG_MSTP_MMC); 104*b28c29d0SBiju Das 105*b28c29d0SBiju Das /* Set SD clock */ 106*b28c29d0SBiju Das mmio_write_32(CPG_CPGWPR, ~((uint32_t) (BIT9 | BIT0))); /* SD phy 200MHz */ 107*b28c29d0SBiju Das 108*b28c29d0SBiju Das /* Stop SDnH clock & SDn=200MHz */ 109*b28c29d0SBiju Das mmio_write_32(CPG_SDxCKCR, (BIT9 | BIT0)); 110*b28c29d0SBiju Das 111*b28c29d0SBiju Das /* MMCIF initialize */ 112*b28c29d0SBiju Das SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */ 113*b28c29d0SBiju Das SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */ 114*b28c29d0SBiju Das SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */ 115*b28c29d0SBiju Das SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */ 116*b28c29d0SBiju Das 117*b28c29d0SBiju Das SETR_32(HOST_MODE, 0x00000000U); /* SD_BUF access width = 64-bit */ 118*b28c29d0SBiju Das SETR_32(SD_OPTION, 0x0000C0EEU); /* Bus width = 1bit, timeout=MAX */ 119*b28c29d0SBiju Das SETR_32(SD_CLK_CTRL, 0x00000000U); /* Disable Automatic Control & Clock Output */ 120*b28c29d0SBiju Das 121*b28c29d0SBiju Das return EMMC_SUCCESS; 122*b28c29d0SBiju Das } 123*b28c29d0SBiju Das 124*b28c29d0SBiju Das static EMMC_ERROR_CODE emmc_reset_controller(void) 125*b28c29d0SBiju Das { 126*b28c29d0SBiju Das EMMC_ERROR_CODE result; 127*b28c29d0SBiju Das 128*b28c29d0SBiju Das /* initialize mmc driver */ 129*b28c29d0SBiju Das emmc_drv_init(); 130*b28c29d0SBiju Das 131*b28c29d0SBiju Das /* initialize H/W */ 132*b28c29d0SBiju Das result = emmc_dev_init(); 133*b28c29d0SBiju Das if (result == EMMC_SUCCESS) { 134*b28c29d0SBiju Das mmc_drv_obj.initialize = TRUE; 135*b28c29d0SBiju Das } 136*b28c29d0SBiju Das 137*b28c29d0SBiju Das return result; 138*b28c29d0SBiju Das 139*b28c29d0SBiju Das } 140*b28c29d0SBiju Das 141*b28c29d0SBiju Das EMMC_ERROR_CODE emmc_terminate(void) 142*b28c29d0SBiju Das { 143*b28c29d0SBiju Das EMMC_ERROR_CODE result; 144*b28c29d0SBiju Das 145*b28c29d0SBiju Das result = emmc_dev_finalize(); 146*b28c29d0SBiju Das 147*b28c29d0SBiju Das emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base)); 148*b28c29d0SBiju Das 149*b28c29d0SBiju Das return result; 150*b28c29d0SBiju Das } 151*b28c29d0SBiju Das 152*b28c29d0SBiju Das EMMC_ERROR_CODE rcar_emmc_init(void) 153*b28c29d0SBiju Das { 154*b28c29d0SBiju Das EMMC_ERROR_CODE result; 155*b28c29d0SBiju Das 156*b28c29d0SBiju Das result = emmc_reset_controller(); 157*b28c29d0SBiju Das if (result == EMMC_SUCCESS) { 158*b28c29d0SBiju Das emmc_driver_config(); 159*b28c29d0SBiju Das } 160*b28c29d0SBiju Das 161*b28c29d0SBiju Das return result; 162*b28c29d0SBiju Das } 163