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