arm-trusted-firmware/drivers/renesas/rcar/emmc/emmc_mount.c
Antonio Nino Diaz 09d40e0e08 Sanitise includes across codebase
Enforce full include path for includes. Deprecate old paths.

The following folders inside include/lib have been left unchanged:

- include/lib/cpus/${ARCH}
- include/lib/el3_runtime/${ARCH}

The reason for this change is that having a global namespace for
includes isn't a good idea. It defeats one of the advantages of having
folders and it introduces problems that are sometimes subtle (because
you may not know the header you are actually including if there are two
of them).

For example, this patch had to be created because two headers were
called the same way: e0ea0928d5 ("Fix gpio includes of mt8173 platform
to avoid collision."). More recently, this patch has had similar
problems: 46f9b2c3a2 ("drivers: add tzc380 support").

This problem was introduced in commit 4ecca33988 ("Move include and
source files to logical locations"). At that time, there weren't too
many headers so it wasn't a real issue. However, time has shown that
this creates problems.

Platforms that want to preserve the way they include headers may add the
removed paths to PLAT_INCLUDES, but this is discouraged.

Change-Id: I39dc53ed98f9e297a5966e723d1936d6ccf2fc8f
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
2019-01-04 10:43:17 +00:00

681 lines
18 KiB
C

/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <lib/mmio.h>
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
#include "micro_delay.h"
#include "rcar_def.h"
static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode);
static EMMC_ERROR_CODE emmc_card_init(void);
static EMMC_ERROR_CODE emmc_high_speed(void);
static EMMC_ERROR_CODE emmc_bus_width(uint32_t width);
static uint32_t emmc_set_timeout_register_value(uint32_t freq);
static void set_sd_clk(uint32_t clkDiv);
static uint32_t emmc_calc_tran_speed(uint32_t *freq);
static void emmc_get_partition_access(void);
static void emmc_set_bootpartition(void);
static void emmc_set_bootpartition(void)
{
uint32_t reg;
reg = mmio_read_32(RCAR_PRR) & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK);
if (reg == RCAR_PRODUCT_M3_CUT10) {
mmc_drv_obj.boot_partition_en =
(EMMC_PARTITION_ID) ((mmc_drv_obj.ext_csd_data[179] &
EMMC_BOOT_PARTITION_EN_MASK) >>
EMMC_BOOT_PARTITION_EN_SHIFT);
} else if ((reg == RCAR_PRODUCT_H3_CUT20)
|| (reg == RCAR_PRODUCT_M3_CUT11)) {
mmc_drv_obj.boot_partition_en = mmc_drv_obj.partition_access;
} else {
if ((mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION) !=
0U) {
mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_2;
} else {
mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_1;
}
}
}
static EMMC_ERROR_CODE emmc_card_init(void)
{
int32_t retry;
uint32_t freq = MMC_400KHZ; /* 390KHz */
EMMC_ERROR_CODE result;
uint32_t resultCalc;
/* state check */
if ((mmc_drv_obj.initialize != TRUE)
|| (mmc_drv_obj.card_power_enable != TRUE)
|| ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0)
) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* clock on (force change) */
mmc_drv_obj.current_freq = 0;
mmc_drv_obj.max_freq = MMC_20MHZ;
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return EMMC_ERR;
}
rcar_micro_delay(1000U); /* wait 1ms */
/* Get current access partition */
emmc_get_partition_access();
/* CMD0, arg=0x00000000 */
result = emmc_send_idle_cmd(0x00000000);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
rcar_micro_delay(200U); /* wait 74clock 390kHz(189.74us) */
/* CMD1 */
emmc_make_nontrans_cmd(CMD1_SEND_OP_COND, EMMC_HOST_OCR_VALUE);
for (retry = 300; retry > 0; retry--) {
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
if ((mmc_drv_obj.r3_ocr & EMMC_OCR_STATUS_BIT) != 0) {
break; /* card is ready. exit loop */
}
rcar_micro_delay(1000U); /* wait 1ms */
}
if (retry == 0) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_TIMEOUT);
return EMMC_ERR_TIMEOUT;
}
switch (mmc_drv_obj.r3_ocr & EMMC_OCR_ACCESS_MODE_MASK) {
case EMMC_OCR_ACCESS_MODE_SECT:
mmc_drv_obj.access_mode = TRUE; /* sector mode */
break;
default:
/* unknown value */
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR);
return EMMC_ERR;
}
/* CMD2 */
emmc_make_nontrans_cmd(CMD2_ALL_SEND_CID_MMC, 0x00000000);
mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.cid_data[0]); /* use CID special buffer */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* CMD3 */
emmc_make_nontrans_cmd(CMD3_SET_RELATIVE_ADDR, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* CMD9 (CSD) */
emmc_make_nontrans_cmd(CMD9_SEND_CSD, EMMC_RCA << 16);
mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.csd_data[0]); /* use CSD special buffer */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* card version check */
if (EMMC_CSD_SPEC_VARS() < 4) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT,
EMMC_ERR_ILLEGAL_CARD);
return EMMC_ERR_ILLEGAL_CARD;
}
/* CMD7 (select card) */
emmc_make_nontrans_cmd(CMD7_SELECT_CARD, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
mmc_drv_obj.selected = TRUE;
/* card speed check */
resultCalc = emmc_calc_tran_speed(&freq); /* Card spec is calculated from TRAN_SPEED(CSD). */
if (resultCalc == 0) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT,
EMMC_ERR_ILLEGAL_CARD);
return EMMC_ERR_ILLEGAL_CARD;
}
mmc_drv_obj.max_freq = freq; /* max frequency (card spec) */
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return EMMC_ERR;
}
/* set read/write timeout */
mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) |
mmc_drv_obj.data_timeout));
/* SET_BLOCKLEN(512byte) */
/* CMD16 */
emmc_make_nontrans_cmd(CMD16_SET_BLOCKLEN, EMMC_BLOCK_LENGTH);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* Transfer Data Length */
SETR_32(SD_SIZE, EMMC_BLOCK_LENGTH);
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
/* CMD12 is not send.
* If BUS initialization is failed, user must be execute Bus initialization again.
* Bus initialization is start CMD0(soft reset command).
*/
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* Set boot partition */
emmc_set_bootpartition();
return EMMC_SUCCESS;
}
static EMMC_ERROR_CODE emmc_high_speed(void)
{
uint32_t freq; /**< High speed mode clock frequency */
EMMC_ERROR_CODE result;
uint8_t cardType;
/* state check */
if (mmc_drv_obj.selected != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_HIGH_SPEED, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* max frequency */
cardType = (uint8_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_CARD_TYPE];
if ((cardType & EMMC_EXT_CSD_CARD_TYPE_52MHZ) != 0)
freq = MMC_52MHZ;
else if ((cardType & EMMC_EXT_CSD_CARD_TYPE_26MHZ) != 0)
freq = MMC_26MHZ;
else
freq = MMC_20MHZ;
/* Hi-Speed-mode selction */
if ((MMC_52MHZ == freq) || (MMC_26MHZ == freq)) {
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING);
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
return result;
}
mmc_drv_obj.hs_timing = TIMING_HIGH_SPEED; /* High-Speed */
}
/* set mmc clock */
mmc_drv_obj.max_freq = freq;
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
return EMMC_ERR;
}
/* set read/write timeout */
mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) |
mmc_drv_obj.data_timeout));
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK_WITHOUT_CRC, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
return result;
}
return EMMC_SUCCESS;
}
static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode)
{
uint32_t value;
/* busy check */
if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK,
EMMC_ERR_CARD_BUSY);
return EMMC_ERR;
}
if (mode == TRUE) {
/* clock ON */
value =
((GETR_32(SD_CLK_CTRL) | MMC_SD_CLK_START) &
SD_CLK_WRITE_MASK);
SETR_32(SD_CLK_CTRL, value); /* on */
mmc_drv_obj.clock_enable = TRUE;
} else {
/* clock OFF */
value =
((GETR_32(SD_CLK_CTRL) & MMC_SD_CLK_STOP) &
SD_CLK_WRITE_MASK);
SETR_32(SD_CLK_CTRL, value); /* off */
mmc_drv_obj.clock_enable = FALSE;
}
return EMMC_SUCCESS;
}
static EMMC_ERROR_CODE emmc_bus_width(uint32_t width)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* parameter check */
if ((width != 8) && (width != 4) && (width != 1)) {
emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if (mmc_drv_obj.selected != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); /* 2 = 8bit, 1 = 4bit, 0 =1bit */
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH,
(EMMC_SWITCH_BUS_WIDTH_1 |
(mmc_drv_obj.bus_width << 8)));
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
/* occurred error */
mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
goto EXIT;
}
switch (mmc_drv_obj.bus_width) {
case HAL_MEMCARD_DATA_WIDTH_1_BIT:
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT15));
break;
case HAL_MEMCARD_DATA_WIDTH_4_BIT:
SETR_32(SD_OPTION, (GETR_32(SD_OPTION) & ~(BIT15 | BIT13)));
break;
case HAL_MEMCARD_DATA_WIDTH_8_BIT:
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT13));
break;
default:
goto EXIT;
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
goto EXIT;
}
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
goto EXIT;
}
return EMMC_SUCCESS;
EXIT:
emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result);
ERROR("BL2: emmc bus_width error end\n");
return result;
}
EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id)
{
EMMC_ERROR_CODE result;
uint32_t arg;
uint32_t partition_config;
/* state check */
if (mmc_drv_obj.mount != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* id = PARTITION_ACCESS(Bit[2:0]) */
if ((id & ~PARTITION_ID_MASK) != 0) {
emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* EXT_CSD[179] value */
partition_config =
(uint32_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_PARTITION_CONFIG];
if ((partition_config & PARTITION_ID_MASK) == id) {
result = EMMC_SUCCESS;
} else {
partition_config =
(uint32_t) ((partition_config & ~PARTITION_ID_MASK) | id);
arg = EMMC_SWITCH_PARTITION_CONFIG | (partition_config << 8);
result = emmc_set_ext_csd(arg);
}
return result;
}
static void set_sd_clk(uint32_t clkDiv)
{
uint32_t dataL;
dataL = (GETR_32(SD_CLK_CTRL) & (~SD_CLK_CTRL_CLKDIV_MASK));
switch (clkDiv) {
case 1:
dataL |= 0x000000FFU;
break; /* 1/1 */
case 2:
dataL |= 0x00000000U;
break; /* 1/2 */
case 4:
dataL |= 0x00000001U;
break; /* 1/4 */
case 8:
dataL |= 0x00000002U;
break; /* 1/8 */
case 16:
dataL |= 0x00000004U;
break; /* 1/16 */
case 32:
dataL |= 0x00000008U;
break; /* 1/32 */
case 64:
dataL |= 0x00000010U;
break; /* 1/64 */
case 128:
dataL |= 0x00000020U;
break; /* 1/128 */
case 256:
dataL |= 0x00000040U;
break; /* 1/256 */
case 512:
dataL |= 0x00000080U;
break; /* 1/512 */
}
SETR_32(SD_CLK_CTRL, dataL);
mmc_drv_obj.current_freq = (uint32_t) clkDiv;
}
static void emmc_get_partition_access(void)
{
uint32_t reg;
EMMC_ERROR_CODE result;
reg = mmio_read_32(RCAR_PRR) & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK);
if ((reg == RCAR_PRODUCT_H3_CUT20) || (reg == RCAR_PRODUCT_M3_CUT11)) {
SETR_32(SD_OPTION, 0x000060EEU); /* 8 bits width */
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH,
HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA);
mmc_drv_obj.get_partition_access_flag = TRUE;
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
mmc_drv_obj.get_partition_access_flag = FALSE;
if (result == EMMC_SUCCESS) {
mmc_drv_obj.partition_access =
(EMMC_PARTITION_ID) (mmc_drv_obj.ext_csd_data[179]
& PARTITION_ID_MASK);
} else if (result == EMMC_ERR_CMD_TIMEOUT) {
mmc_drv_obj.partition_access = PARTITION_ID_BOOT_1;
} else {
emmc_write_error_info(EMMC_FUNCNO_GET_PERTITION_ACCESS,
result);
panic();
}
SETR_32(SD_OPTION, 0x0000C0EEU); /* Initialize */
}
}
static uint32_t emmc_calc_tran_speed(uint32_t *freq)
{
const uint32_t unit[8] = { 10000, 100000, 1000000, 10000000,
0, 0, 0, 0 }; /**< frequency unit (1/10) */
const uint32_t mult[16] = { 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45,
52, 55, 60, 70, 80 };
uint32_t maxFreq;
uint32_t result;
uint32_t tran_speed = EMMC_CSD_TRAN_SPEED();
/* tran_speed = 0x32
* unit[tran_speed&0x7] = uint[0x2] = 1000000
* mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26
* 1000000 * 26 = 26000000 (26MHz)
*/
result = 1;
maxFreq =
unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] *
mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >>
EMMC_TRANSPEED_MULT_SHIFT];
if (maxFreq == 0) {
result = 0;
} else if (MMC_FREQ_52MHZ <= maxFreq)
*freq = MMC_52MHZ;
else if (MMC_FREQ_26MHZ <= maxFreq)
*freq = MMC_26MHZ;
else if (MMC_FREQ_20MHZ <= maxFreq)
*freq = MMC_20MHZ;
else
*freq = MMC_400KHZ;
return result;
}
static uint32_t emmc_set_timeout_register_value(uint32_t freq)
{
uint32_t timeoutCnt; /* SD_OPTION - Timeout Counter */
switch (freq) {
case 1U:
timeoutCnt = 0xE0U;
break; /* SDCLK * 2^27 */
case 2U:
timeoutCnt = 0xE0U;
break; /* SDCLK * 2^27 */
case 4U:
timeoutCnt = 0xD0U;
break; /* SDCLK * 2^26 */
case 8U:
timeoutCnt = 0xC0U;
break; /* SDCLK * 2^25 */
case 16U:
timeoutCnt = 0xB0U;
break; /* SDCLK * 2^24 */
case 32U:
timeoutCnt = 0xA0U;
break; /* SDCLK * 2^23 */
case 64U:
timeoutCnt = 0x90U;
break; /* SDCLK * 2^22 */
case 128U:
timeoutCnt = 0x80U;
break; /* SDCLK * 2^21 */
case 256U:
timeoutCnt = 0x70U;
break; /* SDCLK * 2^20 */
case 512U:
timeoutCnt = 0x70U;
break; /* SDCLK * 2^20 */
default:
timeoutCnt = 0xE0U;
break; /* SDCLK * 2^27 */
}
return timeoutCnt;
}
EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg)
{
EMMC_ERROR_CODE result;
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH, arg);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
return EMMC_SUCCESS;
}
EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq)
{
/* parameter check */
if (freq == NULL) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if ((mmc_drv_obj.initialize != TRUE)
|| (mmc_drv_obj.card_power_enable != TRUE)) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* clock is already running in the desired frequency. */
if ((mmc_drv_obj.clock_enable == TRUE)
&& (mmc_drv_obj.current_freq == *freq)) {
return EMMC_SUCCESS;
}
/* busy check */
if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK,
EMMC_ERR_CARD_BUSY);
return EMMC_ERR;
}
set_sd_clk(*freq);
mmc_drv_obj.clock_enable = FALSE;
return emmc_clock_ctrl(TRUE); /* clock on */
}
EMMC_ERROR_CODE rcar_emmc_mount(void)
{
EMMC_ERROR_CODE result;
/* state check */
if ((mmc_drv_obj.initialize != TRUE)
|| (mmc_drv_obj.card_power_enable != TRUE)
|| ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0)
) {
emmc_write_error_info(EMMC_FUNCNO_MOUNT, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* initialize card (IDLE state --> Transfer state) */
result = emmc_card_init();
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
/* nothing to do. */
}
return result;
}
/* Switching high speed mode */
result = emmc_high_speed();
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
/* nothing to do. */
}
return result;
}
/* Changing the data bus width */
result = emmc_bus_width(8);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_BUS_WIDTH);
if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
/* nothing to do. */
}
return result;
}
/* mount complete */
mmc_drv_obj.mount = TRUE;
return EMMC_SUCCESS;
}