Commit bffde63d authored by Sheetal Tigadoli's avatar Sheetal Tigadoli
Browse files

drivers: Add emmc driver for Broadcom platforms


Add emmc driver for Broadcom platforms

Change-Id: I126a6dfccd41062cb0b856f2c2fb1f724730b95e
Signed-off-by: default avatarSheetal Tigadoli <sheetal.tigadoli@broadcom.com>
Showing with 5997 additions and 1 deletion
+5997 -1
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* 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;
}
/*
* 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 */
/*
* 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 */
This diff is collapsed.
This diff is collapsed.
/*
* 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_ */
/*
* 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 */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment