mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 17:44:19 +00:00
drivers: Add emmc driver for Broadcom platforms
Add emmc driver for Broadcom platforms Change-Id: I126a6dfccd41062cb0b856f2c2fb1f724730b95e Signed-off-by: Sheetal Tigadoli <sheetal.tigadoli@broadcom.com>
This commit is contained in:
parent
3942d3a8ea
commit
bffde63de7
17 changed files with 5997 additions and 1 deletions
1017
drivers/brcm/emmc/emmc_chal_sd.c
Normal file
1017
drivers/brcm/emmc/emmc_chal_sd.c
Normal file
File diff suppressed because it is too large
Load diff
1087
drivers/brcm/emmc/emmc_csl_sdcard.c
Normal file
1087
drivers/brcm/emmc/emmc_csl_sdcard.c
Normal file
File diff suppressed because it is too large
Load diff
842
drivers/brcm/emmc/emmc_csl_sdcmd.c
Normal file
842
drivers/brcm/emmc/emmc_csl_sdcmd.c
Normal file
|
@ -0,0 +1,842 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "bcm_emmc.h"
|
||||
#include "emmc_chal_types.h"
|
||||
#include "emmc_chal_sd.h"
|
||||
#include "emmc_csl_sdprot.h"
|
||||
#include "emmc_csl_sdcmd.h"
|
||||
#include "emmc_csl_sd.h"
|
||||
#include "emmc_chal_sd.h"
|
||||
#include "emmc_pboot_hal_memory_drv.h"
|
||||
|
||||
int sd_cmd0(struct sd_handle *handle)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument = 0x0; /* Go to IDLE state. */
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_GO_IDLE_STATE, argument, 0, NULL);
|
||||
|
||||
if (res == SD_OK) {
|
||||
/* Clear all other interrupts */
|
||||
chal_sd_clear_irq((void *)handle->device, 0xffffffff);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd1(struct sd_handle *handle, uint32_t ocr, uint32_t *ocr_output)
|
||||
{
|
||||
int res;
|
||||
uint32_t options;
|
||||
struct sd_resp resp;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R3_4 << SD_CMDR_RSP_TYPE_S;
|
||||
|
||||
if (ocr_output == NULL) {
|
||||
EMMC_TRACE("Invalid args\n");
|
||||
return SD_FAIL;
|
||||
}
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_SEND_OPCOND, ocr, options, &resp);
|
||||
|
||||
if (res == SD_OK)
|
||||
*ocr_output = resp.data.r3.ocr;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd2(struct sd_handle *handle)
|
||||
{
|
||||
uint32_t options;
|
||||
struct sd_resp resp;
|
||||
|
||||
/* send cmd and parse result */
|
||||
options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S;
|
||||
|
||||
return send_cmd(handle, SD_CMD_ALL_SEND_CID, 0, options, &resp);
|
||||
}
|
||||
|
||||
int sd_cmd3(struct sd_handle *handle)
|
||||
{
|
||||
int res;
|
||||
uint32_t options = 0;
|
||||
uint32_t argument;
|
||||
struct sd_resp resp;
|
||||
|
||||
/* use non zero and non 0x1 value for rca */
|
||||
handle->device->ctrl.rca = 0x5;
|
||||
argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_MMC_SET_RCA, argument, options, &resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
handle->device->ctrl.rca = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd7(struct sd_handle *handle, uint32_t rca)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options;
|
||||
struct sd_resp resp;
|
||||
|
||||
argument = (rca << SD_CMD7_ARG_RCA_SHIFT);
|
||||
|
||||
/*
|
||||
* Response to CMD7 is:
|
||||
* R1 while selectiing from Stand-By State to Transfer State
|
||||
* R1b while selecting from Disconnected State to Programming State.
|
||||
*
|
||||
* In this driver, we only issue a CMD7 once, to go to transfer mode
|
||||
* during init_mmc_card().
|
||||
*/
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_SELECT_DESELECT_CARD, argument, options,
|
||||
&resp);
|
||||
|
||||
if (res == SD_OK)
|
||||
/* Clear all other interrupts */
|
||||
chal_sd_clear_irq((void *)handle->device, 0xffffffff);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CMD8 Get CSD_EXT
|
||||
*/
|
||||
int mmc_cmd8(struct sd_handle *handle, uint8_t *extCsdReg)
|
||||
{
|
||||
uint32_t res, options;
|
||||
struct sd_resp resp;
|
||||
|
||||
data_xfer_setup(handle, extCsdReg, CEATA_EXT_CSDBLOCK_SIZE,
|
||||
SD_XFER_CARD_TO_HOST);
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_READ_EXT_CSD, 0, options, &resp);
|
||||
|
||||
if (res == SD_OK)
|
||||
res = process_data_xfer(handle, extCsdReg, 0,
|
||||
CEATA_EXT_CSDBLOCK_SIZE,
|
||||
SD_XFER_CARD_TO_HOST);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd9(struct sd_handle *handle, struct sd_card_data *card)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options, iBlkNum, multiFactor = 1;
|
||||
uint32_t maxReadBlockLen = 1, maxWriteBlockLen = 1;
|
||||
struct sd_resp resp;
|
||||
|
||||
argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_SEND_CSD, argument, options, &resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
if (handle->card->type == SD_CARD_MMC) {
|
||||
card->csd.mmc.structure = (resp.data.r2.rsp4 >> 22) & 0x3;
|
||||
card->csd.mmc.csdSpecVer = (resp.data.r2.rsp4 >> 18) & 0x0f;
|
||||
card->csd.mmc.taac = (resp.data.r2.rsp4 >> 8) & 0xff;
|
||||
card->csd.mmc.nsac = resp.data.r2.rsp4 & 0xff;
|
||||
card->csd.mmc.speed = resp.data.r2.rsp3 >> 24;
|
||||
card->csd.mmc.classes = (resp.data.r2.rsp3 >> 12) & 0xfff;
|
||||
card->csd.mmc.rdBlkLen = (resp.data.r2.rsp3 >> 8) & 0xf;
|
||||
card->csd.mmc.rdBlkPartial = (resp.data.r2.rsp3 >> 7) & 0x01;
|
||||
card->csd.mmc.wrBlkMisalign = (resp.data.r2.rsp3 >> 6) & 0x1;
|
||||
card->csd.mmc.rdBlkMisalign = (resp.data.r2.rsp3 >> 5) & 0x1;
|
||||
card->csd.mmc.dsr = (resp.data.r2.rsp2 >> 4) & 0x01;
|
||||
card->csd.mmc.size =
|
||||
((resp.data.r2.rsp3 & 0x3) << 10) +
|
||||
((resp.data.r2.rsp2 >> 22) & 0x3ff);
|
||||
card->csd.mmc.vddRdCurrMin = (resp.data.r2.rsp2 >> 19) & 0x7;
|
||||
card->csd.mmc.vddRdCurrMax = (resp.data.r2.rsp2 >> 16) & 0x7;
|
||||
card->csd.mmc.vddWrCurrMin = (resp.data.r2.rsp2 >> 13) & 0x7;
|
||||
card->csd.mmc.vddWrCurrMax = (resp.data.r2.rsp2 >> 10) & 0x7;
|
||||
card->csd.mmc.devSizeMulti = (resp.data.r2.rsp2 >> 7) & 0x7;
|
||||
card->csd.mmc.eraseGrpSize = (resp.data.r2.rsp2 >> 2) & 0x1f;
|
||||
card->csd.mmc.eraseGrpSizeMulti =
|
||||
((resp.data.r2.rsp2 & 0x3) << 3) +
|
||||
((resp.data.r2.rsp1 >> 29) & 0x7);
|
||||
card->csd.mmc.wrProtGroupSize =
|
||||
((resp.data.r2.rsp1 >> 24) & 0x1f);
|
||||
card->csd.mmc.wrProtGroupEnable =
|
||||
(resp.data.r2.rsp1 >> 23) & 0x1;
|
||||
card->csd.mmc.manuDefEcc = (resp.data.r2.rsp1 >> 21) & 0x3;
|
||||
card->csd.mmc.wrSpeedFactor = (resp.data.r2.rsp1 >> 18) & 0x7;
|
||||
card->csd.mmc.wrBlkLen = (resp.data.r2.rsp1 >> 14) & 0xf;
|
||||
card->csd.mmc.wrBlkPartial = (resp.data.r2.rsp1 >> 13) & 0x1;
|
||||
card->csd.mmc.protAppl = (resp.data.r2.rsp1 >> 8) & 0x1;
|
||||
card->csd.mmc.copyFlag = (resp.data.r2.rsp1 >> 7) & 0x1;
|
||||
card->csd.mmc.permWrProt = (resp.data.r2.rsp1 >> 6) & 0x1;
|
||||
card->csd.mmc.tmpWrProt = (resp.data.r2.rsp1 >> 5) & 0x1;
|
||||
card->csd.mmc.fileFormat = (resp.data.r2.rsp1 >> 4) & 0x03;
|
||||
card->csd.mmc.eccCode = resp.data.r2.rsp1 & 0x03;
|
||||
maxReadBlockLen <<= card->csd.mmc.rdBlkLen;
|
||||
maxWriteBlockLen <<= card->csd.mmc.wrBlkLen;
|
||||
|
||||
iBlkNum = card->csd.mmc.size + 1;
|
||||
multiFactor = (1 << (card->csd.mmc.devSizeMulti + 2));
|
||||
|
||||
handle->card->size =
|
||||
iBlkNum * multiFactor * (1 << card->csd.mmc.rdBlkLen);
|
||||
}
|
||||
|
||||
handle->card->maxRdBlkLen = maxReadBlockLen;
|
||||
handle->card->maxWtBlkLen = maxWriteBlockLen;
|
||||
|
||||
if (handle->card->size < 0xA00000) {
|
||||
/*
|
||||
* 10MB Too small size mean, cmd9 response is wrong,
|
||||
* Use default value 1G
|
||||
*/
|
||||
handle->card->size = 0x40000000;
|
||||
handle->card->maxRdBlkLen = 512;
|
||||
handle->card->maxWtBlkLen = 512;
|
||||
}
|
||||
|
||||
if ((handle->card->maxRdBlkLen > 512) ||
|
||||
(handle->card->maxWtBlkLen > 512)) {
|
||||
handle->card->maxRdBlkLen = 512;
|
||||
handle->card->maxWtBlkLen = 512;
|
||||
} else if ((handle->card->maxRdBlkLen == 0) ||
|
||||
(handle->card->maxWtBlkLen == 0)) {
|
||||
handle->card->maxRdBlkLen = 512;
|
||||
handle->card->maxWtBlkLen = 512;
|
||||
}
|
||||
|
||||
handle->device->cfg.blockSize = handle->card->maxRdBlkLen;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd13(struct sd_handle *handle, uint32_t *status)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options;
|
||||
struct sd_resp resp;
|
||||
|
||||
argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_SEND_STATUS, argument, options, &resp);
|
||||
|
||||
if (res == SD_OK) {
|
||||
*status = resp.cardStatus;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd16(struct sd_handle *handle, uint32_t length)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options, ntry;
|
||||
struct sd_resp resp;
|
||||
|
||||
argument = length;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
|
||||
|
||||
ntry = 0;
|
||||
do {
|
||||
res = sd_cmd13(handle, &resp.cardStatus);
|
||||
if (res != SD_OK) {
|
||||
EMMC_TRACE(
|
||||
"cmd13 failed before cmd16: rca 0x%0x, return %d, response 0x%0x\n",
|
||||
handle->device->ctrl.rca, res, resp.cardStatus);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (resp.cardStatus & 0x100)
|
||||
break;
|
||||
|
||||
EMMC_TRACE("cmd13 rsp:0x%08x before cmd16\n", resp.cardStatus);
|
||||
|
||||
if (ntry > handle->device->cfg.retryLimit) {
|
||||
EMMC_TRACE("cmd13 retry reach limit %d\n",
|
||||
handle->device->cfg.retryLimit);
|
||||
return SD_CMD_TIMEOUT;
|
||||
}
|
||||
|
||||
ntry++;
|
||||
EMMC_TRACE("cmd13 retry %d\n", ntry);
|
||||
|
||||
SD_US_DELAY(1000);
|
||||
|
||||
} while (1);
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_SET_BLOCKLEN, argument, options, &resp);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd17(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options, ntry;
|
||||
struct sd_resp resp;
|
||||
|
||||
ntry = 0;
|
||||
do {
|
||||
res = sd_cmd13(handle, &resp.cardStatus);
|
||||
if (res != SD_OK) {
|
||||
EMMC_TRACE(
|
||||
"cmd 13 failed before cmd17: rca 0x%0x, return %d, response 0x%0x\n",
|
||||
handle->device->ctrl.rca, res, resp.cardStatus);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (resp.cardStatus & 0x100)
|
||||
break;
|
||||
|
||||
EMMC_TRACE("cmd13 rsp:0x%08x before cmd17\n", resp.cardStatus);
|
||||
|
||||
if (ntry > handle->device->cfg.retryLimit) {
|
||||
EMMC_TRACE("cmd13 retry reach limit %d\n",
|
||||
handle->device->cfg.retryLimit);
|
||||
return SD_CMD_TIMEOUT;
|
||||
}
|
||||
|
||||
ntry++;
|
||||
EMMC_TRACE("cmd13 retry %d\n", ntry);
|
||||
|
||||
SD_US_DELAY(1000);
|
||||
|
||||
} while (1);
|
||||
|
||||
data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST);
|
||||
|
||||
/* send cmd and parse result */
|
||||
argument = addr;
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
|
||||
|
||||
res = send_cmd(handle, SD_CMD_READ_SINGLE_BLOCK, argument, options,
|
||||
&resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd18(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options, ntry;
|
||||
struct sd_resp resp;
|
||||
|
||||
ntry = 0;
|
||||
do {
|
||||
res = sd_cmd13(handle, &resp.cardStatus);
|
||||
if (res != SD_OK) {
|
||||
EMMC_TRACE(
|
||||
"cmd 13 failed before cmd18: rca 0x%0x, return %d, response 0x%0x\n",
|
||||
handle->device->ctrl.rca, res, resp.cardStatus);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (resp.cardStatus & 0x100)
|
||||
break;
|
||||
|
||||
EMMC_TRACE("cmd13 rsp:0x%08x before cmd18\n", resp.cardStatus);
|
||||
|
||||
if (ntry > handle->device->cfg.retryLimit) {
|
||||
EMMC_TRACE("cmd13 retry reach limit %d\n",
|
||||
handle->device->cfg.retryLimit);
|
||||
return SD_CMD_TIMEOUT;
|
||||
}
|
||||
|
||||
ntry++;
|
||||
EMMC_TRACE("cmd13 retry %d\n", ntry);
|
||||
|
||||
SD_US_DELAY(1000);
|
||||
} while (1);
|
||||
|
||||
data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST);
|
||||
|
||||
argument = addr;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK |
|
||||
SD4_EMMC_TOP_CMD_MSBS_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_BCEN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK |
|
||||
BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT);
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_READ_MULTIPLE_BLOCK, argument, options,
|
||||
&resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
|
||||
static int card_sts_resp(struct sd_handle *handle, uint32_t *status)
|
||||
{
|
||||
int res;
|
||||
uint32_t ntry = 0;
|
||||
|
||||
do {
|
||||
res = sd_cmd13(handle, status);
|
||||
if (res != SD_OK) {
|
||||
EMMC_TRACE(
|
||||
"cmd 13 failed before cmd35: rca 0x%0x, return %d\n",
|
||||
handle->device->ctrl.rca, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (*status & 0x100)
|
||||
break;
|
||||
|
||||
EMMC_TRACE("cmd13 rsp:0x%08x before cmd35\n", resp.cardStatus);
|
||||
|
||||
if (ntry > handle->device->cfg.retryLimit) {
|
||||
EMMC_TRACE("cmd13 retry reach limit %d\n",
|
||||
handle->device->cfg.retryLimit);
|
||||
return SD_CMD_TIMEOUT;
|
||||
}
|
||||
|
||||
ntry++;
|
||||
EMMC_TRACE("cmd13 retry %d\n", ntry);
|
||||
|
||||
SD_US_DELAY(1000);
|
||||
} while (1);
|
||||
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
int sd_cmd35(struct sd_handle *handle, uint32_t start)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options;
|
||||
struct sd_resp resp;
|
||||
|
||||
res = card_sts_resp(handle, &resp.cardStatus);
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
argument = start;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_ERASE_GROUP_START,
|
||||
argument, options, &resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd36(struct sd_handle *handle, uint32_t end)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options;
|
||||
struct sd_resp resp;
|
||||
|
||||
res = card_sts_resp(handle, &resp.cardStatus);
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
argument = end;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_ERASE_GROUP_END,
|
||||
argument, options, &resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd38(struct sd_handle *handle)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options;
|
||||
struct sd_resp resp;
|
||||
|
||||
res = card_sts_resp(handle, &resp.cardStatus);
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
argument = 0;
|
||||
|
||||
options = (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_ERASE, argument, options, &resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
|
||||
|
||||
int sd_cmd24(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer)
|
||||
{
|
||||
int res;
|
||||
uint32_t argument, options, ntry;
|
||||
struct sd_resp resp;
|
||||
|
||||
ntry = 0;
|
||||
do {
|
||||
res = sd_cmd13(handle, &resp.cardStatus);
|
||||
if (res != SD_OK) {
|
||||
EMMC_TRACE(
|
||||
"cmd 13 failed before cmd24: rca 0x%0x, return %d, response 0x%0x\n",
|
||||
handle->device->ctrl.rca, res, &resp.cardStatus);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (resp.cardStatus & 0x100)
|
||||
break;
|
||||
|
||||
EMMC_TRACE("cmd13 rsp:0x%08x before cmd24\n", resp.cardStatus);
|
||||
|
||||
if (ntry > handle->device->cfg.retryLimit) {
|
||||
EMMC_TRACE("cmd13 retry reach limit %d\n",
|
||||
handle->device->cfg.retryLimit);
|
||||
return SD_CMD_TIMEOUT;
|
||||
}
|
||||
|
||||
ntry++;
|
||||
EMMC_TRACE("cmd13 retry %d\n", ntry);
|
||||
|
||||
SD_US_DELAY(1000);
|
||||
|
||||
} while (1);
|
||||
|
||||
data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD);
|
||||
|
||||
argument = addr;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK;
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_WRITE_BLOCK, argument, options, &resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sd_cmd25(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer)
|
||||
{
|
||||
int res = SD_OK;
|
||||
uint32_t argument, options, ntry;
|
||||
struct sd_resp resp;
|
||||
|
||||
ntry = 0;
|
||||
do {
|
||||
res = sd_cmd13(handle, &resp.cardStatus);
|
||||
if (res != SD_OK) {
|
||||
EMMC_TRACE(
|
||||
"cmd 13 failed before cmd25: rca 0x%0x, return %d, response 0x%0x\n",
|
||||
handle->device->ctrl.rca, res, &resp.cardStatus);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (resp.cardStatus & 0x100)
|
||||
break;
|
||||
|
||||
EMMC_TRACE("cmd13 rsp:0x%08x before cmd25\n", resp.cardStatus);
|
||||
|
||||
if (ntry > handle->device->cfg.retryLimit) {
|
||||
EMMC_TRACE("cmd13 retry reach limit %d\n",
|
||||
handle->device->cfg.retryLimit);
|
||||
return SD_CMD_TIMEOUT;
|
||||
}
|
||||
|
||||
ntry++;
|
||||
EMMC_TRACE("cmd13 retry %d\n", ntry);
|
||||
|
||||
SD_US_DELAY(1000);
|
||||
} while (1);
|
||||
|
||||
data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD);
|
||||
|
||||
argument = addr;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_MSBS_MASK |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_BCEN_MASK |
|
||||
SD4_EMMC_TOP_CMD_CRC_EN_MASK |
|
||||
BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT);
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_CMD_WRITE_MULTIPLE_BLOCK,
|
||||
argument, options, &resp);
|
||||
|
||||
if (res != SD_OK)
|
||||
return res;
|
||||
|
||||
res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */
|
||||
|
||||
int mmc_cmd6(struct sd_handle *handle, uint32_t argument)
|
||||
{
|
||||
int res;
|
||||
uint32_t options;
|
||||
struct sd_resp resp;
|
||||
|
||||
options = SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S |
|
||||
SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK;
|
||||
|
||||
EMMC_TRACE("Sending CMD6 with argument 0x%X\n", argument);
|
||||
|
||||
/* send cmd and parse result */
|
||||
res = send_cmd(handle, SD_ACMD_SET_BUS_WIDTH, argument, options, &resp);
|
||||
|
||||
/*
|
||||
* For R1b type response:
|
||||
* controller issues a COMMAND COMPLETE interrupt when the R1
|
||||
* response is received,
|
||||
* then controller monitors DAT0 for busy status,
|
||||
* controller issues a TRANSFER COMPLETE interrupt when busy signal
|
||||
* clears.
|
||||
*/
|
||||
wait_for_event(handle,
|
||||
SD4_EMMC_TOP_INTR_TXDONE_MASK | SD_ERR_INTERRUPTS,
|
||||
handle->device->cfg.wfe_retry);
|
||||
|
||||
if (res == SD_OK) {
|
||||
/* Check result of Cmd6 using Cmd13 to check card status */
|
||||
|
||||
/* Check status using Cmd13 */
|
||||
res = sd_cmd13(handle, &resp.cardStatus);
|
||||
|
||||
if (res == SD_OK) {
|
||||
/* Check bit 7 (SWITCH_ERROR) in card status */
|
||||
if ((resp.cardStatus & 0x80) != 0) {
|
||||
EMMC_TRACE("cmd6 failed: SWITCH_ERROR\n");
|
||||
res = SD_FAIL;
|
||||
}
|
||||
} else {
|
||||
EMMC_TRACE("cmd13 failed after cmd6: ");
|
||||
EMMC_TRACE("rca 0x%0x, return %d, response 0x%0x\n",
|
||||
handle->device->ctrl.rca, res, resp.cardStatus);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#define SD_BUSY_CHECK 0x00203000
|
||||
#define DAT0_LEVEL_MASK 0x100000 /* bit20 in PSTATE */
|
||||
#define DEV_BUSY_TIMEOUT 600000 /* 60 Sec : 600000 * 100us */
|
||||
|
||||
int send_cmd(struct sd_handle *handle, uint32_t cmdIndex, uint32_t argument,
|
||||
uint32_t options, struct sd_resp *resp)
|
||||
{
|
||||
int status = SD_OK;
|
||||
uint32_t event = 0, present, timeout = 0, retry = 0, mask = 3;
|
||||
uint32_t temp_resp[4];
|
||||
|
||||
if (handle == NULL) {
|
||||
EMMC_TRACE("Invalid handle for cmd%d\n", cmdIndex);
|
||||
return SD_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
mask = (SD_BUSY_CHECK & options) ? 3 : 1;
|
||||
|
||||
RETRY_WRITE_CMD:
|
||||
do {
|
||||
/* Make sure it is ok to send command */
|
||||
present =
|
||||
chal_sd_get_present_status((CHAL_HANDLE *) handle->device);
|
||||
timeout++;
|
||||
|
||||
if (present & mask)
|
||||
SD_US_DELAY(1000);
|
||||
else
|
||||
break;
|
||||
|
||||
} while (timeout < EMMC_BUSY_CMD_TIMEOUT_MS);
|
||||
|
||||
if (timeout >= EMMC_BUSY_CMD_TIMEOUT_MS) {
|
||||
status = SD_CMD_MISSING;
|
||||
EMMC_TRACE("cmd%d timedout %dms\n", cmdIndex, timeout);
|
||||
}
|
||||
|
||||
/* Reset both DAT and CMD line if only of them are stuck */
|
||||
if (present & mask)
|
||||
check_error(handle, SD4_EMMC_TOP_INTR_CMDERROR_MASK);
|
||||
|
||||
handle->device->ctrl.argReg = argument;
|
||||
chal_sd_send_cmd((CHAL_HANDLE *) handle->device, cmdIndex,
|
||||
handle->device->ctrl.argReg, options);
|
||||
|
||||
handle->device->ctrl.cmdIndex = cmdIndex;
|
||||
|
||||
event = wait_for_event(handle,
|
||||
(SD4_EMMC_TOP_INTR_CMDDONE_MASK |
|
||||
SD_ERR_INTERRUPTS),
|
||||
handle->device->cfg.wfe_retry);
|
||||
|
||||
if (handle->device->ctrl.cmdStatus == SD_CMD_MISSING) {
|
||||
retry++;
|
||||
|
||||
if (retry >= handle->device->cfg.retryLimit) {
|
||||
status = SD_CMD_MISSING;
|
||||
EMMC_TRACE("cmd%d retry reaches the limit %d\n",
|
||||
cmdIndex, retry);
|
||||
} else {
|
||||
/* reset both DAT & CMD line if one of them is stuck */
|
||||
present = chal_sd_get_present_status((CHAL_HANDLE *)
|
||||
handle->device);
|
||||
|
||||
if (present & mask)
|
||||
check_error(handle,
|
||||
SD4_EMMC_TOP_INTR_CMDERROR_MASK);
|
||||
|
||||
EMMC_TRACE("cmd%d retry %d PSTATE[0x%08x]\n",
|
||||
cmdIndex, retry,
|
||||
chal_sd_get_present_status((CHAL_HANDLE *)
|
||||
handle->device));
|
||||
goto RETRY_WRITE_CMD;
|
||||
}
|
||||
}
|
||||
|
||||
if (handle->device->ctrl.cmdStatus == SD_OK) {
|
||||
if (resp != NULL) {
|
||||
status =
|
||||
chal_sd_get_response((CHAL_HANDLE *) handle->device,
|
||||
temp_resp);
|
||||
process_cmd_response(handle,
|
||||
handle->device->ctrl.cmdIndex,
|
||||
temp_resp[0], temp_resp[1],
|
||||
temp_resp[2], temp_resp[3], resp);
|
||||
}
|
||||
|
||||
/* Check Device busy after CMD */
|
||||
if ((cmdIndex == 5) || (cmdIndex == 6) || (cmdIndex == 7) ||
|
||||
(cmdIndex == 28) || (cmdIndex == 29) || (cmdIndex == 38)) {
|
||||
|
||||
timeout = 0;
|
||||
do {
|
||||
present =
|
||||
chal_sd_get_present_status((CHAL_HANDLE *)
|
||||
handle->device);
|
||||
|
||||
timeout++;
|
||||
|
||||
/* Dat[0]:bit20 low means device busy */
|
||||
if ((present & DAT0_LEVEL_MASK) == 0) {
|
||||
EMMC_TRACE("Device busy: ");
|
||||
EMMC_TRACE(
|
||||
"cmd%d arg:0x%08x: PSTATE[0x%08x]\n",
|
||||
cmdIndex, argument, present);
|
||||
SD_US_DELAY(100);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (timeout < DEV_BUSY_TIMEOUT);
|
||||
}
|
||||
} else if (handle->device->ctrl.cmdStatus &&
|
||||
handle->device->ctrl.cmdStatus != SD_CMD_MISSING) {
|
||||
retry++;
|
||||
status = check_error(handle, handle->device->ctrl.cmdStatus);
|
||||
|
||||
EMMC_TRACE(
|
||||
"cmd%d error: cmdStatus:0x%08x error_status:0x%08x\n",
|
||||
cmdIndex, handle->device->ctrl.cmdStatus, status);
|
||||
|
||||
if ((handle->device->ctrl.cmdIndex == 1) ||
|
||||
(handle->device->ctrl.cmdIndex == 5)) {
|
||||
status = event;
|
||||
} else if ((handle->device->ctrl.cmdIndex == 7) ||
|
||||
(handle->device->ctrl.cmdIndex == 41)) {
|
||||
status = event;
|
||||
} else if ((status == SD_ERROR_RECOVERABLE) &&
|
||||
(retry < handle->device->cfg.retryLimit)) {
|
||||
EMMC_TRACE("cmd%d recoverable error ", cmdIndex);
|
||||
EMMC_TRACE("retry %d PSTATE[0x%08x].\n", retry,
|
||||
chal_sd_get_present_status((CHAL_HANDLE *)
|
||||
handle->device));
|
||||
goto RETRY_WRITE_CMD;
|
||||
} else {
|
||||
EMMC_TRACE("cmd%d retry reaches the limit %d\n",
|
||||
cmdIndex, retry);
|
||||
status = event;
|
||||
}
|
||||
}
|
||||
|
||||
handle->device->ctrl.blkReg = 0;
|
||||
/* clear error status for next command */
|
||||
handle->device->ctrl.cmdStatus = 0;
|
||||
|
||||
return status;
|
||||
}
|
621
drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
Normal file
621
drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
Normal file
|
@ -0,0 +1,621 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <emmc_api.h>
|
||||
#include <cmn_plat_util.h>
|
||||
|
||||
#define MAX_CMD_RETRY 10
|
||||
|
||||
#if EMMC_USE_DMA
|
||||
#define USE_DMA 1
|
||||
#else
|
||||
#define USE_DMA 0
|
||||
#endif
|
||||
|
||||
struct emmc_global_buffer emmc_global_buf;
|
||||
struct emmc_global_buffer *emmc_global_buf_ptr = &emmc_global_buf;
|
||||
|
||||
struct emmc_global_vars emmc_global_vars;
|
||||
struct emmc_global_vars *emmc_global_vars_ptr = &emmc_global_vars;
|
||||
|
||||
static struct sd_handle *sdio_gethandle(void);
|
||||
static uint32_t sdio_idle(struct sd_handle *p_sdhandle);
|
||||
|
||||
static uint32_t sdio_read(struct sd_handle *p_sdhandle,
|
||||
uintptr_t mem_addr,
|
||||
uintptr_t storage_addr,
|
||||
size_t storage_size,
|
||||
size_t bytes_to_read);
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
|
||||
static uint32_t sdio_write(struct sd_handle *p_sdhandle,
|
||||
uintptr_t mem_addr,
|
||||
uintptr_t data_addr,
|
||||
size_t bytes_to_write);
|
||||
#endif
|
||||
|
||||
static struct sd_handle *sdio_init(void);
|
||||
static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle);
|
||||
|
||||
static void init_globals(void)
|
||||
{
|
||||
memset((void *)emmc_global_buf_ptr, 0, sizeof(*emmc_global_buf_ptr));
|
||||
memset((void *)emmc_global_vars_ptr, 0, sizeof(*emmc_global_vars_ptr));
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to change partition
|
||||
*/
|
||||
uint32_t emmc_partition_select(uint32_t partition)
|
||||
{
|
||||
int rc;
|
||||
struct sd_handle *sd_handle = sdio_gethandle();
|
||||
|
||||
if (sd_handle->device == 0) {
|
||||
EMMC_TRACE("eMMC init is not done");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (partition) {
|
||||
case EMMC_BOOT_PARTITION1:
|
||||
rc = set_boot_config(sd_handle,
|
||||
SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT1);
|
||||
EMMC_TRACE(
|
||||
"Change to Boot Partition 1 result:%d (0 means SD_OK)\n",
|
||||
rc);
|
||||
break;
|
||||
|
||||
case EMMC_BOOT_PARTITION2:
|
||||
rc = set_boot_config(sd_handle,
|
||||
SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT2);
|
||||
EMMC_TRACE(
|
||||
"Change to Boot Partition 2 result:%d (0 means SD_OK)\n",
|
||||
rc);
|
||||
break;
|
||||
|
||||
case EMMC_USE_CURRENT_PARTITION:
|
||||
rc = SD_OK;
|
||||
EMMC_TRACE("Stay on current partition");
|
||||
break;
|
||||
|
||||
case EMMC_USER_AREA:
|
||||
default:
|
||||
rc = set_boot_config(sd_handle,
|
||||
SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_USER);
|
||||
EMMC_TRACE("Change to User area result:%d (0 means SD_OK)\n",
|
||||
rc);
|
||||
break;
|
||||
|
||||
}
|
||||
return (rc == SD_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize emmc controller for eMMC
|
||||
* Returns 0 on fail condition
|
||||
*/
|
||||
uint32_t bcm_emmc_init(bool card_rdy_only)
|
||||
{
|
||||
struct sd_handle *p_sdhandle;
|
||||
uint32_t result = 0;
|
||||
|
||||
EMMC_TRACE("Enter emmc_controller_init()\n");
|
||||
|
||||
/* If eMMC is already initialized, skip init */
|
||||
if (emmc_global_vars_ptr->init_done)
|
||||
return 1;
|
||||
|
||||
init_globals();
|
||||
|
||||
p_sdhandle = sdio_init();
|
||||
|
||||
if (p_sdhandle == NULL) {
|
||||
ERROR("eMMC init failed");
|
||||
return result;
|
||||
}
|
||||
|
||||
if (card_rdy_only) {
|
||||
/* Put the card in Ready state, Not complete init */
|
||||
result = bcm_emmc_card_ready_state(p_sdhandle);
|
||||
return !result;
|
||||
}
|
||||
|
||||
if (sdio_idle(p_sdhandle) == EMMC_BOOT_OK) {
|
||||
set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, USE_DMA,
|
||||
SD_DMA_BOUNDARY_256K, EMMC_BLOCK_SIZE,
|
||||
EMMC_WFE_RETRY);
|
||||
|
||||
if (!select_blk_sz(p_sdhandle,
|
||||
p_sdhandle->device->cfg.blockSize)) {
|
||||
emmc_global_vars_ptr->init_done = 1;
|
||||
result = 1;
|
||||
} else {
|
||||
ERROR("Select Block Size failed\n");
|
||||
}
|
||||
} else {
|
||||
ERROR("eMMC init failed");
|
||||
}
|
||||
|
||||
/* Initialization is failed, so deinit HW setting */
|
||||
if (result == 0)
|
||||
emmc_deinit();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to de-init SDIO controller for eMMC
|
||||
*/
|
||||
void emmc_deinit(void)
|
||||
{
|
||||
emmc_global_vars_ptr->init_done = 0;
|
||||
emmc_global_vars_ptr->sdHandle.card = 0;
|
||||
emmc_global_vars_ptr->sdHandle.device = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read eMMC memory
|
||||
* Returns read_size
|
||||
*/
|
||||
uint32_t emmc_read(uintptr_t mem_addr, uintptr_t storage_addr,
|
||||
size_t storage_size, size_t bytes_to_read)
|
||||
{
|
||||
struct sd_handle *sd_handle = sdio_gethandle();
|
||||
|
||||
if (sd_handle->device == 0) {
|
||||
EMMC_TRACE("eMMC init is not done");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sdio_read(sdio_gethandle(), mem_addr, storage_addr,
|
||||
storage_size, bytes_to_read);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
|
||||
#define EXT_CSD_ERASE_GRP_SIZE 224
|
||||
|
||||
static int emmc_block_erase(uintptr_t mem_addr, size_t blocks)
|
||||
{
|
||||
struct sd_handle *sd_handle = sdio_gethandle();
|
||||
|
||||
if (sd_handle->device == 0) {
|
||||
ERROR("eMMC init is not done");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return erase_card(sdio_gethandle(), mem_addr, blocks);
|
||||
}
|
||||
|
||||
int emmc_erase(uintptr_t mem_addr, size_t num_of_blocks, uint32_t partition)
|
||||
{
|
||||
int err = 0;
|
||||
size_t block_count = 0, blocks = 0;
|
||||
size_t erase_group = 0;
|
||||
|
||||
erase_group =
|
||||
emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_ERASE_GRP_SIZE]*1024;
|
||||
|
||||
INFO("eMMC Erase Group Size=0x%lx\n", erase_group);
|
||||
|
||||
emmc_partition_select(partition);
|
||||
|
||||
while (block_count < num_of_blocks) {
|
||||
blocks = ((num_of_blocks - block_count) > erase_group) ?
|
||||
erase_group : (num_of_blocks - block_count);
|
||||
err = emmc_block_erase(mem_addr + block_count, blocks);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
block_count += blocks;
|
||||
}
|
||||
|
||||
if (err == 0)
|
||||
INFO("eMMC Erase of partition %d successful\n", partition);
|
||||
else
|
||||
ERROR("eMMC Erase of partition %d Failed(%i)\n", partition, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
|
||||
/*
|
||||
* Write to eMMC memory
|
||||
* Returns written_size
|
||||
*/
|
||||
uint32_t emmc_write(uintptr_t mem_addr, uintptr_t data_addr,
|
||||
size_t bytes_to_write)
|
||||
{
|
||||
struct sd_handle *sd_handle = sdio_gethandle();
|
||||
|
||||
if (sd_handle->device == 0) {
|
||||
EMMC_TRACE("eMMC init is not done");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sdio_write(sd_handle, mem_addr, data_addr, bytes_to_write);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Send SDIO Cmd
|
||||
* Return 0 for pass condition
|
||||
*/
|
||||
uint32_t send_sdio_cmd(uint32_t cmdIndex, uint32_t argument,
|
||||
uint32_t options, struct sd_resp *resp)
|
||||
{
|
||||
struct sd_handle *sd_handle = sdio_gethandle();
|
||||
|
||||
if (sd_handle->device == 0) {
|
||||
EMMC_TRACE("eMMC init is not done");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return send_cmd(sd_handle, cmdIndex, argument, options, resp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function return SDIO handle
|
||||
*/
|
||||
struct sd_handle *sdio_gethandle(void)
|
||||
{
|
||||
return &emmc_global_vars_ptr->sdHandle;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize SDIO controller
|
||||
*/
|
||||
struct sd_handle *sdio_init(void)
|
||||
{
|
||||
uint32_t SDIO_base;
|
||||
struct sd_handle *p_sdhandle = &emmc_global_vars_ptr->sdHandle;
|
||||
|
||||
SDIO_base = EMMC_CTRL_REGS_BASE_ADDR;
|
||||
|
||||
if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR)
|
||||
EMMC_TRACE(" ---> for SDIO 0 Controller\n\n");
|
||||
|
||||
memset(p_sdhandle, 0, sizeof(struct sd_handle));
|
||||
|
||||
p_sdhandle->device = &emmc_global_vars_ptr->sdDevice;
|
||||
p_sdhandle->card = &emmc_global_vars_ptr->sdCard;
|
||||
|
||||
memset(p_sdhandle->device, 0, sizeof(struct sd_dev));
|
||||
memset(p_sdhandle->card, 0, sizeof(struct sd_card_info));
|
||||
|
||||
if (chal_sd_start((CHAL_HANDLE *) p_sdhandle->device,
|
||||
SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK)
|
||||
return NULL;
|
||||
|
||||
set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, SD_DMA_OFF,
|
||||
SD_DMA_BOUNDARY_4K, EMMC_BLOCK_SIZE, EMMC_WFE_RETRY);
|
||||
|
||||
return &emmc_global_vars_ptr->sdHandle;
|
||||
}
|
||||
|
||||
uint32_t sdio_idle(struct sd_handle *p_sdhandle)
|
||||
{
|
||||
reset_card(p_sdhandle);
|
||||
|
||||
SD_US_DELAY(1000);
|
||||
|
||||
if (init_card(p_sdhandle, SD_CARD_DETECT_MMC) != SD_OK) {
|
||||
reset_card(p_sdhandle);
|
||||
reset_host_ctrl(p_sdhandle);
|
||||
return EMMC_BOOT_NO_CARD;
|
||||
}
|
||||
|
||||
return EMMC_BOOT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function read eMMC
|
||||
*/
|
||||
uint32_t sdio_read(struct sd_handle *p_sdhandle,
|
||||
uintptr_t mem_addr,
|
||||
uintptr_t storage_addr,
|
||||
size_t storage_size, size_t bytes_to_read)
|
||||
{
|
||||
uint32_t offset = 0, blockAddr, readLen = 0, rdCount;
|
||||
uint32_t remSize, manual_copy_size;
|
||||
uint8_t *outputBuf = (uint8_t *) storage_addr;
|
||||
const size_t blockSize = p_sdhandle->device->cfg.blockSize;
|
||||
|
||||
VERBOSE("EMMC READ: dst=0x%lx, src=0x%lx, size=0x%lx\n",
|
||||
storage_addr, mem_addr, bytes_to_read);
|
||||
|
||||
if (storage_size < bytes_to_read)
|
||||
/* Don't have sufficient storage to complete the operation */
|
||||
return 0;
|
||||
|
||||
/* Range check non high capacity memory */
|
||||
if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
|
||||
if (mem_addr > 0x80000000)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* High capacity card use block address mode */
|
||||
if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
|
||||
blockAddr = (uint32_t) (mem_addr / blockSize);
|
||||
offset = (uint32_t) (mem_addr - (blockAddr * blockSize));
|
||||
} else {
|
||||
blockAddr = (uint32_t) (mem_addr / blockSize) * blockSize;
|
||||
offset = (uint32_t) (mem_addr - blockAddr);
|
||||
}
|
||||
|
||||
remSize = bytes_to_read;
|
||||
|
||||
rdCount = 0;
|
||||
|
||||
/* Process first unaligned block of MAX_READ_LENGTH */
|
||||
if (offset > 0) {
|
||||
if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf,
|
||||
blockAddr, SD_MAX_READ_LENGTH)) {
|
||||
|
||||
if (remSize < (blockSize - offset)) {
|
||||
rdCount += remSize;
|
||||
manual_copy_size = remSize;
|
||||
remSize = 0; /* read is done */
|
||||
} else {
|
||||
remSize -= (blockSize - offset);
|
||||
rdCount += (blockSize - offset);
|
||||
manual_copy_size = blockSize - offset;
|
||||
}
|
||||
|
||||
/* Check for overflow */
|
||||
if (manual_copy_size > storage_size ||
|
||||
(((uintptr_t)outputBuf + manual_copy_size) >
|
||||
(storage_addr + storage_size))) {
|
||||
ERROR("EMMC READ: Overflow 1\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(outputBuf,
|
||||
(void *)((uintptr_t)
|
||||
(emmc_global_buf_ptr->u.tempbuf + offset)),
|
||||
manual_copy_size);
|
||||
|
||||
/* Update Physical address */
|
||||
outputBuf += manual_copy_size;
|
||||
|
||||
if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
|
||||
blockAddr++;
|
||||
else
|
||||
blockAddr += blockSize;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (remSize >= blockSize) {
|
||||
|
||||
if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH)
|
||||
readLen = SD_MAX_BLK_TRANSFER_LENGTH;
|
||||
else
|
||||
readLen = (remSize / blockSize) * blockSize;
|
||||
|
||||
/* Check for overflow */
|
||||
if ((rdCount + readLen) > storage_size ||
|
||||
(((uintptr_t) outputBuf + readLen) >
|
||||
(storage_addr + storage_size))) {
|
||||
ERROR("EMMC READ: Overflow\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!read_block(p_sdhandle, outputBuf, blockAddr, readLen)) {
|
||||
if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
|
||||
blockAddr += (readLen / blockSize);
|
||||
else
|
||||
blockAddr += readLen;
|
||||
|
||||
remSize -= readLen;
|
||||
rdCount += readLen;
|
||||
|
||||
/* Update Physical address */
|
||||
outputBuf += readLen;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* process the last unaligned block reading */
|
||||
if (remSize > 0) {
|
||||
if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf,
|
||||
blockAddr, SD_MAX_READ_LENGTH)) {
|
||||
|
||||
rdCount += remSize;
|
||||
/* Check for overflow */
|
||||
if (rdCount > storage_size ||
|
||||
(((uintptr_t) outputBuf + remSize) >
|
||||
(storage_addr + storage_size))) {
|
||||
ERROR("EMMC READ: Overflow\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(outputBuf,
|
||||
emmc_global_buf_ptr->u.tempbuf, remSize);
|
||||
|
||||
/* Update Physical address */
|
||||
outputBuf += remSize;
|
||||
} else {
|
||||
rdCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return rdCount;
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
|
||||
static uint32_t sdio_write(struct sd_handle *p_sdhandle, uintptr_t mem_addr,
|
||||
uintptr_t data_addr, size_t bytes_to_write)
|
||||
{
|
||||
|
||||
uint32_t offset, blockAddr, writeLen, wtCount = 0;
|
||||
uint32_t remSize, manual_copy_size = 0;
|
||||
|
||||
uint8_t *inputBuf = (uint8_t *)data_addr;
|
||||
|
||||
/* range check non high capacity memory */
|
||||
if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
|
||||
if (mem_addr > 0x80000000)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the high capacity card use block address mode */
|
||||
if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
|
||||
blockAddr =
|
||||
(uint32_t)(mem_addr / p_sdhandle->device->cfg.blockSize);
|
||||
offset =
|
||||
(uint32_t)(mem_addr -
|
||||
blockAddr * p_sdhandle->device->cfg.blockSize);
|
||||
} else {
|
||||
blockAddr =
|
||||
((uint32_t)mem_addr / p_sdhandle->device->cfg.blockSize) *
|
||||
p_sdhandle->device->cfg.blockSize;
|
||||
offset = (uint32_t) mem_addr - blockAddr;
|
||||
}
|
||||
|
||||
remSize = bytes_to_write;
|
||||
|
||||
wtCount = 0;
|
||||
|
||||
/* process first unaligned block */
|
||||
if (offset > 0) {
|
||||
if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf,
|
||||
blockAddr, p_sdhandle->device->cfg.blockSize)) {
|
||||
|
||||
if (remSize <
|
||||
(p_sdhandle->device->cfg.blockSize - offset))
|
||||
manual_copy_size = remSize;
|
||||
else
|
||||
manual_copy_size =
|
||||
p_sdhandle->device->cfg.blockSize - offset;
|
||||
|
||||
memcpy((void *)((uintptr_t)
|
||||
(emmc_global_buf_ptr->u.tempbuf + offset)),
|
||||
inputBuf,
|
||||
manual_copy_size);
|
||||
|
||||
/* Update Physical address */
|
||||
|
||||
if (!write_block(p_sdhandle,
|
||||
emmc_global_buf_ptr->u.tempbuf,
|
||||
blockAddr,
|
||||
p_sdhandle->device->cfg.blockSize)) {
|
||||
|
||||
if (remSize <
|
||||
(p_sdhandle->device->cfg.blockSize -
|
||||
offset)) {
|
||||
wtCount += remSize;
|
||||
manual_copy_size = remSize;
|
||||
remSize = 0; /* read is done */
|
||||
} else {
|
||||
remSize -=
|
||||
(p_sdhandle->device->cfg.blockSize -
|
||||
offset);
|
||||
wtCount +=
|
||||
(p_sdhandle->device->cfg.blockSize -
|
||||
offset);
|
||||
manual_copy_size =
|
||||
p_sdhandle->device->cfg.blockSize -
|
||||
offset;
|
||||
}
|
||||
|
||||
inputBuf += manual_copy_size;
|
||||
|
||||
if (p_sdhandle->device->ctrl.ocr &
|
||||
SD_CARD_HIGH_CAPACITY)
|
||||
blockAddr++;
|
||||
else
|
||||
blockAddr +=
|
||||
p_sdhandle->device->cfg.blockSize;
|
||||
} else
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* process block writing */
|
||||
while (remSize >= p_sdhandle->device->cfg.blockSize) {
|
||||
if (remSize >= SD_MAX_READ_LENGTH) {
|
||||
writeLen = SD_MAX_READ_LENGTH;
|
||||
} else {
|
||||
writeLen =
|
||||
(remSize / p_sdhandle->device->cfg.blockSize) *
|
||||
p_sdhandle->device->cfg.blockSize;
|
||||
}
|
||||
|
||||
if (!write_block(p_sdhandle, inputBuf, blockAddr, writeLen)) {
|
||||
if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
|
||||
blockAddr +=
|
||||
(writeLen /
|
||||
p_sdhandle->device->cfg.blockSize);
|
||||
else
|
||||
blockAddr += writeLen;
|
||||
|
||||
remSize -= writeLen;
|
||||
wtCount += writeLen;
|
||||
inputBuf += writeLen;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* process the last unaligned block reading */
|
||||
if (remSize > 0) {
|
||||
if (!read_block(p_sdhandle,
|
||||
emmc_global_buf_ptr->u.tempbuf,
|
||||
blockAddr, p_sdhandle->device->cfg.blockSize)) {
|
||||
|
||||
memcpy(emmc_global_buf_ptr->u.tempbuf,
|
||||
inputBuf, remSize);
|
||||
|
||||
/* Update Physical address */
|
||||
|
||||
if (!write_block(p_sdhandle,
|
||||
emmc_global_buf_ptr->u.tempbuf,
|
||||
blockAddr,
|
||||
p_sdhandle->device->cfg.blockSize)) {
|
||||
wtCount += remSize;
|
||||
inputBuf += remSize;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
wtCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return wtCount;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Function to put the card in Ready state by sending CMD0 and CMD1
|
||||
*/
|
||||
static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle)
|
||||
{
|
||||
int32_t result = 0;
|
||||
uint32_t argument = MMC_CMD_IDLE_RESET_ARG; /* Exit from Boot mode */
|
||||
|
||||
if (p_sdhandle) {
|
||||
send_sdio_cmd(SD_CMD_GO_IDLE_STATE, argument, 0, NULL);
|
||||
|
||||
result = reset_card(p_sdhandle);
|
||||
if (result != SD_OK) {
|
||||
EMMC_TRACE("eMMC Reset error\n");
|
||||
return SD_RESET_ERROR;
|
||||
}
|
||||
SD_US_DELAY(2000);
|
||||
result = mmc_cmd1(p_sdhandle);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
104
include/drivers/brcm/emmc/bcm_emmc.h
Normal file
104
include/drivers/brcm/emmc/bcm_emmc.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EMMC_H
|
||||
#define EMMC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include "emmc_chal_types.h"
|
||||
#include "emmc_chal_sd.h"
|
||||
#include "emmc_csl_sdprot.h"
|
||||
#include "emmc_csl_sdcmd.h"
|
||||
#include "emmc_pboot_hal_memory_drv.h"
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
#define EXT_CSD_SIZE 512
|
||||
|
||||
#ifdef PLAT_SD_MAX_READ_LENGTH
|
||||
#define SD_MAX_READ_LENGTH PLAT_SD_MAX_READ_LENGTH
|
||||
#ifdef USE_EMMC_LARGE_BLK_TRANSFER_LENGTH
|
||||
#define SD_MAX_BLK_TRANSFER_LENGTH 0x10000000
|
||||
#else
|
||||
#define SD_MAX_BLK_TRANSFER_LENGTH 0x1000
|
||||
#endif
|
||||
#else
|
||||
#define SD_MAX_READ_LENGTH EMMC_BLOCK_SIZE
|
||||
#define SD_MAX_BLK_TRANSFER_LENGTH EMMC_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
struct emmc_global_buffer {
|
||||
union {
|
||||
uint8_t Ext_CSD_storage[EXT_CSD_SIZE];
|
||||
uint8_t tempbuf[SD_MAX_READ_LENGTH];
|
||||
} u;
|
||||
};
|
||||
|
||||
struct emmc_global_vars {
|
||||
struct sd_card_data cardData;
|
||||
struct sd_handle sdHandle;
|
||||
struct sd_dev sdDevice;
|
||||
struct sd_card_info sdCard;
|
||||
unsigned int init_done;
|
||||
};
|
||||
|
||||
#define ICFG_SDIO0_CAP0__SLOT_TYPE_R 27
|
||||
#define ICFG_SDIO0_CAP0__INT_MODE_R 26
|
||||
#define ICFG_SDIO0_CAP0__SYS_BUS_64BIT_R 25
|
||||
#define ICFG_SDIO0_CAP0__VOLTAGE_1P8V_R 24
|
||||
#define ICFG_SDIO0_CAP0__VOLTAGE_3P0V_R 23
|
||||
#define ICFG_SDIO0_CAP0__VOLTAGE_3P3V_R 22
|
||||
#define ICFG_SDIO0_CAP0__SUSPEND_RESUME_R 21
|
||||
#define ICFG_SDIO0_CAP0__SDMA_R 20
|
||||
#define ICFG_SDIO0_CAP0__HIGH_SPEED_R 19
|
||||
#define ICFG_SDIO0_CAP0__ADMA2_R 18
|
||||
#define ICFG_SDIO0_CAP0__EXTENDED_MEDIA_R 17
|
||||
#define ICFG_SDIO0_CAP0__MAX_BLOCK_LEN_R 15
|
||||
#define ICFG_SDIO0_CAP0__BASE_CLK_FREQ_R 7
|
||||
#define ICFG_SDIO0_CAP0__TIMEOUT_UNIT_R 6
|
||||
#define ICFG_SDIO0_CAP0__TIMEOUT_CLK_FREQ_R 0
|
||||
#define ICFG_SDIO0_CAP1__SPI_BLOCK_MODE_R 22
|
||||
#define ICFG_SDIO0_CAP1__SPI_MODE_R 21
|
||||
#define ICFG_SDIO0_CAP1__CLK_MULT_R 13
|
||||
#define ICFG_SDIO0_CAP1__RETUNING_MODE_R 11
|
||||
#define ICFG_SDIO0_CAP1__TUNE_SDR50_R 10
|
||||
#define ICFG_SDIO0_CAP1__TIME_RETUNE_R 6
|
||||
#define ICFG_SDIO0_CAP1__DRIVER_D_R 5
|
||||
#define ICFG_SDIO0_CAP1__DRIVER_C_R 4
|
||||
#define ICFG_SDIO0_CAP1__DRIVER_A_R 3
|
||||
#define ICFG_SDIO0_CAP1__DDR50_R 2
|
||||
#define ICFG_SDIO0_CAP1__SDR104_R 1
|
||||
#define ICFG_SDIO0_CAP1__SDR50_R 0
|
||||
|
||||
#define SDIO0_CTRL_REGS_BASE_ADDR (SDIO0_EMMCSDXC_SYSADDR)
|
||||
#define SDIO0_IDM_RESET_CTRL_ADDR (SDIO_IDM0_IDM_RESET_CONTROL)
|
||||
|
||||
#define EMMC_CTRL_REGS_BASE_ADDR SDIO0_CTRL_REGS_BASE_ADDR
|
||||
#define EMMC_IDM_RESET_CTRL_ADDR SDIO0_IDM_RESET_CTRL_ADDR
|
||||
#define EMMC_IDM_IO_CTRL_DIRECT_ADDR SDIO_IDM0_IO_CONTROL_DIRECT
|
||||
|
||||
extern struct emmc_global_buffer *emmc_global_buf_ptr;
|
||||
|
||||
extern struct emmc_global_vars *emmc_global_vars_ptr;
|
||||
|
||||
#define EMMC_CARD_DETECT_TIMEOUT_MS 1200
|
||||
#define EMMC_CMD_TIMEOUT_MS 200
|
||||
#define EMMC_BUSY_CMD_TIMEOUT_MS 200
|
||||
#define EMMC_CLOCK_SETTING_TIMEOUT_MS 100
|
||||
#define EMMC_WFE_RETRY 40000
|
||||
#define EMMC_WFE_RETRY_DELAY_US 10
|
||||
|
||||
#ifdef EMMC_DEBUG
|
||||
#define EMMC_TRACE INFO
|
||||
#else
|
||||
#define EMMC_TRACE(...)
|
||||
#endif
|
||||
|
||||
#endif /* EMMC_H */
|
47
include/drivers/brcm/emmc/emmc_api.h
Normal file
47
include/drivers/brcm/emmc/emmc_api.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef EMMC_API_H
|
||||
#define EMMC_API_H
|
||||
|
||||
#include "bcm_emmc.h"
|
||||
#include "emmc_pboot_hal_memory_drv.h"
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
|
||||
/*
|
||||
* The erasable unit of the eMMC is the Erase Group
|
||||
* Erase group is measured in write blocks which
|
||||
* are the basic writable units of the Device
|
||||
* EMMC_ERASE_GROUP_SIZE is the number of writeable
|
||||
* units (each unit is 512 bytes)
|
||||
*/
|
||||
|
||||
/* Start address (sector) */
|
||||
#define EMMC_ERASE_START_BLOCK 0x0
|
||||
/* Number of blocks to be erased */
|
||||
#define EMMC_ERASE_BLOCK_COUNT 0x1
|
||||
|
||||
#define EMMC_ERASE_USER_AREA 0
|
||||
#define EMMC_ERASE_BOOT_PARTITION1 1
|
||||
#define EMMC_ERASE_BOOT_PARTITION2 2
|
||||
|
||||
/* eMMC partition to be erased */
|
||||
#define EMMC_ERASE_PARTITION EMMC_ERASE_USER_AREA
|
||||
#endif
|
||||
|
||||
uint32_t bcm_emmc_init(bool card_rdy_only);
|
||||
void emmc_deinit(void);
|
||||
|
||||
#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
|
||||
int emmc_erase(uintptr_t mem_addr, size_t num_of_blocks, uint32_t partition);
|
||||
#endif
|
||||
|
||||
uint32_t emmc_partition_select(uint32_t partition);
|
||||
uint32_t emmc_read(uintptr_t mem_addr, uintptr_t storage_addr,
|
||||
size_t storage_size, size_t bytes_to_read);
|
||||
uint32_t emmc_write(uintptr_t mem_addr, uintptr_t data_addr,
|
||||
size_t bytes_to_write);
|
||||
#endif /* EMMC_API_H */
|
1116
include/drivers/brcm/emmc/emmc_brcm_rdb_sd4_top.h
Normal file
1116
include/drivers/brcm/emmc/emmc_brcm_rdb_sd4_top.h
Normal file
File diff suppressed because it is too large
Load diff
202
include/drivers/brcm/emmc/emmc_chal_sd.h
Normal file
202
include/drivers/brcm/emmc/emmc_chal_sd.h
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CHAL_SD_H
|
||||
#define CHAL_SD_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define BASE_CLK_FREQ (200 * 1000 * 1000)
|
||||
#define INIT_CLK_FREQ (400 * 1000)
|
||||
|
||||
#define SD_ERROR_RECOVERABLE 0
|
||||
#define SD_ERROR_NON_RECOVERABLE 1
|
||||
|
||||
#define SD_OK 0
|
||||
#define SD_FAIL (-1)
|
||||
#define SD_INVALID_HANDLE (-2)
|
||||
#define SD_CEATA_INIT_ERROR (-3)
|
||||
#define SD_RESET_ERROR (-4)
|
||||
#define SD_CARD_INIT_ERROR (-5)
|
||||
#define SD_INV_DATA_WIDTH (-6)
|
||||
#define SD_SET_BUS_WIDTH_ERROR (-7)
|
||||
#define SD_DMA_NOT_SUPPORT (-8)
|
||||
#define SD_SDIO_READ_ERROR (-9)
|
||||
#define SD_SDIO_WRITE_ERROR (-10)
|
||||
#define SD_WRITE_ERROR (-11)
|
||||
#define SD_READ_ERROR (-12)
|
||||
#define SD_READ_SIZE_ERROR (-13)
|
||||
#define SD_RW_ADDRESS_ERROR (-14)
|
||||
#define SD_XFER_ADDRESS_ERROR (-15)
|
||||
#define SD_DATA_XFER_ADDR_ERROR (-16)
|
||||
#define SD_DATA_XFER_ERROR (-17)
|
||||
#define SD_WRITE_SIZE_ERROR (-18)
|
||||
#define SD_CMD_STATUS_UPDATE_ERR (-19)
|
||||
#define SD_CMD12_ERROR (-20)
|
||||
#define SD_CMD_DATA_ERROR (-21)
|
||||
#define SD_CMD_TIMEOUT (-22)
|
||||
#define SD_CMD_NO_RESPONSE (-22)
|
||||
#define SD_CMD_ABORT_ERROR (-23)
|
||||
#define SD_CMD_INVALID (-24)
|
||||
#define SD_CMD_RESUME_ERROR (-25)
|
||||
#define SD_CMD_ERR_INVALID_RESPONSE (-26)
|
||||
#define SD_WAIT_TIMEOUT (-27)
|
||||
#define SD_READ_TIMEOUT (-28)
|
||||
#define SD_CEATA_REST_ERROR (-29)
|
||||
#define SD_INIT_CAED_FAILED (-30)
|
||||
#define SD_ERROR_CLOCK_OFFLIMIT (-31)
|
||||
#define SD_INV_SLOT (-32)
|
||||
|
||||
#define SD_NOR_INTERRUPTS 0x000000FF
|
||||
#define SD_ERR_INTERRUPTS 0x03FF0000
|
||||
#define SD_CMD_ERROR_INT 0x010F0000
|
||||
#define SD_DAT_ERROR_INT 0x02F00000
|
||||
#define SD_DAT_TIMEOUT 0x00100000
|
||||
|
||||
/* Operation modes */
|
||||
#define SD_PIO_MODE 0
|
||||
#define SD_INT_MODE 1
|
||||
|
||||
/* Support both ADMA and SDMA (for version 2.0 and above) */
|
||||
#define SD_DMA_OFF 0
|
||||
#define SD_DMA_SDMA 1
|
||||
#define SD_DMA_ADMA 2
|
||||
|
||||
#define SD_NORMAL_SPEED 0
|
||||
#define SD_HIGH_SPEED 1
|
||||
|
||||
#define SD_XFER_CARD_TO_HOST 3
|
||||
#define SD_XFER_HOST_TO_CARD 4
|
||||
|
||||
#define SD_CARD_DETECT_AUTO 0
|
||||
#define SD_CARD_DETECT_SD 1
|
||||
#define SD_CARD_DETECT_SDIO 2
|
||||
#define SD_CARD_DETECT_MMC 3
|
||||
#define SD_CARD_DETECT_CEATA 4
|
||||
|
||||
#define SD_ABORT_SYNC_MODE 0
|
||||
#define SD_ABORT_ASYNC_MODE 1
|
||||
|
||||
#define SD_CMD_ERROR_FLAGS (0x18F << 16)
|
||||
#define SD_DATA_ERROR_FLAGS (0x70 << 16)
|
||||
#define SD_AUTO_CMD12_ERROR_FLAGS (0x9F)
|
||||
|
||||
#define SD_CARD_STATUS_ERROR 0x10000000
|
||||
#define SD_CMD_MISSING 0x80000000
|
||||
#define SD_ERROR_INT 0x8000
|
||||
|
||||
#define SD_TRAN_HIGH_SPEED 0x32
|
||||
#define SD_CARD_HIGH_CAPACITY 0x40000000
|
||||
#define SD_CARD_POWER_UP_STATUS 0x80000000
|
||||
|
||||
#define SD_HOST_CORE_TIMEOUT 0x0E
|
||||
|
||||
/* SD CARD and Host Controllers bus width */
|
||||
#define SD_BUS_DATA_WIDTH_1BIT 0x00
|
||||
#define SD_BUS_DATA_WIDTH_4BIT 0x02
|
||||
#define SD_BUS_DATA_WIDTH_8BIT 0x20
|
||||
|
||||
/* dma boundary settings */
|
||||
#define SD_DMA_BOUNDARY_4K 0
|
||||
#define SD_DMA_BOUNDARY_8K (1 << 12)
|
||||
#define SD_DMA_BOUNDARY_16K (2 << 12)
|
||||
#define SD_DMA_BOUNDARY_32K (3 << 12)
|
||||
#define SD_DMA_BOUNDARY_64K (4 << 12)
|
||||
#define SD_DMA_BOUNDARY_128K (5 << 12)
|
||||
#define SD_DMA_BOUNDARY_256K (6 << 12)
|
||||
#define SD_DMA_BOUNDARY_512K (7 << 12)
|
||||
|
||||
#define SD_CMDR_CMD_NORMAL 0x00000000
|
||||
#define SD_CMDR_CMD_SUSPEND 0x00400000
|
||||
#define SD_CMDR_CMD_RESUME 0x00800000
|
||||
#define SD_CMDR_CMD_ABORT 0x00c00000
|
||||
|
||||
#define SD_CMDR_RSP_TYPE_NONE 0x0
|
||||
#define SD_CMDR_RSP_TYPE_R2 0x1
|
||||
#define SD_CMDR_RSP_TYPE_R3_4 0x2
|
||||
#define SD_CMDR_RSP_TYPE_R1_5_6 0x2
|
||||
#define SD_CMDR_RSP_TYPE_R1b_5b 0x3
|
||||
#define SD_CMDR_RSP_TYPE_S 16
|
||||
|
||||
struct sd_ctrl_info {
|
||||
uint32_t blkReg; /* current block register cache value */
|
||||
uint32_t cmdReg; /* current command register cache value */
|
||||
uint32_t argReg; /* current argument register cache value */
|
||||
uint32_t cmdIndex; /* current command index */
|
||||
uint32_t cmdStatus; /* current command status, cmd/data compelete */
|
||||
uint16_t rca; /* relative card address */
|
||||
uint32_t ocr; /* operation codition */
|
||||
uint32_t eventList; /* events list */
|
||||
uint32_t blkGapEnable;
|
||||
|
||||
uint32_t capability; /* controller's capbilities */
|
||||
uint32_t maxCurrent; /* maximum current supported */
|
||||
uint32_t present; /* if card is inserted or removed */
|
||||
uint32_t version; /* SD spec version 1.0 or 2.0 */
|
||||
uint32_t vendor; /* vendor number */
|
||||
|
||||
uintptr_t sdRegBaseAddr; /* sdio control registers */
|
||||
uintptr_t hostRegBaseAddr; /* SD Host control registers */
|
||||
};
|
||||
|
||||
struct sd_cfg {
|
||||
uint32_t mode; /* interrupt or polling */
|
||||
uint32_t dma; /* dma enabled or disabled */
|
||||
uint32_t retryLimit; /* command retry limit */
|
||||
uint32_t speedMode; /* speed mode, 0 standard, 1 high speed */
|
||||
uint32_t voltage; /* voltage level */
|
||||
uint32_t blockSize; /* access block size (512 for HC card) */
|
||||
uint32_t dmaBoundary; /* dma address boundary */
|
||||
uint32_t detSignal; /* card det signal src, for test purpose only */
|
||||
uint32_t rdWaiting;
|
||||
uint32_t wakeupOut;
|
||||
uint32_t wakeupIn;
|
||||
uint32_t wakeupInt;
|
||||
uint32_t wfe_retry;
|
||||
uint32_t gapInt;
|
||||
uint32_t readWait;
|
||||
uint32_t led;
|
||||
};
|
||||
|
||||
struct sd_dev {
|
||||
struct sd_cfg cfg; /* SD configuration */
|
||||
struct sd_ctrl_info ctrl; /* SD info */
|
||||
};
|
||||
|
||||
int32_t chal_sd_start(CHAL_HANDLE *sdHandle, uint32_t mode,
|
||||
uint32_t sdBase, uint32_t hostBase);
|
||||
int32_t chal_sd_config(CHAL_HANDLE *sdHandle, uint32_t speed,
|
||||
uint32_t retry, uint32_t boundary,
|
||||
uint32_t blkSize, uint32_t dma);
|
||||
int32_t chal_sd_stop(void);
|
||||
int32_t chal_sd_set_dma(CHAL_HANDLE *sdHandle, uint32_t mode);
|
||||
uintptr_t chal_sd_get_dma_addr(CHAL_HANDLE *handle);
|
||||
int32_t chal_sd_config_bus_width(CHAL_HANDLE *sdHandle, int32_t width);
|
||||
int32_t chal_sd_send_cmd(CHAL_HANDLE *sdHandle, uint32_t cmdIndex,
|
||||
uint32_t arg, uint32_t options);
|
||||
int32_t chal_sd_set_dma_addr(CHAL_HANDLE *sdHandle, uintptr_t address);
|
||||
int32_t chal_sd_set_clock(CHAL_HANDLE *sdHandle,
|
||||
uint32_t div_ctrl_setting, uint32_t on);
|
||||
uint32_t chal_sd_freq_2_div_ctrl_setting(uint32_t desired_freq);
|
||||
int32_t chal_sd_setup_xfer(CHAL_HANDLE *sdHandle, uint8_t *data,
|
||||
uint32_t length, int32_t dir);
|
||||
int32_t chal_sd_write_buffer(CHAL_HANDLE *sdHandle, uint32_t length,
|
||||
uint8_t *data);
|
||||
int32_t chal_sd_read_buffer(CHAL_HANDLE *sdHandle, uint32_t length,
|
||||
uint8_t *data);
|
||||
int32_t chal_sd_reset_line(CHAL_HANDLE *sdHandle, uint32_t line);
|
||||
int32_t chal_sd_get_response(CHAL_HANDLE *sdHandle, uint32_t *resp);
|
||||
int32_t chal_sd_clear_pending_irq(CHAL_HANDLE *sdHandle);
|
||||
int32_t chal_sd_get_irq_status(CHAL_HANDLE *sdHandle);
|
||||
int32_t chal_sd_clear_irq(CHAL_HANDLE *sdHandle, uint32_t mask);
|
||||
uint32_t chal_sd_get_present_status(CHAL_HANDLE *sdHandle);
|
||||
int32_t chal_sd_get_atuo12_error(CHAL_HANDLE *sdHandle);
|
||||
void chal_sd_set_speed(CHAL_HANDLE *sdHandle, uint32_t speed);
|
||||
int32_t chal_sd_check_cap(CHAL_HANDLE *sdHandle, uint32_t cap);
|
||||
void chal_sd_set_irq_signal(CHAL_HANDLE *sdHandle, uint32_t mask,
|
||||
uint32_t state);
|
||||
void chal_sd_dump_fifo(CHAL_HANDLE *sdHandle);
|
||||
#endif /* CHAL_SD_H */
|
20
include/drivers/brcm/emmc/emmc_chal_types.h
Normal file
20
include/drivers/brcm/emmc/emmc_chal_types.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CHAL_TYPES_H
|
||||
#define CHAL_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//
|
||||
// Generic cHAL handler
|
||||
//
|
||||
#ifndef CHAL_HANDLE
|
||||
typedef void *CHAL_HANDLE; ///< void pointer (32 bits wide)
|
||||
#endif
|
||||
|
||||
#endif /* _CHAL_TYPES_H_ */
|
96
include/drivers/brcm/emmc/emmc_csl_sd.h
Normal file
96
include/drivers/brcm/emmc/emmc_csl_sd.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CSL_SD_H
|
||||
#define CSL_SD_H
|
||||
|
||||
#define SD_CLOCK_BASE 104000000
|
||||
#define SD_CLOCK_52MHZ 52000000
|
||||
#define SD_CLOCK_26MHZ 26000000
|
||||
#define SD_CLOCK_17MHZ 17330000
|
||||
#define SD_CLOCK_13MHZ 13000000
|
||||
#define SD_CLOCK_10MHZ 10000000
|
||||
#define SD_CLOCK_9MHZ 9000000
|
||||
#define SD_CLOCK_7MHZ 7000000
|
||||
#define SD_CLOCK_5MHZ 5000000
|
||||
#define SD_CLOCK_1MHZ 1000000
|
||||
#define SD_CLOCK_400KHZ 400000
|
||||
|
||||
#define SD_DRIVE_STRENGTH_MASK 0x38000000
|
||||
#if defined(_BCM213x1_) || defined(_BCM21551_) || defined(_ATHENA_)
|
||||
#define SD_DRIVE_STRENGTH 0x28000000
|
||||
#elif defined(_BCM2153_)
|
||||
#define SD_DRIVE_STRENGTH 0x38000000
|
||||
#else
|
||||
#define SD_DRIVE_STRENGTH 0x00000000
|
||||
#endif
|
||||
|
||||
#define SD_NUM_HOST 2
|
||||
|
||||
#define SD_CARD_UNLOCK 0
|
||||
#define SD_CARD_LOCK 0x4
|
||||
#define SD_CARD_CLEAR_PWD 0x2
|
||||
#define SD_CARD_SET_PWD 0x1
|
||||
#define SD_CARD_ERASE_PWD 0x8
|
||||
|
||||
#define SD_CARD_LOCK_STATUS 0x02000000
|
||||
#define SD_CARD_UNLOCK_STATUS 0x01000000
|
||||
|
||||
#define SD_CMD_ERROR_FLAGS (0x18F << 16)
|
||||
#define SD_DATA_ERROR_FLAGS (0x70 << 16)
|
||||
#define SD_AUTO_CMD12_ERROR_FLAGS (0x9F)
|
||||
#define SD_CARD_STATUS_ERROR 0x10000000
|
||||
#define SD_CMD_MISSING 0x80000000
|
||||
|
||||
#define SD_TRAN_HIGH_SPEED 0x32
|
||||
#define SD_CARD_HIGH_CAPACITY 0x40000000
|
||||
#define SD_CARD_POWER_UP_STATUS 0x80000000
|
||||
|
||||
struct sd_dev_info {
|
||||
uint32_t mode; /* interrupt or polling */
|
||||
uint32_t dma; /* dma enabled or disabled */
|
||||
uint32_t voltage; /* voltage level */
|
||||
uint32_t slot; /* if the HC is locatd at slot 0 or slot 1 */
|
||||
uint32_t version; /* 1.0 or 2.0 */
|
||||
uint32_t curSystemAddr; /* system address */
|
||||
uint32_t dataWidth; /* data width for the controller */
|
||||
uint32_t clock; /* clock rate */
|
||||
uint32_t status; /* if device is active on transfer or not */
|
||||
};
|
||||
|
||||
void data_xfer_setup(struct sd_handle *handle, uint8_t *data,
|
||||
uint32_t length, int dir);
|
||||
int reset_card(struct sd_handle *handle);
|
||||
int reset_host_ctrl(struct sd_handle *handle);
|
||||
int init_card(struct sd_handle *handle, int detection);
|
||||
int init_mmc_card(struct sd_handle *handle);
|
||||
int write_buffer(struct sd_handle *handle, uint32_t len, uint8_t *buffer);
|
||||
int read_buffer(struct sd_handle *handle, uint32_t len, uint8_t *buffer);
|
||||
int select_blk_sz(struct sd_handle *handle, uint16_t size);
|
||||
int check_error(struct sd_handle *handle, uint32_t ints);
|
||||
|
||||
int process_data_xfer(struct sd_handle *handle, uint8_t *buffer,
|
||||
uint32_t addr, uint32_t length, int dir);
|
||||
int read_block(struct sd_handle *handle, uint8_t *dst, uint32_t addr,
|
||||
uint32_t len);
|
||||
#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
|
||||
int erase_card(struct sd_handle *handle, uint32_t addr, uint32_t blocks);
|
||||
#endif
|
||||
int write_block(struct sd_handle *handle, uint8_t *src, uint32_t addr,
|
||||
uint32_t len);
|
||||
int process_cmd_response(struct sd_handle *handle, uint32_t cmdIndex,
|
||||
uint32_t rsp0, uint32_t rsp1, uint32_t rsp2,
|
||||
uint32_t rsp3, struct sd_resp *resp);
|
||||
int32_t set_config(struct sd_handle *handle, uint32_t speed,
|
||||
uint32_t retry, uint32_t dma, uint32_t dmaBound,
|
||||
uint32_t blkSize, uint32_t wfe_retry);
|
||||
|
||||
uint32_t wait_for_event(struct sd_handle *handle, uint32_t mask,
|
||||
uint32_t retry);
|
||||
int set_boot_config(struct sd_handle *handle, uint32_t config);
|
||||
|
||||
int mmc_cmd1(struct sd_handle *handle);
|
||||
#endif /* CSL_SD_H */
|
168
include/drivers/brcm/emmc/emmc_csl_sdcmd.h
Normal file
168
include/drivers/brcm/emmc/emmc_csl_sdcmd.h
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CSL_SD_CMD_H
|
||||
#define CSL_SD_CMD_H
|
||||
|
||||
#define SD_CMD_OK 0
|
||||
#define SD_CMD_ERROR -1
|
||||
|
||||
#define SD_CMD_ERR_NO_IO_FUNC 5
|
||||
#define SD_CMD_ERR_INVALID_PARAMETER 6
|
||||
#define SD_CMD_ERR_R1_ILLEGAL_COMMAND 7
|
||||
#define SD_CMD_ERR_R1_COM_CRC_ERROR 8
|
||||
#define SD_CMD_ERR_R1_FUNC_NUM_ERROR 9
|
||||
#define SD_CMD_ERR_R1_ADDRESS_ERROR 10
|
||||
#define SD_CMD_ERR_R1_PARAMETER_ERROR 11
|
||||
#define SD_CMD_ERR_DATA_ERROR_TOKEN 12
|
||||
#define SD_CMD_ERR_DATA_NOT_ACCEPTED 13
|
||||
#define SD_CMD7_ARG_RCA_SHIFT 16
|
||||
|
||||
#define SD_CARD_STATUS_PENDING 0x01
|
||||
#define SD_CARD_STATUS_BUFFER_OVERFLOW 0x01
|
||||
#define SD_CARD_STATUS_DEVICE_BUSY 0x02
|
||||
#define SD_CARD_STATUS_UNSUCCESSFUL 0x03
|
||||
#define SD_CARD_STATUS_NOT_IMPLEMENTED 0x04
|
||||
#define SD_CARD_STATUS_ACCESS_VIOLATION 0x05
|
||||
#define SD_CARD_STATUS_INVALID_HANDLE 0x06
|
||||
#define SD_CARD_STATUS_INVALID_PARAMETER 0x07
|
||||
#define SD_CARD_STATUS_NO_SUCH_DEVICE 0x08
|
||||
#define SD_CARD_STATUS_INVALID_DEVICE_REQUEST 0x09
|
||||
#define SD_CARD_STATUS_NO_MEMORY 0x0A
|
||||
#define SD_CARD_STATUS_BUS_DRIVER_NOT_READY 0x0B
|
||||
#define SD_CARD_STATUS_DATA_ERROR 0x0C
|
||||
#define SD_CARD_STATUS_CRC_ERROR 0x0D
|
||||
#define SD_CARD_STATUS_INSUFFICIENT_RESOURCES 0x0E
|
||||
#define SD_CARD_STATUS_DEVICE_NOT_CONNECTED 0x10
|
||||
#define SD_CARD_STATUS_DEVICE_REMOVED 0x11
|
||||
#define SD_CARD_STATUS_DEVICE_NOT_RESPONDING 0x12
|
||||
#define SD_CARD_STATUS_CANCELED 0x13
|
||||
#define SD_CARD_STATUS_RESPONSE_TIMEOUT 0x14
|
||||
#define SD_CARD_STATUS_DATA_TIMEOUT 0x15
|
||||
#define SD_CARD_STATUS_DEVICE_RESPONSE_ERROR 0x16
|
||||
#define SD_CARD_STATUS_DEVICE_UNSUPPORTED 0x17
|
||||
|
||||
/* Response structure */
|
||||
struct sd_r2_resp {
|
||||
uint32_t rsp4; /* 127:96 */
|
||||
uint32_t rsp3; /* 95:64 */
|
||||
uint32_t rsp2; /* 63:32 */
|
||||
uint32_t rsp1; /* 31:0 */
|
||||
};
|
||||
|
||||
struct sd_r3_resp {
|
||||
uint32_t ocr;
|
||||
};
|
||||
|
||||
struct sd_r4_resp {
|
||||
uint8_t cardReady;
|
||||
uint8_t funcs;
|
||||
uint8_t memPresent;
|
||||
uint32_t ocr;
|
||||
};
|
||||
|
||||
struct sd_r5_resp {
|
||||
uint8_t data;
|
||||
};
|
||||
|
||||
struct sd_r6_resp {
|
||||
uint16_t rca;
|
||||
uint16_t cardStatus;
|
||||
};
|
||||
|
||||
struct sd_r7_resp {
|
||||
uint16_t rca;
|
||||
};
|
||||
|
||||
struct sd_resp {
|
||||
uint8_t r1;
|
||||
uint32_t cardStatus;
|
||||
uint32_t rawData[4];
|
||||
union {
|
||||
struct sd_r2_resp r2;
|
||||
struct sd_r3_resp r3;
|
||||
struct sd_r4_resp r4;
|
||||
struct sd_r5_resp r5;
|
||||
struct sd_r6_resp r6;
|
||||
struct sd_r7_resp r7;
|
||||
} data;
|
||||
};
|
||||
|
||||
struct sd_card_info {
|
||||
uint32_t type; /* card type SD, MMC or SDIO */
|
||||
uint64_t size; /* card size */
|
||||
uint32_t speed; /* card speed */
|
||||
uint32_t voltage; /* voltage supported */
|
||||
uint32_t mId; /* manufacturer ID */
|
||||
uint32_t oId; /* OEM ID */
|
||||
uint32_t classes; /* card class */
|
||||
uint32_t name1; /* product name part 1 */
|
||||
uint32_t name2; /* product name part 2 */
|
||||
uint32_t revision; /* revison */
|
||||
uint32_t sn; /* serial number */
|
||||
uint32_t numIoFuns; /* total I/O function number */
|
||||
uint32_t maxRdBlkLen; /* max read block length */
|
||||
uint32_t maxWtBlkLen; /* max write block length */
|
||||
uint32_t blkMode; /* sdio card block mode support */
|
||||
uint32_t f0Cis; /* sdio card block mode support */
|
||||
uint32_t f1Cis; /* sdio card block mode support */
|
||||
|
||||
uint8_t partRead; /* partial block read allowed */
|
||||
uint8_t partWrite; /* partial block write allowed */
|
||||
uint8_t dsr; /* card DSR */
|
||||
uint8_t rdCurMin; /* min current for read */
|
||||
uint8_t rdCurMax; /* max current for read */
|
||||
uint8_t wtCurMin; /* min current for write */
|
||||
uint8_t wtCurMax; /* max current for write */
|
||||
uint8_t erase; /* erase enable */
|
||||
uint8_t eraseSecSize; /* erase sector size */
|
||||
uint8_t proGrpSize; /* write protection group size */
|
||||
uint8_t protect; /* permanent write protection or not */
|
||||
uint8_t tmpProt; /* temp write protection or not */
|
||||
uint8_t wtSpeed; /* write speed relatively to read */
|
||||
uint8_t version; /* card version 0:1.0 - 1.01, 1:1.10, 2:2.0 */
|
||||
uint8_t eraseState; /* if the data will be 0 or 1 after erase */
|
||||
uint8_t bus; /* data with supported */
|
||||
uint8_t security; /* security support 0, 2:1.01 3:2.0 */
|
||||
uint8_t format; /* file format */
|
||||
uint8_t fileGrp; /* file group */
|
||||
char pwd[20]; /* password */
|
||||
};
|
||||
|
||||
struct sd_handle {
|
||||
struct sd_dev *device;
|
||||
struct sd_card_info *card;
|
||||
};
|
||||
|
||||
int sd_cmd0(struct sd_handle *handle);
|
||||
int sd_cmd1(struct sd_handle *handle, uint32_t initOcr, uint32_t *ocr);
|
||||
int sd_cmd2(struct sd_handle *handle);
|
||||
int sd_cmd3(struct sd_handle *handle);
|
||||
int sd_cmd7(struct sd_handle *handle, uint32_t rca);
|
||||
int sd_cmd9(struct sd_handle *handle, struct sd_card_data *card);
|
||||
int sd_cmd13(struct sd_handle *handle, uint32_t *status);
|
||||
int sd_cmd16(struct sd_handle *handle, uint32_t blockLen);
|
||||
int sd_cmd17(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer);
|
||||
int sd_cmd18(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer);
|
||||
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
|
||||
int sd_cmd24(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer);
|
||||
int sd_cmd25(struct sd_handle *handle,
|
||||
uint32_t addr, uint32_t len, uint8_t *buffer);
|
||||
#endif
|
||||
#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
|
||||
int sd_cmd35(struct sd_handle *handle, uint32_t start);
|
||||
int sd_cmd36(struct sd_handle *handle, uint32_t end);
|
||||
int sd_cmd38(struct sd_handle *handle);
|
||||
#endif
|
||||
int mmc_cmd6(struct sd_handle *handle, uint32_t argument);
|
||||
int mmc_cmd8(struct sd_handle *handle, uint8_t *extCsdReg);
|
||||
|
||||
int send_cmd(struct sd_handle *handle, uint32_t cmdIndex,
|
||||
uint32_t argument, uint32_t options, struct sd_resp *resp);
|
||||
#endif /* CSL_SD_CMD_H */
|
435
include/drivers/brcm/emmc/emmc_csl_sdprot.h
Normal file
435
include/drivers/brcm/emmc/emmc_csl_sdprot.h
Normal file
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef CSL_SD_PROT_H
|
||||
#define CSL_SD_PROT_H
|
||||
|
||||
#define SD_CARD_UNKNOWN 0 /* bad type or unrecognized */
|
||||
#define SD_CARD_SD 1 /* IO only card */
|
||||
#define SD_CARD_SDIO 2 /* memory only card */
|
||||
#define SD_CARD_COMBO 3 /* IO and memory combo card */
|
||||
#define SD_CARD_MMC 4 /* memory only card */
|
||||
#define SD_CARD_CEATA 5 /* IO and memory combo card */
|
||||
|
||||
#define SD_IO_FIXED_ADDRESS 0 /* fix Address */
|
||||
#define SD_IO_INCREMENT_ADDRESS 1
|
||||
|
||||
#define SD_HIGH_CAPACITY_CARD 0x40000000
|
||||
|
||||
#define MMC_CMD_IDLE_RESET_ARG 0xF0F0F0F0
|
||||
|
||||
/* Supported operating voltages are 3.2-3.3 and 3.3-3.4 */
|
||||
#define MMC_OCR_OP_VOLT 0x00300000
|
||||
/* Enable sector access mode */
|
||||
#define MMC_OCR_SECTOR_ACCESS_MODE 0x40000000
|
||||
|
||||
/* command index */
|
||||
#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */
|
||||
#define SD_CMD_SEND_OPCOND 1
|
||||
#define SD_CMD_ALL_SEND_CID 2
|
||||
#define SD_CMD_MMC_SET_RCA 3
|
||||
#define SD_CMD_MMC_SET_DSR 4
|
||||
#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */
|
||||
#define SD_ACMD_SET_BUS_WIDTH 6
|
||||
#define SD_CMD_SWITCH_FUNC 6
|
||||
#define SD_CMD_SELECT_DESELECT_CARD 7
|
||||
#define SD_CMD_READ_EXT_CSD 8
|
||||
#define SD_CMD_SEND_CSD 9
|
||||
#define SD_CMD_SEND_CID 10
|
||||
#define SD_CMD_STOP_TRANSMISSION 12
|
||||
#define SD_CMD_SEND_STATUS 13
|
||||
#define SD_ACMD_SD_STATUS 13
|
||||
#define SD_CMD_GO_INACTIVE_STATE 15
|
||||
#define SD_CMD_SET_BLOCKLEN 16
|
||||
#define SD_CMD_READ_SINGLE_BLOCK 17
|
||||
#define SD_CMD_READ_MULTIPLE_BLOCK 18
|
||||
#define SD_CMD_WRITE_BLOCK 24
|
||||
#define SD_CMD_WRITE_MULTIPLE_BLOCK 25
|
||||
#define SD_CMD_PROGRAM_CSD 27
|
||||
#define SD_CMD_SET_WRITE_PROT 28
|
||||
#define SD_CMD_CLR_WRITE_PROT 29
|
||||
#define SD_CMD_SEND_WRITE_PROT 30
|
||||
#define SD_CMD_ERASE_WR_BLK_START 32
|
||||
#define SD_CMD_ERASE_WR_BLK_END 33
|
||||
#define SD_CMD_ERASE_GROUP_START 35
|
||||
#define SD_CMD_ERASE_GROUP_END 36
|
||||
#define SD_CMD_ERASE 38
|
||||
#define SD_CMD_LOCK_UNLOCK 42
|
||||
#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */
|
||||
#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */
|
||||
#define SD_CMD_APP_CMD 55
|
||||
#define SD_CMD_GEN_CMD 56
|
||||
#define SD_CMD_READ_OCR 58
|
||||
#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */
|
||||
#define SD_ACMD_SEND_NUM_WR_BLOCKS 22
|
||||
#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23
|
||||
#define SD_ACMD_SD_SEND_OP_COND 41
|
||||
#define SD_ACMD_SET_CLR_CARD_DETECT 42
|
||||
#define SD_ACMD_SEND_SCR 51
|
||||
|
||||
/* response parameters */
|
||||
#define SD_RSP_NO_NONE 0
|
||||
#define SD_RSP_NO_1 1
|
||||
#define SD_RSP_NO_2 2
|
||||
#define SD_RSP_NO_3 3
|
||||
#define SD_RSP_NO_4 4
|
||||
#define SD_RSP_NO_5 5
|
||||
#define SD_RSP_NO_6 6
|
||||
|
||||
/* Modified R6 response (to CMD3) */
|
||||
#define SD_RSP_MR6_COM_CRC_ERROR 0x8000
|
||||
#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000
|
||||
#define SD_RSP_MR6_ERROR 0x2000
|
||||
|
||||
/* Modified R1 in R4 Response (to CMD5) */
|
||||
#define SD_RSP_MR1_SBIT 0x80
|
||||
#define SD_RSP_MR1_PARAMETER_ERROR 0x40
|
||||
#define SD_RSP_MR1_RFU5 0x20
|
||||
#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10
|
||||
#define SD_RSP_MR1_COM_CRC_ERROR 0x80
|
||||
#define SD_RSP_MR1_ILLEGAL_COMMAND 0x40
|
||||
#define SD_RSP_MR1_RFU1 0x20
|
||||
#define SD_RSP_MR1_IDLE_STATE 0x01
|
||||
|
||||
/* R5 response (to CMD52 and CMD53) */
|
||||
#define SD_RSP_R5_COM_CRC_ERROR 0x80
|
||||
#define SD_RSP_R5_ILLEGAL_COMMAND 0x40
|
||||
#define SD_RSP_R5_IO_CURRENTSTATE1 0x20
|
||||
#define SD_RSP_R5_IO_CURRENTSTATE0 0x10
|
||||
#define SD_RSP_R5_ERROR 0x80
|
||||
#define SD_RSP_R5_RFU 0x40
|
||||
#define SD_RSP_R5_FUNC_NUM_ERROR 0x20
|
||||
#define SD_RSP_R5_OUT_OF_RANGE 0x01
|
||||
|
||||
/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */
|
||||
#define SD_OP_READ 0 /* Read_Write */
|
||||
#define SD_OP_WRITE 1 /* Read_Write */
|
||||
|
||||
#define SD_RW_NORMAL 0 /* no RAW */
|
||||
#define SD_RW_RAW 1 /* RAW */
|
||||
|
||||
#define SD_BYTE_MODE 0 /* Byte Mode */
|
||||
#define SD_BLOCK_MODE 1 /* BlockMode */
|
||||
|
||||
#define SD_FIXED_ADDRESS 0 /* fix Address */
|
||||
#define SD_INCREMENT_ADDRESS 1 /* IncrementAddress */
|
||||
|
||||
#define SD_CMD5_ARG_IO_OCR_MASK 0x00FFFFFF
|
||||
#define SD_CMD5_ARG_IO_OCR_SHIFT 0
|
||||
#define SD_CMD55_ARG_RCA_SHIFT 16
|
||||
#define SD_CMD59_ARG_CRC_OPTION_MASK 0x01
|
||||
#define SD_CMD59_ARG_CRC_OPTION_SHIFT 0
|
||||
|
||||
/* SD_CMD_IO_RW_DIRECT Argument */
|
||||
#define SdioIoRWDirectArg(rw, raw, func, addr, data) \
|
||||
(((rw & 1) << 31) | ((func & 0x7) << 28) | \
|
||||
((raw & 1) << 27) | ((addr & 0x1FFFF) << 9) | \
|
||||
(data & 0xFF))
|
||||
|
||||
/* build SD_CMD_IO_RW_EXTENDED Argument */
|
||||
#define SdioIoRWExtArg(rw, blk, func, addr, inc_addr, count) \
|
||||
(((rw & 1) << 31) | ((func & 0x7) << 28) | \
|
||||
((blk & 1) << 27) | ((inc_addr & 1) << 26) | \
|
||||
((addr & 0x1FFFF) << 9) | (count & 0x1FF))
|
||||
|
||||
/*
|
||||
* The Common I/O area shall be implemented on all SDIO cards and
|
||||
* is accessed the the host via I/O reads and writes to function 0,
|
||||
* the registers within the CIA are provided to enable/disable
|
||||
* the operationo fthe i/o funciton.
|
||||
*/
|
||||
|
||||
/* cccr_sdio_rev */
|
||||
#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */
|
||||
#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */
|
||||
|
||||
/* sd_rev */
|
||||
#define SDIO_REV_PHY_MASK 0x0f /* SD format version number */
|
||||
#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */
|
||||
#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */
|
||||
#define SDIO_INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */
|
||||
#define SDIO_INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */
|
||||
#define SDIO_INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */
|
||||
#define SDIO_IO_ABORT_RESET_ALL 0x08 /* I/O card reset */
|
||||
#define SDIO_IO_ABORT_FUNC_MASK 0x07 /* abort selection: function x */
|
||||
#define SDIO_BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */
|
||||
#define SDIO_BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */
|
||||
#define SDIO_BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */
|
||||
#define SDIO_BUS_DATA_WIDTH_MASK 0x03 /* bus width mask */
|
||||
#define SDIO_BUS_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */
|
||||
#define SDIO_BUS_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */
|
||||
|
||||
/* capability */
|
||||
#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */
|
||||
#define SDIO_CAP_LSC 0x40 /* low speed card */
|
||||
#define SDIO_CAP_E4MI 0x20 /* enable int between block in 4-bit mode */
|
||||
#define SDIO_CAP_S4MI 0x10 /* support int between block in 4-bit mode */
|
||||
#define SDIO_CAP_SBS 0x08 /* support suspend/resume */
|
||||
#define SDIO_CAP_SRW 0x04 /* support read wait */
|
||||
#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */
|
||||
#define SDIO_CAP_SDC 0x01 /* Support Direct cmd during multi-uint8 transfer */
|
||||
|
||||
/* CIA FBR1 registers */
|
||||
#define SDIO_FUNC1_INFO 0x100 /* basic info for function 1 */
|
||||
#define SDIO_FUNC1_EXT 0x101 /* extension of standard I/O device */
|
||||
#define SDIO_CIS_FUNC1_BASE_LOW 0x109 /* function 1 cis address bit 0-7 */
|
||||
#define SDIO_CIS_FUNC1_BASE_MID 0x10A /* function 1 cis address bit 8-15 */
|
||||
#define SDIO_CIS_FUNC1_BASE_HIGH 0x10B /* function 1 cis address bit 16 */
|
||||
#define SDIO_CSA_BASE_LOW 0x10C /* CSA base address uint8_t 0 */
|
||||
#define SDIO_CSA_BASE_MID 0x10D /* CSA base address uint8_t 1 */
|
||||
#define SDIO_CSA_BASE_HIGH 0x10E /* CSA base address uint8_t 2 */
|
||||
#define SDIO_CSA_DATA_OFFSET 0x10F /* CSA data register */
|
||||
#define SDIO_IO_BLK_SIZE_LOW 0x110 /* I/O block size uint8_t 0 */
|
||||
#define SDIO_IO_BLK_SIZE_HIGH 0x111 /* I/O block size uint8_t 1 */
|
||||
|
||||
/* SD_SDIO_FUNC1_INFO bits */
|
||||
#define SDIO_FUNC1_INFO_DIC 0x0f /* device interface code */
|
||||
#define SDIO_FUNC1_INFO_CSA 0x40 /* CSA support flag */
|
||||
#define SDIO_FUNC1_INFO_CSA_EN 0x80 /* CSA enabled */
|
||||
|
||||
/* SD_SDIO_FUNC1_EXT bits */
|
||||
#define SDIO_FUNC1_EXT_SHP 0x03 /* support high power */
|
||||
#define SDIO_FUNC1_EXT_EHP 0x04 /* enable high power */
|
||||
|
||||
/* devctr */
|
||||
/* I/O device interface code */
|
||||
#define SDIO_DEVCTR_DEVINTER 0x0f
|
||||
/* support CSA */
|
||||
#define SDIO_DEVCTR_CSA_SUP 0x40
|
||||
/* enable CSA */
|
||||
#define SDIO_DEVCTR_CSA_EN 0x80
|
||||
|
||||
/* ext_dev */
|
||||
/* supports high-power mask */
|
||||
#define SDIO_HIGHPWR_SUPPORT_M 0x3
|
||||
/* enable high power */
|
||||
#define SDIO_HIGHPWR_EN 0x4
|
||||
/* standard power function(up to 200mA */
|
||||
#define SDIO_HP_STD 0
|
||||
/* need high power to operate */
|
||||
#define SDIO_HP_REQUIRED 0x2
|
||||
/* can work with standard power, but prefer high power */
|
||||
#define SDIO_HP_DESIRED 0x3
|
||||
|
||||
/* misc define */
|
||||
/* macro to calculate fbr register base */
|
||||
#define FBR_REG_BASE(n) (n*0x100)
|
||||
#define SDIO_FUNC_0 0
|
||||
#define SDIO_FUNC_1 1
|
||||
#define SDIO_FUNC_2 2
|
||||
#define SDIO_FUNC_3 3
|
||||
#define SDIO_FUNC_4 4
|
||||
#define SDIO_FUNC_5 5
|
||||
#define SDIO_FUNC_6 6
|
||||
#define SDIO_FUNC_7 7
|
||||
|
||||
/* maximum block size for block mode operation */
|
||||
#define SDIO_MAX_BLOCK_SIZE 2048
|
||||
/* minimum block size for block mode operation */
|
||||
#define SDIO_MIN_BLOCK_SIZE 1
|
||||
|
||||
/* Card registers: status bit position */
|
||||
#define SDIO_STATUS_OUTOFRANGE 31
|
||||
#define SDIO_STATUS_COMCRCERROR 23
|
||||
#define SDIO_STATUS_ILLEGALCOMMAND 22
|
||||
#define SDIO_STATUS_ERROR 19
|
||||
#define SDIO_STATUS_IOCURRENTSTATE3 12
|
||||
#define SDIO_STATUS_IOCURRENTSTATE2 11
|
||||
#define SDIO_STATUS_IOCURRENTSTATE1 10
|
||||
#define SDIO_STATUS_IOCURRENTSTATE0 9
|
||||
#define SDIO_STATUS_FUN_NUM_ERROR 4
|
||||
|
||||
#define GET_SDIOCARD_STATUS(x) ((x >> 9) & 0x0f)
|
||||
#define SDIO_STATUS_STATE_IDLE 0
|
||||
#define SDIO_STATUS_STATE_READY 1
|
||||
#define SDIO_STATUS_STATE_IDENT 2
|
||||
#define SDIO_STATUS_STATE_STBY 3
|
||||
#define SDIO_STATUS_STATE_TRAN 4
|
||||
#define SDIO_STATUS_STATE_DATA 5
|
||||
#define SDIO_STATUS_STATE_RCV 6
|
||||
#define SDIO_STATUS_STATE_PRG 7
|
||||
#define SDIO_STATUS_STATE_DIS 8
|
||||
|
||||
/* sprom */
|
||||
#define SBSDIO_SPROM_CS 0x10000 /* command and status */
|
||||
#define SBSDIO_SPROM_INFO 0x10001 /* info register */
|
||||
#define SBSDIO_SPROM_DATA_LOW 0x10002 /* indirect access data uint8_t 0 */
|
||||
#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* indirect access data uint8_t 1 */
|
||||
#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* indirect access addr uint8_t 0 */
|
||||
#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* indirect access addr uint8_t 0 */
|
||||
#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu data output */
|
||||
#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu enable */
|
||||
#define SBSDIO_WATERMARK 0x10008 /* retired in rev 7 */
|
||||
#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */
|
||||
|
||||
#define SBSDIO_SPROM_IDLE 0
|
||||
#define SBSDIO_SPROM_WRITE 1
|
||||
#define SBSDIO_SPROM_READ 2
|
||||
#define SBSDIO_SPROM_WEN 4
|
||||
#define SBSDIO_SPROM_WDS 7
|
||||
#define SBSDIO_SPROM_DONE 8
|
||||
|
||||
/* SBSDIO_SPROM_INFO */
|
||||
#define SBSDIO_SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */
|
||||
#define SBSDIO_SROM_BLANK 0x04 /* depreciated in corerev 6 */
|
||||
#define SBSDIO_SROM_OTP 0x80 /* OTP present */
|
||||
|
||||
/* SBSDIO_CHIP_CTRL */
|
||||
/* or'd with onchip xtal_pu, 1: power on oscillator */
|
||||
#define SBSDIO_CHIP_CTRL_XTAL 0x01
|
||||
|
||||
/* SBSDIO_WATERMARK */
|
||||
/* number of bytes minus 1 for sd device to wait before sending data to host */
|
||||
#define SBSDIO_WATERMARK_MASK 0x3f
|
||||
|
||||
/* SBSDIO_DEVICE_CTL */
|
||||
/* 1: device will assert busy signal when receiving CMD53 */
|
||||
#define SBSDIO_DEVCTL_SETBUSY 0x01
|
||||
/* 1: assertion of sdio interrupt is synchronous to the sdio clock */
|
||||
#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02
|
||||
|
||||
/* function 1 OCP space */
|
||||
/* sb offset addr is <= 15 bits, 32k */
|
||||
#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF
|
||||
#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
|
||||
/* sdsdio function 1 OCP space has 16/32 bit section */
|
||||
#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000
|
||||
|
||||
/* direct(mapped) cis space */
|
||||
/* MAPPED common CIS address */
|
||||
#define SBSDIO_CIS_BASE_COMMON 0x1000
|
||||
/* function 0(common) cis size in bytes */
|
||||
#define SBSDIO_CIS_FUNC0_LIMIT 0x020
|
||||
/* funciton 1 cis size in bytes */
|
||||
#define SBSDIO_CIS_SIZE_LIMIT 0x200
|
||||
/* cis offset addr is < 17 bits */
|
||||
#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF
|
||||
/* manfid tuple length, include tuple, link bytes */
|
||||
#define SBSDIO_CIS_MANFID_TUPLE_LEN 6
|
||||
|
||||
/* indirect cis access (in sprom) */
|
||||
/* 8 control bytes first, CIS starts from 8th uint8_t */
|
||||
#define SBSDIO_SPROM_CIS_OFFSET 0x8
|
||||
/* sdio uint8_t mode: maximum length of one data comamnd */
|
||||
#define SBSDIO_BYTEMODE_DATALEN_MAX 64
|
||||
/* 4317 supports less */
|
||||
#define SBSDIO_BYTEMODE_DATALEN_MAX_4317 52
|
||||
/* sdio core function one address mask */
|
||||
#define SBSDIO_CORE_ADDR_MASK 0x1FFFF
|
||||
|
||||
/* CEATA defines */
|
||||
#define CEATA_EXT_CSDBLOCK_SIZE 512
|
||||
#define CEATA_FAST_IO 39
|
||||
#define CEATA_MULTIPLE_REGISTER_RW 60
|
||||
#define CEATA_MULTIPLE_BLOCK_RW 61
|
||||
|
||||
/* defines CE ATA task file registers */
|
||||
#define CEATA_SCT_CNT_EXP_REG 0x02
|
||||
#define CEATA_LBA_LOW_EXP_REG 0x03
|
||||
#define CEATA_LBA_MID_EXP_REG 0x04
|
||||
#define CEATA_LBA_HIGH_EXP_REG 0x05
|
||||
#define CEATA_CNTRL_REG 0x06
|
||||
#define CEATA_FEATURE_REG 0x09 /* write */
|
||||
#define CEATA_ERROR_REG 0x09 /* read */
|
||||
#define CEATA_SCT_CNT_REG 0x0A
|
||||
#define CEATA_LBA_LOW_REG 0x0B
|
||||
#define CEATA_LBA_MID_REG 0x0C
|
||||
#define CEATA_LBA_HIGH_REG 0x0D
|
||||
#define CEATA_DEV_HEAD_REG 0x0E
|
||||
#define CEATA_STA_REG 0x0F /* read */
|
||||
#define CEATA_CMD_REG 0x0F /* write */
|
||||
|
||||
/* defines CEATA control and status registers for ce ata client driver */
|
||||
#define CEATA_SCR_TEMPC_REG 0x80
|
||||
#define CEATA_SCR_TEMPMAXP_REG 0x84
|
||||
#define CEATA_TEMPMINP_REG 0x88
|
||||
#define CEATA_SCR_STATUS_REG 0x8C
|
||||
#define CEATA_SCR_REALLOCSA_REG 0x90
|
||||
#define CEATA_SCR_ERETRACTSA_REG 0x94
|
||||
#define CEATA_SCR_CAPABILITIES_REG 0x98
|
||||
#define CEATA_SCR_CONTROL_REG 0xC0
|
||||
|
||||
/* defines for SCR capabilities register bits for ce ata client driver */
|
||||
#define CEATA_SCR_CAP_512 0x00000001
|
||||
#define CEATA_SCR_CAP_1K 0x00000002
|
||||
#define CEATA_SCR_CAP_4K 0x00000004
|
||||
|
||||
/* defines CE ATA Control reg bits for ce ata client driver */
|
||||
#define CEATA_CNTRL_ENABLE_INTR 0x00
|
||||
#define CEATA_CNTRL_DISABLE_INTR 0x02
|
||||
#define CEATA_CNTRL_SRST 0x04
|
||||
#define CEATA_CNTRL_RSRST 0x00
|
||||
|
||||
/* define CE ATA Status reg bits for ce ata client driver */
|
||||
#define CEATA_STA_ERROR_BIT 0x01
|
||||
#define CEATA_STA_OVR_BIT 0x02
|
||||
#define CEATA_STA_SPT_BIT 0x04
|
||||
#define CEATA_STA_DRQ_BIT 0x08
|
||||
#define CEATA_STA_DRDY_BIT 0x40
|
||||
#define CEATA_STA_BSY_BIT 0x80
|
||||
|
||||
/* define CE ATA Error reg bits for ce ata client driver */
|
||||
#define CEATA_ERROR_ABORTED_BIT 0x04
|
||||
#define CEATA_ERROR_IDNF_BIT 0x10
|
||||
#define CEATA_ERROR_UNCORRECTABLE_BIT 0x40
|
||||
#define CEATA_ERROR_ICRC_BIT 0x80
|
||||
|
||||
/* define CE ATA Commands for ce ata client driver */
|
||||
#define CEATA_CMD_IDENTIFY_DEVICE 0xEC
|
||||
#define CEATA_CMD_READ_DMA_EXT 0x25
|
||||
#define CEATA_CMD_WRITE_DMA_EXT 0x35
|
||||
#define CEATA_CMD_STANDBY_IMMEDIATE 0xE0
|
||||
#define CEATA_CMD_FLUSH_CACHE_EXT 0xEA
|
||||
|
||||
struct csd_mmc {
|
||||
uint32_t padding:8;
|
||||
uint32_t structure:2;
|
||||
uint32_t csdSpecVer:4;
|
||||
uint32_t reserved1:2;
|
||||
uint32_t taac:8;
|
||||
uint32_t nsac:8;
|
||||
uint32_t speed:8;
|
||||
uint32_t classes:12;
|
||||
uint32_t rdBlkLen:4;
|
||||
uint32_t rdBlkPartial:1;
|
||||
uint32_t wrBlkMisalign:1;
|
||||
uint32_t rdBlkMisalign:1;
|
||||
uint32_t dsr:1;
|
||||
uint32_t reserved2:2;
|
||||
uint32_t size:12;
|
||||
uint32_t vddRdCurrMin:3;
|
||||
uint32_t vddRdCurrMax:3;
|
||||
uint32_t vddWrCurrMin:3;
|
||||
uint32_t vddWrCurrMax:3;
|
||||
uint32_t devSizeMulti:3;
|
||||
uint32_t eraseGrpSize:5;
|
||||
uint32_t eraseGrpSizeMulti:5;
|
||||
uint32_t wrProtGroupSize:5;
|
||||
uint32_t wrProtGroupEnable:1;
|
||||
uint32_t manuDefEcc:2;
|
||||
uint32_t wrSpeedFactor:3;
|
||||
uint32_t wrBlkLen:4;
|
||||
uint32_t wrBlkPartial:1;
|
||||
uint32_t reserved5:4;
|
||||
uint32_t protAppl:1;
|
||||
uint32_t fileFormatGrp:1;
|
||||
uint32_t copyFlag:1;
|
||||
uint32_t permWrProt:1;
|
||||
uint32_t tmpWrProt:1;
|
||||
uint32_t fileFormat:2;
|
||||
uint32_t eccCode:2;
|
||||
};
|
||||
|
||||
/* CSD register*/
|
||||
union sd_csd {
|
||||
uint32_t csd[4];
|
||||
struct csd_mmc mmc;
|
||||
};
|
||||
|
||||
struct sd_card_data {
|
||||
union sd_csd csd;
|
||||
};
|
||||
#endif /* CSL_SD_PROT_H */
|
94
include/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.h
Normal file
94
include/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PBOOT_HAL_MEMORY_EMMC_DRV_H
|
||||
#define PBOOT_HAL_MEMORY_EMMC_DRV_H
|
||||
|
||||
#include <drivers/delay_timer.h>
|
||||
|
||||
#include "emmc_chal_types.h"
|
||||
#include "emmc_chal_sd.h"
|
||||
#include "emmc_csl_sdprot.h"
|
||||
#include "emmc_csl_sdcmd.h"
|
||||
#include "emmc_csl_sd.h"
|
||||
#include "emmc_brcm_rdb_sd4_top.h"
|
||||
|
||||
#define CLK_SDIO_DIV_52MHZ 0x0
|
||||
#define SYSCFG_IOCR4_PAD_10MA 0x38000000
|
||||
|
||||
#define SDCLK_CNT_PER_MS 52000
|
||||
#define BOOT_ACK_TIMEOUT (50 * SDCLK_CNT_PER_MS)
|
||||
#define BOOT_DATA_TIMEOUT (1000 * SDCLK_CNT_PER_MS)
|
||||
|
||||
#define EMMC_BOOT_OK 0
|
||||
#define EMMC_BOOT_ERROR 1
|
||||
#define EMMC_BOOT_TIMEOUT 2
|
||||
#define EMMC_BOOT_INVALIDIMAGE 3
|
||||
#define EMMC_BOOT_NO_CARD 4
|
||||
|
||||
#define EMMC_USER_AREA 0
|
||||
#define EMMC_BOOT_PARTITION1 1
|
||||
#define EMMC_BOOT_PARTITION2 2
|
||||
#define EMMC_USE_CURRENT_PARTITION 3
|
||||
|
||||
#define EMMC_BOOT_PARTITION_SIZE (128*1024)
|
||||
#define EMMC_BLOCK_SIZE 512
|
||||
#define EMMC_DMA_SIZE (4*1024)
|
||||
|
||||
/*
|
||||
* EMMC4.3 definitions
|
||||
* Table 6 EXT_CSD access mode
|
||||
* Access
|
||||
* Bits Access Name Operation
|
||||
* 00 Command Set The command set is changed according to the Cmd Set field of
|
||||
* the argument
|
||||
* 01 Set Bits The bits in the pointed uint8_t are set,
|
||||
* according to the 1 bits in the Value field.
|
||||
* 10 Clear Bits The bits in the pointed uint8_t are cleared,
|
||||
* according to the 1 bits in the Value field.
|
||||
* 11 Write Byte The Value field is written into the pointed uint8_t.
|
||||
*/
|
||||
|
||||
#define SDIO_HW_EMMC_EXT_CSD_WRITE_BYTE 0X03000000
|
||||
|
||||
/* Boot bus width1 BOOT_BUS_WIDTH 1 R/W [177] */
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_BUS_WIDTH_OFFSET 0X00B10000
|
||||
|
||||
/* Boot configuration BOOT_CONFIG 1 R/W [179] */
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_CONFIG_OFFSET 0X00B30000
|
||||
|
||||
/* Bus width mode BUS_WIDTH 1 WO [183] */
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BUS_WIDTH_OFFSET 0X00B70000
|
||||
|
||||
/*
|
||||
* Bit 6: BOOT_ACK (non-volatile)
|
||||
* 0x0 : No boot acknowledge sent (default)
|
||||
* 0x1 : Boot acknowledge sent during boot operation
|
||||
* Bit[5:3] : BOOT_PARTITION_ENABLE (non-volatile)
|
||||
* User selects boot data that will be sent to master
|
||||
* 0x0 : Device not boot enabled (default)
|
||||
* 0x1 : Boot partition 1 enabled for boot
|
||||
* 0x2 : Boot partition 2 enabled for boot
|
||||
* 0x3-0x6 : Reserved
|
||||
* 0x7 : User area enabled for boot
|
||||
* Bit[2:0] : BOOT_PARTITION_ACCESS
|
||||
* User selects boot partition for read and write operation
|
||||
* 0x0 : No access to boot partition (default)
|
||||
* 0x1 : R/W boot partition 1
|
||||
* 0x2 : R/W boot partition 2
|
||||
* 0x3-0x7 : Reserved
|
||||
*/
|
||||
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT1 0X00000100
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT2 0X00000200
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_USER 0X00000000
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_EN_BOOT1 0X00004800
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_EN_BOOT2 0X00005000
|
||||
#define SDIO_HW_EMMC_EXT_CSD_BOOT_EN_USER 0X00007800
|
||||
|
||||
#define SD_US_DELAY(x) udelay(x)
|
||||
|
||||
#endif
|
|
@ -28,6 +28,10 @@ SYSCNT_FREQ := $(GENTIMER_ACTUAL_CLOCK)
|
|||
$(eval $(call add_define,SYSCNT_FREQ))
|
||||
endif
|
||||
|
||||
ifeq (${DRIVER_EMMC_ENABLE},)
|
||||
DRIVER_EMMC_ENABLE :=1
|
||||
endif
|
||||
|
||||
# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
|
||||
ifeq (${BRCM_DISABLE_TRUSTED_WDOG},)
|
||||
BRCM_DISABLE_TRUSTED_WDOG := 0
|
||||
|
@ -89,6 +93,14 @@ ifneq (${USE_CRMU_SRAM},)
|
|||
$(eval $(call add_define,USE_CRMU_SRAM))
|
||||
endif
|
||||
|
||||
# Use PIO mode if DDR is not used
|
||||
ifeq (${USE_DDR},yes)
|
||||
EMMC_USE_DMA := 1
|
||||
else
|
||||
EMMC_USE_DMA := 0
|
||||
endif
|
||||
$(eval $(call add_define,EMMC_USE_DMA))
|
||||
|
||||
# On BRCM platforms, separate the code and read-only data sections to allow
|
||||
# mapping the former as executable and the latter as execute-never.
|
||||
SEPARATE_CODE_AND_RODATA := 1
|
||||
|
@ -97,7 +109,8 @@ SEPARATE_CODE_AND_RODATA := 1
|
|||
USE_TBBR_DEFS := 1
|
||||
|
||||
PLAT_INCLUDES += -Iplat/brcm/board/common \
|
||||
-Iinclude/drivers/brcm
|
||||
-Iinclude/drivers/brcm \
|
||||
-Iinclude/drivers/brcm/emmc
|
||||
|
||||
PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \
|
||||
plat/brcm/board/common/cmn_sec.c \
|
||||
|
@ -116,6 +129,22 @@ PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \
|
|||
plat/brcm/board/common/sbl_util.c \
|
||||
drivers/arm/sp805/sp805.c
|
||||
|
||||
# Add eMMC driver
|
||||
ifeq (${DRIVER_EMMC_ENABLE},1)
|
||||
$(eval $(call add_define,DRIVER_EMMC_ENABLE))
|
||||
|
||||
EMMC_SOURCES += drivers/brcm/emmc/emmc_chal_sd.c \
|
||||
drivers/brcm/emmc/emmc_csl_sdcard.c \
|
||||
drivers/brcm/emmc/emmc_csl_sdcmd.c \
|
||||
drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
|
||||
|
||||
PLAT_BL_COMMON_SOURCES += ${EMMC_SOURCES}
|
||||
|
||||
ifeq (${DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT},)
|
||||
$(eval $(call add_define,DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT))
|
||||
endif
|
||||
endif
|
||||
|
||||
BL2_SOURCES += plat/brcm/common/brcm_bl2_mem_params_desc.c \
|
||||
plat/brcm/common/brcm_image_load.c \
|
||||
common/desc_image_load.c
|
||||
|
|
109
plat/brcm/board/stingray/driver/plat_emmc.c
Normal file
109
plat/brcm/board/stingray/driver/plat_emmc.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2016 - 2020, Broadcom
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#define ICFG_IPROC_IOPAD_CTRL_4 (IPROC_ROOT + 0x9c0)
|
||||
#define ICFG_IPROC_IOPAD_CTRL_5 (IPROC_ROOT + 0x9c4)
|
||||
#define ICFG_IPROC_IOPAD_CTRL_6 (IPROC_ROOT + 0x9c8)
|
||||
#define ICFG_IPROC_IOPAD_CTRL_7 (IPROC_ROOT + 0x9cc)
|
||||
|
||||
#define IOPAD_CTRL4_SDIO0_CD_IND_R 30
|
||||
#define IOPAD_CTRL4_SDIO0_CD_SRC_R 31
|
||||
#define IOPAD_CTRL4_SDIO0_CD_HYS_R 29
|
||||
#define IOPAD_CTRL4_SDIO0_CD_PULL_R 28
|
||||
#define IOPAD_CTRL4_SDIO0_CD_DRIVE_R 24
|
||||
#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R 23
|
||||
#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R 21
|
||||
#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R 17
|
||||
|
||||
#define IOPAD_CTRL4_SDIO0_DATA0_SRC_R 15
|
||||
#define IOPAD_CTRL4_SDIO0_DATA0_HYS_R 13
|
||||
#define IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R 9
|
||||
#define IOPAD_CTRL4_SDIO0_DATA1_SRC_R 7
|
||||
#define IOPAD_CTRL4_SDIO0_DATA1_HYS_R 5
|
||||
#define IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R 1
|
||||
|
||||
#define IOPAD_CTRL5_SDIO0_DATA2_SRC_R 31
|
||||
#define IOPAD_CTRL5_SDIO0_DATA2_HYS_R 29
|
||||
#define IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R 25
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_SRC_R 23
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_IND_R 22
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_HYS_R 21
|
||||
#define IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R 17
|
||||
#define IOPAD_CTRL5_SDIO0_DATA4_SRC_R 15
|
||||
#define IOPAD_CTRL5_SDIO0_DATA4_HYS_R 13
|
||||
#define IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R 9
|
||||
#define IOPAD_CTRL5_SDIO0_DATA5_SRC_R 7
|
||||
#define IOPAD_CTRL5_SDIO0_DATA5_HYS_R 5
|
||||
#define IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R 1
|
||||
|
||||
#define IOPAD_CTRL6_SDIO0_DATA6_SRC_R 31
|
||||
#define IOPAD_CTRL6_SDIO0_DATA6_HYS_R 29
|
||||
#define IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R 25
|
||||
#define IOPAD_CTRL6_SDIO0_DATA7_SRC_R 23
|
||||
#define IOPAD_CTRL6_SDIO0_DATA7_HYS_R 21
|
||||
#define IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R 17
|
||||
|
||||
void emmc_soft_reset(void)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
val = (BIT(IOPAD_CTRL6_SDIO0_DATA7_SRC_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA7_HYS_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA6_SRC_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA6_HYS_R) |
|
||||
BIT(IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R));
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
|
||||
|
||||
val = (BIT(IOPAD_CTRL5_SDIO0_DATA3_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA3_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA4_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA4_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA5_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA5_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R));
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_5, val);
|
||||
|
||||
val = (BIT(IOPAD_CTRL4_SDIO0_DATA0_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA0_HYS_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA1_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA1_HYS_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA2_SRC_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA2_HYS_R) |
|
||||
BIT(IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R));
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
|
||||
|
||||
val = (BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CD_SRC_R) |
|
||||
BIT(IOPAD_CTRL4_SDIO0_CD_HYS_R));
|
||||
|
||||
/*
|
||||
* set pull-down, clear pull-up=0
|
||||
* bit 12: pull-down bit 11: pull-up
|
||||
* Note: In emulation, this pull-down setting was not
|
||||
* sufficient. Board design likely requires pull down on
|
||||
* this pin for eMMC.
|
||||
*/
|
||||
|
||||
val |= BIT(IOPAD_CTRL4_SDIO0_CD_PULL_R);
|
||||
|
||||
mmio_write_32(ICFG_IPROC_IOPAD_CTRL_4, val);
|
||||
}
|
|
@ -24,6 +24,13 @@ ERRATA_A72_859971 := 1
|
|||
DRIVER_CC_ENABLE := 1
|
||||
$(eval $(call add_define,DRIVER_CC_ENABLE))
|
||||
|
||||
# Enable to erase eMMC
|
||||
INCLUDE_EMMC_DRIVER_ERASE_CODE := 0
|
||||
|
||||
ifeq (${INCLUDE_EMMC_DRIVER_ERASE_CODE},1)
|
||||
$(eval $(call add_define,INCLUDE_EMMC_DRIVER_ERASE_CODE))
|
||||
endif
|
||||
|
||||
# BL31 is in DRAM
|
||||
ARM_BL31_IN_DRAM := 1
|
||||
|
||||
|
@ -178,6 +185,7 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \
|
|||
drivers/ti/uart/aarch64/16550_console.S \
|
||||
plat/${SOC_DIR}/src/tz_sec.c \
|
||||
drivers/arm/tzc/tzc400.c \
|
||||
plat/${SOC_DIR}/driver/plat_emmc.c \
|
||||
plat/${SOC_DIR}/src/topology.c
|
||||
|
||||
ifeq (${USE_CHIMP},yes)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <chip_id.h>
|
||||
#include <cmn_plat_util.h>
|
||||
#include <dmu.h>
|
||||
#include <emmc_api.h>
|
||||
#include <fru.h>
|
||||
#ifdef USE_GPIO
|
||||
#include <drivers/gpio.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue