GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,172 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights
* reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stddef.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include "rom_api.h"
typedef int32_t(*secure_boot_api_f) (uint32_t a, uint32_t b, void *c);
extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert_addr);
#define RCAR_IMAGE_ID_MAX (10)
#define RCAR_CERT_MAGIC_NUM (0xE291F358U)
#define RCAR_BOOT_KEY_CERT (0xE6300C00U)
#define RCAR_BOOT_KEY_CERT_NEW (0xE6300F00U)
#define RST_BASE (0xE6160000U)
#define RST_MODEMR (RST_BASE + 0x0060U)
#define MFISOFTMDR (0xE6260600U)
#define MODEMR_MD5_MASK (0x00000020U)
#define MODEMR_MD5_SHIFT (5U)
#define SOFTMD_BOOTMODE_MASK (0x00000001U)
#define SOFTMD_NORMALBOOT (0x1U)
static secure_boot_api_f secure_boot_api;
int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id)
{
return 1;
}
int auth_mod_verify_img(unsigned int img_id, void *ptr, unsigned int len)
{
int32_t ret = 0, index = 0;
uint32_t cert_addr = 0U;
static const struct img_to_cert_t {
uint32_t id;
int32_t cert;
const char *name;
} image[RCAR_IMAGE_ID_MAX] = {
{ BL31_IMAGE_ID, SOC_FW_CONTENT_CERT_ID, "BL31" },
{ BL32_IMAGE_ID, TRUSTED_OS_FW_CONTENT_CERT_ID, "BL32" },
{ BL33_IMAGE_ID, NON_TRUSTED_FW_CONTENT_CERT_ID, "BL33" },
{ BL332_IMAGE_ID, BL332_CERT_ID, "BL332" },
{ BL333_IMAGE_ID, BL333_CERT_ID, "BL333" },
{ BL334_IMAGE_ID, BL334_CERT_ID, "BL334" },
{ BL335_IMAGE_ID, BL335_CERT_ID, "BL335" },
{ BL336_IMAGE_ID, BL336_CERT_ID, "BL336" },
{ BL337_IMAGE_ID, BL337_CERT_ID, "BL337" },
{ BL338_IMAGE_ID, BL338_CERT_ID, "BL338" },
};
#if IMAGE_BL2
switch (img_id) {
case TRUSTED_KEY_CERT_ID:
case SOC_FW_KEY_CERT_ID:
case TRUSTED_OS_FW_KEY_CERT_ID:
case NON_TRUSTED_FW_KEY_CERT_ID:
case BL332_KEY_CERT_ID:
case BL333_KEY_CERT_ID:
case BL334_KEY_CERT_ID:
case BL335_KEY_CERT_ID:
case BL336_KEY_CERT_ID:
case BL337_KEY_CERT_ID:
case BL338_KEY_CERT_ID:
case SOC_FW_CONTENT_CERT_ID:
case TRUSTED_OS_FW_CONTENT_CERT_ID:
case NON_TRUSTED_FW_CONTENT_CERT_ID:
case BL332_CERT_ID:
case BL333_CERT_ID:
case BL334_CERT_ID:
case BL335_CERT_ID:
case BL336_CERT_ID:
case BL337_CERT_ID:
case BL338_CERT_ID:
return ret;
case BL31_IMAGE_ID:
case BL32_IMAGE_ID:
case BL33_IMAGE_ID:
case BL332_IMAGE_ID:
case BL333_IMAGE_ID:
case BL334_IMAGE_ID:
case BL335_IMAGE_ID:
case BL336_IMAGE_ID:
case BL337_IMAGE_ID:
case BL338_IMAGE_ID:
goto verify_image;
default:
return -1;
}
verify_image:
for (index = 0; index < RCAR_IMAGE_ID_MAX; index++) {
if (img_id != image[index].id)
continue;
ret = rcar_get_certificate(image[index].cert, &cert_addr);
break;
}
if (ret || (index == RCAR_IMAGE_ID_MAX)) {
ERROR("Verification Failed for image id = %d\n", img_id);
return ret;
}
#if RCAR_BL2_DCACHE == 1
/* clean and disable */
write_sctlr_el3(read_sctlr_el3() & ~SCTLR_C_BIT);
dcsw_op_all(DCCISW);
#endif
ret = (mmio_read_32(RCAR_BOOT_KEY_CERT_NEW) == RCAR_CERT_MAGIC_NUM) ?
secure_boot_api(RCAR_BOOT_KEY_CERT_NEW, cert_addr, NULL) :
secure_boot_api(RCAR_BOOT_KEY_CERT, cert_addr, NULL);
if (ret)
ERROR("Verification Failed 0x%x, %s\n", ret, image[index].name);
#if RCAR_BL2_DCACHE == 1
/* enable */
write_sctlr_el3(read_sctlr_el3() | SCTLR_C_BIT);
#endif /* RCAR_BL2_DCACHE */
#endif /* IMAGE_BL2 */
return ret;
}
static int32_t normal_boot_verify(uint32_t a, uint32_t b, void *c)
{
return 0;
}
void auth_mod_init(void)
{
#if RCAR_SECURE_BOOT
uint32_t soft_md = mmio_read_32(MFISOFTMDR) & SOFTMD_BOOTMODE_MASK;
uint32_t md = mmio_read_32(RST_MODEMR) & MODEMR_MD5_MASK;
uint32_t lcs, ret;
secure_boot_api = (secure_boot_api_f) &rcar_rom_secure_boot_api;
ret = rcar_rom_get_lcs(&lcs);
if (ret) {
ERROR("BL2: Failed to get the LCS. (%d)\n", ret);
panic();
}
switch (lcs) {
case LCS_SE:
if (soft_md == SOFTMD_NORMALBOOT)
secure_boot_api = &normal_boot_verify;
break;
case LCS_SD:
secure_boot_api = &normal_boot_verify;
break;
default:
if (md >> MODEMR_MD5_SHIFT)
secure_boot_api = &normal_boot_verify;
}
NOTICE("BL2: %s boot\n",
secure_boot_api == &normal_boot_verify ? "Normal" : "Secure");
#else
NOTICE("BL2: Normal boot\n");
secure_boot_api = &normal_boot_verify;
#endif
}
@@ -0,0 +1,630 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
#include "avs_driver.h"
#include "cpg_registers.h"
#include "rcar_def.h"
#include "rcar_private.h"
#if (AVS_SETTING_ENABLE == 1)
#if PMIC_ROHM_BD9571
/* Read PMIC register for debug. 1:enable / 0:disable */
#define AVS_READ_PMIC_REG_ENABLE 0
/* The re-try number of times of the AVS setting. */
#define AVS_RETRY_NUM (1U)
#endif /* PMIC_ROHM_BD9571 */
/* Base address of Adaptive Voltage Scaling module registers*/
#define AVS_BASE (0xE60A0000U)
/* Adaptive Dynamic Voltage ADJust Parameter2 registers */
#define ADVADJP2 (AVS_BASE + 0x013CU)
/* Mask VOLCOND bit in ADVADJP2 registers */
#define ADVADJP2_VOLCOND_MASK (0x000001FFU) /* VOLCOND[8:0] */
#if PMIC_ROHM_BD9571
/* I2C for DVFS bit in CPG registers for module standby and software reset*/
#define CPG_SYS_DVFS_BIT (0x04000000U)
#endif /* PMIC_ROHM_BD9571 */
/* ADVFS Module bit in CPG registers for module standby and software reset*/
#define CPG_SYS_ADVFS_BIT (0x02000000U)
#if PMIC_ROHM_BD9571
/* Base address of IICDVFS registers*/
#define IIC_DVFS_BASE (0xE60B0000U)
/* IIC bus data register */
#define IIC_ICDR (IIC_DVFS_BASE + 0x0000U)
/* IIC bus control register */
#define IIC_ICCR (IIC_DVFS_BASE + 0x0004U)
/* IIC bus status register */
#define IIC_ICSR (IIC_DVFS_BASE + 0x0008U)
/* IIC interrupt control register */
#define IIC_ICIC (IIC_DVFS_BASE + 0x000CU)
/* IIC clock control register low */
#define IIC_ICCL (IIC_DVFS_BASE + 0x0010U)
/* IIC clock control register high */
#define IIC_ICCH (IIC_DVFS_BASE + 0x0014U)
/* Bit in ICSR register */
#define ICSR_BUSY (0x10U)
#define ICSR_AL (0x08U)
#define ICSR_TACK (0x04U)
#define ICSR_WAIT (0x02U)
#define ICSR_DTE (0x01U)
/* Bit in ICIC register */
#define ICIC_TACKE (0x04U)
#define ICIC_WAITE (0x02U)
#define ICIC_DTEE (0x01U)
/* I2C bus interface enable */
#define ICCR_ENABLE (0x80U)
/* Start condition */
#define ICCR_START (0x94U)
/* Stop condition */
#define ICCR_STOP (0x90U)
/* Restart condition with change to receive mode change */
#define ICCR_START_RECV (0x81U)
/* Stop condition for receive mode */
#define ICCR_STOP_RECV (0xC0U)
/* Low-level period of SCL */
#define ICCL_FREQ_8p33M (0x07U) /* for CP Phy 8.3333MHz */
#define ICCL_FREQ_10M (0x09U) /* for CP Phy 10MHz */
#define ICCL_FREQ_12p5M (0x0BU) /* for CP Phy 12.5MHz */
#define ICCL_FREQ_16p66M (0x0EU) /* for CP Phy 16.6666MHz */
/* High-level period of SCL */
#define ICCH_FREQ_8p33M (0x01U) /* for CP Phy 8.3333MHz */
#define ICCH_FREQ_10M (0x02U) /* for CP Phy 10MHz */
#define ICCH_FREQ_12p5M (0x03U) /* for CP Phy 12.5MHz */
#define ICCH_FREQ_16p66M (0x05U) /* for CP Phy 16.6666MHz */
/* PMIC */
/* ROHM BD9571 slave address + (W) */
#define PMIC_W_SLAVE_ADDRESS (0x60U)
/* ROHM BD9571 slave address + (R) */
#define PMIC_R_SLAVE_ADDRESS (0x61U)
/* ROHM BD9571 DVFS SetVID register */
#define PMIC_DVFS_SETVID (0x54U)
#endif /* PMIC_ROHM_BD9571 */
/* Individual information */
#define EFUSE_AVS0 (0U)
#define EFUSE_AVS_NUM ARRAY_SIZE(init_vol_tbl)
typedef struct {
uint32_t avs; /* AVS code */
uint8_t vol; /* Voltage */
} initial_voltage_t;
static const initial_voltage_t init_vol_tbl[] = {
/* AVS code, ROHM BD9571 DVFS SetVID register */
{0x00U, 0x53U}, /* AVS0, 0.83V */
{0x01U, 0x52U}, /* AVS1, 0.82V */
{0x02U, 0x51U}, /* AVS2, 0.81V */
{0x04U, 0x50U}, /* AVS3, 0.80V */
{0x08U, 0x4FU}, /* AVS4, 0.79V */
{0x10U, 0x4EU}, /* AVS5, 0.78V */
{0x20U, 0x4DU}, /* AVS6, 0.77V */
{0x40U, 0x4CU} /* AVS7, 0.76V */
};
#if PMIC_ROHM_BD9571
/* Kind of AVS settings status */
typedef enum {
avs_status_none = 0,
avs_status_init,
avs_status_start_condition,
avs_status_set_slave_addr,
avs_status_write_reg_addr,
avs_status_write_reg_data,
avs_status_stop_condition,
avs_status_end,
avs_status_complete,
avs_status_al_start,
avs_status_al_transfer,
avs_status_nack,
avs_status_error_stop,
ave_status_error_end
} avs_status_t;
/* Kind of AVS error */
typedef enum {
avs_error_none = 0,
avs_error_al,
avs_error_nack
} avs_error_t;
static avs_status_t avs_status;
static uint32_t avs_retry;
#endif /* PMIC_ROHM_BD9571 */
static uint32_t efuse_avs = EFUSE_AVS0;
#if PMIC_ROHM_BD9571
/* prototype */
static avs_error_t avs_check_error(void);
static void avs_set_iic_clock(void);
#if AVS_READ_PMIC_REG_ENABLE == 1
static uint8_t avs_read_pmic_reg(uint8_t addr);
static void avs_poll(uint8_t bit_pos, uint8_t val);
#endif
#endif /* PMIC_ROHM_BD9571 */
#endif /* (AVS_SETTING_ENABLE==1) */
/*
* Initialize to enable the AVS setting.
*/
void rcar_avs_init(void)
{
#if (AVS_SETTING_ENABLE == 1)
uint32_t val;
#if PMIC_ROHM_BD9571
/* Initialize AVS status */
avs_status = avs_status_init;
#endif /* PMIC_ROHM_BD9571 */
/* Enable clock supply to ADVFS. */
mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, CPG_SYS_ADVFS_BIT);
/* Read AVS code (Initial values are derived from eFuse) */
val = mmio_read_32(ADVADJP2) & ADVADJP2_VOLCOND_MASK;
for (efuse_avs = 0U; efuse_avs < EFUSE_AVS_NUM; efuse_avs++) {
if (val == init_vol_tbl[efuse_avs].avs)
break;
}
if (efuse_avs >= EFUSE_AVS_NUM)
efuse_avs = EFUSE_AVS0; /* Not applicable */
#if PMIC_ROHM_BD9571
/* Enable clock supply to DVFS. */
mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, CPG_SYS_DVFS_BIT);
/* Disable I2C module and All internal registers initialized. */
mmio_write_8(IIC_ICCR, 0x00U);
while ((mmio_read_8(IIC_ICCR) & ICCR_ENABLE) != 0U) {
/* Disable I2C module and all internal registers initialized. */
mmio_write_8(IIC_ICCR, 0x00U);
}
/* Set next status */
avs_status = avs_status_start_condition;
#endif /* PMIC_ROHM_BD9571 */
#endif /* (AVS_SETTING_ENABLE==1) */
}
/*
* Set the value of register corresponding to the voltage
* by transfer of I2C to PIMC.
*/
void rcar_avs_setting(void)
{
#if (AVS_SETTING_ENABLE == 1)
#if PMIC_ROHM_BD9571
avs_error_t err;
switch (avs_status) {
case avs_status_start_condition:
/* Set ICCR.ICE=1 to activate the I2C module. */
mmio_write_8(IIC_ICCR, mmio_read_8(IIC_ICCR) | ICCR_ENABLE);
/* Set frequency of 400kHz */
avs_set_iic_clock();
/* Set ICIC.TACKE=1, ICIC.WAITE=1, ICIC.DTEE=1 to */
/* enable interrupt control. */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC)
| ICIC_TACKE | ICIC_WAITE | ICIC_DTEE);
/* Write H'94 in ICCR to issue start condition */
mmio_write_8(IIC_ICCR, ICCR_START);
/* Set next status */
avs_status = avs_status_set_slave_addr;
break;
case avs_status_set_slave_addr:
/* Check error. */
err = avs_check_error();
if (err == avs_error_al) {
/* Recovery sequence of just after start. */
avs_status = avs_status_al_start;
} else if (err == avs_error_nack) {
/* Recovery sequence of detected NACK */
avs_status = avs_status_nack;
} else {
/* Was data transmission enabled ? */
if ((mmio_read_8(IIC_ICSR) & ICSR_DTE) == ICSR_DTE) {
/* Clear ICIC.DTEE to disable a DTE interrupt */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC)
& (uint8_t) (~ICIC_DTEE));
/* Send PMIC slave address + (W) */
mmio_write_8(IIC_ICDR, PMIC_W_SLAVE_ADDRESS);
/* Set next status */
avs_status = avs_status_write_reg_addr;
}
}
break;
case avs_status_write_reg_addr:
/* Check error. */
err = avs_check_error();
if (err == avs_error_al) {
/* Recovery sequence of during data transfer. */
avs_status = avs_status_al_transfer;
} else if (err == avs_error_nack) {
/* Recovery sequence of detected NACK */
avs_status = avs_status_nack;
} else {
/* If wait state after data transmission. */
if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) {
/* Write PMIC DVFS_SetVID address */
mmio_write_8(IIC_ICDR, PMIC_DVFS_SETVID);
/* Clear ICSR.WAIT to exit from wait state. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR)
& (uint8_t) (~ICSR_WAIT));
/* Set next status */
avs_status = avs_status_write_reg_data;
}
}
break;
case avs_status_write_reg_data:
/* Check error. */
err = avs_check_error();
if (err == avs_error_al) {
/* Recovery sequence of during data transfer. */
avs_status = avs_status_al_transfer;
} else if (err == avs_error_nack) {
/* Recovery sequence of detected NACK */
avs_status = avs_status_nack;
} else {
/* If wait state after data transmission. */
if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) {
/* Dose efuse_avs exceed the number of */
/* the tables? */
if (efuse_avs >= EFUSE_AVS_NUM) {
ERROR("%s%s=%u\n", "AVS number of ",
"eFuse is out of range. number",
efuse_avs);
/* Infinite loop */
panic();
}
/* Write PMIC DVFS_SetVID value */
mmio_write_8(IIC_ICDR,
init_vol_tbl[efuse_avs].vol);
/* Clear ICSR.WAIT to exit from wait state. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR)
& (uint8_t) (~ICSR_WAIT));
/* Set next status */
avs_status = avs_status_stop_condition;
}
}
break;
case avs_status_stop_condition:
err = avs_check_error();
if (err == avs_error_al) {
/* Recovery sequence of during data transfer. */
avs_status = avs_status_al_transfer;
} else if (err == avs_error_nack) {
/* Recovery sequence of detected NACK */
avs_status = avs_status_nack;
} else {
/* If wait state after data transmission. */
if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) {
/* Write H'90 in ICCR to issue stop condition */
mmio_write_8(IIC_ICCR, ICCR_STOP);
/* Clear ICSR.WAIT to exit from wait state. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR)
& (uint8_t) (~ICSR_WAIT));
/* Set next status */
avs_status = avs_status_end;
}
}
break;
case avs_status_end:
/* Is this module not busy?. */
if ((mmio_read_8(IIC_ICSR) & ICSR_BUSY) == 0U) {
/* Set ICCR=H'00 to disable the I2C module. */
mmio_write_8(IIC_ICCR, 0x00U);
/* Set next status */
avs_status = avs_status_complete;
}
break;
case avs_status_al_start:
/* Clear ICSR.AL bit */
mmio_write_8(IIC_ICSR, (mmio_read_8(IIC_ICSR)
& (uint8_t) (~ICSR_AL)));
/* Transmit a clock pulse */
mmio_write_8(IIC_ICDR, init_vol_tbl[EFUSE_AVS0].vol);
/* Set next status */
avs_status = avs_status_error_stop;
break;
case avs_status_al_transfer:
/* Clear ICSR.AL bit */
mmio_write_8(IIC_ICSR, (mmio_read_8(IIC_ICSR)
& (uint8_t) (~ICSR_AL)));
/* Set next status */
avs_status = avs_status_error_stop;
break;
case avs_status_nack:
/* Write H'90 in ICCR to issue stop condition */
mmio_write_8(IIC_ICCR, ICCR_STOP);
/* Disable a WAIT and DTEE interrupt. */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC)
& (uint8_t) (~(ICIC_WAITE | ICIC_DTEE)));
/* Clear ICSR.TACK bit */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR)
& (uint8_t) (~ICSR_TACK));
/* Set next status */
avs_status = ave_status_error_end;
break;
case avs_status_error_stop:
/* If wait state after data transmission. */
if ((mmio_read_8(IIC_ICSR) & ICSR_WAIT) == ICSR_WAIT) {
/* Write H'90 in ICCR to issue stop condition */
mmio_write_8(IIC_ICCR, ICCR_STOP);
/* Clear ICSR.WAIT to exit from wait state. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR)
& (uint8_t) (~ICSR_WAIT));
/* Set next status */
avs_status = ave_status_error_end;
}
break;
case ave_status_error_end:
/* Is this module not busy?. */
if ((mmio_read_8(IIC_ICSR) & ICSR_BUSY) == 0U) {
/* Set ICCR=H'00 to disable the I2C module. */
mmio_write_8(IIC_ICCR, 0x00U);
/* Increment the re-try number of times. */
avs_retry++;
/* Set start a re-try to status. */
avs_status = avs_status_start_condition;
}
break;
case avs_status_complete:
/* After "avs_status" became the "avs_status_complete", */
/* "avs_setting()" function may be called. */
break;
default:
/* This case is not possible. */
ERROR("AVS setting is in invalid status. status=%u\n",
avs_status);
/* Infinite loop */
panic();
break;
}
#endif /* PMIC_ROHM_BD9571 */
#endif /* (AVS_SETTING_ENABLE==1) */
}
/*
* Finish the AVS setting.
*/
void rcar_avs_end(void)
{
#if (AVS_SETTING_ENABLE == 1)
uint32_t mstp;
#if PMIC_ROHM_BD9571
/* While status is not completion, be repeated. */
while (avs_status != avs_status_complete)
rcar_avs_setting();
NOTICE("AVS setting succeeded. DVFS_SetVID=0x%x\n",
init_vol_tbl[efuse_avs].vol);
#if AVS_READ_PMIC_REG_ENABLE == 1
{
uint8_t addr = PMIC_DVFS_SETVID;
uint8_t value = avs_read_pmic_reg(addr);
NOTICE("Read PMIC register. address=0x%x value=0x%x\n",
addr, value);
}
#endif
/* Bit of the module which wants to disable clock supply. */
mstp = CPG_SYS_DVFS_BIT;
/* Disables the supply of clock signal to a module. */
cpg_write(CPG_SMSTPCR9, mmio_read_32(CPG_SMSTPCR9) | mstp);
#endif /* PMIC_ROHM_BD9571 */
/* Bit of the module which wants to disable clock supply. */
mstp = CPG_SYS_ADVFS_BIT;
/* Disables the supply of clock signal to a module. */
cpg_write(CPG_SMSTPCR9, mmio_read_32(CPG_SMSTPCR9) | mstp);
#endif /* (AVS_SETTING_ENABLE==1) */
}
#if (AVS_SETTING_ENABLE == 1)
#if PMIC_ROHM_BD9571
/*
* Check error and judge re-try.
*/
static avs_error_t avs_check_error(void)
{
avs_error_t ret;
if ((mmio_read_8(IIC_ICSR) & ICSR_AL) == ICSR_AL) {
NOTICE("%s AVS status=%d Retry=%u\n",
"Loss of arbitration is detected.", avs_status, avs_retry);
/* Check of retry number of times */
if (avs_retry >= AVS_RETRY_NUM) {
ERROR("AVS setting failed in retry. max=%u\n",
AVS_RETRY_NUM);
/* Infinite loop */
panic();
}
/* Set the error detected to error status. */
ret = avs_error_al;
} else if ((mmio_read_8(IIC_ICSR) & ICSR_TACK) == ICSR_TACK) {
NOTICE("%s AVS status=%d Retry=%u\n",
"Non-acknowledge is detected.", avs_status, avs_retry);
/* Check of retry number of times */
if (avs_retry >= AVS_RETRY_NUM) {
ERROR("AVS setting failed in retry. max=%u\n",
AVS_RETRY_NUM);
/* Infinite loop */
panic();
}
/* Set the error detected to error status. */
ret = avs_error_nack;
} else {
/* Not error. */
ret = avs_error_none;
}
return ret;
}
/*
* Set I2C for DVFS clock.
*/
static void avs_set_iic_clock(void)
{
uint32_t md_pin;
/* Read Mode pin register. */
md_pin = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14;
/* Set the module clock (CP phy) for the IIC-DVFS. */
/* CP phy is EXTAL / 2. */
switch (md_pin) {
case MD14_MD13_TYPE_0: /* EXTAL = 16.6666MHz */
mmio_write_8(IIC_ICCL, ICCL_FREQ_8p33M);
mmio_write_8(IIC_ICCH, ICCH_FREQ_8p33M);
break;
case MD14_MD13_TYPE_1: /* EXTAL = 20MHz */
mmio_write_8(IIC_ICCL, ICCL_FREQ_10M);
mmio_write_8(IIC_ICCH, ICCH_FREQ_10M);
break;
case MD14_MD13_TYPE_2: /* EXTAL = 25MHz (H3/M3) */
mmio_write_8(IIC_ICCL, ICCL_FREQ_12p5M);
mmio_write_8(IIC_ICCH, ICCH_FREQ_12p5M);
break;
case MD14_MD13_TYPE_3: /* EXTAL = 33.3333MHz */
mmio_write_8(IIC_ICCL, ICCL_FREQ_16p66M);
mmio_write_8(IIC_ICCH, ICCH_FREQ_16p66M);
break;
default: /* This case is not possible. */
/* CP Phy frequency is to be set for the 16.66MHz */
mmio_write_8(IIC_ICCL, ICCL_FREQ_16p66M);
mmio_write_8(IIC_ICCH, ICCH_FREQ_16p66M);
break;
}
}
#if AVS_READ_PMIC_REG_ENABLE == 1
/*
* Read the value of the register of PMIC.
*/
static uint8_t avs_read_pmic_reg(uint8_t addr)
{
uint8_t reg;
/* Set ICCR.ICE=1 to activate the I2C module. */
mmio_write_8(IIC_ICCR, mmio_read_8(IIC_ICCR) | ICCR_ENABLE);
/* Set frequency of 400kHz */
avs_set_iic_clock();
/*
* Set ICIC.WAITE=1, ICIC.DTEE=1 to enable data transmission
* interrupt and wait interrupt.
*/
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_WAITE | ICIC_DTEE);
/* Write H'94 in ICCR to issue start condition */
mmio_write_8(IIC_ICCR, ICCR_START);
/* Wait for a until ICSR.DTE becomes 1. */
avs_poll(ICSR_DTE, 1U);
/* Clear ICIC.DTEE to disable a DTE interrupt. */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE));
/* Send slave address of PMIC */
mmio_write_8(IIC_ICDR, PMIC_W_SLAVE_ADDRESS);
/* Wait for a until ICSR.WAIT becomes 1. */
avs_poll(ICSR_WAIT, 1U);
/* write PMIC address */
mmio_write_8(IIC_ICDR, addr);
/* Clear ICSR.WAIT to exit from WAIT status. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT));
/* Wait for a until ICSR.WAIT becomes 1. */
avs_poll(ICSR_WAIT, 1U);
/* Write H'94 in ICCR to issue restart condition */
mmio_write_8(IIC_ICCR, ICCR_START);
/* Clear ICSR.WAIT to exit from WAIT status. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT));
/* Set ICIC.DTEE=1 to enable data transmission interrupt. */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_DTEE);
/* Wait for a until ICSR.DTE becomes 1. */
avs_poll(ICSR_DTE, 1U);
/* Clear ICIC.DTEE to disable a DTE interrupt. */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE));
/* Send slave address of PMIC */
mmio_write_8(IIC_ICDR, PMIC_R_SLAVE_ADDRESS);
/* Wait for a until ICSR.WAIT becomes 1. */
avs_poll(ICSR_WAIT, 1U);
/* Write H'81 to ICCR to issue the repeated START condition */
/* for changing the transmission mode to the receive mode. */
mmio_write_8(IIC_ICCR, ICCR_START_RECV);
/* Clear ICSR.WAIT to exit from WAIT status. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT));
/* Wait for a until ICSR.WAIT becomes 1. */
avs_poll(ICSR_WAIT, 1U);
/* Set ICCR to H'C0 for the STOP condition */
mmio_write_8(IIC_ICCR, ICCR_STOP_RECV);
/* Clear ICSR.WAIT to exit from WAIT status. */
mmio_write_8(IIC_ICSR, mmio_read_8(IIC_ICSR) & (uint8_t) (~ICSR_WAIT));
/* Set ICIC.DTEE=1 to enable data transmission interrupt. */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) | ICIC_DTEE);
/* Wait for a until ICSR.DTE becomes 1. */
avs_poll(ICSR_DTE, 1U);
/* Receive DVFS SetVID register */
/* Clear ICIC.DTEE to disable a DTE interrupt. */
mmio_write_8(IIC_ICIC, mmio_read_8(IIC_ICIC) & (uint8_t) (~ICIC_DTEE));
/* Receive DVFS SetVID register */
reg = mmio_read_8(IIC_ICDR);
/* Wait until ICSR.BUSY is cleared. */
avs_poll(ICSR_BUSY, 0U);
/* Set ICCR=H'00 to disable the I2C module. */
mmio_write_8(IIC_ICCR, 0x00U);
return reg;
}
/*
* Wait processing by the polling.
*/
static void avs_poll(uint8_t bit_pos, uint8_t val)
{
uint8_t bit_val = 0U;
if (val != 0U)
bit_val = bit_pos;
while (1) {
if ((mmio_read_8(IIC_ICSR) & bit_pos) == bit_val)
break;
}
}
#endif /* AVS_READ_PMIC_REG_ENABLE */
#endif /* PMIC_ROHM_BD9571 */
#endif /* (AVS_SETTING_ENABLE==1) */
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights
* reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef AVS_DRIVER_H
#define AVS_DRIVER_H
/* AVS Setting. 1:enable / 0:disable */
#ifndef AVS_SETTING_ENABLE
#define AVS_SETTING_ENABLE 1
#endif /* AVS_SETTING_ENABLE */
void rcar_avs_init(void);
void rcar_avs_setting(void);
void rcar_avs_end(void);
#endif /* AVS_DRIVER_H */
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/mmio.h>
#include "cpg_registers.h"
#include "rcar_private.h"
#if IMAGE_BL31
void __attribute__ ((section(".system_ram"))) cpg_write(uintptr_t regadr, uint32_t regval)
#else
void cpg_write(uintptr_t regadr, uint32_t regval)
#endif
{
uint32_t value = regval;
mmio_write_32(CPG_CPGWPR, ~value);
mmio_write_32(regadr, value);
}
#if IMAGE_BL31
void __attribute__ ((section(".system_ram"))) mstpcr_write(uint32_t mstpcr, uint32_t mstpsr,
uint32_t target_bit)
#else
void mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit)
#endif
{
uint32_t reg;
reg = mmio_read_32(mstpcr);
reg &= ~target_bit;
cpg_write(mstpcr, reg);
while ((mmio_read_32(mstpsr) & target_bit) != 0U) {
}
}
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <console_macros.S>
#include <drivers/renesas/rcar/console/console.h>
.globl console_rcar_register
.globl console_rcar_init
.globl console_rcar_putc
.globl console_rcar_flush
.extern rcar_log_init
.extern rcar_set_log_data
/* -----------------------------------------------
* int console_rcar_register(
* uintptr_t base, uint32_t clk, uint32_t baud,
* console_t *console)
* Function to initialize and register a new rcar
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
* x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
*/
func console_rcar_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
str x0, [x6, #CONSOLE_T_BASE]
bl rcar_log_init
cbz x0, register_fail
mov x0, x6
mov x30, x7
finish_console_register rcar, putc=1, getc=0, flush=1
register_fail:
ret x7
endfunc console_rcar_register
/* ---------------------------------------------
* int console_rcar_init(unsigned long base_addr,
* unsigned int uart_clk, unsigned int baud_rate)
* Function to initialize the console without a
* C Runtime to print debug information. This
* function will be accessed by crash reporting.
* In: x0 - console base address
* w1 - Uart clock in Hz
* w2 - Baud rate
* Out: return 1 on success
* Clobber list : x1, x2
* ---------------------------------------------
*/
func console_rcar_init
mov w0, #1
ret
endfunc console_rcar_init
/* --------------------------------------------------------
* int console_rcar_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
* x1 - pointer to console_t structure
* Out : return -1 on error else return character.
* Clobber list : x2
* --------------------------------------------------------
*/
func console_rcar_putc
b rcar_set_log_data
endfunc console_rcar_putc
/* ---------------------------------------------
* void console_rcar_flush(void)
* Function to force a write of all buffered
* data that hasn't been output. It returns void
* Clobber list : x0, x1
* ---------------------------------------------
*/
func console_rcar_flush
ret
endfunc console_rcar_flush
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdarg.h>
#include <stdint.h>
#include <platform_def.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <lib/bakery_lock.h>
#include "rcar_def.h"
#include "rcar_private.h"
#include "rcar_printf.h"
#define INDEX_TIMER_COUNT (4U)
#define RCAR_LOG_HEAD (('T' << 0) | ('L' << 8) | ('O' << 16) | ('G' << 24))
/*
* The log is initialized and used before BL31 xlat tables are initialized,
* therefore the log memory is a device memory at that point. Make sure the
* memory is correclty aligned and accessed only with up-to 32bit, aligned,
* writes.
*/
CASSERT((RCAR_BL31_LOG_BASE & 0x7) == 0, assert_bl31_log_base_unaligned);
CASSERT((RCAR_BL31_LOG_MAX & 0x7) == 0, assert_bl31_log_max_unaligned);
extern RCAR_INSTANTIATE_LOCK typedef struct log_head {
uint32_t head;
uint32_t index;
uint32_t size;
uint32_t res;
} loghead_t;
typedef struct log_map {
loghead_t header;
uint8_t log_data[RCAR_BL31_LOG_MAX];
uint8_t res_data[RCAR_LOG_RES_SIZE];
} logmap_t;
int32_t rcar_set_log_data(int32_t c)
{
logmap_t *t_log;
t_log = (logmap_t *) RCAR_BL31_LOG_BASE;
rcar_lock_get();
/*
* If index is broken, then index and size initialize
*/
if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) {
t_log->header.index = 0U;
t_log->header.size = 0U;
}
/*
* data store to log area then index and size renewal
*/
t_log->log_data[t_log->header.index] = (uint8_t) c;
t_log->header.index++;
if (t_log->header.size < t_log->header.index) {
t_log->header.size = t_log->header.index;
}
if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) {
t_log->header.index = 0U;
}
rcar_lock_release();
return 1;
}
int32_t rcar_log_init(void)
{
logmap_t *t_log = (logmap_t *)RCAR_BL31_LOG_BASE;
uint32_t *log_data = (uint32_t *)t_log->log_data;
int16_t init_flag = 0;
int i;
if (t_log->header.head != RCAR_LOG_HEAD) {
/*
* Log header is not "TLOG", then log area initialize
*/
init_flag = 1;
}
if (t_log->header.index >= (uint32_t) RCAR_BL31_LOG_MAX) {
/*
* index is broken, then log area initialize
*/
init_flag = 1;
}
if (init_flag == 1) {
for (i = 0; i < RCAR_BL31_LOG_MAX; i += 4)
*log_data++ = 0;
t_log->header.head = RCAR_LOG_HEAD;
t_log->header.index = 0U;
t_log->header.size = 0U;
}
rcar_lock_init();
return 1;
}
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RCAR_PRINTF_H
#define RCAR_PRINTF_H
#include <string.h>
int32_t rcar_set_log_data(int32_t c);
int32_t rcar_log_init(void);
#endif /* RCAR_PRINTF_H */
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef BOOT_INIT_DRAM_H
#define BOOT_INIT_DRAM_H
extern int32_t rcar_dram_init(void);
#define INITDRAM_OK 0
#define INITDRAM_NG 0xffffffff
#define INITDRAM_ERR_I 0xffffffff
#define INITDRAM_ERR_O 0xfffffffe
#define INITDRAM_ERR_T 0xfffffff0
#endif /* BOOT_INIT_DRAM_H */
@@ -0,0 +1,17 @@
#
# Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
ifeq ($(RCAR_LSI),$(filter $(RCAR_LSI),${RCAR_E3} ${RZ_G2E}))
include drivers/renesas/common/ddr/ddr_a/ddr_a.mk
BL2_SOURCES += drivers/renesas/common/ddr/dram_sub_func.c
else ifeq (${RCAR_LSI},${RCAR_D3})
include drivers/renesas/common/ddr/ddr_a/ddr_a.mk
else ifeq (${RCAR_LSI},${RCAR_V3M})
include drivers/renesas/common/ddr/ddr_a/ddr_a.mk
else
include drivers/renesas/common/ddr/ddr_b/ddr_b.mk
BL2_SOURCES += drivers/renesas/common/ddr/dram_sub_func.c
endif
@@ -0,0 +1,8 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "../ddr_regs.h"
@@ -0,0 +1,13 @@
#
# Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
ifeq ($(RCAR_LSI),$(filter $(RCAR_LSI),${RCAR_E3} ${RZ_G2E}))
BL2_SOURCES += drivers/renesas/common/ddr/ddr_a/ddr_init_e3.c
else ifeq (${RCAR_LSI},${RCAR_D3})
BL2_SOURCES += drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c
else
BL2_SOURCES += drivers/renesas/common/ddr/ddr_a/ddr_init_v3m.c
endif
@@ -0,0 +1,735 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <lib/mmio.h>
#include <common/debug.h>
#include "rcar_def.h"
#include "../ddr_regs.h"
#define RCAR_DDR_VERSION "rev.0.02"
/* Average periodic refresh interval[ns]. Support 3900,7800 */
#define REFRESH_RATE 3900
#if RCAR_LSI != RCAR_D3
#error "Don't have DDR initialize routine."
#endif
static void init_ddr_d3_1866(void)
{
uint32_t i, r2, r3, r5, r6, r7, r12;
mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
mmio_write_32(DBSC_DBKIND, 0x00000007);
mmio_write_32(DBSC_DBMEMCONF_0_0, 0x0f030a01);
mmio_write_32(DBSC_DBPHYCONF0, 0x00000001);
mmio_write_32(DBSC_DBTR0, 0x0000000D);
mmio_write_32(DBSC_DBTR1, 0x00000009);
mmio_write_32(DBSC_DBTR2, 0x00000000);
mmio_write_32(DBSC_DBTR3, 0x0000000D);
mmio_write_32(DBSC_DBTR4, 0x000D000D);
mmio_write_32(DBSC_DBTR5, 0x0000002D);
mmio_write_32(DBSC_DBTR6, 0x00000020);
mmio_write_32(DBSC_DBTR7, 0x00060006);
mmio_write_32(DBSC_DBTR8, 0x00000021);
mmio_write_32(DBSC_DBTR9, 0x00000007);
mmio_write_32(DBSC_DBTR10, 0x0000000E);
mmio_write_32(DBSC_DBTR11, 0x0000000C);
mmio_write_32(DBSC_DBTR12, 0x00140014);
mmio_write_32(DBSC_DBTR13, 0x000000F2);
mmio_write_32(DBSC_DBTR14, 0x00170006);
mmio_write_32(DBSC_DBTR15, 0x00060005);
mmio_write_32(DBSC_DBTR16, 0x09210507);
mmio_write_32(DBSC_DBTR17, 0x040E0000);
mmio_write_32(DBSC_DBTR18, 0x00000200);
mmio_write_32(DBSC_DBTR19, 0x0129004B);
mmio_write_32(DBSC_DBTR20, 0x020000FB);
mmio_write_32(DBSC_DBTR21, 0x00040004);
mmio_write_32(DBSC_DBBL, 0x00000000);
mmio_write_32(DBSC_DBODT0, 0x00000001);
mmio_write_32(DBSC_DBADJ0, 0x00000001);
mmio_write_32(DBSC_DBSYSCONF1, 0x00000002);
mmio_write_32(DBSC_DBDFICNT_0, 0x00000010);
mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
mmio_write_32(DBSC_DBSCHRW1, 0x00000046);
mmio_write_32(DBSC_SCFCTST0, 0x0C050B03);
mmio_write_32(DBSC_SCFCTST1, 0x0305030C);
mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A);
mmio_write_32(DBSC_DBCMD, 0x01000001);
mmio_write_32(DBSC_DBCMD, 0x08000000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x80010000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000008);
mmio_write_32(DBSC_DBPDRGD_0, 0x000B8000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058A04);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000091);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BB6B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000095);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BBAD);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000099);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BB6B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058A00);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000021);
mmio_write_32(DBSC_DBPDRGD_0, 0x0024641E);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010073);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x0C058A00);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058A00);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000003);
mmio_write_32(DBSC_DBPDRGD_0, 0x0780C700);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000007);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(30)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000004);
mmio_write_32(DBSC_DBPDRGD_0,
(uint32_t) (REFRESH_RATE * 928 / 125) - 400
+ 0x0A300000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000022);
mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000023);
mmio_write_32(DBSC_DBPDRGD_0, 0x35A00D77);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000024);
mmio_write_32(DBSC_DBPDRGD_0, 0x2A8A2C28);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000025);
mmio_write_32(DBSC_DBPDRGD_0, 0x30005E00);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000026);
mmio_write_32(DBSC_DBPDRGD_0, 0x0014CB49);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000027);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000F14);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000028);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000046);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000029);
if (REFRESH_RATE > 3900) {
mmio_write_32(DBSC_DBPDRGD_0, 0x00000020);
} else {
mmio_write_32(DBSC_DBPDRGD_0, 0x000000A0);
}
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003047);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000020);
mmio_write_32(DBSC_DBPDRGD_0, 0x00181884);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000001A);
mmio_write_32(DBSC_DBPDRGD_0, 0x33C03C10);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A7);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A8);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A9);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C7);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C8);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C9);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000000E);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0x0000FF00) >> 0x9;
r3 = (r2 << 16) + (r2 << 8) + r2;
r6 = (r2 << 24) + (r2 << 16) + (r2 << 8) + r2;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000011);
mmio_write_32(DBSC_DBPDRGD_0, r3);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000012);
mmio_write_32(DBSC_DBPDRGD_0, r3);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000016);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000017);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000018);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000019);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010181);
mmio_write_32(DBSC_DBCMD, 0x08000001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010601);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
for (i = 0; i < 2; i++) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB1 + i * 0x20);
r5 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFF00) >> 0x8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB4 + i * 0x20);
r6 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFF;
mmio_write_32(DBSC_DBPDRGA_0, 0xB3 + i * 0x20);
r7 = mmio_read_32(DBSC_DBPDRGD_0) & 0x7;
if (r6 > 0) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | ((r7 + 0x1) & 0x7));
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | r6);
} else {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | r7);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 |
((r6 + (r5 << 1)) & 0xFF));
}
}
mmio_write_32(DBSC_DBPDRGA_0, 0x00000005);
mmio_write_32(DBSC_DBPDRGD_0, 0xC1AA00C0);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010801);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000005);
mmio_write_32(DBSC_DBPDRGD_0, 0xC1AA00D8);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x0001F001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003087);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010401);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
for (i = 0; i < 2; i++) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB1 + i * 0x20);
r5 = ((mmio_read_32(DBSC_DBPDRGD_0) & 0xFF00) >> 0x8);
mmio_write_32(DBSC_DBPDRGA_0, 0xB4 + i * 0x20);
r6 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFF;
mmio_write_32(DBSC_DBPDRGA_0, 0xB3 + i * 0x20);
r7 = mmio_read_32(DBSC_DBPDRGD_0) & 0x7;
r12 = (r5 >> 0x2);
if (r12 < r6) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | ((r7 + 0x1) & 0x7));
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | ((r6 - r12) & 0xFF));
} else {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | (r7 & 0x7));
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 |
((r6 + r5 +
(r5 >> 1) + r12) & 0xFF));
}
}
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00015001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000003);
mmio_write_32(DBSC_DBPDRGD_0, 0x0380C700);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000007);
while (mmio_read_32(DBSC_DBPDRGD_0) & BIT(30))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000021);
mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E);
mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
mmio_write_32(DBSC_DBCALCNF,
(uint32_t) (64000000 / REFRESH_RATE) + 0x01000000);
mmio_write_32(DBSC_DBRFCNF1,
(uint32_t) (REFRESH_RATE * 116 / 125) + 0x00080000);
mmio_write_32(DBSC_DBRFCNF2, 0x00010000);
mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001);
mmio_write_32(DBSC_DBRFEN, 0x00000001);
mmio_write_32(DBSC_DBACEN, 0x00000001);
mmio_write_32(DBSC_DBPDLK_0, 0x00000000);
mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
#ifdef ddr_qos_init_setting // only for non qos_init
mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
mmio_write_32(DBSC_DBCAM0CNF1, 0x00043218);
mmio_write_32(DBSC_DBCAM0CNF2, 0x000000F4);
mmio_write_32(DBSC_DBSCHCNT0, 0x000f0037);
mmio_write_32(DBSC_DBSCHSZ0, 0x00000001);
mmio_write_32(DBSC_DBSCHRW0, 0x22421111);
mmio_write_32(DBSC_SCFCTST2, 0x012F1123);
mmio_write_32(DBSC_DBSCHQOS00, 0x00000F00);
mmio_write_32(DBSC_DBSCHQOS01, 0x00000B00);
mmio_write_32(DBSC_DBSCHQOS02, 0x00000000);
mmio_write_32(DBSC_DBSCHQOS03, 0x00000000);
mmio_write_32(DBSC_DBSCHQOS40, 0x00000300);
mmio_write_32(DBSC_DBSCHQOS41, 0x000002F0);
mmio_write_32(DBSC_DBSCHQOS42, 0x00000200);
mmio_write_32(DBSC_DBSCHQOS43, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS90, 0x00000300);
mmio_write_32(DBSC_DBSCHQOS91, 0x000002F0);
mmio_write_32(DBSC_DBSCHQOS92, 0x00000200);
mmio_write_32(DBSC_DBSCHQOS93, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS130, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS131, 0x000000F0);
mmio_write_32(DBSC_DBSCHQOS132, 0x000000A0);
mmio_write_32(DBSC_DBSCHQOS133, 0x00000040);
mmio_write_32(DBSC_DBSCHQOS140, 0x000000C0);
mmio_write_32(DBSC_DBSCHQOS141, 0x000000B0);
mmio_write_32(DBSC_DBSCHQOS142, 0x00000080);
mmio_write_32(DBSC_DBSCHQOS143, 0x00000040);
mmio_write_32(DBSC_DBSCHQOS150, 0x00000040);
mmio_write_32(DBSC_DBSCHQOS151, 0x00000030);
mmio_write_32(DBSC_DBSCHQOS152, 0x00000020);
mmio_write_32(DBSC_DBSCHQOS153, 0x00000010);
mmio_write_32(0xE67F0018, 0x00000001);
mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
#endif
}
static void init_ddr_d3_1600(void)
{
uint32_t i, r2, r3, r5, r6, r7, r12;
mmio_write_32(CPG_CPGWPR, 0x5A5AFFFF);
mmio_write_32(CPG_CPGWPCR, 0xA5A50000);
mmio_write_32(CPG_SRCR4, 0x20000000);
mmio_write_32(0xE61500DC, 0xe2200000);
while (!(mmio_read_32(CPG_PLLECR) & BIT(11)))
;
mmio_write_32(CPG_SRSTCLR4, 0x20000000);
mmio_write_32(CPG_CPGWPCR, 0xA5A50001);
mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
mmio_write_32(DBSC_DBKIND, 0x00000007);
mmio_write_32(DBSC_DBMEMCONF_0_0, 0x0f030a01);
mmio_write_32(DBSC_DBPHYCONF0, 0x00000001);
mmio_write_32(DBSC_DBTR0, 0x0000000B);
mmio_write_32(DBSC_DBTR1, 0x00000008);
mmio_write_32(DBSC_DBTR2, 0x00000000);
mmio_write_32(DBSC_DBTR3, 0x0000000B);
mmio_write_32(DBSC_DBTR4, 0x000B000B);
mmio_write_32(DBSC_DBTR5, 0x00000027);
mmio_write_32(DBSC_DBTR6, 0x0000001C);
mmio_write_32(DBSC_DBTR7, 0x00060006);
mmio_write_32(DBSC_DBTR8, 0x00000020);
mmio_write_32(DBSC_DBTR9, 0x00000006);
mmio_write_32(DBSC_DBTR10, 0x0000000C);
mmio_write_32(DBSC_DBTR11, 0x0000000A);
mmio_write_32(DBSC_DBTR12, 0x00120012);
mmio_write_32(DBSC_DBTR13, 0x000000CE);
mmio_write_32(DBSC_DBTR14, 0x00140005);
mmio_write_32(DBSC_DBTR15, 0x00050004);
mmio_write_32(DBSC_DBTR16, 0x071F0305);
mmio_write_32(DBSC_DBTR17, 0x040C0000);
mmio_write_32(DBSC_DBTR18, 0x00000200);
mmio_write_32(DBSC_DBTR19, 0x01000040);
mmio_write_32(DBSC_DBTR20, 0x020000D6);
mmio_write_32(DBSC_DBTR21, 0x00040004);
mmio_write_32(DBSC_DBBL, 0x00000000);
mmio_write_32(DBSC_DBODT0, 0x00000001);
mmio_write_32(DBSC_DBADJ0, 0x00000001);
mmio_write_32(DBSC_DBSYSCONF1, 0x00000002);
mmio_write_32(DBSC_DBDFICNT_0, 0x00000010);
mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
mmio_write_32(DBSC_DBSCHRW1, 0x00000046);
mmio_write_32(DBSC_SCFCTST0, 0x0D050B03);
mmio_write_32(DBSC_SCFCTST1, 0x0306030C);
mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A);
mmio_write_32(DBSC_DBCMD, 0x01000001);
mmio_write_32(DBSC_DBCMD, 0x08000000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x80010000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000008);
mmio_write_32(DBSC_DBPDRGD_0, 0x000B8000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058904);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000091);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BB6B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000095);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BBAD);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000099);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BB6B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058900);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000021);
mmio_write_32(DBSC_DBPDRGD_0, 0x0024641E);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010073);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x0C058900);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058900);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000003);
mmio_write_32(DBSC_DBPDRGD_0, 0x0780C700);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000007);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(30)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000004);
mmio_write_32(DBSC_DBPDRGD_0,
(uint32_t) (REFRESH_RATE * 792 / 125) - 400 + 0x08B00000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000022);
mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000023);
mmio_write_32(DBSC_DBPDRGD_0, 0x2D9C0B66);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000024);
mmio_write_32(DBSC_DBPDRGD_0, 0x2A88B400);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000025);
mmio_write_32(DBSC_DBPDRGD_0, 0x30005200);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000026);
mmio_write_32(DBSC_DBPDRGD_0, 0x0014A9C9);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000027);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000D70);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000028);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000046);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000029);
if (REFRESH_RATE > 3900) {
mmio_write_32(DBSC_DBPDRGD_0, 0x00000018);
} else {
mmio_write_32(DBSC_DBPDRGD_0, 0x00000098);
}
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003047);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000020);
mmio_write_32(DBSC_DBPDRGD_0, 0x00181884);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000001A);
mmio_write_32(DBSC_DBPDRGD_0, 0x33C03C10);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A7);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A8);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A9);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C7);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C8);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C9);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000000E);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0x0000FF00) >> 0x9;
r3 = (r2 << 16) + (r2 << 8) + r2;
r6 = (r2 << 24) + (r2 << 16) + (r2 << 8) + r2;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000011);
mmio_write_32(DBSC_DBPDRGD_0, r3);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000012);
mmio_write_32(DBSC_DBPDRGD_0, r3);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000016);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000017);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000018);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000019);
mmio_write_32(DBSC_DBPDRGD_0, r6);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010181);
mmio_write_32(DBSC_DBCMD, 0x08000001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010601);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
for (i = 0; i < 2; i++) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB1 + i * 0x20);
r5 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFF00) >> 0x8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB4 + i * 0x20);
r6 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFF;
mmio_write_32(DBSC_DBPDRGA_0, 0xB3 + i * 0x20);
r7 = mmio_read_32(DBSC_DBPDRGD_0) & 0x7;
if (r6 > 0) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | ((r7 + 0x1) & 0x7));
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | r6);
} else {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | r7);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 |
((r6 + (r5 << 1)) & 0xFF));
}
}
mmio_write_32(DBSC_DBPDRGA_0, 0x00000005);
mmio_write_32(DBSC_DBPDRGD_0, 0xC1AA00C0);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010801);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000005);
mmio_write_32(DBSC_DBPDRGD_0, 0xC1AA00D8);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x0001F001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
r2 = mmio_read_32(DBSC_DBPDRGD_0);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF);
mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00));
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003087);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010401);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
for (i = 0; i < 2; i++) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB1 + i * 0x20);
r5 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFF00) >> 0x8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB4 + i * 0x20);
r6 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFF;
mmio_write_32(DBSC_DBPDRGA_0, 0xB3 + i * 0x20);
r7 = mmio_read_32(DBSC_DBPDRGD_0) & 0x7;
r12 = (r5 >> 0x2);
if (r12 < r6) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | ((r7 + 0x1) & 0x7));
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | ((r6 - r12) & 0xFF));
} else {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | (r7 & 0x7));
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00;
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 |
((r6 + r5 +
(r5 >> 1) + r12) & 0xFF));
}
}
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00015001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000003);
mmio_write_32(DBSC_DBPDRGD_0, 0x0380C700);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000007);
while (mmio_read_32(DBSC_DBPDRGD_0) & BIT(30))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000021);
mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E);
mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
mmio_write_32(DBSC_DBCALCNF,
(uint32_t) (64000000 / REFRESH_RATE) + 0x01000000);
mmio_write_32(DBSC_DBRFCNF1,
(uint32_t) (REFRESH_RATE * 99 / 125) + 0x00080000);
mmio_write_32(DBSC_DBRFCNF2, 0x00010000);
mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001);
mmio_write_32(DBSC_DBRFEN, 0x00000001);
mmio_write_32(DBSC_DBACEN, 0x00000001);
mmio_write_32(DBSC_DBPDLK_0, 0x00000000);
mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
#ifdef ddr_qos_init_setting // only for non qos_init
mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
mmio_write_32(DBSC_DBCAM0CNF1, 0x00043218);
mmio_write_32(DBSC_DBCAM0CNF2, 0x000000F4);
mmio_write_32(DBSC_DBSCHCNT0, 0x000f0037);
mmio_write_32(DBSC_DBSCHSZ0, 0x00000001);
mmio_write_32(DBSC_DBSCHRW0, 0x22421111);
mmio_write_32(DBSC_SCFCTST2, 0x012F1123);
mmio_write_32(DBSC_DBSCHQOS00, 0x00000F00);
mmio_write_32(DBSC_DBSCHQOS01, 0x00000B00);
mmio_write_32(DBSC_DBSCHQOS02, 0x00000000);
mmio_write_32(DBSC_DBSCHQOS03, 0x00000000);
mmio_write_32(DBSC_DBSCHQOS40, 0x00000300);
mmio_write_32(DBSC_DBSCHQOS41, 0x000002F0);
mmio_write_32(DBSC_DBSCHQOS42, 0x00000200);
mmio_write_32(DBSC_DBSCHQOS43, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS90, 0x00000300);
mmio_write_32(DBSC_DBSCHQOS91, 0x000002F0);
mmio_write_32(DBSC_DBSCHQOS92, 0x00000200);
mmio_write_32(DBSC_DBSCHQOS93, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS130, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS131, 0x000000F0);
mmio_write_32(DBSC_DBSCHQOS132, 0x000000A0);
mmio_write_32(DBSC_DBSCHQOS133, 0x00000040);
mmio_write_32(DBSC_DBSCHQOS140, 0x000000C0);
mmio_write_32(DBSC_DBSCHQOS141, 0x000000B0);
mmio_write_32(DBSC_DBSCHQOS142, 0x00000080);
mmio_write_32(DBSC_DBSCHQOS143, 0x00000040);
mmio_write_32(DBSC_DBSCHQOS150, 0x00000040);
mmio_write_32(DBSC_DBSCHQOS151, 0x00000030);
mmio_write_32(DBSC_DBSCHQOS152, 0x00000020);
mmio_write_32(DBSC_DBSCHQOS153, 0x00000010);
mmio_write_32(0xE67F0018, 0x00000001);
mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
#endif
}
#define PRR 0xFFF00044U
#define PRR_PRODUCT_MASK 0x00007F00U
#define PRR_PRODUCT_D3 0x00005800U
#define MODEMR_MD19 BIT(19)
int32_t rcar_dram_init(void)
{
uint32_t reg;
uint32_t ddr_mbps;
reg = mmio_read_32(PRR);
if ((reg & PRR_PRODUCT_MASK) != PRR_PRODUCT_D3) {
ERROR("LSI Product ID (PRR=0x%x) DDR initialize not supported.\n",
reg);
panic();
}
reg = mmio_read_32(RST_MODEMR);
if (reg & MODEMR_MD19) {
init_ddr_d3_1866();
ddr_mbps = 1866;
} else {
init_ddr_d3_1600();
ddr_mbps = 1600;
}
NOTICE("BL2: DDR%d(%s)\n", ddr_mbps, RCAR_DDR_VERSION);
return 0;
}
@@ -0,0 +1,339 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/mmio.h>
#include <lib/utils_def.h>
#include <stdint.h>
#include "boot_init_dram.h"
#include "rcar_def.h"
#include "../ddr_regs.h"
static uint32_t init_ddr_v3m_1600(void)
{
uint32_t i, r2, r5, r6, r7, r12;
mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
mmio_write_32(DBSC_DBKIND, 0x00000007);
#if RCAR_DRAM_DDR3L_MEMCONF == 0
mmio_write_32(DBSC_DBMEMCONF_0_0, 0x0f030a02); // 1GB: Eagle
#else
mmio_write_32(DBSC_DBMEMCONF_0_0, 0x10030a02); // 2GB: V3MSK
#endif
mmio_write_32(DBSC_DBPHYCONF0, 0x00000001);
mmio_write_32(DBSC_DBTR0, 0x0000000B);
mmio_write_32(DBSC_DBTR1, 0x00000008);
mmio_write_32(DBSC_DBTR3, 0x0000000B);
mmio_write_32(DBSC_DBTR4, 0x000B000B);
mmio_write_32(DBSC_DBTR5, 0x00000027);
mmio_write_32(DBSC_DBTR6, 0x0000001C);
mmio_write_32(DBSC_DBTR7, 0x00060006);
mmio_write_32(DBSC_DBTR8, 0x00000020);
mmio_write_32(DBSC_DBTR9, 0x00000006);
mmio_write_32(DBSC_DBTR10, 0x0000000C);
mmio_write_32(DBSC_DBTR11, 0x0000000B);
mmio_write_32(DBSC_DBTR12, 0x00120012);
mmio_write_32(DBSC_DBTR13, 0x01180118);
mmio_write_32(DBSC_DBTR14, 0x00140005);
mmio_write_32(DBSC_DBTR15, 0x00050004);
mmio_write_32(DBSC_DBTR16, 0x071D0305);
mmio_write_32(DBSC_DBTR17, 0x040C0010);
mmio_write_32(DBSC_DBTR18, 0x00000200);
mmio_write_32(DBSC_DBTR19, 0x01000040);
mmio_write_32(DBSC_DBTR20, 0x02000120);
mmio_write_32(DBSC_DBTR21, 0x00040004);
mmio_write_32(DBSC_DBBL, 0x00000000);
mmio_write_32(DBSC_DBODT0, 0x00000001);
mmio_write_32(DBSC_DBADJ0, 0x00000001);
mmio_write_32(DBSC_DBCAM0CNF1, 0x00082010);
mmio_write_32(DBSC_DBCAM0CNF2, 0x00002000);
mmio_write_32(DBSC_DBSCHCNT0, 0x080f003f);
mmio_write_32(DBSC_DBSCHCNT1, 0x00001010);
mmio_write_32(DBSC_DBSCHSZ0, 0x00000001);
mmio_write_32(DBSC_DBSCHRW0, 0x00000200);
mmio_write_32(DBSC_DBSCHRW1, 0x00000040);
mmio_write_32(DBSC_DBSCHQOS40, 0x00000600);
mmio_write_32(DBSC_DBSCHQOS41, 0x00000480);
mmio_write_32(DBSC_DBSCHQOS42, 0x00000300);
mmio_write_32(DBSC_DBSCHQOS43, 0x00000180);
mmio_write_32(DBSC_DBSCHQOS90, 0x00000400);
mmio_write_32(DBSC_DBSCHQOS91, 0x00000300);
mmio_write_32(DBSC_DBSCHQOS92, 0x00000200);
mmio_write_32(DBSC_DBSCHQOS93, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS130, 0x00000300);
mmio_write_32(DBSC_DBSCHQOS131, 0x00000240);
mmio_write_32(DBSC_DBSCHQOS132, 0x00000180);
mmio_write_32(DBSC_DBSCHQOS133, 0x000000c0);
mmio_write_32(DBSC_DBSCHQOS140, 0x00000200);
mmio_write_32(DBSC_DBSCHQOS141, 0x00000180);
mmio_write_32(DBSC_DBSCHQOS142, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS143, 0x00000080);
mmio_write_32(DBSC_DBSCHQOS150, 0x00000100);
mmio_write_32(DBSC_DBSCHQOS151, 0x000000c0);
mmio_write_32(DBSC_DBSCHQOS152, 0x00000080);
mmio_write_32(DBSC_DBSCHQOS153, 0x00000040);
mmio_write_32(DBSC_DBSYSCONF1, 0x00000002);
mmio_write_32(DBSC_DBCAM0CNF1, 0x00040C04);
mmio_write_32(DBSC_DBCAM0CNF2, 0x000001c4);
mmio_write_32(DBSC_DBSCHSZ0, 0x00000003);
mmio_write_32(DBSC_DBSCHRW1, 0x001a0080);
mmio_write_32(DBSC_DBDFICNT_0, 0x00000010);
mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A);
mmio_write_32(DBSC_DBCMD, 0x01000001);
mmio_write_32(DBSC_DBCMD, 0x08000000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x80010000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000008);
mmio_write_32(DBSC_DBPDRGD_0, 0x000B8000);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058904);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000091);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BB6D);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000095);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BB6B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000099);
mmio_write_32(DBSC_DBPDRGD_0, 0x0007BB6D);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058900);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000021);
mmio_write_32(DBSC_DBPDRGD_0, 0x0024641E);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010073);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x0C058900);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000090);
mmio_write_32(DBSC_DBPDRGD_0, 0x04058900);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000003);
mmio_write_32(DBSC_DBPDRGD_0, 0x0780C700);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000007);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(30)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000004);
mmio_write_32(DBSC_DBPDRGD_0, 0x08C0C170);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000022);
mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000023);
mmio_write_32(DBSC_DBPDRGD_0, 0x2D9C0B66);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000024);
mmio_write_32(DBSC_DBPDRGD_0, 0x2A88C400);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000025);
mmio_write_32(DBSC_DBPDRGD_0, 0x30005200);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000026);
mmio_write_32(DBSC_DBPDRGD_0, 0x0014A9C9);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000027);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000D70);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000028);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000004);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000029);
mmio_write_32(DBSC_DBPDRGD_0, 0x00000018);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003047);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000020);
mmio_write_32(DBSC_DBPDRGD_0, 0x00181884);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000001A);
mmio_write_32(DBSC_DBPDRGD_0, 0x13C03C10);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A7);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A8);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A9);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C7);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C8);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C9);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000E7);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000E8);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000E9);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000107);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000108);
mmio_write_32(DBSC_DBPDRGD_0, 0x0D0D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000109);
mmio_write_32(DBSC_DBPDRGD_0, 0x000D0D0D);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010181);
mmio_write_32(DBSC_DBCMD, 0x08000001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010601);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
for (i = 0; i < 4; i++) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB1 + i * 0x20);
r5 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFF00) >> 8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB4 + i * 0x20);
r6 = mmio_read_32(DBSC_DBPDRGD_0) & 0xFF;
mmio_write_32(DBSC_DBPDRGA_0, 0xB3 + i * 0x20);
r7 = mmio_read_32(DBSC_DBPDRGD_0) & 0x7;
if (r6 > 0) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8);
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, ((r7 + 1) & 0x7) | r2);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | r6);
} else {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8);
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 | r7);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 |
(((r5 << 1) + r6) & 0xFF));
}
}
mmio_write_32(DBSC_DBPDRGA_0, 0x00000005);
mmio_write_32(DBSC_DBPDRGD_0, 0xC1AA00A0);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000E0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000100);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010801);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000005);
mmio_write_32(DBSC_DBPDRGD_0, 0xC1AA00B8);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x0001F001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000E0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000100);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C000285);
mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C);
mmio_write_32(DBSC_DBPDRGD_0, 0x81003087);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00010401);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
for (i = 0; i < 4; i++) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB1 + i * 0x20);
r5 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFF00) >> 8;
mmio_write_32(DBSC_DBPDRGA_0, 0xB4 + i * 0x20);
r6 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFF);
mmio_write_32(DBSC_DBPDRGA_0, 0xB3 + i * 0x20);
r7 = (mmio_read_32(DBSC_DBPDRGD_0) & 0x7);
r12 = (r5 >> 2);
if (r6 - r12 > 0) {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8);
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, ((r7 + 1) & 0x7) | r2);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, ((r6 - r12) & 0xFF) | r2);
} else {
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFFF8);
mmio_write_32(DBSC_DBPDRGA_0, 0xB2 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, (r7 & 0x7) | r2);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
r2 = (mmio_read_32(DBSC_DBPDRGD_0) & 0xFFFFFF00);
mmio_write_32(DBSC_DBPDRGA_0, 0xB0 + i * 0x20);
mmio_write_32(DBSC_DBPDRGD_0, r2 |
((r6 + r5 +
(r5 >> 1) + r12) & 0xFF));
}
}
mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000C0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x000000E0);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000100);
mmio_write_32(DBSC_DBPDRGD_0, 0x7C0002C5);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000001);
mmio_write_32(DBSC_DBPDRGD_0, 0x00015001);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000006);
while (!(mmio_read_32(DBSC_DBPDRGD_0) & BIT(0)))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000003);
mmio_write_32(DBSC_DBPDRGD_0, 0x0380C700);
mmio_write_32(DBSC_DBPDRGA_0, 0x00000007);
while (mmio_read_32(DBSC_DBPDRGD_0) & BIT(30))
;
mmio_write_32(DBSC_DBPDRGA_0, 0x00000021);
mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E);
mmio_write_32(DBSC_DBBUS0CNF1, 0x00000000);
mmio_write_32(DBSC_DBBUS0CNF0, 0x00010001);
mmio_write_32(DBSC_DBCALCNF, 0x0100200E);
mmio_write_32(DBSC_DBRFCNF1, 0x00081860);
mmio_write_32(DBSC_DBRFCNF2, 0x00010000);
mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001);
mmio_write_32(DBSC_DBRFEN, 0x00000001);
mmio_write_32(DBSC_DBACEN, 0x00000001);
mmio_write_32(DBSC_DBPDLK_0, 0x00000000);
mmio_write_32(0xE67F0024, 0x00000001);
mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
return INITDRAM_OK;
}
int32_t rcar_dram_init(void)
{
return init_ddr_v3m_1600();
}
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define RCAR_DDR_VERSION "rev.0.41"
#define DRAM_CH_CNT 0x04
#define SLICE_CNT 0x04
#define CS_CNT 0x02
/* order : CS0A, CS0B, CS1A, CS1B */
#define CSAB_CNT (CS_CNT * 2)
/* order : CH0A, CH0B, CH1A, CH1B, CH2A, CH2B, CH3A, CH3B */
#define CHAB_CNT (DRAM_CH_CNT * 2)
/* pll setting */
#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva)))
#define CLK_MUL(a, diva, b, divb) (((a) * (b)) / ((diva) * (divb)))
/* for ddr deisity setting */
#define DBMEMCONF_REG(d3, row, bank, col, dw) \
(((d3) << 30) | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw))
#define DBMEMCONF_REGD(density) \
(DBMEMCONF_REG((density) % 2, ((density) + 1) / \
2 + (29 - 3 - 10 - 2), 3, 10, 2))
#define DBMEMCONF_VAL(ch, cs) (DBMEMCONF_REGD(DBMEMCONF_DENS(ch, cs)))
/* refresh mode */
#define DBSC_REFINTS (0x0)
/* system registers */
#define CPG_FRQCRB (CPG_BASE + 0x0004U)
#define CPG_PLLECR (CPG_BASE + 0x00D0U)
#define CPG_MSTPSR5 (CPG_BASE + 0x003CU)
#define CPG_SRCR4 (CPG_BASE + 0x00BCU)
#define CPG_PLL3CR (CPG_BASE + 0x00DCU)
#define CPG_ZB3CKCR (CPG_BASE + 0x0380U)
#define CPG_FRQCRD (CPG_BASE + 0x00E4U)
#define CPG_SMSTPCR5 (CPG_BASE + 0x0144U)
#define CPG_CPGWPR (CPG_BASE + 0x0900U)
#define CPG_SRSTCLR4 (CPG_BASE + 0x0950U)
#define CPG_FRQCRB_KICK_BIT BIT(31)
#define CPG_PLLECR_PLL3E_BIT BIT(3)
#define CPG_PLLECR_PLL3ST_BIT BIT(11)
#define CPG_ZB3CKCR_ZB3ST_BIT BIT(11)
#define RST_BASE (0xE6160000U)
#define RST_MODEMR (RST_BASE + 0x0060U)
#define LIFEC_CHIPID(x) (0xE6110040U + 0x04U * (x))
/* DBSC registers */
#include "../ddr_regs.h"
#define DBSC_DBMONCONF4 0xE6793010U
#define DBSC_PLL_LOCK(ch) (0xE6794054U + 0x100U * (ch))
#define DBSC_PLL_LOCK_0 0xE6794054U
#define DBSC_PLL_LOCK_1 0xE6794154U
#define DBSC_PLL_LOCK_2 0xE6794254U
#define DBSC_PLL_LOCK_3 0xE6794354U
/* STAT registers */
#define MSTAT_SL_INIT 0xE67E8000U
#define MSTAT_REF_ARS 0xE67E8004U
#define MSTATQ_STATQC 0xE67E8008U
#define MSTATQ_WTENABLE 0xE67E8030U
#define MSTATQ_WTREFRESH 0xE67E8034U
#define MSTATQ_WTSETTING0 0xE67E8038U
#define MSTATQ_WTSETTING1 0xE67E803CU
#define QOS_BASE1 (0xE67F0000U)
#define QOSCTRL_RAS (QOS_BASE1 + 0x0000U)
#define QOSCTRL_FIXTH (QOS_BASE1 + 0x0004U)
#define QOSCTRL_RAEN (QOS_BASE1 + 0x0018U)
#define QOSCTRL_REGGD (QOS_BASE1 + 0x0020U)
#define QOSCTRL_DANN (QOS_BASE1 + 0x0030U)
#define QOSCTRL_DANT (QOS_BASE1 + 0x0038U)
#define QOSCTRL_EC (QOS_BASE1 + 0x003CU)
#define QOSCTRL_EMS (QOS_BASE1 + 0x0040U)
#define QOSCTRL_INSFC (QOS_BASE1 + 0x0050U)
#define QOSCTRL_BERR (QOS_BASE1 + 0x0054U)
#define QOSCTRL_RACNT0 (QOS_BASE1 + 0x0080U)
#define QOSCTRL_STATGEN0 (QOS_BASE1 + 0x0088U)
/* other module */
#define THS1_THCTR 0xE6198020U
#define THS1_TEMP 0xE6198028U
@@ -0,0 +1,7 @@
#
# Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
BL2_SOURCES += drivers/renesas/common/ddr/ddr_b/boot_init_dram.c
@@ -0,0 +1,441 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define DDR_PHY_SLICE_REGSET_OFS_H3 0x0400
#define DDR_PHY_ADR_V_REGSET_OFS_H3 0x0600
#define DDR_PHY_ADR_I_REGSET_OFS_H3 0x0680
#define DDR_PHY_ADR_G_REGSET_OFS_H3 0x0700
#define DDR_PI_REGSET_OFS_H3 0x0200
#define DDR_PHY_SLICE_REGSET_SIZE_H3 0x80
#define DDR_PHY_ADR_V_REGSET_SIZE_H3 0x80
#define DDR_PHY_ADR_I_REGSET_SIZE_H3 0x80
#define DDR_PHY_ADR_G_REGSET_SIZE_H3 0x80
#define DDR_PI_REGSET_SIZE_H3 0x100
#define DDR_PHY_SLICE_REGSET_NUM_H3 88
#define DDR_PHY_ADR_V_REGSET_NUM_H3 37
#define DDR_PHY_ADR_I_REGSET_NUM_H3 37
#define DDR_PHY_ADR_G_REGSET_NUM_H3 59
#define DDR_PI_REGSET_NUM_H3 181
static const uint32_t DDR_PHY_SLICE_REGSET_H3[DDR_PHY_SLICE_REGSET_NUM_H3] = {
/*0400*/ 0x000004f0,
/*0401*/ 0x00000000,
/*0402*/ 0x00000000,
/*0403*/ 0x00000100,
/*0404*/ 0x01003c0c,
/*0405*/ 0x02003c0c,
/*0406*/ 0x00010300,
/*0407*/ 0x04000100,
/*0408*/ 0x00000300,
/*0409*/ 0x000700c0,
/*040a*/ 0x00b00201,
/*040b*/ 0x00000020,
/*040c*/ 0x00000000,
/*040d*/ 0x00000000,
/*040e*/ 0x00000000,
/*040f*/ 0x00000000,
/*0410*/ 0x00000000,
/*0411*/ 0x00000000,
/*0412*/ 0x00000000,
/*0413*/ 0x09000000,
/*0414*/ 0x04080000,
/*0415*/ 0x04080400,
/*0416*/ 0x00000000,
/*0417*/ 0x32103210,
/*0418*/ 0x00800708,
/*0419*/ 0x000f000c,
/*041a*/ 0x00000100,
/*041b*/ 0x55aa55aa,
/*041c*/ 0x33cc33cc,
/*041d*/ 0x0ff00ff0,
/*041e*/ 0x0f0ff0f0,
/*041f*/ 0x00008e38,
/*0420*/ 0x76543210,
/*0421*/ 0x00000001,
/*0422*/ 0x00000000,
/*0423*/ 0x00000000,
/*0424*/ 0x00000000,
/*0425*/ 0x00000000,
/*0426*/ 0x00000000,
/*0427*/ 0x00000000,
/*0428*/ 0x00000000,
/*0429*/ 0x00000000,
/*042a*/ 0x00000000,
/*042b*/ 0x00000000,
/*042c*/ 0x00000000,
/*042d*/ 0x00000000,
/*042e*/ 0x00000000,
/*042f*/ 0x00000000,
/*0430*/ 0x00000000,
/*0431*/ 0x00000000,
/*0432*/ 0x00000000,
/*0433*/ 0x00200000,
/*0434*/ 0x08200820,
/*0435*/ 0x08200820,
/*0436*/ 0x08200820,
/*0437*/ 0x08200820,
/*0438*/ 0x08200820,
/*0439*/ 0x00000820,
/*043a*/ 0x03000300,
/*043b*/ 0x03000300,
/*043c*/ 0x03000300,
/*043d*/ 0x03000300,
/*043e*/ 0x00000300,
/*043f*/ 0x00000000,
/*0440*/ 0x00000000,
/*0441*/ 0x00000000,
/*0442*/ 0x00000000,
/*0443*/ 0x00a000a0,
/*0444*/ 0x00a000a0,
/*0445*/ 0x00a000a0,
/*0446*/ 0x00a000a0,
/*0447*/ 0x00a000a0,
/*0448*/ 0x00a000a0,
/*0449*/ 0x00a000a0,
/*044a*/ 0x00a000a0,
/*044b*/ 0x00a000a0,
/*044c*/ 0x01040109,
/*044d*/ 0x00000200,
/*044e*/ 0x01000000,
/*044f*/ 0x00000200,
/*0450*/ 0x4041a151,
/*0451*/ 0xc00141a0,
/*0452*/ 0x0e0100c0,
/*0453*/ 0x0010000c,
/*0454*/ 0x0c064208,
/*0455*/ 0x000f0c18,
/*0456*/ 0x00e00140,
/*0457*/ 0x00000c20
};
static const uint32_t DDR_PHY_ADR_V_REGSET_H3[DDR_PHY_ADR_V_REGSET_NUM_H3] = {
/*0600*/ 0x00000000,
/*0601*/ 0x00000000,
/*0602*/ 0x00000000,
/*0603*/ 0x00000000,
/*0604*/ 0x00000000,
/*0605*/ 0x00000000,
/*0606*/ 0x00000002,
/*0607*/ 0x00000000,
/*0608*/ 0x00000000,
/*0609*/ 0x00000000,
/*060a*/ 0x00400320,
/*060b*/ 0x00000040,
/*060c*/ 0x00dcba98,
/*060d*/ 0x00000000,
/*060e*/ 0x00dcba98,
/*060f*/ 0x01000000,
/*0610*/ 0x00020003,
/*0611*/ 0x00000000,
/*0612*/ 0x00000000,
/*0613*/ 0x00000000,
/*0614*/ 0x00002a01,
/*0615*/ 0x00000015,
/*0616*/ 0x00000015,
/*0617*/ 0x0000002a,
/*0618*/ 0x00000033,
/*0619*/ 0x0000000c,
/*061a*/ 0x0000000c,
/*061b*/ 0x00000033,
/*061c*/ 0x00418820,
/*061d*/ 0x003f0000,
/*061e*/ 0x0000003f,
/*061f*/ 0x0002006e,
/*0620*/ 0x02000200,
/*0621*/ 0x02000200,
/*0622*/ 0x00000200,
/*0623*/ 0x42080010,
/*0624*/ 0x00000003
};
static const uint32_t DDR_PHY_ADR_I_REGSET_H3[DDR_PHY_ADR_I_REGSET_NUM_H3] = {
/*0680*/ 0x04040404,
/*0681*/ 0x00000404,
/*0682*/ 0x00000000,
/*0683*/ 0x00000000,
/*0684*/ 0x00000000,
/*0685*/ 0x00000000,
/*0686*/ 0x00000002,
/*0687*/ 0x00000000,
/*0688*/ 0x00000000,
/*0689*/ 0x00000000,
/*068a*/ 0x00400320,
/*068b*/ 0x00000040,
/*068c*/ 0x00000000,
/*068d*/ 0x00000000,
/*068e*/ 0x00000000,
/*068f*/ 0x01000000,
/*0690*/ 0x00020003,
/*0691*/ 0x00000000,
/*0692*/ 0x00000000,
/*0693*/ 0x00000000,
/*0694*/ 0x00002a01,
/*0695*/ 0x00000015,
/*0696*/ 0x00000015,
/*0697*/ 0x0000002a,
/*0698*/ 0x00000033,
/*0699*/ 0x0000000c,
/*069a*/ 0x0000000c,
/*069b*/ 0x00000033,
/*069c*/ 0x00000000,
/*069d*/ 0x00000000,
/*069e*/ 0x00000000,
/*069f*/ 0x0002006e,
/*06a0*/ 0x02000200,
/*06a1*/ 0x02000200,
/*06a2*/ 0x00000200,
/*06a3*/ 0x42080010,
/*06a4*/ 0x00000003
};
static const uint32_t DDR_PHY_ADR_G_REGSET_H3[DDR_PHY_ADR_G_REGSET_NUM_H3] = {
/*0700*/ 0x00000001,
/*0701*/ 0x00000000,
/*0702*/ 0x00000005,
/*0703*/ 0x04000f00,
/*0704*/ 0x00020080,
/*0705*/ 0x00020055,
/*0706*/ 0x00000000,
/*0707*/ 0x00000000,
/*0708*/ 0x00000000,
/*0709*/ 0x00000050,
/*070a*/ 0x00000000,
/*070b*/ 0x01010100,
/*070c*/ 0x00000200,
/*070d*/ 0x00001102,
/*070e*/ 0x00000000,
/*070f*/ 0x000f1f00,
/*0710*/ 0x0f1f0f1f,
/*0711*/ 0x0f1f0f1f,
/*0712*/ 0x00020003,
/*0713*/ 0x02000200,
/*0714*/ 0x00000200,
/*0715*/ 0x00001102,
/*0716*/ 0x00000064,
/*0717*/ 0x00000000,
/*0718*/ 0x00000000,
/*0719*/ 0x00000502,
/*071a*/ 0x027f6e00,
/*071b*/ 0x007f007f,
/*071c*/ 0x00007f3c,
/*071d*/ 0x00047f6e,
/*071e*/ 0x0003154f,
/*071f*/ 0x0001154f,
/*0720*/ 0x0001154f,
/*0721*/ 0x0001154f,
/*0722*/ 0x0001154f,
/*0723*/ 0x00003fee,
/*0724*/ 0x0001154f,
/*0725*/ 0x00003fee,
/*0726*/ 0x0001154f,
/*0727*/ 0x00007f3c,
/*0728*/ 0x0001154f,
/*0729*/ 0x00000000,
/*072a*/ 0x00000000,
/*072b*/ 0x00000000,
/*072c*/ 0x65000000,
/*072d*/ 0x00000000,
/*072e*/ 0x00000000,
/*072f*/ 0x00000201,
/*0730*/ 0x00000000,
/*0731*/ 0x00000000,
/*0732*/ 0x00000000,
/*0733*/ 0x00000000,
/*0734*/ 0x00000000,
/*0735*/ 0x00000000,
/*0736*/ 0x00000000,
/*0737*/ 0x00000000,
/*0738*/ 0x00000000,
/*0739*/ 0x00000000,
/*073a*/ 0x00000000
};
static const uint32_t DDR_PI_REGSET_H3[DDR_PI_REGSET_NUM_H3] = {
/*0200*/ 0x00000b00,
/*0201*/ 0x00000100,
/*0202*/ 0x00000000,
/*0203*/ 0x0000ffff,
/*0204*/ 0x00000000,
/*0205*/ 0x0000ffff,
/*0206*/ 0x00000000,
/*0207*/ 0x304cffff,
/*0208*/ 0x00000200,
/*0209*/ 0x00000200,
/*020a*/ 0x00000200,
/*020b*/ 0x00000200,
/*020c*/ 0x0000304c,
/*020d*/ 0x00000200,
/*020e*/ 0x00000200,
/*020f*/ 0x00000200,
/*0210*/ 0x00000200,
/*0211*/ 0x0000304c,
/*0212*/ 0x00000200,
/*0213*/ 0x00000200,
/*0214*/ 0x00000200,
/*0215*/ 0x00000200,
/*0216*/ 0x00010000,
/*0217*/ 0x00000003,
/*0218*/ 0x01000001,
/*0219*/ 0x00000000,
/*021a*/ 0x00000000,
/*021b*/ 0x00000000,
/*021c*/ 0x00000000,
/*021d*/ 0x00000000,
/*021e*/ 0x00000000,
/*021f*/ 0x00000000,
/*0220*/ 0x00000000,
/*0221*/ 0x00000000,
/*0222*/ 0x00000000,
/*0223*/ 0x00000000,
/*0224*/ 0x00000000,
/*0225*/ 0x00000000,
/*0226*/ 0x00000000,
/*0227*/ 0x00000000,
/*0228*/ 0x00000000,
/*0229*/ 0x0f000101,
/*022a*/ 0x08492d25,
/*022b*/ 0x500e0c04,
/*022c*/ 0x0002500e,
/*022d*/ 0x00460003,
/*022e*/ 0x182600cf,
/*022f*/ 0x182600cf,
/*0230*/ 0x00000005,
/*0231*/ 0x00000000,
/*0232*/ 0x00000000,
/*0233*/ 0x00000000,
/*0234*/ 0x00000000,
/*0235*/ 0x00000000,
/*0236*/ 0x00000000,
/*0237*/ 0x00000000,
/*0238*/ 0x01000000,
/*0239*/ 0x00040404,
/*023a*/ 0x01280a00,
/*023b*/ 0x00000000,
/*023c*/ 0x000f0000,
/*023d*/ 0x00001803,
/*023e*/ 0x00000000,
/*023f*/ 0x00000000,
/*0240*/ 0x00060002,
/*0241*/ 0x00010001,
/*0242*/ 0x01000101,
/*0243*/ 0x04020201,
/*0244*/ 0x00080804,
/*0245*/ 0x00000000,
/*0246*/ 0x08030000,
/*0247*/ 0x15150408,
/*0248*/ 0x00000000,
/*0249*/ 0x00000000,
/*024a*/ 0x00000000,
/*024b*/ 0x001e0f0f,
/*024c*/ 0x00000000,
/*024d*/ 0x01000300,
/*024e*/ 0x00000000,
/*024f*/ 0x00000000,
/*0250*/ 0x01000000,
/*0251*/ 0x00010101,
/*0252*/ 0x000e0e0e,
/*0253*/ 0x000c0c0c,
/*0254*/ 0x02060601,
/*0255*/ 0x00000000,
/*0256*/ 0x00000003,
/*0257*/ 0x00181703,
/*0258*/ 0x00280006,
/*0259*/ 0x00280016,
/*025a*/ 0x00000016,
/*025b*/ 0x00000000,
/*025c*/ 0x00000000,
/*025d*/ 0x00000000,
/*025e*/ 0x140a0000,
/*025f*/ 0x0005010a,
/*0260*/ 0x03018d03,
/*0261*/ 0x000a018d,
/*0262*/ 0x00060100,
/*0263*/ 0x01000006,
/*0264*/ 0x018e018e,
/*0265*/ 0x018e0100,
/*0266*/ 0x1111018e,
/*0267*/ 0x10010204,
/*0268*/ 0x09090650,
/*0269*/ 0x20110202,
/*026a*/ 0x00201000,
/*026b*/ 0x00201000,
/*026c*/ 0x04041000,
/*026d*/ 0x18020100,
/*026e*/ 0x00010118,
/*026f*/ 0x004b004a,
/*0270*/ 0x050f0000,
/*0271*/ 0x0c01021e,
/*0272*/ 0x34000000,
/*0273*/ 0x00000000,
/*0274*/ 0x00000000,
/*0275*/ 0x00000000,
/*0276*/ 0x312ed400,
/*0277*/ 0xd4111132,
/*0278*/ 0x1132312e,
/*0279*/ 0x312ed411,
/*027a*/ 0x00111132,
/*027b*/ 0x32312ed4,
/*027c*/ 0x2ed41111,
/*027d*/ 0x11113231,
/*027e*/ 0x32312ed4,
/*027f*/ 0xd4001111,
/*0280*/ 0x1132312e,
/*0281*/ 0x312ed411,
/*0282*/ 0xd4111132,
/*0283*/ 0x1132312e,
/*0284*/ 0x2ed40011,
/*0285*/ 0x11113231,
/*0286*/ 0x32312ed4,
/*0287*/ 0x2ed41111,
/*0288*/ 0x11113231,
/*0289*/ 0x00020000,
/*028a*/ 0x018d018d,
/*028b*/ 0x0c08018d,
/*028c*/ 0x1f121d22,
/*028d*/ 0x4301b344,
/*028e*/ 0x10172006,
/*028f*/ 0x121d220c,
/*0290*/ 0x01b3441f,
/*0291*/ 0x17200643,
/*0292*/ 0x1d220c10,
/*0293*/ 0x00001f12,
/*0294*/ 0x4301b344,
/*0295*/ 0x10172006,
/*0296*/ 0x00020002,
/*0297*/ 0x00020002,
/*0298*/ 0x00020002,
/*0299*/ 0x00020002,
/*029a*/ 0x00020002,
/*029b*/ 0x00000000,
/*029c*/ 0x00000000,
/*029d*/ 0x00000000,
/*029e*/ 0x00000000,
/*029f*/ 0x00000000,
/*02a0*/ 0x00000000,
/*02a1*/ 0x00000000,
/*02a2*/ 0x00000000,
/*02a3*/ 0x00000000,
/*02a4*/ 0x00000000,
/*02a5*/ 0x00000000,
/*02a6*/ 0x00000000,
/*02a7*/ 0x01000400,
/*02a8*/ 0x00304c00,
/*02a9*/ 0x0001e2f8,
/*02aa*/ 0x0000304c,
/*02ab*/ 0x0001e2f8,
/*02ac*/ 0x0000304c,
/*02ad*/ 0x0001e2f8,
/*02ae*/ 0x08000000,
/*02af*/ 0x00000100,
/*02b0*/ 0x00000000,
/*02b1*/ 0x00000000,
/*02b2*/ 0x00000000,
/*02b3*/ 0x00000000,
/*02b4*/ 0x00000002
};
@@ -0,0 +1,538 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define DDR_PHY_SLICE_REGSET_OFS_H3VER2 0x0400
#define DDR_PHY_ADR_V_REGSET_OFS_H3VER2 0x0600
#define DDR_PHY_ADR_I_REGSET_OFS_H3VER2 0x0640
#define DDR_PHY_ADR_G_REGSET_OFS_H3VER2 0x0680
#define DDR_PI_REGSET_OFS_H3VER2 0x0200
#define DDR_PHY_SLICE_REGSET_SIZE_H3VER2 0x80
#define DDR_PHY_ADR_V_REGSET_SIZE_H3VER2 0x40
#define DDR_PHY_ADR_I_REGSET_SIZE_H3VER2 0x40
#define DDR_PHY_ADR_G_REGSET_SIZE_H3VER2 0x80
#define DDR_PI_REGSET_SIZE_H3VER2 0x100
#define DDR_PHY_SLICE_REGSET_NUM_H3VER2 97
#define DDR_PHY_ADR_V_REGSET_NUM_H3VER2 37
#define DDR_PHY_ADR_I_REGSET_NUM_H3VER2 37
#define DDR_PHY_ADR_G_REGSET_NUM_H3VER2 79
#define DDR_PI_REGSET_NUM_H3VER2 245
static const uint32_t DDR_PHY_SLICE_REGSET_H3VER2
[DDR_PHY_SLICE_REGSET_NUM_H3VER2] = {
/*0400*/ 0x76543210,
/*0401*/ 0x0004f008,
/*0402*/ 0x00020133,
/*0403*/ 0x00000000,
/*0404*/ 0x00000000,
/*0405*/ 0x00010000,
/*0406*/ 0x016e6e0e,
/*0407*/ 0x026e6e0e,
/*0408*/ 0x00010300,
/*0409*/ 0x04000100,
/*040a*/ 0x01000000,
/*040b*/ 0x00000000,
/*040c*/ 0x00000000,
/*040d*/ 0x00000100,
/*040e*/ 0x001700c0,
/*040f*/ 0x020100b0,
/*0410*/ 0x00030020,
/*0411*/ 0x00000000,
/*0412*/ 0x00000000,
/*0413*/ 0x00000000,
/*0414*/ 0x00000000,
/*0415*/ 0x00000000,
/*0416*/ 0x00000000,
/*0417*/ 0x00000000,
/*0418*/ 0x09000000,
/*0419*/ 0x04080000,
/*041a*/ 0x04080400,
/*041b*/ 0x08000000,
/*041c*/ 0x0c008007,
/*041d*/ 0x00000f00,
/*041e*/ 0x00000100,
/*041f*/ 0x55aa55aa,
/*0420*/ 0x33cc33cc,
/*0421*/ 0x0ff00ff0,
/*0422*/ 0x0f0ff0f0,
/*0423*/ 0x00018e38,
/*0424*/ 0x00000000,
/*0425*/ 0x00000000,
/*0426*/ 0x00000000,
/*0427*/ 0x00000000,
/*0428*/ 0x00000000,
/*0429*/ 0x00000000,
/*042a*/ 0x00000000,
/*042b*/ 0x00000000,
/*042c*/ 0x00000000,
/*042d*/ 0x00000000,
/*042e*/ 0x00000000,
/*042f*/ 0x00000000,
/*0430*/ 0x00000000,
/*0431*/ 0x00000000,
/*0432*/ 0x00000000,
/*0433*/ 0x00000000,
/*0434*/ 0x00000000,
/*0435*/ 0x00000000,
/*0436*/ 0x00000000,
/*0437*/ 0x00000000,
/*0438*/ 0x00000104,
/*0439*/ 0x00082020,
/*043a*/ 0x08200820,
/*043b*/ 0x08200820,
/*043c*/ 0x08200820,
/*043d*/ 0x08200820,
/*043e*/ 0x08200820,
/*043f*/ 0x00000000,
/*0440*/ 0x00000000,
/*0441*/ 0x03000300,
/*0442*/ 0x03000300,
/*0443*/ 0x03000300,
/*0444*/ 0x03000300,
/*0445*/ 0x00000300,
/*0446*/ 0x00000000,
/*0447*/ 0x00000000,
/*0448*/ 0x00000000,
/*0449*/ 0x00000000,
/*044a*/ 0x00000000,
/*044b*/ 0x00a000a0,
/*044c*/ 0x00a000a0,
/*044d*/ 0x00a000a0,
/*044e*/ 0x00a000a0,
/*044f*/ 0x00a000a0,
/*0450*/ 0x00a000a0,
/*0451*/ 0x00a000a0,
/*0452*/ 0x00a000a0,
/*0453*/ 0x00a000a0,
/*0454*/ 0x01040109,
/*0455*/ 0x00000200,
/*0456*/ 0x01000000,
/*0457*/ 0x00000200,
/*0458*/ 0x00000004,
/*0459*/ 0x4041a151,
/*045a*/ 0xc00141a0,
/*045b*/ 0x0e0000c0,
/*045c*/ 0x0010000c,
/*045d*/ 0x063e4208,
/*045e*/ 0x0f0c180c,
/*045f*/ 0x00e00140,
/*0460*/ 0x00000c20
};
static const uint32_t
DDR_PHY_ADR_V_REGSET_H3VER2[DDR_PHY_ADR_V_REGSET_NUM_H3VER2] = {
/*0600*/ 0x00000000,
/*0601*/ 0x00000000,
/*0602*/ 0x00000000,
/*0603*/ 0x00000000,
/*0604*/ 0x00000000,
/*0605*/ 0x00000000,
/*0606*/ 0x00000000,
/*0607*/ 0x00010000,
/*0608*/ 0x00000200,
/*0609*/ 0x00000000,
/*060a*/ 0x00000000,
/*060b*/ 0x00000000,
/*060c*/ 0x00400320,
/*060d*/ 0x00000040,
/*060e*/ 0x00dcba98,
/*060f*/ 0x03000000,
/*0610*/ 0x00000200,
/*0611*/ 0x00000000,
/*0612*/ 0x00000000,
/*0613*/ 0x00000000,
/*0614*/ 0x0000002a,
/*0615*/ 0x00000015,
/*0616*/ 0x00000015,
/*0617*/ 0x0000002a,
/*0618*/ 0x00000033,
/*0619*/ 0x0000000c,
/*061a*/ 0x0000000c,
/*061b*/ 0x00000033,
/*061c*/ 0x00418820,
/*061d*/ 0x003f0000,
/*061e*/ 0x0000003f,
/*061f*/ 0x0002c06e,
/*0620*/ 0x02c002c0,
/*0621*/ 0x02c002c0,
/*0622*/ 0x000002c0,
/*0623*/ 0x42080010,
/*0624*/ 0x0000033e
};
static const uint32_t
DDR_PHY_ADR_I_REGSET_H3VER2[DDR_PHY_ADR_I_REGSET_NUM_H3VER2] = {
/*0640*/ 0x00000000,
/*0641*/ 0x00000000,
/*0642*/ 0x00000000,
/*0643*/ 0x00000000,
/*0644*/ 0x00000000,
/*0645*/ 0x00000000,
/*0646*/ 0x00000000,
/*0647*/ 0x00000000,
/*0648*/ 0x00000000,
/*0649*/ 0x00000000,
/*064a*/ 0x00000000,
/*064b*/ 0x00000000,
/*064c*/ 0x00000000,
/*064d*/ 0x00000000,
/*064e*/ 0x00000000,
/*064f*/ 0x00000000,
/*0650*/ 0x00000000,
/*0651*/ 0x00000000,
/*0652*/ 0x00000000,
/*0653*/ 0x00000000,
/*0654*/ 0x00000000,
/*0655*/ 0x00000000,
/*0656*/ 0x00000000,
/*0657*/ 0x00000000,
/*0658*/ 0x00000000,
/*0659*/ 0x00000000,
/*065a*/ 0x00000000,
/*065b*/ 0x00000000,
/*065c*/ 0x00000000,
/*065d*/ 0x00000000,
/*065e*/ 0x00000000,
/*065f*/ 0x00000000,
/*0660*/ 0x00000000,
/*0661*/ 0x00000000,
/*0662*/ 0x00000000,
/*0663*/ 0x00000000,
/*0664*/ 0x00000000
};
static const uint32_t
DDR_PHY_ADR_G_REGSET_H3VER2[DDR_PHY_ADR_G_REGSET_NUM_H3VER2] = {
/*0680*/ 0x00000000,
/*0681*/ 0x00000100,
/*0682*/ 0x00000000,
/*0683*/ 0x00050000,
/*0684*/ 0x0f000000,
/*0685*/ 0x00800400,
/*0686*/ 0x00020032,
/*0687*/ 0x00020055,
/*0688*/ 0x00000000,
/*0689*/ 0x00000000,
/*068a*/ 0x00000000,
/*068b*/ 0x00000050,
/*068c*/ 0x00000000,
/*068d*/ 0x01010100,
/*068e*/ 0x01000200,
/*068f*/ 0x00000000,
/*0690*/ 0x00010100,
/*0691*/ 0x00000000,
/*0692*/ 0x00000000,
/*0693*/ 0x00000000,
/*0694*/ 0x00000000,
/*0695*/ 0x00005064,
/*0696*/ 0x01421142,
/*0697*/ 0x00000142,
/*0698*/ 0x00000000,
/*0699*/ 0x000f1100,
/*069a*/ 0x0f110f11,
/*069b*/ 0x09000f11,
/*069c*/ 0x00000003,
/*069d*/ 0x0002c000,
/*069e*/ 0x02c002c0,
/*069f*/ 0x000002c0,
/*06a0*/ 0x03421342,
/*06a1*/ 0x00000342,
/*06a2*/ 0x00000000,
/*06a3*/ 0x00000000,
/*06a4*/ 0x05020000,
/*06a5*/ 0x14000000,
/*06a6*/ 0x027f6e00,
/*06a7*/ 0x047f027f,
/*06a8*/ 0x00027f6e,
/*06a9*/ 0x00047f6e,
/*06aa*/ 0x0003554f,
/*06ab*/ 0x0001554f,
/*06ac*/ 0x0001554f,
/*06ad*/ 0x0001554f,
/*06ae*/ 0x0001554f,
/*06af*/ 0x00003fee,
/*06b0*/ 0x0001554f,
/*06b1*/ 0x00003fee,
/*06b2*/ 0x0001554f,
/*06b3*/ 0x00027f6e,
/*06b4*/ 0x0001554f,
/*06b5*/ 0x00004011,
/*06b6*/ 0x00004410,
/*06b7*/ 0x00000000,
/*06b8*/ 0x00000000,
/*06b9*/ 0x00000000,
/*06ba*/ 0x00000065,
/*06bb*/ 0x00000000,
/*06bc*/ 0x00020201,
/*06bd*/ 0x00000000,
/*06be*/ 0x03000000,
/*06bf*/ 0x00000008,
/*06c0*/ 0x00000000,
/*06c1*/ 0x00000000,
/*06c2*/ 0x00000000,
/*06c3*/ 0x00000000,
/*06c4*/ 0x00000001,
/*06c5*/ 0x00000000,
/*06c6*/ 0x00000000,
/*06c7*/ 0x00000000,
/*06c8*/ 0x000000e4,
/*06c9*/ 0x00010198,
/*06ca*/ 0x00000000,
/*06cb*/ 0x00000000,
/*06cc*/ 0x07010000,
/*06cd*/ 0x00000104,
/*06ce*/ 0x00000000
};
static const uint32_t DDR_PI_REGSET_H3VER2[DDR_PI_REGSET_NUM_H3VER2] = {
/*0200*/ 0x00000b00,
/*0201*/ 0x00000100,
/*0202*/ 0x00640000,
/*0203*/ 0x00000000,
/*0204*/ 0x0000ffff,
/*0205*/ 0x00000000,
/*0206*/ 0x0000ffff,
/*0207*/ 0x00000000,
/*0208*/ 0x0000ffff,
/*0209*/ 0x0000304c,
/*020a*/ 0x00000200,
/*020b*/ 0x00000200,
/*020c*/ 0x00000200,
/*020d*/ 0x00000200,
/*020e*/ 0x0000304c,
/*020f*/ 0x00000200,
/*0210*/ 0x00000200,
/*0211*/ 0x00000200,
/*0212*/ 0x00000200,
/*0213*/ 0x0000304c,
/*0214*/ 0x00000200,
/*0215*/ 0x00000200,
/*0216*/ 0x00000200,
/*0217*/ 0x00000200,
/*0218*/ 0x00010000,
/*0219*/ 0x00000003,
/*021a*/ 0x01000001,
/*021b*/ 0x00000000,
/*021c*/ 0x00000000,
/*021d*/ 0x00000000,
/*021e*/ 0x00000000,
/*021f*/ 0x00000000,
/*0220*/ 0x00000000,
/*0221*/ 0x00000000,
/*0222*/ 0x00000000,
/*0223*/ 0x00000000,
/*0224*/ 0x00000000,
/*0225*/ 0x00000000,
/*0226*/ 0x00000000,
/*0227*/ 0x00000000,
/*0228*/ 0x00000000,
/*0229*/ 0x00000000,
/*022a*/ 0x00000000,
/*022b*/ 0x0f000101,
/*022c*/ 0x08492d25,
/*022d*/ 0x500e0c04,
/*022e*/ 0x0002500e,
/*022f*/ 0x00000301,
/*0230*/ 0x00000046,
/*0231*/ 0x000000cf,
/*0232*/ 0x00001826,
/*0233*/ 0x000000cf,
/*0234*/ 0x00001826,
/*0235*/ 0x00000005,
/*0236*/ 0x00000000,
/*0237*/ 0x00000000,
/*0238*/ 0x00000000,
/*0239*/ 0x00000000,
/*023a*/ 0x00000000,
/*023b*/ 0x00000000,
/*023c*/ 0x00000000,
/*023d*/ 0x00000000,
/*023e*/ 0x04010000,
/*023f*/ 0x00000404,
/*0240*/ 0x0101280a,
/*0241*/ 0x00000000,
/*0242*/ 0x00000000,
/*0243*/ 0x0003000f,
/*0244*/ 0x00000018,
/*0245*/ 0x00000000,
/*0246*/ 0x00000000,
/*0247*/ 0x00060002,
/*0248*/ 0x00010001,
/*0249*/ 0x01000101,
/*024a*/ 0x04020201,
/*024b*/ 0x00080804,
/*024c*/ 0x00000000,
/*024d*/ 0x08030000,
/*024e*/ 0x15150408,
/*024f*/ 0x00000000,
/*0250*/ 0x00000000,
/*0251*/ 0x00000000,
/*0252*/ 0x0f0f0000,
/*0253*/ 0x0000001e,
/*0254*/ 0x00000000,
/*0255*/ 0x01000300,
/*0256*/ 0x00000100,
/*0257*/ 0x00000000,
/*0258*/ 0x00000000,
/*0259*/ 0x01000000,
/*025a*/ 0x00000101,
/*025b*/ 0x55555a5a,
/*025c*/ 0x55555a5a,
/*025d*/ 0x55555a5a,
/*025e*/ 0x55555a5a,
/*025f*/ 0x0e0e0001,
/*0260*/ 0x0c0c000e,
/*0261*/ 0x0601000c,
/*0262*/ 0x17170106,
/*0263*/ 0x00020202,
/*0264*/ 0x03000000,
/*0265*/ 0x00000000,
/*0266*/ 0x00181703,
/*0267*/ 0x00280006,
/*0268*/ 0x00280016,
/*0269*/ 0x00000016,
/*026a*/ 0x00000000,
/*026b*/ 0x00000000,
/*026c*/ 0x00000000,
/*026d*/ 0x0a000000,
/*026e*/ 0x00010a14,
/*026f*/ 0x00030005,
/*0270*/ 0x0003018d,
/*0271*/ 0x000a018d,
/*0272*/ 0x00060100,
/*0273*/ 0x01000006,
/*0274*/ 0x018e018e,
/*0275*/ 0x018e0100,
/*0276*/ 0x1111018e,
/*0277*/ 0x10010204,
/*0278*/ 0x09090650,
/*0279*/ 0xff110202,
/*027a*/ 0x00ff1000,
/*027b*/ 0x00ff1000,
/*027c*/ 0x04041000,
/*027d*/ 0x18020100,
/*027e*/ 0x01010018,
/*027f*/ 0x004a004a,
/*0280*/ 0x004b004a,
/*0281*/ 0x050f0000,
/*0282*/ 0x0c01021e,
/*0283*/ 0x34000000,
/*0284*/ 0x00000000,
/*0285*/ 0x00000000,
/*0286*/ 0x00000000,
/*0287*/ 0x00000000,
/*0288*/ 0x36312ed4,
/*0289*/ 0x2ed41111,
/*028a*/ 0x11113631,
/*028b*/ 0x36312ed4,
/*028c*/ 0xd4001111,
/*028d*/ 0x1136312e,
/*028e*/ 0x312ed411,
/*028f*/ 0xd4111136,
/*0290*/ 0x1136312e,
/*0291*/ 0x2ed40011,
/*0292*/ 0x11113631,
/*0293*/ 0x36312ed4,
/*0294*/ 0x2ed41111,
/*0295*/ 0x11113631,
/*0296*/ 0x312ed400,
/*0297*/ 0xd4111136,
/*0298*/ 0x1136312e,
/*0299*/ 0x312ed411,
/*029a*/ 0x00111136,
/*029b*/ 0x018d0200,
/*029c*/ 0x018d018d,
/*029d*/ 0x1d220c08,
/*029e*/ 0x00001f12,
/*029f*/ 0x4301b344,
/*02a0*/ 0x10172006,
/*02a1*/ 0x121d220c,
/*02a2*/ 0x01b3441f,
/*02a3*/ 0x17200643,
/*02a4*/ 0x1d220c10,
/*02a5*/ 0x00001f12,
/*02a6*/ 0x4301b344,
/*02a7*/ 0x10172006,
/*02a8*/ 0x00020002,
/*02a9*/ 0x00020002,
/*02aa*/ 0x00020002,
/*02ab*/ 0x00020002,
/*02ac*/ 0x00020002,
/*02ad*/ 0x00000000,
/*02ae*/ 0x00000000,
/*02af*/ 0x00000000,
/*02b0*/ 0x00000000,
/*02b1*/ 0x00000000,
/*02b2*/ 0x00000000,
/*02b3*/ 0x00000000,
/*02b4*/ 0x00000000,
/*02b5*/ 0x00000000,
/*02b6*/ 0x00000000,
/*02b7*/ 0x00000000,
/*02b8*/ 0x00000000,
/*02b9*/ 0x00000400,
/*02ba*/ 0x05040302,
/*02bb*/ 0x01000f0e,
/*02bc*/ 0x07060504,
/*02bd*/ 0x03020100,
/*02be*/ 0x02010000,
/*02bf*/ 0x00000103,
/*02c0*/ 0x0000304c,
/*02c1*/ 0x0001e2f8,
/*02c2*/ 0x0000304c,
/*02c3*/ 0x0001e2f8,
/*02c4*/ 0x0000304c,
/*02c5*/ 0x0001e2f8,
/*02c6*/ 0x08000000,
/*02c7*/ 0x00000100,
/*02c8*/ 0x00000000,
/*02c9*/ 0x00000000,
/*02ca*/ 0x00000000,
/*02cb*/ 0x00000000,
/*02cc*/ 0x00010000,
/*02cd*/ 0x00000000,
/*02ce*/ 0x00000000,
/*02cf*/ 0x00000000,
/*02d0*/ 0x00000000,
/*02d1*/ 0x00000000,
/*02d2*/ 0x00000000,
/*02d3*/ 0x00000000,
/*02d4*/ 0x00000000,
/*02d5*/ 0x00000000,
/*02d6*/ 0x00000000,
/*02d7*/ 0x00000000,
/*02d8*/ 0x00000000,
/*02d9*/ 0x00000000,
/*02da*/ 0x00000000,
/*02db*/ 0x00000000,
/*02dc*/ 0x00000000,
/*02dd*/ 0x00000000,
/*02de*/ 0x00000000,
/*02df*/ 0x00000000,
/*02e0*/ 0x00000000,
/*02e1*/ 0x00000000,
/*02e2*/ 0x00000000,
/*02e3*/ 0x00000000,
/*02e4*/ 0x00000000,
/*02e5*/ 0x00000000,
/*02e6*/ 0x00000000,
/*02e7*/ 0x00000000,
/*02e8*/ 0x00000000,
/*02e9*/ 0x00000000,
/*02ea*/ 0x00000000,
/*02eb*/ 0x00000000,
/*02ec*/ 0x00000000,
/*02ed*/ 0x00000000,
/*02ee*/ 0x00000002,
/*02ef*/ 0x00000000,
/*02f0*/ 0x00000000,
/*02f1*/ 0x00000000,
/*02f2*/ 0x00000000,
/*02f3*/ 0x00000000,
/*02f4*/ 0x00000000
};
@@ -0,0 +1,468 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define DDR_PHY_SLICE_REGSET_OFS_M3 0x0800
#define DDR_PHY_ADR_V_REGSET_OFS_M3 0x0a00
#define DDR_PHY_ADR_I_REGSET_OFS_M3 0x0a80
#define DDR_PHY_ADR_G_REGSET_OFS_M3 0x0b80
#define DDR_PI_REGSET_OFS_M3 0x0200
#define DDR_PHY_SLICE_REGSET_SIZE_M3 0x80
#define DDR_PHY_ADR_V_REGSET_SIZE_M3 0x80
#define DDR_PHY_ADR_I_REGSET_SIZE_M3 0x80
#define DDR_PHY_ADR_G_REGSET_SIZE_M3 0x80
#define DDR_PI_REGSET_SIZE_M3 0x100
#define DDR_PHY_SLICE_REGSET_NUM_M3 89
#define DDR_PHY_ADR_V_REGSET_NUM_M3 37
#define DDR_PHY_ADR_I_REGSET_NUM_M3 37
#define DDR_PHY_ADR_G_REGSET_NUM_M3 64
#define DDR_PI_REGSET_NUM_M3 202
static const uint32_t DDR_PHY_SLICE_REGSET_M3[DDR_PHY_SLICE_REGSET_NUM_M3] = {
/*0800*/ 0x76543210,
/*0801*/ 0x0004f008,
/*0802*/ 0x00000000,
/*0803*/ 0x00000000,
/*0804*/ 0x00010000,
/*0805*/ 0x036e6e0e,
/*0806*/ 0x026e6e0e,
/*0807*/ 0x00010300,
/*0808*/ 0x04000100,
/*0809*/ 0x00000300,
/*080a*/ 0x001700c0,
/*080b*/ 0x00b00201,
/*080c*/ 0x00030020,
/*080d*/ 0x00000000,
/*080e*/ 0x00000000,
/*080f*/ 0x00000000,
/*0810*/ 0x00000000,
/*0811*/ 0x00000000,
/*0812*/ 0x00000000,
/*0813*/ 0x00000000,
/*0814*/ 0x09000000,
/*0815*/ 0x04080000,
/*0816*/ 0x04080400,
/*0817*/ 0x00000000,
/*0818*/ 0x32103210,
/*0819*/ 0x00800708,
/*081a*/ 0x000f000c,
/*081b*/ 0x00000100,
/*081c*/ 0x55aa55aa,
/*081d*/ 0x33cc33cc,
/*081e*/ 0x0ff00ff0,
/*081f*/ 0x0f0ff0f0,
/*0820*/ 0x00018e38,
/*0821*/ 0x00000000,
/*0822*/ 0x00000000,
/*0823*/ 0x00000000,
/*0824*/ 0x00000000,
/*0825*/ 0x00000000,
/*0826*/ 0x00000000,
/*0827*/ 0x00000000,
/*0828*/ 0x00000000,
/*0829*/ 0x00000000,
/*082a*/ 0x00000000,
/*082b*/ 0x00000000,
/*082c*/ 0x00000000,
/*082d*/ 0x00000000,
/*082e*/ 0x00000000,
/*082f*/ 0x00000000,
/*0830*/ 0x00000000,
/*0831*/ 0x00000000,
/*0832*/ 0x00000000,
/*0833*/ 0x00200000,
/*0834*/ 0x08200820,
/*0835*/ 0x08200820,
/*0836*/ 0x08200820,
/*0837*/ 0x08200820,
/*0838*/ 0x08200820,
/*0839*/ 0x00000820,
/*083a*/ 0x03000300,
/*083b*/ 0x03000300,
/*083c*/ 0x03000300,
/*083d*/ 0x03000300,
/*083e*/ 0x00000300,
/*083f*/ 0x00000000,
/*0840*/ 0x00000000,
/*0841*/ 0x00000000,
/*0842*/ 0x00000000,
/*0843*/ 0x00a00000,
/*0844*/ 0x00a000a0,
/*0845*/ 0x00a000a0,
/*0846*/ 0x00a000a0,
/*0847*/ 0x00a000a0,
/*0848*/ 0x00a000a0,
/*0849*/ 0x00a000a0,
/*084a*/ 0x00a000a0,
/*084b*/ 0x00a000a0,
/*084c*/ 0x010900a0,
/*084d*/ 0x02000104,
/*084e*/ 0x00000000,
/*084f*/ 0x00010000,
/*0850*/ 0x00000200,
/*0851*/ 0x4041a151,
/*0852*/ 0xc00141a0,
/*0853*/ 0x0e0100c0,
/*0854*/ 0x0010000c,
/*0855*/ 0x0c064208,
/*0856*/ 0x000f0c18,
/*0857*/ 0x00e00140,
/*0858*/ 0x00000c20
};
static const uint32_t DDR_PHY_ADR_V_REGSET_M3[DDR_PHY_ADR_V_REGSET_NUM_M3] = {
/*0a00*/ 0x00000000,
/*0a01*/ 0x00000000,
/*0a02*/ 0x00000000,
/*0a03*/ 0x00000000,
/*0a04*/ 0x00000000,
/*0a05*/ 0x00000000,
/*0a06*/ 0x00000002,
/*0a07*/ 0x00000000,
/*0a08*/ 0x00000000,
/*0a09*/ 0x00000000,
/*0a0a*/ 0x00400320,
/*0a0b*/ 0x00000040,
/*0a0c*/ 0x00dcba98,
/*0a0d*/ 0x00000000,
/*0a0e*/ 0x00dcba98,
/*0a0f*/ 0x01000000,
/*0a10*/ 0x00020003,
/*0a11*/ 0x00000000,
/*0a12*/ 0x00000000,
/*0a13*/ 0x00000000,
/*0a14*/ 0x0000002a,
/*0a15*/ 0x00000015,
/*0a16*/ 0x00000015,
/*0a17*/ 0x0000002a,
/*0a18*/ 0x00000033,
/*0a19*/ 0x0000000c,
/*0a1a*/ 0x0000000c,
/*0a1b*/ 0x00000033,
/*0a1c*/ 0x0a418820,
/*0a1d*/ 0x003f0000,
/*0a1e*/ 0x0000003f,
/*0a1f*/ 0x0002c06e,
/*0a20*/ 0x02c002c0,
/*0a21*/ 0x02c002c0,
/*0a22*/ 0x000002c0,
/*0a23*/ 0x42080010,
/*0a24*/ 0x00000003
};
static const uint32_t DDR_PHY_ADR_I_REGSET_M3[DDR_PHY_ADR_I_REGSET_NUM_M3] = {
/*0a80*/ 0x04040404,
/*0a81*/ 0x00000404,
/*0a82*/ 0x00000000,
/*0a83*/ 0x00000000,
/*0a84*/ 0x00000000,
/*0a85*/ 0x00000000,
/*0a86*/ 0x00000002,
/*0a87*/ 0x00000000,
/*0a88*/ 0x00000000,
/*0a89*/ 0x00000000,
/*0a8a*/ 0x00400320,
/*0a8b*/ 0x00000040,
/*0a8c*/ 0x00000000,
/*0a8d*/ 0x00000000,
/*0a8e*/ 0x00000000,
/*0a8f*/ 0x01000000,
/*0a90*/ 0x00020003,
/*0a91*/ 0x00000000,
/*0a92*/ 0x00000000,
/*0a93*/ 0x00000000,
/*0a94*/ 0x0000002a,
/*0a95*/ 0x00000015,
/*0a96*/ 0x00000015,
/*0a97*/ 0x0000002a,
/*0a98*/ 0x00000033,
/*0a99*/ 0x0000000c,
/*0a9a*/ 0x0000000c,
/*0a9b*/ 0x00000033,
/*0a9c*/ 0x00000000,
/*0a9d*/ 0x00000000,
/*0a9e*/ 0x00000000,
/*0a9f*/ 0x0002c06e,
/*0aa0*/ 0x02c002c0,
/*0aa1*/ 0x02c002c0,
/*0aa2*/ 0x000002c0,
/*0aa3*/ 0x42080010,
/*0aa4*/ 0x00000003
};
static const uint32_t DDR_PHY_ADR_G_REGSET_M3[DDR_PHY_ADR_G_REGSET_NUM_M3] = {
/*0b80*/ 0x00000001,
/*0b81*/ 0x00000000,
/*0b82*/ 0x00000005,
/*0b83*/ 0x04000f00,
/*0b84*/ 0x00020080,
/*0b85*/ 0x00020055,
/*0b86*/ 0x00000000,
/*0b87*/ 0x00000000,
/*0b88*/ 0x00000000,
/*0b89*/ 0x00000050,
/*0b8a*/ 0x00000000,
/*0b8b*/ 0x01010100,
/*0b8c*/ 0x00000600,
/*0b8d*/ 0x50640000,
/*0b8e*/ 0x01421142,
/*0b8f*/ 0x00000142,
/*0b90*/ 0x00000000,
/*0b91*/ 0x000f1600,
/*0b92*/ 0x0f160f16,
/*0b93*/ 0x0f160f16,
/*0b94*/ 0x00000003,
/*0b95*/ 0x0002c000,
/*0b96*/ 0x02c002c0,
/*0b97*/ 0x000002c0,
/*0b98*/ 0x03421342,
/*0b99*/ 0x00000342,
/*0b9a*/ 0x00000000,
/*0b9b*/ 0x00000000,
/*0b9c*/ 0x05020000,
/*0b9d*/ 0x00000000,
/*0b9e*/ 0x00027f6e,
/*0b9f*/ 0x047f027f,
/*0ba0*/ 0x00027f6e,
/*0ba1*/ 0x00047f6e,
/*0ba2*/ 0x0003554f,
/*0ba3*/ 0x0001554f,
/*0ba4*/ 0x0001554f,
/*0ba5*/ 0x0001554f,
/*0ba6*/ 0x0001554f,
/*0ba7*/ 0x00003fee,
/*0ba8*/ 0x0001554f,
/*0ba9*/ 0x00003fee,
/*0baa*/ 0x0001554f,
/*0bab*/ 0x00027f6e,
/*0bac*/ 0x0001554f,
/*0bad*/ 0x00000000,
/*0bae*/ 0x00000000,
/*0baf*/ 0x00000000,
/*0bb0*/ 0x65000000,
/*0bb1*/ 0x00000000,
/*0bb2*/ 0x00000000,
/*0bb3*/ 0x00000201,
/*0bb4*/ 0x00000000,
/*0bb5*/ 0x00000000,
/*0bb6*/ 0x00000000,
/*0bb7*/ 0x00000000,
/*0bb8*/ 0x00000000,
/*0bb9*/ 0x00000000,
/*0bba*/ 0x00000000,
/*0bbb*/ 0x00000000,
/*0bbc*/ 0x06e40000,
/*0bbd*/ 0x00000000,
/*0bbe*/ 0x00000000,
/*0bbf*/ 0x00010000
};
static const uint32_t DDR_PI_REGSET_M3[DDR_PI_REGSET_NUM_M3] = {
/*0200*/ 0x00000b00,
/*0201*/ 0x00000100,
/*0202*/ 0x00000000,
/*0203*/ 0x0000ffff,
/*0204*/ 0x00000000,
/*0205*/ 0x0000ffff,
/*0206*/ 0x00000000,
/*0207*/ 0x304cffff,
/*0208*/ 0x00000200,
/*0209*/ 0x00000200,
/*020a*/ 0x00000200,
/*020b*/ 0x00000200,
/*020c*/ 0x0000304c,
/*020d*/ 0x00000200,
/*020e*/ 0x00000200,
/*020f*/ 0x00000200,
/*0210*/ 0x00000200,
/*0211*/ 0x0000304c,
/*0212*/ 0x00000200,
/*0213*/ 0x00000200,
/*0214*/ 0x00000200,
/*0215*/ 0x00000200,
/*0216*/ 0x00010000,
/*0217*/ 0x00000003,
/*0218*/ 0x01000001,
/*0219*/ 0x00000000,
/*021a*/ 0x00000000,
/*021b*/ 0x00000000,
/*021c*/ 0x00000000,
/*021d*/ 0x00000000,
/*021e*/ 0x00000000,
/*021f*/ 0x00000000,
/*0220*/ 0x00000000,
/*0221*/ 0x00000000,
/*0222*/ 0x00000000,
/*0223*/ 0x00000000,
/*0224*/ 0x00000000,
/*0225*/ 0x00000000,
/*0226*/ 0x00000000,
/*0227*/ 0x00000000,
/*0228*/ 0x00000000,
/*0229*/ 0x0f000101,
/*022a*/ 0x08492d25,
/*022b*/ 0x0e0c0004,
/*022c*/ 0x000e5000,
/*022d*/ 0x00000250,
/*022e*/ 0x00460003,
/*022f*/ 0x182600cf,
/*0230*/ 0x182600cf,
/*0231*/ 0x00000005,
/*0232*/ 0x00000000,
/*0233*/ 0x00000000,
/*0234*/ 0x00000000,
/*0235*/ 0x00000000,
/*0236*/ 0x00000000,
/*0237*/ 0x00000000,
/*0238*/ 0x00000000,
/*0239*/ 0x01000000,
/*023a*/ 0x00040404,
/*023b*/ 0x01280a00,
/*023c*/ 0x00000000,
/*023d*/ 0x000f0000,
/*023e*/ 0x00001803,
/*023f*/ 0x00000000,
/*0240*/ 0x00000000,
/*0241*/ 0x00060002,
/*0242*/ 0x00010001,
/*0243*/ 0x01000101,
/*0244*/ 0x04020201,
/*0245*/ 0x00080804,
/*0246*/ 0x00000000,
/*0247*/ 0x08030000,
/*0248*/ 0x15150408,
/*0249*/ 0x00000000,
/*024a*/ 0x00000000,
/*024b*/ 0x00000000,
/*024c*/ 0x000f0f00,
/*024d*/ 0x0000001e,
/*024e*/ 0x00000000,
/*024f*/ 0x01000300,
/*0250*/ 0x00000000,
/*0251*/ 0x00000000,
/*0252*/ 0x01000000,
/*0253*/ 0x00010101,
/*0254*/ 0x000e0e0e,
/*0255*/ 0x000c0c0c,
/*0256*/ 0x02060601,
/*0257*/ 0x00000000,
/*0258*/ 0x00000003,
/*0259*/ 0x00181703,
/*025a*/ 0x00280006,
/*025b*/ 0x00280016,
/*025c*/ 0x00000016,
/*025d*/ 0x00000000,
/*025e*/ 0x00000000,
/*025f*/ 0x00000000,
/*0260*/ 0x140a0000,
/*0261*/ 0x0005010a,
/*0262*/ 0x03018d03,
/*0263*/ 0x000a018d,
/*0264*/ 0x00060100,
/*0265*/ 0x01000006,
/*0266*/ 0x018e018e,
/*0267*/ 0x018e0100,
/*0268*/ 0x1111018e,
/*0269*/ 0x10010204,
/*026a*/ 0x09090650,
/*026b*/ 0x20110202,
/*026c*/ 0x00201000,
/*026d*/ 0x00201000,
/*026e*/ 0x04041000,
/*026f*/ 0x18020100,
/*0270*/ 0x00010118,
/*0271*/ 0x004b004a,
/*0272*/ 0x050f0000,
/*0273*/ 0x0c01021e,
/*0274*/ 0x34000000,
/*0275*/ 0x00000000,
/*0276*/ 0x00000000,
/*0277*/ 0x00000000,
/*0278*/ 0x0000d400,
/*0279*/ 0x0031002e,
/*027a*/ 0x00111136,
/*027b*/ 0x002e00d4,
/*027c*/ 0x11360031,
/*027d*/ 0x0000d411,
/*027e*/ 0x0031002e,
/*027f*/ 0x00111136,
/*0280*/ 0x002e00d4,
/*0281*/ 0x11360031,
/*0282*/ 0x0000d411,
/*0283*/ 0x0031002e,
/*0284*/ 0x00111136,
/*0285*/ 0x002e00d4,
/*0286*/ 0x11360031,
/*0287*/ 0x00d40011,
/*0288*/ 0x0031002e,
/*0289*/ 0x00111136,
/*028a*/ 0x002e00d4,
/*028b*/ 0x11360031,
/*028c*/ 0x0000d411,
/*028d*/ 0x0031002e,
/*028e*/ 0x00111136,
/*028f*/ 0x002e00d4,
/*0290*/ 0x11360031,
/*0291*/ 0x0000d411,
/*0292*/ 0x0031002e,
/*0293*/ 0x00111136,
/*0294*/ 0x002e00d4,
/*0295*/ 0x11360031,
/*0296*/ 0x02000011,
/*0297*/ 0x018d018d,
/*0298*/ 0x0c08018d,
/*0299*/ 0x1f121d22,
/*029a*/ 0x4301b344,
/*029b*/ 0x10172006,
/*029c*/ 0x1d220c10,
/*029d*/ 0x00001f12,
/*029e*/ 0x4301b344,
/*029f*/ 0x10172006,
/*02a0*/ 0x1d220c10,
/*02a1*/ 0x00001f12,
/*02a2*/ 0x4301b344,
/*02a3*/ 0x10172006,
/*02a4*/ 0x02000210,
/*02a5*/ 0x02000200,
/*02a6*/ 0x02000200,
/*02a7*/ 0x02000200,
/*02a8*/ 0x02000200,
/*02a9*/ 0x00000000,
/*02aa*/ 0x00000000,
/*02ab*/ 0x00000000,
/*02ac*/ 0x00000000,
/*02ad*/ 0x00000000,
/*02ae*/ 0x00000000,
/*02af*/ 0x00000000,
/*02b0*/ 0x00000000,
/*02b1*/ 0x00000000,
/*02b2*/ 0x00000000,
/*02b3*/ 0x00000000,
/*02b4*/ 0x00000000,
/*02b5*/ 0x00000400,
/*02b6*/ 0x15141312,
/*02b7*/ 0x11100f0e,
/*02b8*/ 0x080b0c0d,
/*02b9*/ 0x05040a09,
/*02ba*/ 0x01000706,
/*02bb*/ 0x00000302,
/*02bc*/ 0x01030201,
/*02bd*/ 0x00304c00,
/*02be*/ 0x0001e2f8,
/*02bf*/ 0x0000304c,
/*02c0*/ 0x0001e2f8,
/*02c1*/ 0x0000304c,
/*02c2*/ 0x0001e2f8,
/*02c3*/ 0x08000000,
/*02c4*/ 0x00000100,
/*02c5*/ 0x00000000,
/*02c6*/ 0x00000000,
/*02c7*/ 0x00000000,
/*02c8*/ 0x00000000,
/*02c9*/ 0x00000002
};
@@ -0,0 +1,587 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define DDR_PHY_SLICE_REGSET_OFS_M3N 0x0800
#define DDR_PHY_ADR_V_REGSET_OFS_M3N 0x0a00
#define DDR_PHY_ADR_I_REGSET_OFS_M3N 0x0a80
#define DDR_PHY_ADR_G_REGSET_OFS_M3N 0x0b80
#define DDR_PI_REGSET_OFS_M3N 0x0200
#define DDR_PHY_SLICE_REGSET_SIZE_M3N 0x80
#define DDR_PHY_ADR_V_REGSET_SIZE_M3N 0x80
#define DDR_PHY_ADR_I_REGSET_SIZE_M3N 0x80
#define DDR_PHY_ADR_G_REGSET_SIZE_M3N 0x80
#define DDR_PI_REGSET_SIZE_M3N 0x100
#define DDR_PHY_SLICE_REGSET_NUM_M3N 101
#define DDR_PHY_ADR_V_REGSET_NUM_M3N 37
#define DDR_PHY_ADR_I_REGSET_NUM_M3N 37
#define DDR_PHY_ADR_G_REGSET_NUM_M3N 87
#define DDR_PI_REGSET_NUM_M3N 286
static const uint32_t DDR_PHY_SLICE_REGSET_M3N[DDR_PHY_SLICE_REGSET_NUM_M3N] = {
/*0800*/ 0x76543210,
/*0801*/ 0x0004f008,
/*0802*/ 0x00020200,
/*0803*/ 0x00000000,
/*0804*/ 0x00000000,
/*0805*/ 0x00010000,
/*0806*/ 0x036e6e0e,
/*0807*/ 0x026e6e0e,
/*0808*/ 0x00000103,
/*0809*/ 0x00040001,
/*080a*/ 0x00000103,
/*080b*/ 0x00000001,
/*080c*/ 0x00000000,
/*080d*/ 0x00000000,
/*080e*/ 0x00000100,
/*080f*/ 0x001800c0,
/*0810*/ 0x020100b0,
/*0811*/ 0x00030020,
/*0812*/ 0x00000000,
/*0813*/ 0x00000000,
/*0814*/ 0x0000aaaa,
/*0815*/ 0x00005555,
/*0816*/ 0x0000b5b5,
/*0817*/ 0x00004a4a,
/*0818*/ 0x00000000,
/*0819*/ 0x09000000,
/*081a*/ 0x04080000,
/*081b*/ 0x08040000,
/*081c*/ 0x00000004,
/*081d*/ 0x00800710,
/*081e*/ 0x000f000c,
/*081f*/ 0x00000100,
/*0820*/ 0x55aa55aa,
/*0821*/ 0x33cc33cc,
/*0822*/ 0x0ff00ff0,
/*0823*/ 0x0f0ff0f0,
/*0824*/ 0x00018e38,
/*0825*/ 0x00000000,
/*0826*/ 0x00000000,
/*0827*/ 0x00000000,
/*0828*/ 0x00000000,
/*0829*/ 0x00000000,
/*082a*/ 0x00000000,
/*082b*/ 0x00000000,
/*082c*/ 0x00000000,
/*082d*/ 0x00000000,
/*082e*/ 0x00000000,
/*082f*/ 0x00000000,
/*0830*/ 0x00000000,
/*0831*/ 0x00000000,
/*0832*/ 0x00000000,
/*0833*/ 0x00000000,
/*0834*/ 0x00000000,
/*0835*/ 0x00000000,
/*0836*/ 0x00000000,
/*0837*/ 0x00000000,
/*0838*/ 0x00000000,
/*0839*/ 0x00000000,
/*083a*/ 0x00000104,
/*083b*/ 0x00082020,
/*083c*/ 0x08200820,
/*083d*/ 0x08200820,
/*083e*/ 0x08200820,
/*083f*/ 0x08200820,
/*0840*/ 0x08200820,
/*0841*/ 0x00000000,
/*0842*/ 0x00000000,
/*0843*/ 0x03000300,
/*0844*/ 0x03000300,
/*0845*/ 0x03000300,
/*0846*/ 0x03000300,
/*0847*/ 0x00000300,
/*0848*/ 0x00000000,
/*0849*/ 0x00000000,
/*084a*/ 0x00000000,
/*084b*/ 0x00000000,
/*084c*/ 0x00000000,
/*084d*/ 0x00a000a0,
/*084e*/ 0x00a000a0,
/*084f*/ 0x00a000a0,
/*0850*/ 0x00a000a0,
/*0851*/ 0x00a000a0,
/*0852*/ 0x00a000a0,
/*0853*/ 0x00a000a0,
/*0854*/ 0x00a000a0,
/*0855*/ 0x00a000a0,
/*0856*/ 0x01040119,
/*0857*/ 0x00000200,
/*0858*/ 0x01000000,
/*0859*/ 0x00000200,
/*085a*/ 0x00000004,
/*085b*/ 0x4041a151,
/*085c*/ 0x0141a0a0,
/*085d*/ 0x0000c0c0,
/*085e*/ 0x0e0c000e,
/*085f*/ 0x10001000,
/*0860*/ 0x0c073e42,
/*0861*/ 0x000f0c28,
/*0862*/ 0x00e00140,
/*0863*/ 0x000c0020,
/*0864*/ 0x00000203
};
static const uint32_t DDR_PHY_ADR_V_REGSET_M3N[DDR_PHY_ADR_V_REGSET_NUM_M3N] = {
/*0a00*/ 0x00000000,
/*0a01*/ 0x00000000,
/*0a02*/ 0x00000000,
/*0a03*/ 0x00000000,
/*0a04*/ 0x00000000,
/*0a05*/ 0x00000000,
/*0a06*/ 0x00000000,
/*0a07*/ 0x01000000,
/*0a08*/ 0x00020000,
/*0a09*/ 0x00000000,
/*0a0a*/ 0x00000000,
/*0a0b*/ 0x00000000,
/*0a0c*/ 0x00400000,
/*0a0d*/ 0x00000080,
/*0a0e*/ 0x00dcba98,
/*0a0f*/ 0x03000000,
/*0a10*/ 0x00000200,
/*0a11*/ 0x00000000,
/*0a12*/ 0x00000000,
/*0a13*/ 0x00000000,
/*0a14*/ 0x0000002a,
/*0a15*/ 0x00000015,
/*0a16*/ 0x00000015,
/*0a17*/ 0x0000002a,
/*0a18*/ 0x00000033,
/*0a19*/ 0x0000000c,
/*0a1a*/ 0x0000000c,
/*0a1b*/ 0x00000033,
/*0a1c*/ 0x0a418820,
/*0a1d*/ 0x003f0000,
/*0a1e*/ 0x0000013f,
/*0a1f*/ 0x0002c06e,
/*0a20*/ 0x02c002c0,
/*0a21*/ 0x02c002c0,
/*0a22*/ 0x000002c0,
/*0a23*/ 0x42080010,
/*0a24*/ 0x0000033e
};
static const uint32_t DDR_PHY_ADR_I_REGSET_M3N[DDR_PHY_ADR_I_REGSET_NUM_M3N] = {
/*0a80*/ 0x00000000,
/*0a81*/ 0x00000000,
/*0a82*/ 0x00000000,
/*0a83*/ 0x00000000,
/*0a84*/ 0x00000000,
/*0a85*/ 0x00000000,
/*0a86*/ 0x00000000,
/*0a87*/ 0x01000000,
/*0a88*/ 0x00020000,
/*0a89*/ 0x00000000,
/*0a8a*/ 0x00000000,
/*0a8b*/ 0x00000000,
/*0a8c*/ 0x00400000,
/*0a8d*/ 0x00000080,
/*0a8e*/ 0x00000000,
/*0a8f*/ 0x03000000,
/*0a90*/ 0x00000200,
/*0a91*/ 0x00000000,
/*0a92*/ 0x00000000,
/*0a93*/ 0x00000000,
/*0a94*/ 0x0000002a,
/*0a95*/ 0x00000015,
/*0a96*/ 0x00000015,
/*0a97*/ 0x0000002a,
/*0a98*/ 0x00000033,
/*0a99*/ 0x0000000c,
/*0a9a*/ 0x0000000c,
/*0a9b*/ 0x00000033,
/*0a9c*/ 0x00000000,
/*0a9d*/ 0x00000000,
/*0a9e*/ 0x00000000,
/*0a9f*/ 0x0002c06e,
/*0aa0*/ 0x02c002c0,
/*0aa1*/ 0x02c002c0,
/*0aa2*/ 0x000002c0,
/*0aa3*/ 0x42080010,
/*0aa4*/ 0x0000033e
};
static const uint32_t DDR_PHY_ADR_G_REGSET_M3N[DDR_PHY_ADR_G_REGSET_NUM_M3N] = {
/*0b80*/ 0x00000000,
/*0b81*/ 0x00000100,
/*0b82*/ 0x00000000,
/*0b83*/ 0x00050000,
/*0b84*/ 0x00000000,
/*0b85*/ 0x0004000f,
/*0b86*/ 0x00280080,
/*0b87*/ 0x02005502,
/*0b88*/ 0x00000000,
/*0b89*/ 0x00000000,
/*0b8a*/ 0x00000000,
/*0b8b*/ 0x00000050,
/*0b8c*/ 0x00000000,
/*0b8d*/ 0x01010100,
/*0b8e*/ 0x00010000,
/*0b8f*/ 0x00000000,
/*0b90*/ 0x00000101,
/*0b91*/ 0x00000000,
/*0b92*/ 0x00000000,
/*0b93*/ 0x00000000,
/*0b94*/ 0x00000000,
/*0b95*/ 0x00005064,
/*0b96*/ 0x01421142,
/*0b97*/ 0x00000142,
/*0b98*/ 0x00000000,
/*0b99*/ 0x000f1600,
/*0b9a*/ 0x0f160f16,
/*0b9b*/ 0x0f160f16,
/*0b9c*/ 0x00000003,
/*0b9d*/ 0x0002c000,
/*0b9e*/ 0x02c002c0,
/*0b9f*/ 0x000002c0,
/*0ba0*/ 0x08040201,
/*0ba1*/ 0x03421342,
/*0ba2*/ 0x00000342,
/*0ba3*/ 0x00000000,
/*0ba4*/ 0x00000000,
/*0ba5*/ 0x05030000,
/*0ba6*/ 0x00010700,
/*0ba7*/ 0x00000014,
/*0ba8*/ 0x00027f6e,
/*0ba9*/ 0x047f027f,
/*0baa*/ 0x00027f6e,
/*0bab*/ 0x00047f6e,
/*0bac*/ 0x0003554f,
/*0bad*/ 0x0001554f,
/*0bae*/ 0x0001554f,
/*0baf*/ 0x0001554f,
/*0bb0*/ 0x0001554f,
/*0bb1*/ 0x00003fee,
/*0bb2*/ 0x0001554f,
/*0bb3*/ 0x00003fee,
/*0bb4*/ 0x0001554f,
/*0bb5*/ 0x00027f6e,
/*0bb6*/ 0x0001554f,
/*0bb7*/ 0x00004011,
/*0bb8*/ 0x00004410,
/*0bb9*/ 0x00000000,
/*0bba*/ 0x00000000,
/*0bbb*/ 0x00000000,
/*0bbc*/ 0x00000265,
/*0bbd*/ 0x00000000,
/*0bbe*/ 0x00040401,
/*0bbf*/ 0x00000000,
/*0bc0*/ 0x03000000,
/*0bc1*/ 0x00000020,
/*0bc2*/ 0x00000000,
/*0bc3*/ 0x00000000,
/*0bc4*/ 0x04102006,
/*0bc5*/ 0x00041020,
/*0bc6*/ 0x01c98c98,
/*0bc7*/ 0x00400000,
/*0bc8*/ 0x00000000,
/*0bc9*/ 0x0001ffff,
/*0bca*/ 0x00000000,
/*0bcb*/ 0x00000000,
/*0bcc*/ 0x00000001,
/*0bcd*/ 0x00000000,
/*0bce*/ 0x00000000,
/*0bcf*/ 0x00000000,
/*0bd0*/ 0x76543210,
/*0bd1*/ 0x06010198,
/*0bd2*/ 0x00000000,
/*0bd3*/ 0x00000000,
/*0bd4*/ 0x04070000,
/*0bd5*/ 0x00000001,
/*0bd6*/ 0x00000f00
};
static const uint32_t DDR_PI_REGSET_M3N[DDR_PI_REGSET_NUM_M3N] = {
/*0200*/ 0x00000b00,
/*0201*/ 0x00000101,
/*0202*/ 0x01640000,
/*0203*/ 0x00000014,
/*0204*/ 0x00000014,
/*0205*/ 0x00000014,
/*0206*/ 0x00000014,
/*0207*/ 0x00000000,
/*0208*/ 0x00000000,
/*0209*/ 0x0000ffff,
/*020a*/ 0x00000000,
/*020b*/ 0x0000ffff,
/*020c*/ 0x00000000,
/*020d*/ 0x0000ffff,
/*020e*/ 0x0000304c,
/*020f*/ 0x00000200,
/*0210*/ 0x00000200,
/*0211*/ 0x00000200,
/*0212*/ 0x00000200,
/*0213*/ 0x0000304c,
/*0214*/ 0x00000200,
/*0215*/ 0x00000200,
/*0216*/ 0x00000200,
/*0217*/ 0x00000200,
/*0218*/ 0x0000304c,
/*0219*/ 0x00000200,
/*021a*/ 0x00000200,
/*021b*/ 0x00000200,
/*021c*/ 0x00000200,
/*021d*/ 0x00010000,
/*021e*/ 0x00000003,
/*021f*/ 0x01000001,
/*0220*/ 0x00000000,
/*0221*/ 0x00000000,
/*0222*/ 0x00000000,
/*0223*/ 0x00000000,
/*0224*/ 0x00000000,
/*0225*/ 0x00000000,
/*0226*/ 0x00000000,
/*0227*/ 0x00000000,
/*0228*/ 0x00000000,
/*0229*/ 0x00000000,
/*022a*/ 0x00000000,
/*022b*/ 0x00000000,
/*022c*/ 0x00000000,
/*022d*/ 0x00000000,
/*022e*/ 0x00000000,
/*022f*/ 0x00000000,
/*0230*/ 0x0f000101,
/*0231*/ 0x084d3129,
/*0232*/ 0x0e0c0004,
/*0233*/ 0x000e5000,
/*0234*/ 0x01000250,
/*0235*/ 0x00000003,
/*0236*/ 0x00000046,
/*0237*/ 0x000000cf,
/*0238*/ 0x00001826,
/*0239*/ 0x000000cf,
/*023a*/ 0x00001826,
/*023b*/ 0x00000000,
/*023c*/ 0x00000000,
/*023d*/ 0x00000000,
/*023e*/ 0x00000000,
/*023f*/ 0x00000000,
/*0240*/ 0x00000000,
/*0241*/ 0x00000000,
/*0242*/ 0x00000000,
/*0243*/ 0x00000000,
/*0244*/ 0x00000000,
/*0245*/ 0x01000000,
/*0246*/ 0x00040404,
/*0247*/ 0x01280a00,
/*0248*/ 0x00000001,
/*0249*/ 0x00000000,
/*024a*/ 0x03000f00,
/*024b*/ 0x00200020,
/*024c*/ 0x00000020,
/*024d*/ 0x00000000,
/*024e*/ 0x00000000,
/*024f*/ 0x00010002,
/*0250*/ 0x01010001,
/*0251*/ 0x02010100,
/*0252*/ 0x08040402,
/*0253*/ 0x00000008,
/*0254*/ 0x00000000,
/*0255*/ 0x04080803,
/*0256*/ 0x00001515,
/*0257*/ 0x00000000,
/*0258*/ 0x000000aa,
/*0259*/ 0x00000055,
/*025a*/ 0x000000b5,
/*025b*/ 0x0000004a,
/*025c*/ 0x00000056,
/*025d*/ 0x000000a9,
/*025e*/ 0x000000a9,
/*025f*/ 0x000000b5,
/*0260*/ 0x00000000,
/*0261*/ 0x00000000,
/*0262*/ 0x0f000000,
/*0263*/ 0x00001e0f,
/*0264*/ 0x000007d0,
/*0265*/ 0x01000300,
/*0266*/ 0x00000100,
/*0267*/ 0x00000000,
/*0268*/ 0x00000000,
/*0269*/ 0x01000000,
/*026a*/ 0x00010101,
/*026b*/ 0x000e0e0e,
/*026c*/ 0x000c0c0c,
/*026d*/ 0x01060601,
/*026e*/ 0x04041717,
/*026f*/ 0x00000004,
/*0270*/ 0x00000300,
/*0271*/ 0x17030000,
/*0272*/ 0x00060018,
/*0273*/ 0x00160028,
/*0274*/ 0x00160028,
/*0275*/ 0x00000000,
/*0276*/ 0x00000000,
/*0277*/ 0x00000000,
/*0278*/ 0x0a000000,
/*0279*/ 0x00010a14,
/*027a*/ 0x00030005,
/*027b*/ 0x0003018d,
/*027c*/ 0x000a018d,
/*027d*/ 0x00060100,
/*027e*/ 0x01000006,
/*027f*/ 0x018e018e,
/*0280*/ 0x018e0100,
/*0281*/ 0x1e1a018e,
/*0282*/ 0x1e1a1e1a,
/*0283*/ 0x01010204,
/*0284*/ 0x06501001,
/*0285*/ 0x090d0a07,
/*0286*/ 0x090d0a07,
/*0287*/ 0x0811180f,
/*0288*/ 0x00ff1102,
/*0289*/ 0x00ff1000,
/*028a*/ 0x00ff1000,
/*028b*/ 0x04041000,
/*028c*/ 0x18020100,
/*028d*/ 0x01010018,
/*028e*/ 0x005f005f,
/*028f*/ 0x005f005f,
/*0290*/ 0x050f0000,
/*0291*/ 0x051e051e,
/*0292*/ 0x0c01021e,
/*0293*/ 0x00000c0c,
/*0294*/ 0x00003400,
/*0295*/ 0x00000000,
/*0296*/ 0x00000000,
/*0297*/ 0x00000000,
/*0298*/ 0x00000000,
/*0299*/ 0x002e00d4,
/*029a*/ 0x11360031,
/*029b*/ 0x00d41611,
/*029c*/ 0x0031002e,
/*029d*/ 0x16111136,
/*029e*/ 0x002e00d4,
/*029f*/ 0x11360031,
/*02a0*/ 0x00001611,
/*02a1*/ 0x002e00d4,
/*02a2*/ 0x11360031,
/*02a3*/ 0x00d41611,
/*02a4*/ 0x0031002e,
/*02a5*/ 0x16111136,
/*02a6*/ 0x002e00d4,
/*02a7*/ 0x11360031,
/*02a8*/ 0x00001611,
/*02a9*/ 0x002e00d4,
/*02aa*/ 0x11360031,
/*02ab*/ 0x00d41611,
/*02ac*/ 0x0031002e,
/*02ad*/ 0x16111136,
/*02ae*/ 0x002e00d4,
/*02af*/ 0x11360031,
/*02b0*/ 0x00001611,
/*02b1*/ 0x002e00d4,
/*02b2*/ 0x11360031,
/*02b3*/ 0x00d41611,
/*02b4*/ 0x0031002e,
/*02b5*/ 0x16111136,
/*02b6*/ 0x002e00d4,
/*02b7*/ 0x11360031,
/*02b8*/ 0x00001611,
/*02b9*/ 0x00018d00,
/*02ba*/ 0x018d018d,
/*02bb*/ 0x1d220c08,
/*02bc*/ 0x00001f12,
/*02bd*/ 0x4301b344,
/*02be*/ 0x17032006,
/*02bf*/ 0x220c1010,
/*02c0*/ 0x001f121d,
/*02c1*/ 0x4301b344,
/*02c2*/ 0x17062006,
/*02c3*/ 0x220c1010,
/*02c4*/ 0x001f121d,
/*02c5*/ 0x4301b344,
/*02c6*/ 0x17182006,
/*02c7*/ 0x00021010,
/*02c8*/ 0x00020002,
/*02c9*/ 0x00020002,
/*02ca*/ 0x00020002,
/*02cb*/ 0x00020002,
/*02cc*/ 0x00000002,
/*02cd*/ 0x00000000,
/*02ce*/ 0x00000000,
/*02cf*/ 0x00000000,
/*02d0*/ 0x00000000,
/*02d1*/ 0x00000000,
/*02d2*/ 0x00000000,
/*02d3*/ 0x00000000,
/*02d4*/ 0x00000000,
/*02d5*/ 0x00000000,
/*02d6*/ 0x00000000,
/*02d7*/ 0x00000000,
/*02d8*/ 0x00000000,
/*02d9*/ 0x00000400,
/*02da*/ 0x15141312,
/*02db*/ 0x11100f0e,
/*02dc*/ 0x080b0c0d,
/*02dd*/ 0x05040a09,
/*02de*/ 0x01000706,
/*02df*/ 0x00000302,
/*02e0*/ 0x01030201,
/*02e1*/ 0x00304c08,
/*02e2*/ 0x0001e2f8,
/*02e3*/ 0x0000304c,
/*02e4*/ 0x0001e2f8,
/*02e5*/ 0x0000304c,
/*02e6*/ 0x0001e2f8,
/*02e7*/ 0x08000000,
/*02e8*/ 0x00000100,
/*02e9*/ 0x00000000,
/*02ea*/ 0x00000000,
/*02eb*/ 0x00000000,
/*02ec*/ 0x00000000,
/*02ed*/ 0x00010000,
/*02ee*/ 0x00000000,
/*02ef*/ 0x00000000,
/*02f0*/ 0x00000000,
/*02f1*/ 0x00000000,
/*02f2*/ 0x00000000,
/*02f3*/ 0x00000000,
/*02f4*/ 0x00000000,
/*02f5*/ 0x00000000,
/*02f6*/ 0x00000000,
/*02f7*/ 0x00000000,
/*02f8*/ 0x00000000,
/*02f9*/ 0x00000000,
/*02fa*/ 0x00000000,
/*02fb*/ 0x00000000,
/*02fc*/ 0x00000000,
/*02fd*/ 0x00000000,
/*02fe*/ 0x00000000,
/*02ff*/ 0x00000000,
/*0300*/ 0x00000000,
/*0301*/ 0x00000000,
/*0302*/ 0x00000000,
/*0303*/ 0x00000000,
/*0304*/ 0x00000000,
/*0305*/ 0x00000000,
/*0306*/ 0x00000000,
/*0307*/ 0x00000000,
/*0308*/ 0x00000000,
/*0309*/ 0x00000000,
/*030a*/ 0x00000000,
/*030b*/ 0x00000000,
/*030c*/ 0x00000000,
/*030d*/ 0x00000000,
/*030e*/ 0x00000000,
/*030f*/ 0x00050002,
/*0310*/ 0x015c0057,
/*0311*/ 0x01000100,
/*0312*/ 0x01020001,
/*0313*/ 0x00010300,
/*0314*/ 0x05000104,
/*0315*/ 0x01060001,
/*0316*/ 0x00010700,
/*0317*/ 0x00000000,
/*0318*/ 0x00000000,
/*0319*/ 0x00000001,
/*031a*/ 0x00000000,
/*031b*/ 0x00000000,
/*031c*/ 0x00000000,
/*031d*/ 0x20080101
};
@@ -0,0 +1,165 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <lib/mmio.h>
#include "dram_sub_func.h"
#include "rcar_def.h"
#if RCAR_SYSTEM_SUSPEND
/* Local defines */
#define DRAM_BACKUP_GPIO_USE 0
#include "iic_dvfs.h"
#if PMIC_ROHM_BD9571
#define PMIC_SLAVE_ADDR 0x30U
#define PMIC_BKUP_MODE_CNT 0x20U
#define PMIC_QLLM_CNT 0x27U
#define BIT_BKUP_CTRL_OUT BIT(4)
#define BIT_QLLM_DDR0_EN BIT(0)
#define BIT_QLLM_DDR1_EN BIT(1)
#endif
#define GPIO_BKUP_REQB_SHIFT_SALVATOR 9U /* GP1_9 (BKUP_REQB) */
#define GPIO_BKUP_TRG_SHIFT_SALVATOR 8U /* GP1_8 (BKUP_TRG) */
#define GPIO_BKUP_REQB_SHIFT_EBISU 14U /* GP6_14(BKUP_REQB) */
#define GPIO_BKUP_TRG_SHIFT_EBISU 13U /* GP6_13(BKUP_TRG) */
#define GPIO_BKUP_REQB_SHIFT_CONDOR 1U /* GP3_1 (BKUP_REQB) */
#define GPIO_BKUP_TRG_SHIFT_CONDOR 0U /* GP3_0 (BKUP_TRG) */
#define DRAM_BKUP_TRG_LOOP_CNT 1000U
#endif
void rcar_dram_get_boot_status(uint32_t *status)
{
#if RCAR_SYSTEM_SUSPEND
uint32_t reg_data;
uint32_t product;
uint32_t shift;
uint32_t gpio;
product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
if (product == PRR_PRODUCT_V3H) {
shift = GPIO_BKUP_TRG_SHIFT_CONDOR;
gpio = GPIO_INDT3;
} else if (product == PRR_PRODUCT_E3) {
shift = GPIO_BKUP_TRG_SHIFT_EBISU;
gpio = GPIO_INDT6;
} else {
shift = GPIO_BKUP_TRG_SHIFT_SALVATOR;
gpio = GPIO_INDT1;
}
reg_data = mmio_read_32(gpio);
if (reg_data & BIT(shift))
*status = DRAM_BOOT_STATUS_WARM;
else
*status = DRAM_BOOT_STATUS_COLD;
#else /* RCAR_SYSTEM_SUSPEND */
*status = DRAM_BOOT_STATUS_COLD;
#endif /* RCAR_SYSTEM_SUSPEND */
}
int32_t rcar_dram_update_boot_status(uint32_t status)
{
int32_t ret = 0;
#if RCAR_SYSTEM_SUSPEND
uint32_t reg_data;
#if PMIC_ROHM_BD9571
#if DRAM_BACKUP_GPIO_USE == 0
uint8_t bkup_mode_cnt = 0U;
#else
uint32_t reqb, outd;
#endif
uint8_t qllm_cnt = 0U;
int32_t i2c_dvfs_ret = -1;
#endif
uint32_t loop_count;
uint32_t product;
uint32_t trg;
uint32_t gpio;
product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
if (product == PRR_PRODUCT_V3H) {
#if DRAM_BACKUP_GPIO_USE == 1
reqb = GPIO_BKUP_REQB_SHIFT_CONDOR;
outd = GPIO_OUTDT3;
#endif
trg = GPIO_BKUP_TRG_SHIFT_CONDOR;
gpio = GPIO_INDT3;
} else if (product == PRR_PRODUCT_E3) {
#if DRAM_BACKUP_GPIO_USE == 1
reqb = GPIO_BKUP_REQB_SHIFT_EBISU;
outd = GPIO_OUTDT6;
#endif
trg = GPIO_BKUP_TRG_SHIFT_EBISU;
gpio = GPIO_INDT6;
} else {
#if DRAM_BACKUP_GPIO_USE == 1
reqb = GPIO_BKUP_REQB_SHIFT_SALVATOR;
outd = GPIO_OUTDT1;
#endif
trg = GPIO_BKUP_TRG_SHIFT_SALVATOR;
gpio = GPIO_INDT1;
}
if (status == DRAM_BOOT_STATUS_WARM) {
#if DRAM_BACKUP_GPIO_USE == 1
mmio_setbits_32(outd, BIT(reqb));
#else
#if PMIC_ROHM_BD9571
/* Set BKUP_CRTL_OUT=High (BKUP mode cnt register) */
i2c_dvfs_ret = rcar_iic_dvfs_receive(PMIC_SLAVE_ADDR,
PMIC_BKUP_MODE_CNT,
&bkup_mode_cnt);
if (i2c_dvfs_ret) {
ERROR("BKUP mode cnt READ ERROR.\n");
ret = DRAM_UPDATE_STATUS_ERR;
} else {
bkup_mode_cnt &= (uint8_t)~BIT_BKUP_CTRL_OUT;
i2c_dvfs_ret = rcar_iic_dvfs_send(PMIC_SLAVE_ADDR,
PMIC_BKUP_MODE_CNT,
bkup_mode_cnt);
if (i2c_dvfs_ret) {
ERROR("BKUP mode cnt WRITE ERROR. value = %d\n",
bkup_mode_cnt);
ret = DRAM_UPDATE_STATUS_ERR;
}
}
#endif /* PMIC_ROHM_BD9571 */
#endif /* DRAM_BACKUP_GPIO_USE == 1 */
/* Wait BKUP_TRG=Low */
loop_count = DRAM_BKUP_TRG_LOOP_CNT;
while (loop_count > 0) {
reg_data = mmio_read_32(gpio);
if (!(reg_data & BIT(trg)))
break;
loop_count--;
}
if (!loop_count) {
ERROR("\nWarm booting...\n"
" The potential of BKUP_TRG did not switch to Low.\n"
" If you expect the operation of cold boot,\n"
" check the board configuration (ex, Dip-SW) and/or the H/W failure.\n");
ret = DRAM_UPDATE_STATUS_ERR;
}
}
#if PMIC_ROHM_BD9571
if (!ret) {
qllm_cnt = BIT_QLLM_DDR0_EN | BIT_QLLM_DDR1_EN;
i2c_dvfs_ret = rcar_iic_dvfs_send(PMIC_SLAVE_ADDR,
PMIC_QLLM_CNT,
qllm_cnt);
if (i2c_dvfs_ret) {
ERROR("QLLM cnt WRITE ERROR. value = %d\n", qllm_cnt);
ret = DRAM_UPDATE_STATUS_ERR;
}
}
#endif
#endif
return ret;
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef DRAM_SUB_FUNC_H
#define DRAM_SUB_FUNC_H
#define DRAM_UPDATE_STATUS_ERR -1
#define DRAM_BOOT_STATUS_COLD 0
#define DRAM_BOOT_STATUS_WARM 1
int32_t rcar_dram_update_boot_status(uint32_t status);
void rcar_dram_get_boot_status(uint32_t *status);
#endif /* DRAM_SUB_FUNC_H */
@@ -0,0 +1,257 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef BOOT_INIT_DRAM_REGDEF_H_
#define BOOT_INIT_DRAM_REGDEF_H_
/* DBSC registers */
#define DBSC_DBSYSCONF0 0xE6790000U
#define DBSC_DBSYSCONF1 0xE6790004U
#define DBSC_DBPHYCONF0 0xE6790010U
#define DBSC_DBKIND 0xE6790020U
#define DBSC_DBMEMCONF(ch, cs) (0xE6790030U + 0x10U * (ch) + 0x04U * (cs))
#define DBSC_DBMEMCONF_0_0 0xE6790030U
#define DBSC_DBMEMCONF_0_1 0xE6790034U
#define DBSC_DBMEMCONF_0_2 0xE6790038U
#define DBSC_DBMEMCONF_0_3 0xE679003CU
#define DBSC_DBMEMCONF_1_2 0xE6790048U
#define DBSC_DBMEMCONF_1_3 0xE679004CU
#define DBSC_DBMEMCONF_1_0 0xE6790040U
#define DBSC_DBMEMCONF_1_1 0xE6790044U
#define DBSC_DBMEMCONF_2_0 0xE6790050U
#define DBSC_DBMEMCONF_2_1 0xE6790054U
#define DBSC_DBMEMCONF_2_2 0xE6790058U
#define DBSC_DBMEMCONF_2_3 0xE679005CU
#define DBSC_DBMEMCONF_3_0 0xE6790060U
#define DBSC_DBMEMCONF_3_1 0xE6790064U
#define DBSC_DBMEMCONF_3_2 0xE6790068U
#define DBSC_DBMEMCONF_3_3 0xE679006CU
#define DBSC_DBSYSCNT0 0xE6790100U
#define DBSC_DBSVCR1 0xE6790104U
#define DBSC_DBSTATE0 0xE6790108U
#define DBSC_DBSTATE1 0xE679010CU
#define DBSC_DBINTEN 0xE6790180U
#define DBSC_DBINTSTAT0 0xE6790184U
#define DBSC_DBACEN 0xE6790200U
#define DBSC_DBRFEN 0xE6790204U
#define DBSC_DBCMD 0xE6790208U
#define DBSC_DBWAIT 0xE6790210U
#define DBSC_DBSYSCTRL0 0xE6790280U
#define DBSC_DBTR(x) (0xE6790300U + 0x04U * (x))
#define DBSC_DBTR0 0xE6790300U
#define DBSC_DBTR1 0xE6790304U
#define DBSC_DBTR2 0xE6790308U
#define DBSC_DBTR3 0xE679030CU
#define DBSC_DBTR4 0xE6790310U
#define DBSC_DBTR5 0xE6790314U
#define DBSC_DBTR6 0xE6790318U
#define DBSC_DBTR7 0xE679031CU
#define DBSC_DBTR8 0xE6790320U
#define DBSC_DBTR9 0xE6790324U
#define DBSC_DBTR10 0xE6790328U
#define DBSC_DBTR11 0xE679032CU
#define DBSC_DBTR12 0xE6790330U
#define DBSC_DBTR13 0xE6790334U
#define DBSC_DBTR14 0xE6790338U
#define DBSC_DBTR15 0xE679033CU
#define DBSC_DBTR16 0xE6790340U
#define DBSC_DBTR17 0xE6790344U
#define DBSC_DBTR18 0xE6790348U
#define DBSC_DBTR19 0xE679034CU
#define DBSC_DBTR20 0xE6790350U
#define DBSC_DBTR21 0xE6790354U
#define DBSC_DBTR22 0xE6790358U
#define DBSC_DBTR23 0xE679035CU
#define DBSC_DBTR24 0xE6790360U
#define DBSC_DBTR25 0xE6790364U
#define DBSC_DBTR26 0xE6790368U
#define DBSC_DBBL 0xE6790400U
#define DBSC_DBRFCNF1 0xE6790414U
#define DBSC_DBRFCNF2 0xE6790418U
#define DBSC_DBTSPCNF 0xE6790420U
#define DBSC_DBCALCNF 0xE6790424U
#define DBSC_DBRNK(x) (0xE6790430U + 0x04U * (x))
#define DBSC_DBRNK2 0xE6790438U
#define DBSC_DBRNK3 0xE679043CU
#define DBSC_DBRNK4 0xE6790440U
#define DBSC_DBRNK5 0xE6790444U
#define DBSC_DBPDNCNF 0xE6790450U
#define DBSC_DBODT(x) (0xE6790460U + 0x04U * (x))
#define DBSC_DBODT0 0xE6790460U
#define DBSC_DBODT1 0xE6790464U
#define DBSC_DBODT2 0xE6790468U
#define DBSC_DBODT3 0xE679046CU
#define DBSC_DBODT4 0xE6790470U
#define DBSC_DBODT5 0xE6790474U
#define DBSC_DBODT6 0xE6790478U
#define DBSC_DBODT7 0xE679047CU
#define DBSC_DBADJ0 0xE6790500U
#define DBSC_DBDBICNT 0xE6790518U
#define DBSC_DBDFIPMSTRCNF 0xE6790520U
#define DBSC_DBDFICUPDCNF 0xE679052CU
#define DBSC_DBDFISTAT(ch) (0xE6790600U + 0x40U * (ch))
#define DBSC_DBDFISTAT_0 0xE6790600U
#define DBSC_DBDFISTAT_1 0xE6790640U
#define DBSC_DBDFISTAT_2 0xE6790680U
#define DBSC_DBDFISTAT_3 0xE67906C0U
#define DBSC_DBDFICNT(ch) (0xE6790604U + 0x40U * (ch))
#define DBSC_DBDFICNT_0 0xE6790604U
#define DBSC_DBDFICNT_1 0xE6790644U
#define DBSC_DBDFICNT_2 0xE6790684U
#define DBSC_DBDFICNT_3 0xE67906C4U
#define DBSC_DBPDCNT0(ch) (0xE6790610U + 0x40U * (ch))
#define DBSC_DBPDCNT0_0 0xE6790610U
#define DBSC_DBPDCNT0_1 0xE6790650U
#define DBSC_DBPDCNT0_2 0xE6790690U
#define DBSC_DBPDCNT0_3 0xE67906D0U
#define DBSC_DBPDCNT1(ch) (0xE6790614U + 0x40U * (ch))
#define DBSC_DBPDCNT1_0 0xE6790614U
#define DBSC_DBPDCNT1_1 0xE6790654U
#define DBSC_DBPDCNT1_2 0xE6790694U
#define DBSC_DBPDCNT1_3 0xE67906D4U
#define DBSC_DBPDCNT2(ch) (0xE6790618U + 0x40U * (ch))
#define DBSC_DBPDCNT2_0 0xE6790618U
#define DBSC_DBPDCNT2_1 0xE6790658U
#define DBSC_DBPDCNT2_2 0xE6790698U
#define DBSC_DBPDCNT2_3 0xE67906D8U
#define DBSC_DBPDCNT3(ch) (0xE679061CU + 0x40U * (ch))
#define DBSC_DBPDCNT3_0 0xE679061CU
#define DBSC_DBPDCNT3_1 0xE679065CU
#define DBSC_DBPDCNT3_2 0xE679069CU
#define DBSC_DBPDCNT3_3 0xE67906DCU
#define DBSC_DBPDLK(ch) (0xE6790620U + 0x40U * (ch))
#define DBSC_DBPDLK_0 0xE6790620U
#define DBSC_DBPDLK_1 0xE6790660U
#define DBSC_DBPDLK_2 0xE67906a0U
#define DBSC_DBPDLK_3 0xE67906e0U
#define DBSC_DBPDRGA(ch) (0xE6790624U + 0x40U * (ch))
#define DBSC_DBPDRGD(ch) (0xE6790628U + 0x40U * (ch))
#define DBSC_DBPDRGA_0 0xE6790624U
#define DBSC_DBPDRGD_0 0xE6790628U
#define DBSC_DBPDRGA_1 0xE6790664U
#define DBSC_DBPDRGD_1 0xE6790668U
#define DBSC_DBPDRGA_2 0xE67906A4U
#define DBSC_DBPDRGD_2 0xE67906A8U
#define DBSC_DBPDRGA_3 0xE67906E4U
#define DBSC_DBPDRGD_3 0xE67906E8U
#define DBSC_DBPDSTAT(ch) (0xE6790630U + 0x40U * (ch))
#define DBSC_DBPDSTAT_0 0xE6790630U
#define DBSC_DBPDSTAT_1 0xE6790670U
#define DBSC_DBPDSTAT_2 0xE67906B0U
#define DBSC_DBPDSTAT_3 0xE67906F0U
#define DBSC_DBBUS0CNF0 0xE6790800U
#define DBSC_DBBUS0CNF1 0xE6790804U
#define DBSC_DBCAM0CNF1 0xE6790904U
#define DBSC_DBCAM0CNF2 0xE6790908U
#define DBSC_DBCAM0CNF3 0xE679090CU
#define DBSC_DBBSWAP 0xE67909F0U
#define DBSC_DBBCAMDIS 0xE67909FCU
#define DBSC_DBSCHCNT0 0xE6791000U
#define DBSC_DBSCHCNT1 0xE6791004U
#define DBSC_DBSCHSZ0 0xE6791010U
#define DBSC_DBSCHRW0 0xE6791020U
#define DBSC_DBSCHRW1 0xE6791024U
#define DBSC_DBSCHQOS_0(x) (0xE6791030U + 0x10U * (x))
#define DBSC_DBSCHQOS_1(x) (0xE6791034U + 0x10U * (x))
#define DBSC_DBSCHQOS_2(x) (0xE6791038U + 0x10U * (x))
#define DBSC_DBSCHQOS_3(x) (0xE679103CU + 0x10U * (x))
#define DBSC_DBSCHQOS00 0xE6791030U
#define DBSC_DBSCHQOS01 0xE6791034U
#define DBSC_DBSCHQOS02 0xE6791038U
#define DBSC_DBSCHQOS03 0xE679103CU
#define DBSC_DBSCHQOS10 0xE6791040U
#define DBSC_DBSCHQOS11 0xE6791044U
#define DBSC_DBSCHQOS12 0xE6791048U
#define DBSC_DBSCHQOS13 0xE679104CU
#define DBSC_DBSCHQOS20 0xE6791050U
#define DBSC_DBSCHQOS21 0xE6791054U
#define DBSC_DBSCHQOS22 0xE6791058U
#define DBSC_DBSCHQOS23 0xE679105CU
#define DBSC_DBSCHQOS30 0xE6791060U
#define DBSC_DBSCHQOS31 0xE6791064U
#define DBSC_DBSCHQOS32 0xE6791068U
#define DBSC_DBSCHQOS33 0xE679106CU
#define DBSC_DBSCHQOS40 0xE6791070U
#define DBSC_DBSCHQOS41 0xE6791074U
#define DBSC_DBSCHQOS42 0xE6791078U
#define DBSC_DBSCHQOS43 0xE679107CU
#define DBSC_DBSCHQOS50 0xE6791080U
#define DBSC_DBSCHQOS51 0xE6791084U
#define DBSC_DBSCHQOS52 0xE6791088U
#define DBSC_DBSCHQOS53 0xE679108CU
#define DBSC_DBSCHQOS60 0xE6791090U
#define DBSC_DBSCHQOS61 0xE6791094U
#define DBSC_DBSCHQOS62 0xE6791098U
#define DBSC_DBSCHQOS63 0xE679109CU
#define DBSC_DBSCHQOS70 0xE67910A0U
#define DBSC_DBSCHQOS71 0xE67910A4U
#define DBSC_DBSCHQOS72 0xE67910A8U
#define DBSC_DBSCHQOS73 0xE67910ACU
#define DBSC_DBSCHQOS80 0xE67910B0U
#define DBSC_DBSCHQOS81 0xE67910B4U
#define DBSC_DBSCHQOS82 0xE67910B8U
#define DBSC_DBSCHQOS83 0xE67910BCU
#define DBSC_DBSCHQOS90 0xE67910C0U
#define DBSC_DBSCHQOS91 0xE67910C4U
#define DBSC_DBSCHQOS92 0xE67910C8U
#define DBSC_DBSCHQOS93 0xE67910CCU
#define DBSC_DBSCHQOS100 0xE67910D0U
#define DBSC_DBSCHQOS101 0xE67910D4U
#define DBSC_DBSCHQOS102 0xE67910D8U
#define DBSC_DBSCHQOS103 0xE67910DCU
#define DBSC_DBSCHQOS110 0xE67910E0U
#define DBSC_DBSCHQOS111 0xE67910E4U
#define DBSC_DBSCHQOS112 0xE67910E8U
#define DBSC_DBSCHQOS113 0xE67910ECU
#define DBSC_DBSCHQOS120 0xE67910F0U
#define DBSC_DBSCHQOS121 0xE67910F4U
#define DBSC_DBSCHQOS122 0xE67910F8U
#define DBSC_DBSCHQOS123 0xE67910FCU
#define DBSC_DBSCHQOS130 0xE6791100U
#define DBSC_DBSCHQOS131 0xE6791104U
#define DBSC_DBSCHQOS132 0xE6791108U
#define DBSC_DBSCHQOS133 0xE679110CU
#define DBSC_DBSCHQOS140 0xE6791110U
#define DBSC_DBSCHQOS141 0xE6791114U
#define DBSC_DBSCHQOS142 0xE6791118U
#define DBSC_DBSCHQOS143 0xE679111CU
#define DBSC_DBSCHQOS150 0xE6791120U
#define DBSC_DBSCHQOS151 0xE6791124U
#define DBSC_DBSCHQOS152 0xE6791128U
#define DBSC_DBSCHQOS153 0xE679112CU
#define DBSC_DBSCTR0 0xE6791700U
#define DBSC_DBSCTR1 0xE6791708U
#define DBSC_DBSCHRW2 0xE679170CU
#define DBSC_SCFCTST01(x) (0xE6791700U + 0x08U * (x))
#define DBSC_SCFCTST0 0xE6791700U
#define DBSC_SCFCTST1 0xE6791708U
#define DBSC_SCFCTST2 0xE679170CU
#define DBSC_DBMRRDR(chab) (0xE6791800U + 0x04U * (chab))
#define DBSC_DBMRRDR_0 0xE6791800U
#define DBSC_DBMRRDR_1 0xE6791804U
#define DBSC_DBMRRDR_2 0xE6791808U
#define DBSC_DBMRRDR_3 0xE679180CU
#define DBSC_DBMRRDR_4 0xE6791810U
#define DBSC_DBMRRDR_5 0xE6791814U
#define DBSC_DBMRRDR_6 0xE6791818U
#define DBSC_DBMRRDR_7 0xE679181CU
#define DBSC_DBMEMSWAPCONF0 0xE6792000U
/* CPG registers */
#define CPG_BASE 0xE6150000U
#define CPG_FRQCRB (CPG_BASE + 0x0004U)
#define CPG_PLLECR (CPG_BASE + 0x00D0U)
#define CPG_MSTPSR5 (CPG_BASE + 0x003CU)
#define CPG_SRCR4 (CPG_BASE + 0x00BCU)
#define CPG_PLL3CR (CPG_BASE + 0x00DCU)
#define CPG_ZB3CKCR (CPG_BASE + 0x0380U)
#define CPG_FRQCRD (CPG_BASE + 0x00E4U)
#define CPG_SMSTPCR5 (CPG_BASE + 0x0144U)
#define CPG_CPGWPR (CPG_BASE + 0x0900U)
#define CPG_SRSTCLR4 (CPG_BASE + 0x0950U)
#endif /* BOOT_INIT_DRAM_REGDEF_H_*/
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include "micro_delay.h"
#define RCAR_CONV_MICROSEC 1000000U
void
#if IMAGE_BL31
__attribute__ ((section(".system_ram")))
#endif
rcar_micro_delay(uint64_t micro_sec)
{
uint64_t freq;
uint64_t base_count;
uint64_t get_count;
uint64_t wait_time = 0U;
freq = read_cntfrq_el0();
base_count = read_cntpct_el0();
while (micro_sec > wait_time) {
get_count = read_cntpct_el0();
wait_time = ((get_count - base_count) * RCAR_CONV_MICROSEC) / freq;
}
}
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MICRO_DELAY_H
#define MICRO_DELAY_H
#ifndef __ASSEMBLER__
#include <stdint.h>
void rcar_micro_delay(uint64_t micro_sec);
#endif
#endif /* MICRO_DELAY_H */
@@ -0,0 +1,153 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <string.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include "cpg_registers.h"
#include "rcar_def.h"
#include "rcar_private.h"
/* DMA CHANNEL setting (0/16/32) */
#if RCAR_LSI == RCAR_V3M
#define DMA_CH 16
#else
#define DMA_CH 0
#endif
#if (DMA_CH == 0)
#define SYS_DMAC_BIT ((uint32_t)1U << 19U)
#define DMA_BASE (0xE6700000U)
#elif (DMA_CH == 16)
#define SYS_DMAC_BIT ((uint32_t)1U << 18U)
#define DMA_BASE (0xE7300000U)
#elif (DMA_CH == 32)
#define SYS_DMAC_BIT ((uint32_t)1U << 17U)
#define DMA_BASE (0xE7320000U)
#else
#define SYS_DMAC_BIT ((uint32_t)1U << 19U)
#define DMA_BASE (0xE6700000U)
#endif
/* DMA operation */
#define DMA_DMAOR (DMA_BASE + 0x0060U)
/* DMA secure control */
#define DMA_DMASEC (DMA_BASE + 0x0030U)
/* DMA channel clear */
#define DMA_DMACHCLR (DMA_BASE + 0x0080U)
/* DMA source address */
#define DMA_DMASAR (DMA_BASE + 0x8000U)
/* DMA destination address */
#define DMA_DMADAR (DMA_BASE + 0x8004U)
/* DMA transfer count */
#define DMA_DMATCR (DMA_BASE + 0x8008U)
/* DMA channel control */
#define DMA_DMACHCR (DMA_BASE + 0x800CU)
/* DMA fixed destination address */
#define DMA_DMAFIXDAR (DMA_BASE + 0x8014U)
#define DMA_USE_CHANNEL (0x00000001U)
#define DMAOR_INITIAL (0x0301U)
#define DMACHCLR_CH_ALL (0x0000FFFFU)
#define DMAFIXDAR_32BIT_SHIFT (32U)
#define DMAFIXDAR_DAR_MASK (0x000000FFU)
#define DMADAR_BOUNDARY_ADDR (0x100000000ULL)
#define DMATCR_CNT_SHIFT (6U)
#define DMATCR_MAX (0x00FFFFFFU)
#define DMACHCR_TRN_MODE (0x00105409U)
#define DMACHCR_DE_BIT (0x00000001U)
#define DMACHCR_TE_BIT (0x00000002U)
#define DMACHCR_CHE_BIT (0x80000000U)
#define DMA_SIZE_UNIT FLASH_TRANS_SIZE_UNIT
#define DMA_FRACTION_MASK (0xFFU)
#define DMA_DST_LIMIT (0x10000000000ULL)
/* transfer length limit */
#define DMA_LENGTH_LIMIT ((DMATCR_MAX * (1U << DMATCR_CNT_SHIFT)) \
& ~DMA_FRACTION_MASK)
static void dma_enable(void)
{
mstpcr_write(CPG_SMSTPCR2, CPG_MSTPSR2, SYS_DMAC_BIT);
}
static void dma_setup(void)
{
mmio_write_16(DMA_DMAOR, 0);
mmio_write_32(DMA_DMACHCLR, DMACHCLR_CH_ALL);
}
static void dma_start(uintptr_t dst, uint32_t src, uint32_t len)
{
mmio_write_16(DMA_DMAOR, DMAOR_INITIAL);
mmio_write_32(DMA_DMAFIXDAR, (dst >> DMAFIXDAR_32BIT_SHIFT) &
DMAFIXDAR_DAR_MASK);
mmio_write_32(DMA_DMADAR, dst & UINT32_MAX);
mmio_write_32(DMA_DMASAR, src);
mmio_write_32(DMA_DMATCR, len >> DMATCR_CNT_SHIFT);
mmio_write_32(DMA_DMASEC, DMA_USE_CHANNEL);
mmio_write_32(DMA_DMACHCR, DMACHCR_TRN_MODE);
}
static void dma_end(void)
{
while ((mmio_read_32(DMA_DMACHCR) & DMACHCR_TE_BIT) == 0) {
if ((mmio_read_32(DMA_DMACHCR) & DMACHCR_CHE_BIT) != 0U) {
ERROR("BL2: DMA - Channel Address Error\n");
panic();
break;
}
}
/* DMA transfer Disable */
mmio_clrbits_32(DMA_DMACHCR, DMACHCR_DE_BIT);
while ((mmio_read_32(DMA_DMACHCR) & DMACHCR_DE_BIT) != 0)
;
mmio_write_32(DMA_DMASEC, 0);
mmio_write_16(DMA_DMAOR, 0);
mmio_write_32(DMA_DMACHCLR, DMA_USE_CHANNEL);
}
void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len)
{
uint32_t dma_len = len;
if (len & DMA_FRACTION_MASK)
dma_len = (len + DMA_SIZE_UNIT) & ~DMA_FRACTION_MASK;
if (!dma_len || dma_len > DMA_LENGTH_LIMIT) {
ERROR("BL2: DMA - size invalid, length (0x%x)\n", dma_len);
panic();
}
if (src & DMA_FRACTION_MASK) {
ERROR("BL2: DMA - src address invalid (0x%x), len=(0x%x)\n",
src, dma_len);
panic();
}
if ((dst & UINT32_MAX) + dma_len > DMADAR_BOUNDARY_ADDR ||
(dst + dma_len > DMA_DST_LIMIT) ||
(dst & DMA_FRACTION_MASK)) {
ERROR("BL2: DMA - dest address invalid (0x%lx), len=(0x%x)\n",
dst, dma_len);
panic();
}
dma_start(dst, src, dma_len);
dma_end();
}
void rcar_dma_init(void)
{
dma_enable();
dma_setup();
}
@@ -0,0 +1,493 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include "emmc_config.h"
#include "emmc_def.h"
#include "emmc_hal.h"
#include "emmc_registers.h"
#include "emmc_std.h"
#include "micro_delay.h"
static void emmc_little_to_big(uint8_t *p, uint32_t value)
{
if (p == NULL)
return;
p[0] = (uint8_t) (value >> 24);
p[1] = (uint8_t) (value >> 16);
p[2] = (uint8_t) (value >> 8);
p[3] = (uint8_t) value;
}
static void emmc_softreset(void)
{
int32_t loop = 10000;
int32_t retry = 1000;
/* flag clear */
mmc_drv_obj.during_cmd_processing = FALSE;
mmc_drv_obj.during_transfer = FALSE;
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.state_machine_blocking = FALSE;
mmc_drv_obj.force_terminate = FALSE;
mmc_drv_obj.dma_error_flag = FALSE;
/* during operation ? */
if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0)
goto reset;
/* wait CMDSEQ = 0 */
while (loop > 0) {
if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0)
break; /* ready */
loop--;
if ((loop == 0) && (retry > 0)) {
rcar_micro_delay(1000U); /* wait 1ms */
loop = 10000;
retry--;
}
}
reset:
/* reset */
SETR_32(SOFT_RST, (GETR_32(SOFT_RST) & (~SOFT_RST_SDRST)));
SETR_32(SOFT_RST, (GETR_32(SOFT_RST) | SOFT_RST_SDRST));
/* initialize */
SETR_32(SD_INFO1, 0x00000000U);
SETR_32(SD_INFO2, SD_INFO2_CLEAR);
SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */
}
static void emmc_read_response(uint32_t *response)
{
uint8_t *p;
if (response == NULL)
return;
/* read response */
if (mmc_drv_obj.response_length != EMMC_MAX_RESPONSE_LENGTH) {
*response = GETR_32(SD_RSP10); /* [39:8] */
return;
}
/* CSD or CID */
p = (uint8_t *) (response);
emmc_little_to_big(p, ((GETR_32(SD_RSP76) << 8)
| (GETR_32(SD_RSP54) >> 24))); /* [127:96] */
emmc_little_to_big(p + 4, ((GETR_32(SD_RSP54) << 8)
| (GETR_32(SD_RSP32) >> 24))); /* [95:64] */
emmc_little_to_big(p + 8, ((GETR_32(SD_RSP32) << 8)
| (GETR_32(SD_RSP10) >> 24))); /* [63:32] */
emmc_little_to_big(p + 12, (GETR_32(SD_RSP10) << 8));
}
static EMMC_ERROR_CODE emmc_response_check(uint32_t *response,
uint32_t error_mask)
{
HAL_MEMCARD_RESPONSE_TYPE response_type =
((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK);
if (response == NULL)
return EMMC_ERR_PARAM;
if (response_type == HAL_MEMCARD_RESPONSE_NONE)
return EMMC_SUCCESS;
if (response_type <= HAL_MEMCARD_RESPONSE_R1b) {
/* R1 or R1b */
mmc_drv_obj.current_state =
(EMMC_R1_STATE) ((*response & EMMC_R1_STATE_MASK) >>
EMMC_R1_STATE_SHIFT);
if ((*response & error_mask) != 0) {
if ((0x80 & *response) != 0) {
ERROR("BL2: emmc SWITCH_ERROR\n");
}
return EMMC_ERR_CARD_STATUS_BIT;
}
return EMMC_SUCCESS;
}
if (response_type == HAL_MEMCARD_RESPONSE_R4) {
if ((*response & EMMC_R4_STATUS) != 0)
return EMMC_ERR_CARD_STATUS_BIT;
}
return EMMC_SUCCESS;
}
static void emmc_WaitCmd2Cmd_8Cycle(void)
{
uint32_t dataL, wait = 0;
dataL = GETR_32(SD_CLK_CTRL);
dataL &= 0x000000FF;
switch (dataL) {
case 0xFF:
case 0x00:
case 0x01:
case 0x02:
case 0x04:
case 0x08:
case 0x10:
case 0x20:
wait = 10U;
break;
case 0x40:
wait = 20U;
break;
case 0x80:
wait = 30U;
break;
}
rcar_micro_delay(wait);
}
static void cmdErrSdInfo2Log(void)
{
ERROR("BL2: emmc ERR SD_INFO2 = 0x%x\n", mmc_drv_obj.error_info.info2);
}
static void emmc_data_transfer_dma(void)
{
mmc_drv_obj.during_dma_transfer = TRUE;
mmc_drv_obj.dma_error_flag = FALSE;
SETR_32(SD_INFO1_MASK, 0x00000000U);
SETR_32(SD_INFO2_MASK, (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
/* DMAC setting */
if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) {
/* transfer complete interrupt enable */
SETR_32(DM_CM_INFO1_MASK,
(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE));
SETR_32(DM_CM_INFO2_MASK,
(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE));
/* BUFF --> FIFO */
SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH0 |
DM_CM_DTRAN_MODE_BIT_WIDTH));
} else {
/* transfer complete interrupt enable */
SETR_32(DM_CM_INFO1_MASK,
(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE));
SETR_32(DM_CM_INFO2_MASK,
(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE));
/* FIFO --> BUFF */
SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH1
| DM_CM_DTRAN_MODE_BIT_WIDTH));
}
SETR_32(DM_DTRAN_ADDR, (((uintptr_t) mmc_drv_obj.buff_address_virtual &
DM_DTRAN_ADDR_WRITE_MASK)));
SETR_32(DM_CM_DTRAN_CTRL, DM_CM_DTRAN_CTRL_START);
}
EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response)
{
EMMC_ERROR_CODE rtn_code = EMMC_SUCCESS;
HAL_MEMCARD_RESPONSE_TYPE response_type;
HAL_MEMCARD_COMMAND_TYPE cmd_type;
EMMC_INT_STATE state;
uint32_t err_not_care_flag = FALSE;
/* parameter check */
if (response == NULL) {
emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if (mmc_drv_obj.clock_enable != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
if (mmc_drv_obj.state_machine_blocking == TRUE) {
emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR);
return EMMC_ERR;
}
state = ESTATE_BEGIN;
response_type =
((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd &
HAL_MEMCARD_RESPONSE_TYPE_MASK);
cmd_type =
((HAL_MEMCARD_COMMAND_TYPE) mmc_drv_obj.cmd_info.cmd &
HAL_MEMCARD_COMMAND_TYPE_MASK);
/* state machine */
while ((mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END)) {
/* The interrupt factor flag is observed. */
emmc_interrupt();
/* wait interrupt */
if (mmc_drv_obj.state_machine_blocking == TRUE)
continue;
switch (state) {
case ESTATE_BEGIN:
/* Busy check */
if ((mmc_drv_obj.error_info.info2 & SD_INFO2_CBSY) != 0) {
emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD,
EMMC_ERR_CARD_BUSY);
return EMMC_ERR_CARD_BUSY;
}
/* clear register */
SETR_32(SD_INFO1, 0x00000000U);
SETR_32(SD_INFO2, SD_INFO2_CLEAR);
SETR_32(SD_INFO1_MASK, SD_INFO1_INFO0);
SETR_32(SD_INFO2_MASK,
(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
state = ESTATE_ISSUE_CMD;
/* through */
case ESTATE_ISSUE_CMD:
/* ARG */
SETR_32(SD_ARG, mmc_drv_obj.cmd_info.arg);
/* issue cmd */
SETR_32(SD_CMD, mmc_drv_obj.cmd_info.hw);
/* Set driver flag */
mmc_drv_obj.during_cmd_processing = TRUE;
mmc_drv_obj.state_machine_blocking = TRUE;
if (response_type == HAL_MEMCARD_RESPONSE_NONE) {
state = ESTATE_NON_RESP_CMD;
} else {
state = ESTATE_RCV_RESP;
}
break;
case ESTATE_NON_RESP_CMD:
/* interrupt disable */
SETR_32(SD_INFO1_MASK, 0x00000000U);
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
/* error interrupt */
cmdErrSdInfo2Log();
rtn_code = EMMC_ERR_INFO2;
state = ESTATE_ERROR;
} else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) ==
0) {
/* not receive expected interrupt */
rtn_code = EMMC_ERR_RESPONSE;
state = ESTATE_ERROR;
} else {
emmc_WaitCmd2Cmd_8Cycle();
state = ESTATE_END;
}
break;
case ESTATE_RCV_RESP:
/* interrupt disable */
SETR_32(SD_INFO1_MASK, 0x00000000U);
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
if ((mmc_drv_obj.get_partition_access_flag ==
TRUE)
&& ((mmc_drv_obj.int_event2 & SD_INFO2_ERR6)
!= 0U)) {
err_not_care_flag = TRUE;
rtn_code = EMMC_ERR_CMD_TIMEOUT;
} else {
/* error interrupt */
cmdErrSdInfo2Log();
rtn_code = EMMC_ERR_INFO2;
}
state = ESTATE_ERROR;
break;
} else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) ==
0) {
/* not receive expected interrupt */
rtn_code = EMMC_ERR_RESPONSE;
state = ESTATE_ERROR;
break;
}
/* read response */
emmc_read_response(response);
/* check response */
rtn_code = emmc_response_check(response, error_mask);
if (rtn_code != EMMC_SUCCESS) {
state = ESTATE_ERROR;
break;
}
if (response_type == HAL_MEMCARD_RESPONSE_R1b) {
/* R1b */
SETR_32(SD_INFO2_MASK,
(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
state = ESTATE_RCV_RESPONSE_BUSY;
} else {
state = ESTATE_CHECK_RESPONSE_COMPLETE;
}
break;
case ESTATE_RCV_RESPONSE_BUSY:
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
/* error interrupt */
cmdErrSdInfo2Log();
rtn_code = EMMC_ERR_INFO2;
state = ESTATE_ERROR;
break;
}
/* DAT0 not Busy */
if ((SD_INFO2_DAT0 & mmc_drv_obj.error_info.info2) != 0) {
state = ESTATE_CHECK_RESPONSE_COMPLETE;
break;
}
break;
case ESTATE_CHECK_RESPONSE_COMPLETE:
if (cmd_type >= HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE) {
state = ESTATE_DATA_TRANSFER;
} else {
emmc_WaitCmd2Cmd_8Cycle();
state = ESTATE_END;
}
break;
case ESTATE_DATA_TRANSFER:
/* ADTC command */
mmc_drv_obj.during_transfer = TRUE;
mmc_drv_obj.state_machine_blocking = TRUE;
if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
/* DMA */
emmc_data_transfer_dma();
} else {
/* PIO */
/* interrupt enable (FIFO read/write enable) */
if (mmc_drv_obj.cmd_info.dir ==
HAL_MEMCARD_WRITE) {
SETR_32(SD_INFO2_MASK,
(SD_INFO2_BWE | SD_INFO2_ALL_ERR
| SD_INFO2_CLEAR));
} else {
SETR_32(SD_INFO2_MASK,
(SD_INFO2_BRE | SD_INFO2_ALL_ERR
| SD_INFO2_CLEAR));
}
}
state = ESTATE_DATA_TRANSFER_COMPLETE;
break;
case ESTATE_DATA_TRANSFER_COMPLETE:
/* check interrupt */
if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
/* error interrupt */
cmdErrSdInfo2Log();
rtn_code = EMMC_ERR_INFO2;
state = ESTATE_TRANSFER_ERROR;
break;
}
/* DMAC error ? */
if (mmc_drv_obj.dma_error_flag == TRUE) {
/* Error occurred in DMAC driver. */
rtn_code = EMMC_ERR_FROM_DMAC_TRANSFER;
state = ESTATE_TRANSFER_ERROR;
} else if (mmc_drv_obj.during_dma_transfer == TRUE) {
/* DMAC not finished. unknown error */
rtn_code = EMMC_ERR;
state = ESTATE_TRANSFER_ERROR;
} else {
SETR_32(SD_INFO1_MASK, SD_INFO1_INFO2);
SETR_32(SD_INFO2_MASK,
(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
mmc_drv_obj.state_machine_blocking = TRUE;
state = ESTATE_ACCESS_END;
}
break;
case ESTATE_ACCESS_END:
/* clear flag */
if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
/* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR);
SETR_32(SD_STOP, 0x00000000U);
mmc_drv_obj.during_dma_transfer = FALSE;
}
SETR_32(SD_INFO1_MASK, 0x00000000U);
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
SETR_32(SD_INFO1, 0x00000000U);
SETR_32(SD_INFO2, SD_INFO2_CLEAR);
if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO2) != 0) {
emmc_WaitCmd2Cmd_8Cycle();
state = ESTATE_END;
} else {
state = ESTATE_ERROR;
}
break;
case ESTATE_TRANSFER_ERROR:
/* The error occurred in the Data transfer. */
if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
/* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR);
SETR_32(SD_STOP, 0x00000000U);
mmc_drv_obj.during_dma_transfer = FALSE;
}
/* through */
case ESTATE_ERROR:
if (err_not_care_flag == TRUE) {
mmc_drv_obj.during_cmd_processing = FALSE;
} else {
emmc_softreset();
emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD,
rtn_code);
}
return rtn_code;
default:
state = ESTATE_END;
break;
} /* switch (state) */
} /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */
/* force terminate */
if (mmc_drv_obj.force_terminate == TRUE) {
/* timeout timer is expired. Or, PIO data transfer error. */
/* Timeout occurred in the DMA transfer. */
if (mmc_drv_obj.during_dma_transfer == TRUE) {
mmc_drv_obj.during_dma_transfer = FALSE;
}
ERROR("BL2: emmc exec_cmd:EMMC_ERR_FORCE_TERMINATE\n");
emmc_softreset();
return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */
}
/* success */
mmc_drv_obj.during_cmd_processing = FALSE;
mmc_drv_obj.during_transfer = FALSE;
return EMMC_SUCCESS;
}
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef EMMC_CONFIG_H
#define EMMC_CONFIG_H
/* RCA */
#define EMMC_RCA 1UL
/* 314ms (freq = 400KHz, timeout Counter = 0x04(SDCLK * 2^17) */
#define EMMC_RW_DATA_TIMEOUT 0x40UL
/* how many times to try after fail. Don't change. */
#define EMMC_RETRY_COUNT 0
#define EMMC_CMD_MAX 60UL /* Don't change. */
#define LOADIMAGE_FLAGS_DMA_ENABLE 0x00000001UL
#endif /* EMMC_CONFIG_H */
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file emmc_def.h
* @brief eMMC boot is expecting this header file
*
*/
#ifndef EMMC_DEF_H
#define EMMC_DEF_H
#include "emmc_std.h"
/* ************************ HEADER (INCLUDE) SECTION *********************** */
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */
#define EMMC_POWER_ON (1U)
/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */
/* ********************** DECLARATION OF EXTERNAL DATA ********************* */
extern st_mmc_base mmc_drv_obj;
/* ************************** FUNCTION PROTOTYPES ************************** */
/** @brief for assembler program
*/
uint32_t _rom_emmc_finalize(void);
/** @brief eMMC driver API
*/
EMMC_ERROR_CODE rcar_emmc_init(void);
EMMC_ERROR_CODE emmc_terminate(void);
EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode);
EMMC_ERROR_CODE rcar_emmc_mount(void);
EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq);
EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg);
EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id);
EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual,
uint32_t sector_number, uint32_t count,
uint32_t feature_flags);
EMMC_ERROR_CODE emmc_write_sector(uint32_t *buff_address_virtual,
uint32_t sector_number, uint32_t count,
uint32_t feature_flags);
EMMC_ERROR_CODE emmc_erase_sector(uint32_t *start_address,
uint32_t *end_address);
uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom);
/** @brief interrupt service
*/
uint32_t emmc_interrupt(void);
/** @brief DMA
*/
/** @brief send command API
*/
EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response);
void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg);
void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg,
uint32_t *buff_address_virtual, uint32_t len,
HAL_MEMCARD_OPERATION dir,
HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode);
EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg);
/** @brief for error information
*/
void emmc_write_error_info(uint16_t func_no, EMMC_ERROR_CODE error_code);
void emmc_write_error_info_func_no(uint16_t func_no);
/* ********************************* CODE ********************************** */
#endif /* EMMC_DEF_H */
/* ******************************** END ************************************ */
@@ -0,0 +1,535 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef EMMC_HAL_H
#define EMMC_HAL_H
/* memory card error/status types */
#define HAL_MEMCARD_OUT_OF_RANGE 0x80000000L
#define HAL_MEMCARD_ADDRESS_ERROR 0x40000000L
#define HAL_MEMCARD_BLOCK_LEN_ERROR 0x20000000L
#define HAL_MEMCARD_ERASE_SEQ_ERROR 0x10000000L
#define HAL_MEMCARD_ERASE_PARAM 0x08000000L
#define HAL_MEMCARD_WP_VIOLATION 0x04000000L
#define HAL_MEMCARD_CARD_IS_LOCKED 0x02000000L
#define HAL_MEMCARD_LOCK_UNLOCK_FAILED 0x01000000L
#define HAL_MEMCARD_COM_CRC_ERROR 0x00800000L
#define HAL_MEMCARD_ILEGAL_COMMAND 0x00400000L
#define HAL_MEMCARD_CARD_ECC_FAILED 0x00200000L
#define HAL_MEMCARD_CC_ERROR 0x00100000L
#define HAL_MEMCARD_ERROR 0x00080000L
#define HAL_MEMCARD_UNDERRUN 0x00040000L
#define HAL_MEMCARD_OVERRUN 0x00020000L
#define HAL_MEMCARD_CIDCSD_OVERWRITE 0x00010000L
#define HAL_MEMCARD_WP_ERASE_SKIP 0x00008000L
#define HAL_MEMCARD_CARD_ECC_DISABLED 0x00004000L
#define HAL_MEMCARD_ERASE_RESET 0x00002000L
#define HAL_MEMCARD_CARD_STATE 0x00001E00L
#define HAL_MEMCARD_CARD_READY_FOR_DATA 0x00000100L
#define HAL_MEMCARD_APP_CMD 0x00000020L
#define HAL_MEMCARD_SWITCH_ERROR 0x00000080L
#define HAL_MEMCARD_AKE_SEQ_ERROR 0x00000008L
#define HAL_MEMCARD_NO_ERRORS 0x00000000L
/* Memory card response types */
#define HAL_MEMCARD_COMMAND_INDEX_MASK 0x0003f
/* Type of the return value. */
typedef enum {
HAL_MEMCARD_FAIL = 0U,
HAL_MEMCARD_OK = 1U,
HAL_MEMCARD_DMA_ALLOC_FAIL = 2U, /* DMA channel allocation failed */
HAL_MEMCARD_DMA_TRANSFER_FAIL = 3U, /* DMA transfer failed */
HAL_MEMCARD_CARD_STATUS_ERROR = 4U, /* card status non-masked error */
HAL_MEMCARD_CMD_TIMEOUT = 5U, /* Command timeout occurred */
HAL_MEMCARD_DATA_TIMEOUT = 6U, /* Data timeout occurred */
HAL_MEMCARD_CMD_CRC_ERROR = 7U, /* Command CRC error occurred */
HAL_MEMCARD_DATA_CRC_ERROR = 8U /* Data CRC error occurred */
} HAL_MEMCARD_RETURN;
/* memory access operation */
typedef enum {
HAL_MEMCARD_READ = 0U, /* read */
HAL_MEMCARD_WRITE = 1U /* write */
} HAL_MEMCARD_OPERATION;
/* Type of data width on memorycard bus */
typedef enum {
HAL_MEMCARD_DATA_WIDTH_1_BIT = 0U,
HAL_MEMCARD_DATA_WIDTH_4_BIT = 1U,
HAL_MEMCARD_DATA_WIDTH_8_BIT = 2U
} HAL_MEMCARD_DATA_WIDTH; /* data (bus) width types */
/* Presence of the memory card */
typedef enum {
HAL_MEMCARD_CARD_IS_IN = 0U,
HAL_MEMCARD_CARD_IS_OUT = 1U
} HAL_MEMCARD_PRESENCE_STATUS; /* presence status of the memory card */
/* mode of data transfer */
typedef enum {
HAL_MEMCARD_DMA = 0U,
HAL_MEMCARD_NOT_DMA = 1U
} HAL_MEMCARD_DATA_TRANSFER_MODE;
/* Memory card response types. */
typedef enum hal_memcard_response_type {
HAL_MEMCARD_RESPONSE_NONE = 0x00000U,
HAL_MEMCARD_RESPONSE_R1 = 0x00100U,
HAL_MEMCARD_RESPONSE_R1b = 0x00200U,
HAL_MEMCARD_RESPONSE_R2 = 0x00300U,
HAL_MEMCARD_RESPONSE_R3 = 0x00400U,
HAL_MEMCARD_RESPONSE_R4 = 0x00500U,
HAL_MEMCARD_RESPONSE_R5 = 0x00600U,
HAL_MEMCARD_RESPONSE_R6 = 0x00700U,
HAL_MEMCARD_RESPONSE_R7 = 0x00800U,
HAL_MEMCARD_RESPONSE_TYPE_MASK = 0x00f00U
} HAL_MEMCARD_RESPONSE_TYPE;
/* Memory card command types. */
typedef enum hal_memcard_command_type {
HAL_MEMCARD_COMMAND_TYPE_BC = 0x00000U,
HAL_MEMCARD_COMMAND_TYPE_BCR = 0x01000U,
HAL_MEMCARD_COMMAND_TYPE_AC = 0x02000U,
HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE = 0x03000U,
HAL_MEMCARD_COMMAND_TYPE_ADTC_READ = 0x04000U,
HAL_MEMCARD_COMMAND_TYPE_MASK = 0x07000U
} HAL_MEMCARD_COMMAND_TYPE;
/* Type of memory card */
typedef enum hal_memcard_command_card_type {
HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON = 0x00000U,
HAL_MEMCARD_COMMAND_CARD_TYPE_MMC = 0x08000U,
HAL_MEMCARD_COMMAND_CARD_TYPE_SD = 0x10000U,
HAL_MEMCARD_COMMAND_CARD_TYPE_MASK = 0x18000U
} HAL_MEMCARD_COMMAND_CARD_TYPE;
/* Memory card application command. */
typedef enum hal_memcard_command_app_norm {
HAL_MEMCARD_COMMAND_NORMAL = 0x00000U,
HAL_MEMCARD_COMMAND_APP = 0x20000U,
HAL_MEMCARD_COMMAND_APP_NORM_MASK = 0x20000U
} HAL_MEMCARD_COMMAND_APP_NORM;
/* Memory card command codes. */
typedef enum {
/* class 0 and class 1 */
/* CMD0 */
CMD0_GO_IDLE_STATE =
0U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC |
(uint32_t) HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD1 */
CMD1_SEND_OP_COND =
1U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD2 */
CMD2_ALL_SEND_CID_MMC =
2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
CMD2_ALL_SEND_CID_SD =
2U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD3 */
CMD3_SET_RELATIVE_ADDR =
3U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
CMD3_SEND_RELATIVE_ADDR =
3U | (uint32_t)HAL_MEMCARD_RESPONSE_R6 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD4 */
CMD4_SET_DSR =
4U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD5 */
CMD5_SLEEP_AWAKE =
5U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD6 */
CMD6_SWITCH =
6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
CMD6_SWITCH_FUNC =
6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
ACMD6_SET_BUS_WIDTH =
6U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_APP,
/* CMD7 */
CMD7_SELECT_CARD =
7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD7(from Disconnected State to Programming State) */
CMD7_SELECT_CARD_PROG =
7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
CMD7_DESELECT_CARD =
7U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD8 */
CMD8_SEND_EXT_CSD =
8U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
CMD8_SEND_IF_COND =
8U | (uint32_t)HAL_MEMCARD_RESPONSE_R7 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD9 */
CMD9_SEND_CSD =
9U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD10 */
CMD10_SEND_CID =
10U | (uint32_t)HAL_MEMCARD_RESPONSE_R2 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD11 */
CMD11_READ_DAT_UNTIL_STOP =
11U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD12 */
CMD12_STOP_TRANSMISSION =
12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD12(R1b : write case) */
CMD12_STOP_TRANSMISSION_WRITE =
12U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD13 */
CMD13_SEND_STATUS =
13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
ACMD13_SD_STATUS =
13U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_APP,
/* CMD14 */
CMD14_BUSTEST_R =
14U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD15 */
CMD15_GO_INACTIVE_STATE =
15U | (uint32_t)HAL_MEMCARD_RESPONSE_NONE |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* class 2 */
/* CMD16 */
CMD16_SET_BLOCKLEN =
16U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD17 */
CMD17_READ_SINGLE_BLOCK =
17U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD18 */
CMD18_READ_MULTIPLE_BLOCK =
18U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD19 */
CMD19_BUS_TEST_W =
19U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* class 3 */
/* CMD20 */
CMD20_WRITE_DAT_UNTIL_STOP =
20U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD21 */
CMD21 = 21U,
/* CMD22 */
CMD22 = 22U,
ACMD22_SEND_NUM_WR_BLOCKS =
22U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_APP,
/* class 4 */
/* CMD23 */
CMD23_SET_BLOCK_COUNT =
23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
ACMD23_SET_WR_BLK_ERASE_COUNT =
23U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_APP,
/* CMD24 */
CMD24_WRITE_BLOCK =
24U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD25 */
CMD25_WRITE_MULTIPLE_BLOCK =
25U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD26 */
CMD26_PROGRAM_CID =
26U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD27 */
CMD27_PROGRAM_CSD =
27U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* class 6 */
/* CMD28 */
CMD28_SET_WRITE_PROT =
28U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD29 */
CMD29_CLR_WRITE_PROT =
29U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD30 */
CMD30_SEND_WRITE_PROT =
30U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD31 */
CMD30_SEND_WRITE_PROT_TYPE =
31U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* class 5 */
/* CMD32 */
CMD32_ERASE_WR_BLK_START =
32U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD33 */
CMD33_ERASE_WR_BLK_END =
33U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD34 */
CMD34 = 34U,
/* CMD35 */
CMD35_ERASE_GROUP_START =
35U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD36 */
CMD36_ERASE_GROUP_END =
36U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD37 */
CMD37 = 37U,
/* CMD38 */
CMD38_ERASE =
38U | (uint32_t)HAL_MEMCARD_RESPONSE_R1b |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* class 9 */
/* CMD39 */
CMD39_FASTIO =
39U | (uint32_t)HAL_MEMCARD_RESPONSE_R4 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD40 */
CMD40_GO_IRQSTATE =
40U | (uint32_t)HAL_MEMCARD_RESPONSE_R5 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_MMC |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD41 */
CMD41 = 41,
ACMD41_SD_SEND_OP_COND =
41U | (uint32_t)HAL_MEMCARD_RESPONSE_R3 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_BCR |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_APP,
/* class 7 */
/* CMD42 */
CMD42_LOCK_UNLOCK =
42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
ACMD42_SET_CLR_CARD_DETECT =
42U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_APP,
CMD43 = 43U, /* CMD43 */
CMD44 = 44U, /* CMD44 */
CMD45 = 45U, /* CMD45 */
CMD46 = 46U, /* CMD46 */
CMD47 = 47U, /* CMD47 */
CMD48 = 48U, /* CMD48 */
CMD49 = 49U, /* CMD49 */
CMD50 = 50U, /* CMD50 */
CMD51 = 51U, /* CMD51 */
ACMD51_SEND_SCR =
51U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_READ |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_SD |
(uint32_t)HAL_MEMCARD_COMMAND_APP,
CMD52 = 52U, /* CMD52 */
CMD53 = 53U, /* CMD53 */
CMD54 = 54U, /* CMD54 */
/* class 8 */
/* CMD55 */
CMD55_APP_CMD =
55U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_AC |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
/* CMD56 */
CMD56_GEN_CMD =
56U | (uint32_t)HAL_MEMCARD_RESPONSE_R1 |
(uint32_t)HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE |
(uint32_t)HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON |
(uint32_t)HAL_MEMCARD_COMMAND_NORMAL,
CMD57 = 57U, /* CMD57 */
CMD58 = 58U, /* CMD58 */
CMD59 = 59U, /* CMD59 */
CMD60 = 60U, /* CMD60 */
CMD61 = 61U, /* CMD61 */
CMD62 = 62U, /* CMD62 */
CMD63 = 63U /* CMD63 */
} HAL_MEMCARD_COMMAND;
/*
* Configuration structure from HAL layer.
*
* If some field is not available it should be filled with 0xFF.
* The API version is 32-bit unsigned integer telling the version of the API.
* The integer is divided to four sections which each can be treated as a 8-bit
* unsigned number:
* Bits 31-24 make the most significant part of the version number. This number
* starts from 1 i.e. the second version of the API will be 0x02xxxxxx. This
* number changes only, if the API itself changes so much that it is not
* compatible anymore with older releases.
* Bits 23-16 API minor version number. For example API version 2.1 would be
* 0x0201xxxx.
* Bits 15-8 are the number of the year when release is done. The 0 is year
* 2000, 1 is year 2001 and so on
* Bits 7- are the week number when release is done. First full week of the
* year is 1
*
* Example: let's assume that release 2.1 is done on week 10 year 2008
* the version will get the value 0x0201080A
*/
typedef struct {
/*
* Version of the chipset API implementation
*
* bits [31:24] API specification major version number.<br>
* bits [23:16] API specification minor version number.<br>
* bits [15:8] API implementation year. (2000 = 0, 2001 = 1, ...)
* bits [7:0] API implementation week.
* Example: API spec version 4.0, implementation w46 2008 => 0x0400082E
*/
uint32_t api_version;
/* maximum block count which can be transferred at once */
uint32_t max_block_count;
/* maximum clock frequence in Hz supported by HW */
uint32_t max_clock_freq;
/* maximum data bus width supported by HW */
uint16_t max_data_width;
/* Is high-speed mode supported by HW (yes=1, no=0) */
uint8_t hs_mode_supported;
/* Is memory card removable (yes=1, no=0) */
uint8_t card_removable;
} HAL_MEMCARD_HW_CONF;
/* Configuration structure to HAL layer. */
typedef struct {
/* how many times to try after fail, for instance sending command */
uint32_t retries_after_fail;
} HAL_MEMCARD_INIT_CONF;
#endif /* EMMC_HAL_H */
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stddef.h>
#include <lib/mmio.h>
#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"
#include "rcar_private.h"
#include "cpg_registers.h"
st_mmc_base mmc_drv_obj;
EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode)
{
if (mode == TRUE) {
/* power on (Vcc&Vccq is always power on) */
mmc_drv_obj.card_power_enable = TRUE;
} else {
/* power off (Vcc&Vccq is always power on) */
mmc_drv_obj.card_power_enable = FALSE;
mmc_drv_obj.mount = FALSE;
mmc_drv_obj.selected = FALSE;
}
return EMMC_SUCCESS;
}
static inline void emmc_set_retry_count(uint32_t retry)
{
mmc_drv_obj.retries_after_fail = retry;
}
static inline void emmc_set_data_timeout(uint32_t data_timeout)
{
mmc_drv_obj.data_timeout = data_timeout;
}
static void emmc_memset(uint8_t *buff, uint8_t data, uint32_t cnt)
{
if (buff == NULL) {
return;
}
while (cnt > 0) {
*buff++ = data;
cnt--;
}
}
static void emmc_driver_config(void)
{
emmc_set_retry_count(EMMC_RETRY_COUNT);
emmc_set_data_timeout(EMMC_RW_DATA_TIMEOUT);
}
static void emmc_drv_init(void)
{
emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base));
mmc_drv_obj.card_present = HAL_MEMCARD_CARD_IS_IN;
mmc_drv_obj.data_timeout = EMMC_RW_DATA_TIMEOUT;
mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
}
static EMMC_ERROR_CODE emmc_dev_finalize(void)
{
EMMC_ERROR_CODE result;
uint32_t dataL;
/*
* MMC power off
* the power supply of eMMC device is always turning on.
* RST_n : Hi --> Low level.
*/
result = rcar_emmc_memcard_power(FALSE);
/* host controller reset */
SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */
SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */
SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */
SETR_32(SD_CLK_CTRL, 0x00000000U); /* MMC clock stop */
dataL = mmio_read_32(SMSTPCR3);
if ((dataL & CPG_MSTP_MMC) == 0U) {
dataL |= (CPG_MSTP_MMC);
mmio_write_32(CPG_CPGWPR, (~dataL));
mmio_write_32(SMSTPCR3, dataL);
}
return result;
}
static EMMC_ERROR_CODE emmc_dev_init(void)
{
/* Enable clock supply to eMMC. */
mstpcr_write(SMSTPCR3, CPG_MSTPSR3, CPG_MSTP_MMC);
/* Set SD clock */
mmio_write_32(CPG_CPGWPR, ~((uint32_t) (BIT9 | BIT0))); /* SD phy 200MHz */
/* Stop SDnH clock & SDn=200MHz */
mmio_write_32(CPG_SDxCKCR, (BIT9 | BIT0));
/* MMCIF initialize */
SETR_32(SD_INFO1, 0x00000000U); /* all interrupt clear */
SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* all interrupt clear */
SETR_32(SD_INFO1_MASK, 0x00000000U); /* all interrupt disable */
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* all interrupt disable */
SETR_32(HOST_MODE, 0x00000000U); /* SD_BUF access width = 64-bit */
SETR_32(SD_OPTION, 0x0000C0EEU); /* Bus width = 1bit, timeout=MAX */
SETR_32(SD_CLK_CTRL, 0x00000000U); /* Disable Automatic Control & Clock Output */
return EMMC_SUCCESS;
}
static EMMC_ERROR_CODE emmc_reset_controller(void)
{
EMMC_ERROR_CODE result;
/* initialize mmc driver */
emmc_drv_init();
/* initialize H/W */
result = emmc_dev_init();
if (result == EMMC_SUCCESS) {
mmc_drv_obj.initialize = TRUE;
}
return result;
}
EMMC_ERROR_CODE emmc_terminate(void)
{
EMMC_ERROR_CODE result;
result = emmc_dev_finalize();
emmc_memset((uint8_t *) (&mmc_drv_obj), 0, sizeof(st_mmc_base));
return result;
}
EMMC_ERROR_CODE rcar_emmc_init(void)
{
EMMC_ERROR_CODE result;
result = emmc_reset_controller();
if (result == EMMC_SUCCESS) {
emmc_driver_config();
}
return result;
}
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights
* reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stddef.h>
#include <lib/mmio.h>
#include "emmc_config.h"
#include "emmc_def.h"
#include "emmc_hal.h"
#include "emmc_registers.h"
#include "emmc_std.h"
#include "rcar_def.h"
static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual);
uint32_t emmc_interrupt(void)
{
EMMC_ERROR_CODE result;
uint32_t prr_data;
uint32_t cut_ver;
uint32_t end_bit;
prr_data = mmio_read_32((uintptr_t) RCAR_PRR);
cut_ver = prr_data & PRR_CUT_MASK;
if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_H3) {
if (cut_ver == PRR_PRODUCT_10) {
end_bit = BIT17;
} else if (cut_ver == PRR_PRODUCT_11) {
end_bit = BIT17;
} else {
end_bit = BIT20;
}
} else if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_M3) {
if (cut_ver == PRR_PRODUCT_10) {
end_bit = BIT17;
} else {
end_bit = BIT20;
}
} else {
end_bit = BIT20;
}
/* SD_INFO */
mmc_drv_obj.error_info.info1 = GETR_32(SD_INFO1);
mmc_drv_obj.error_info.info2 = GETR_32(SD_INFO2);
/* SD_INFO EVENT */
mmc_drv_obj.int_event1 =
mmc_drv_obj.error_info.info1 & GETR_32(SD_INFO1_MASK);
mmc_drv_obj.int_event2 =
mmc_drv_obj.error_info.info2 & GETR_32(SD_INFO2_MASK);
/* ERR_STS */
mmc_drv_obj.error_info.status1 = GETR_32(SD_ERR_STS1);
mmc_drv_obj.error_info.status2 = GETR_32(SD_ERR_STS2);
/* DM_CM_INFO */
mmc_drv_obj.error_info.dm_info1 = GETR_32(DM_CM_INFO1);
mmc_drv_obj.error_info.dm_info2 = GETR_32(DM_CM_INFO2);
/* DM_CM_INFO EVENT */
mmc_drv_obj.dm_event1 =
mmc_drv_obj.error_info.dm_info1 & GETR_32(DM_CM_INFO1_MASK);
mmc_drv_obj.dm_event2 =
mmc_drv_obj.error_info.dm_info2 & GETR_32(DM_CM_INFO2_MASK);
/* ERR SD_INFO2 */
if ((SD_INFO2_ALL_ERR & mmc_drv_obj.int_event2) != 0) {
SETR_32(SD_INFO1_MASK, 0x00000000U); /* interrupt disable */
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* interrupt disable */
SETR_32(SD_INFO1, 0x00000000U); /* interrupt clear */
SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* interrupt clear */
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* PIO Transfer */
/* BWE/BRE */
else if (((SD_INFO2_BWE | SD_INFO2_BRE) & mmc_drv_obj.int_event2)) {
/* BWE */
if (SD_INFO2_BWE & mmc_drv_obj.int_event2) {
SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE));
}
/* BRE */
else {
SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE));
}
result = emmc_trans_sector(mmc_drv_obj.buff_address_virtual);
mmc_drv_obj.buff_address_virtual += EMMC_BLOCK_LENGTH;
mmc_drv_obj.remain_size -= EMMC_BLOCK_LENGTH;
if (result != EMMC_SUCCESS) {
/* data transfer error */
emmc_write_error_info(EMMC_FUNCNO_NONE, result);
/* Panic */
SETR_32(SD_INFO1_MASK, 0x00000000U);
SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
SETR_32(SD_INFO1, 0x00000000U);
/* interrupt clear */
SETR_32(SD_INFO2, SD_INFO2_CLEAR);
mmc_drv_obj.force_terminate = TRUE;
} else {
mmc_drv_obj.during_transfer = FALSE;
}
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* DMA_TRANSFER */
/* DM_CM_INFO1: DMA-ch0 transfer complete or error occurred */
else if ((BIT16 & mmc_drv_obj.dm_event1) != 0) {
SETR_32(DM_CM_INFO1, 0x00000000U);
SETR_32(DM_CM_INFO2, 0x00000000U);
/* interrupt clear */
SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE));
/* DM_CM_INFO2: DMA-ch0 error occurred */
if ((BIT16 & mmc_drv_obj.dm_event2) != 0) {
mmc_drv_obj.dma_error_flag = TRUE;
} else {
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.during_transfer = FALSE;
}
/* wait next interrupt */
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* DM_CM_INFO1: DMA-ch1 transfer complete or error occurred */
else if ((end_bit & mmc_drv_obj.dm_event1) != 0U) {
SETR_32(DM_CM_INFO1, 0x00000000U);
SETR_32(DM_CM_INFO2, 0x00000000U);
/* interrupt clear */
SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE));
/* DM_CM_INFO2: DMA-ch1 error occurred */
if ((BIT17 & mmc_drv_obj.dm_event2) != 0) {
mmc_drv_obj.dma_error_flag = TRUE;
} else {
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.during_transfer = FALSE;
}
/* wait next interrupt */
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* Response end */
else if ((SD_INFO1_INFO0 & mmc_drv_obj.int_event1) != 0) {
/* interrupt clear */
SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO0));
mmc_drv_obj.state_machine_blocking = FALSE;
}
/* Access end */
else if ((SD_INFO1_INFO2 & mmc_drv_obj.int_event1) != 0) {
/* interrupt clear */
SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO2));
mmc_drv_obj.state_machine_blocking = FALSE;
} else {
/* nothing to do. */
}
return (uint32_t) 0;
}
static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual)
{
uint32_t length, i;
uint64_t *bufPtrLL;
if (buff_address_virtual == NULL) {
return EMMC_ERR_PARAM;
}
if ((mmc_drv_obj.during_transfer != TRUE)
|| (mmc_drv_obj.remain_size == 0)) {
return EMMC_ERR_STATE;
}
bufPtrLL = (uint64_t *) buff_address_virtual;
length = mmc_drv_obj.remain_size;
/* data transefer */
for (i = 0; i < (length >> 3); i++) {
/* Write */
if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) {
SETR_64(SD_BUF0, *bufPtrLL); /* buffer --> FIFO */
}
/* Read */
else {
/* Checks when the read data reaches SD_SIZE. */
/* The BRE bit is cleared at emmc_interrupt function. */
if (((i %
(uint32_t) (EMMC_BLOCK_LENGTH >>
EMMC_BUF_SIZE_SHIFT)) == 0U)
&& (i != 0U)) {
/* BRE check */
while (((GETR_32(SD_INFO2)) & SD_INFO2_BRE) ==
0U) {
/* ERROR check */
if (((GETR_32(SD_INFO2)) &
SD_INFO2_ALL_ERR) != 0U) {
return EMMC_ERR_TRANSFER;
}
}
/* BRE clear */
SETR_32(SD_INFO2,
(uint32_t) (GETR_32(SD_INFO2) &
~SD_INFO2_BRE));
}
*bufPtrLL = GETR_64(SD_BUF0); /* FIFO --> buffer */
}
bufPtrLL++;
}
return EMMC_SUCCESS;
}
@@ -0,0 +1,686 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <lib/mmio.h>
#include "emmc_config.h"
#include "emmc_def.h"
#include "emmc_hal.h"
#include "emmc_registers.h"
#include "emmc_std.h"
#include "micro_delay.h"
#include "rcar_def.h"
static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode);
static EMMC_ERROR_CODE emmc_card_init(void);
static EMMC_ERROR_CODE emmc_high_speed(void);
static EMMC_ERROR_CODE emmc_bus_width(uint32_t width);
static uint32_t emmc_set_timeout_register_value(uint32_t freq);
static void set_sd_clk(uint32_t clkDiv);
static uint32_t emmc_calc_tran_speed(uint32_t *freq);
static void emmc_get_partition_access(void);
static void emmc_set_bootpartition(void);
static void emmc_set_bootpartition(void)
{
uint32_t reg;
reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
if (reg == PRR_PRODUCT_M3_CUT10) {
mmc_drv_obj.boot_partition_en =
(EMMC_PARTITION_ID) ((mmc_drv_obj.ext_csd_data[179] &
EMMC_BOOT_PARTITION_EN_MASK) >>
EMMC_BOOT_PARTITION_EN_SHIFT);
} else if ((reg == PRR_PRODUCT_H3_CUT20)
|| (reg == PRR_PRODUCT_M3_CUT11)) {
mmc_drv_obj.boot_partition_en = mmc_drv_obj.partition_access;
} else {
if ((mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION) !=
0U) {
mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_2;
} else {
mmc_drv_obj.boot_partition_en = PARTITION_ID_BOOT_1;
}
}
}
static EMMC_ERROR_CODE emmc_card_init(void)
{
int32_t retry;
uint32_t freq = MMC_400KHZ; /* 390KHz */
EMMC_ERROR_CODE result;
uint32_t result_calc;
/* state check */
if ((mmc_drv_obj.initialize != TRUE)
|| (mmc_drv_obj.card_power_enable != TRUE)
|| ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0)
) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* clock on (force change) */
mmc_drv_obj.current_freq = 0;
mmc_drv_obj.max_freq = MMC_20MHZ;
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return EMMC_ERR;
}
rcar_micro_delay(1000U); /* wait 1ms */
/* Get current access partition */
emmc_get_partition_access();
/* CMD0, arg=0x00000000 */
result = emmc_send_idle_cmd(0x00000000);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
rcar_micro_delay(200U); /* wait 74clock 390kHz(189.74us) */
/* CMD1 */
emmc_make_nontrans_cmd(CMD1_SEND_OP_COND, EMMC_HOST_OCR_VALUE);
for (retry = 300; retry > 0; retry--) {
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
if ((mmc_drv_obj.r3_ocr & EMMC_OCR_STATUS_BIT) != 0) {
break; /* card is ready. exit loop */
}
rcar_micro_delay(1000U); /* wait 1ms */
}
if (retry == 0) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR_TIMEOUT);
return EMMC_ERR_TIMEOUT;
}
switch (mmc_drv_obj.r3_ocr & EMMC_OCR_ACCESS_MODE_MASK) {
case EMMC_OCR_ACCESS_MODE_SECT:
mmc_drv_obj.access_mode = TRUE; /* sector mode */
break;
default:
/* unknown value */
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT, EMMC_ERR);
return EMMC_ERR;
}
/* CMD2 */
emmc_make_nontrans_cmd(CMD2_ALL_SEND_CID_MMC, 0x00000000);
mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.cid_data[0]); /* use CID special buffer */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* CMD3 */
emmc_make_nontrans_cmd(CMD3_SET_RELATIVE_ADDR, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* CMD9 (CSD) */
emmc_make_nontrans_cmd(CMD9_SEND_CSD, EMMC_RCA << 16);
mmc_drv_obj.response = (uint32_t *) (&mmc_drv_obj.csd_data[0]); /* use CSD special buffer */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* card version check */
if (EMMC_CSD_SPEC_VARS() < 4) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT,
EMMC_ERR_ILLEGAL_CARD);
return EMMC_ERR_ILLEGAL_CARD;
}
/* CMD7 (select card) */
emmc_make_nontrans_cmd(CMD7_SELECT_CARD, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
mmc_drv_obj.selected = TRUE;
/*
* card speed check
* Card spec is calculated from TRAN_SPEED(CSD)
*/
result_calc = emmc_calc_tran_speed(&freq);
if (result_calc == 0) {
emmc_write_error_info(EMMC_FUNCNO_CARD_INIT,
EMMC_ERR_ILLEGAL_CARD);
return EMMC_ERR_ILLEGAL_CARD;
}
mmc_drv_obj.max_freq = freq; /* max frequency (card spec) */
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return EMMC_ERR;
}
/* set read/write timeout */
mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) |
mmc_drv_obj.data_timeout));
/* SET_BLOCKLEN(512byte) */
/* CMD16 */
emmc_make_nontrans_cmd(CMD16_SET_BLOCKLEN, EMMC_BLOCK_LENGTH);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* Transfer Data Length */
SETR_32(SD_SIZE, EMMC_BLOCK_LENGTH);
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
/*
* CMD12 is not send.
* If BUS initialization is failed, user must be execute Bus initialization again.
* Bus initialization is start CMD0(soft reset command).
*/
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
return result;
}
/* Set boot partition */
emmc_set_bootpartition();
return EMMC_SUCCESS;
}
static EMMC_ERROR_CODE emmc_high_speed(void)
{
uint32_t freq; /* High speed mode clock frequency */
EMMC_ERROR_CODE result;
uint8_t cardType;
/* state check */
if (mmc_drv_obj.selected != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_HIGH_SPEED, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* max frequency */
cardType = (uint8_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_CARD_TYPE];
if ((cardType & EMMC_EXT_CSD_CARD_TYPE_52MHZ) != 0)
freq = MMC_52MHZ;
else if ((cardType & EMMC_EXT_CSD_CARD_TYPE_26MHZ) != 0)
freq = MMC_26MHZ;
else
freq = MMC_20MHZ;
/* Hi-Speed-mode selection */
if ((freq == MMC_52MHZ) || (freq == MMC_26MHZ)) {
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING);
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
return result;
}
mmc_drv_obj.hs_timing = TIMING_HIGH_SPEED; /* High-Speed */
}
/* set mmc clock */
mmc_drv_obj.max_freq = freq;
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
return EMMC_ERR;
}
/* set read/write timeout */
mmc_drv_obj.data_timeout = emmc_set_timeout_register_value(freq);
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(SD_OPTION_TIMEOUT_CNT_MASK)) |
mmc_drv_obj.data_timeout));
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK_WITHOUT_CRC, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
return result;
}
return EMMC_SUCCESS;
}
static EMMC_ERROR_CODE emmc_clock_ctrl(uint8_t mode)
{
uint32_t value;
/* busy check */
if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK,
EMMC_ERR_CARD_BUSY);
return EMMC_ERR;
}
if (mode == TRUE) {
/* clock ON */
value =
((GETR_32(SD_CLK_CTRL) | MMC_SD_CLK_START) &
SD_CLK_WRITE_MASK);
SETR_32(SD_CLK_CTRL, value); /* on */
mmc_drv_obj.clock_enable = TRUE;
} else {
/* clock OFF */
value =
((GETR_32(SD_CLK_CTRL) & MMC_SD_CLK_STOP) &
SD_CLK_WRITE_MASK);
SETR_32(SD_CLK_CTRL, value); /* off */
mmc_drv_obj.clock_enable = FALSE;
}
return EMMC_SUCCESS;
}
static EMMC_ERROR_CODE emmc_bus_width(uint32_t width)
{
EMMC_ERROR_CODE result = EMMC_ERR;
/* parameter check */
if ((width != 8) && (width != 4) && (width != 1)) {
emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if (mmc_drv_obj.selected != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* 2 = 8bit, 1 = 4bit, 0 =1bit */
mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2);
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH,
(EMMC_SWITCH_BUS_WIDTH_1 |
(mmc_drv_obj.bus_width << 8)));
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
/* occurred error */
mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
goto EXIT;
}
switch (mmc_drv_obj.bus_width) {
case HAL_MEMCARD_DATA_WIDTH_1_BIT:
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT15));
break;
case HAL_MEMCARD_DATA_WIDTH_4_BIT:
SETR_32(SD_OPTION, (GETR_32(SD_OPTION) & ~(BIT15 | BIT13)));
break;
case HAL_MEMCARD_DATA_WIDTH_8_BIT:
SETR_32(SD_OPTION,
((GETR_32(SD_OPTION) & ~(BIT15 | BIT13)) | BIT13));
break;
default:
goto EXIT;
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
goto EXIT;
}
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
goto EXIT;
}
return EMMC_SUCCESS;
EXIT:
emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result);
ERROR("BL2: emmc bus_width error end\n");
return result;
}
EMMC_ERROR_CODE emmc_select_partition(EMMC_PARTITION_ID id)
{
EMMC_ERROR_CODE result;
uint32_t arg;
uint32_t partition_config;
/* state check */
if (mmc_drv_obj.mount != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* id = PARTITION_ACCESS(Bit[2:0]) */
if ((id & ~PARTITION_ID_MASK) != 0) {
emmc_write_error_info(EMMC_FUNCNO_NONE, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* EXT_CSD[179] value */
partition_config =
(uint32_t) mmc_drv_obj.ext_csd_data[EMMC_EXT_CSD_PARTITION_CONFIG];
if ((partition_config & PARTITION_ID_MASK) == id) {
result = EMMC_SUCCESS;
} else {
partition_config =
(uint32_t) ((partition_config & ~PARTITION_ID_MASK) | id);
arg = EMMC_SWITCH_PARTITION_CONFIG | (partition_config << 8);
result = emmc_set_ext_csd(arg);
}
return result;
}
static void set_sd_clk(uint32_t clkDiv)
{
uint32_t dataL;
dataL = (GETR_32(SD_CLK_CTRL) & (~SD_CLK_CTRL_CLKDIV_MASK));
switch (clkDiv) {
case 1:
dataL |= 0x000000FFU;
break; /* 1/1 */
case 2:
dataL |= 0x00000000U;
break; /* 1/2 */
case 4:
dataL |= 0x00000001U;
break; /* 1/4 */
case 8:
dataL |= 0x00000002U;
break; /* 1/8 */
case 16:
dataL |= 0x00000004U;
break; /* 1/16 */
case 32:
dataL |= 0x00000008U;
break; /* 1/32 */
case 64:
dataL |= 0x00000010U;
break; /* 1/64 */
case 128:
dataL |= 0x00000020U;
break; /* 1/128 */
case 256:
dataL |= 0x00000040U;
break; /* 1/256 */
case 512:
dataL |= 0x00000080U;
break; /* 1/512 */
}
SETR_32(SD_CLK_CTRL, dataL);
mmc_drv_obj.current_freq = (uint32_t) clkDiv;
}
static void emmc_get_partition_access(void)
{
uint32_t reg;
EMMC_ERROR_CODE result;
reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
if ((reg == PRR_PRODUCT_H3_CUT20) || (reg == PRR_PRODUCT_M3_CUT11)) {
SETR_32(SD_OPTION, 0x000060EEU); /* 8 bits width */
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000U,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH,
HAL_MEMCARD_READ, HAL_MEMCARD_NOT_DMA);
mmc_drv_obj.get_partition_access_flag = TRUE;
result =
emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
mmc_drv_obj.get_partition_access_flag = FALSE;
if (result == EMMC_SUCCESS) {
mmc_drv_obj.partition_access =
(EMMC_PARTITION_ID) (mmc_drv_obj.ext_csd_data[179]
& PARTITION_ID_MASK);
} else if (result == EMMC_ERR_CMD_TIMEOUT) {
mmc_drv_obj.partition_access = PARTITION_ID_BOOT_1;
} else {
emmc_write_error_info(EMMC_FUNCNO_GET_PERTITION_ACCESS,
result);
panic();
}
SETR_32(SD_OPTION, 0x0000C0EEU); /* Initialize */
}
}
static uint32_t emmc_calc_tran_speed(uint32_t *freq)
{
const uint32_t unit[8] = { 10000U, 100000U, 1000000U, 10000000U,
0U, 0U, 0U, 0U }; /* frequency unit (1/10) */
const uint32_t mult[16] = { 0U, 10U, 12U, 13U, 15U, 20U, 26U, 30U, 35U,
40U, 45U, 52U, 55U, 60U, 70U, 80U };
uint32_t tran_speed = EMMC_CSD_TRAN_SPEED();
uint32_t max_freq;
uint32_t result;
/*
* tran_speed = 0x32
* unit[tran_speed&0x7] = uint[0x2] = 1000000
* mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26
* 1000000 * 26 = 26000000 (26MHz)
*/
result = 1;
max_freq =
unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] *
mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >>
EMMC_TRANSPEED_MULT_SHIFT];
if (max_freq == 0) {
result = 0;
} else if (max_freq >= MMC_FREQ_52MHZ) {
*freq = MMC_52MHZ;
} else if (max_freq >= MMC_FREQ_26MHZ) {
*freq = MMC_26MHZ;
} else if (max_freq >= MMC_FREQ_20MHZ) {
*freq = MMC_20MHZ;
} else {
*freq = MMC_400KHZ;
}
return result;
}
static uint32_t emmc_set_timeout_register_value(uint32_t freq)
{
uint32_t timeout_cnt; /* SD_OPTION - Timeout Counter */
switch (freq) {
case 1U:
timeout_cnt = 0xE0U;
break; /* SDCLK * 2^27 */
case 2U:
timeout_cnt = 0xE0U;
break; /* SDCLK * 2^27 */
case 4U:
timeout_cnt = 0xD0U;
break; /* SDCLK * 2^26 */
case 8U:
timeout_cnt = 0xC0U;
break; /* SDCLK * 2^25 */
case 16U:
timeout_cnt = 0xB0U;
break; /* SDCLK * 2^24 */
case 32U:
timeout_cnt = 0xA0U;
break; /* SDCLK * 2^23 */
case 64U:
timeout_cnt = 0x90U;
break; /* SDCLK * 2^22 */
case 128U:
timeout_cnt = 0x80U;
break; /* SDCLK * 2^21 */
case 256U:
timeout_cnt = 0x70U;
break; /* SDCLK * 2^20 */
case 512U:
timeout_cnt = 0x70U;
break; /* SDCLK * 2^20 */
default:
timeout_cnt = 0xE0U;
break; /* SDCLK * 2^27 */
}
return timeout_cnt;
}
EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg)
{
EMMC_ERROR_CODE result;
/* CMD6 */
emmc_make_nontrans_cmd(CMD6_SWITCH, arg);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* CMD8 (EXT_CSD) */
emmc_make_trans_cmd(CMD8_SEND_EXT_CSD, 0x00000000,
(uint32_t *) (&mmc_drv_obj.ext_csd_data[0]),
EMMC_MAX_EXT_CSD_LENGTH, HAL_MEMCARD_READ,
HAL_MEMCARD_NOT_DMA);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
return EMMC_SUCCESS;
}
EMMC_ERROR_CODE emmc_set_request_mmc_clock(uint32_t *freq)
{
/* parameter check */
if (freq == NULL) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if ((mmc_drv_obj.initialize != TRUE)
|| (mmc_drv_obj.card_power_enable != TRUE)) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* clock is already running in the desired frequency. */
if ((mmc_drv_obj.clock_enable == TRUE)
&& (mmc_drv_obj.current_freq == *freq)) {
return EMMC_SUCCESS;
}
/* busy check */
if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0) {
emmc_write_error_info(EMMC_FUNCNO_SET_CLOCK,
EMMC_ERR_CARD_BUSY);
return EMMC_ERR;
}
set_sd_clk(*freq);
mmc_drv_obj.clock_enable = FALSE;
return emmc_clock_ctrl(TRUE); /* clock on */
}
EMMC_ERROR_CODE rcar_emmc_mount(void)
{
EMMC_ERROR_CODE result;
/* state check */
if ((mmc_drv_obj.initialize != TRUE)
|| (mmc_drv_obj.card_power_enable != TRUE)
|| ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) != 0)
) {
emmc_write_error_info(EMMC_FUNCNO_MOUNT, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* initialize card (IDLE state --> Transfer state) */
result = emmc_card_init();
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_CARD_INIT);
if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
/* nothing to do. */
}
return result;
}
/* Switching high speed mode */
result = emmc_high_speed();
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_HIGH_SPEED);
if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
/* nothing to do. */
}
return result;
}
/* Changing the data bus width */
result = emmc_bus_width(8);
if (result != EMMC_SUCCESS) {
emmc_write_error_info_func_no(EMMC_FUNCNO_BUS_WIDTH);
if (emmc_clock_ctrl(FALSE) != EMMC_SUCCESS) {
/* nothing to do. */
}
return result;
}
/* mount complete */
mmc_drv_obj.mount = TRUE;
return EMMC_SUCCESS;
}
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include "emmc_config.h"
#include "emmc_def.h"
#include "emmc_hal.h"
#include "emmc_registers.h"
#include "emmc_std.h"
#define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b))
#define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU
static EMMC_ERROR_CODE emmc_multiple_block_read(uint32_t *buff_address_virtual,
uint32_t sector_number, uint32_t count,
HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode)
{
EMMC_ERROR_CODE result;
/* parameter check */
if ((count > EMMC_RW_SECTOR_COUNT_MAX)
|| (count == 0)
|| ((transfer_mode != HAL_MEMCARD_DMA)
&& (transfer_mode != HAL_MEMCARD_NOT_DMA))
) {
emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* CMD23 */
emmc_make_nontrans_cmd(CMD23_SET_BLOCK_COUNT, count);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
SETR_32(SD_SECCNT, count);
SETR_32(SD_STOP, 0x00000100);
/* SD_BUF Read/Write DMA Transfer enable */
SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE));
/* CMD18 */
emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number,
buff_address_virtual,
count << EMMC_SECTOR_SIZE_SHIFT, HAL_MEMCARD_READ,
transfer_mode);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result; /* CMD18 error code */
}
/* CMD13 */
emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
#if RCAR_BL2_DCACHE == 1
if (transfer_mode == HAL_MEMCARD_NOT_DMA) {
flush_dcache_range((uint64_t) buff_address_virtual,
((size_t) count << EMMC_SECTOR_SIZE_SHIFT));
}
#endif /* RCAR_BL2_DCACHE == 1 */
/* ready status check */
if ((mmc_drv_obj.r1_card_status & EMMC_R1_READY) == 0) {
emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR,
EMMC_ERR_CARD_BUSY);
return EMMC_ERR_CARD_BUSY;
}
/* state check */
if (mmc_drv_obj.current_state != EMMC_R1_STATE_TRAN) {
emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR,
EMMC_ERR_CARD_STATE);
return EMMC_ERR_CARD_STATE;
}
return EMMC_SUCCESS;
}
EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual,
uint32_t sector_number,
uint32_t count, uint32_t feature_flags)
{
uint32_t trans_count;
uint32_t remain;
EMMC_ERROR_CODE result;
HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode;
/* parameter check */
if (count == 0) {
emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM);
return EMMC_ERR_PARAM;
}
/* state check */
if (mmc_drv_obj.mount != TRUE) {
emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_STATE);
return EMMC_ERR_STATE;
}
/* DMA? */
if ((feature_flags & LOADIMAGE_FLAGS_DMA_ENABLE) != 0) {
transfer_mode = HAL_MEMCARD_DMA;
} else {
transfer_mode = HAL_MEMCARD_NOT_DMA;
}
remain = count;
while (remain != 0) {
trans_count = MIN_EMMC(remain, EMMC_RW_SECTOR_COUNT_MAX);
result =
emmc_multiple_block_read(buff_address_virtual,
sector_number, trans_count,
transfer_mode);
if (result != EMMC_SUCCESS) {
return result;
}
buff_address_virtual += (EMMC_BLOCK_LENGTH_DW * trans_count);
sector_number += trans_count;
remain -= trans_count;
}
return EMMC_SUCCESS;
}
@@ -0,0 +1,215 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef EMMC_REGISTERS_H
#define EMMC_REGISTERS_H
/* MMC channel select */
#define MMC_CH0 (0U) /* SDHI2/MMC0 */
#define MMC_CH1 (1U) /* SDHI3/MMC1 */
#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2M) || (RCAR_LSI == RZ_G2H) || (RCAR_LSI == RZ_G2N)
#define USE_MMC_CH (MMC_CH1) /* R-Car E3 or RZ/G2{H,M,N} */
#else /* RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2{H,M,N} */
#define USE_MMC_CH (MMC_CH0) /* R-Car H3/M3/M3N */
#endif /* RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2{H,M,N} */
#define BIT0 (0x00000001U)
#define BIT1 (0x00000002U)
#define BIT2 (0x00000004U)
#define BIT3 (0x00000008U)
#define BIT4 (0x00000010U)
#define BIT5 (0x00000020U)
#define BIT6 (0x00000040U)
#define BIT7 (0x00000080U)
#define BIT8 (0x00000100U)
#define BIT9 (0x00000200U)
#define BIT10 (0x00000400U)
#define BIT11 (0x00000800U)
#define BIT12 (0x00001000U)
#define BIT13 (0x00002000U)
#define BIT14 (0x00004000U)
#define BIT15 (0x00008000U)
#define BIT16 (0x00010000U)
#define BIT17 (0x00020000U)
#define BIT18 (0x00040000U)
#define BIT19 (0x00080000U)
#define BIT20 (0x00100000U)
#define BIT21 (0x00200000U)
#define BIT22 (0x00400000U)
#define BIT23 (0x00800000U)
#define BIT24 (0x01000000U)
#define BIT25 (0x02000000U)
#define BIT26 (0x04000000U)
#define BIT27 (0x08000000U)
#define BIT28 (0x10000000U)
#define BIT29 (0x20000000U)
#define BIT30 (0x40000000U)
#define BIT31 (0x80000000U)
#if USE_MMC_CH == MMC_CH0
#define CPG_SDxCKCR (CPG_SD2CKCR) /* SDHI2/MMC0 */
#else /* USE_MMC_CH == MMC_CH0 */
#define CPG_SDxCKCR (CPG_SD3CKCR) /* SDHI3/MMC1 */
#endif /* USE_MMC_CH == MMC_CH0 */
/* Boot Status register */
#define MFISBTSTSR (0xE6260604U)
#define MFISBTSTSR_BOOT_PARTITION (0x00000010U)
/* eMMC registers */
#define MMC0_SD_BASE (0xEE140000U)
#define MMC1_SD_BASE (0xEE160000U)
#if USE_MMC_CH == MMC_CH0
#define MMC_SD_BASE (MMC0_SD_BASE)
#else /* USE_MMC_CH == MMC_CH0 */
#define MMC_SD_BASE (MMC1_SD_BASE)
#endif /* USE_MMC_CH == MMC_CH0 */
#define SD_CMD (MMC_SD_BASE + 0x0000U)
#define SD_PORTSEL (MMC_SD_BASE + 0x0008U)
#define SD_ARG (MMC_SD_BASE + 0x0010U)
#define SD_ARG1 (MMC_SD_BASE + 0x0018U)
#define SD_STOP (MMC_SD_BASE + 0x0020U)
#define SD_SECCNT (MMC_SD_BASE + 0x0028U)
#define SD_RSP10 (MMC_SD_BASE + 0x0030U)
#define SD_RSP1 (MMC_SD_BASE + 0x0038U)
#define SD_RSP32 (MMC_SD_BASE + 0x0040U)
#define SD_RSP3 (MMC_SD_BASE + 0x0048U)
#define SD_RSP54 (MMC_SD_BASE + 0x0050U)
#define SD_RSP5 (MMC_SD_BASE + 0x0058U)
#define SD_RSP76 (MMC_SD_BASE + 0x0060U)
#define SD_RSP7 (MMC_SD_BASE + 0x0068U)
#define SD_INFO1 (MMC_SD_BASE + 0x0070U)
#define SD_INFO2 (MMC_SD_BASE + 0x0078U)
#define SD_INFO1_MASK (MMC_SD_BASE + 0x0080U)
#define SD_INFO2_MASK (MMC_SD_BASE + 0x0088U)
#define SD_CLK_CTRL (MMC_SD_BASE + 0x0090U)
#define SD_SIZE (MMC_SD_BASE + 0x0098U)
#define SD_OPTION (MMC_SD_BASE + 0x00A0U)
#define SD_ERR_STS1 (MMC_SD_BASE + 0x00B0U)
#define SD_ERR_STS2 (MMC_SD_BASE + 0x00B8U)
#define SD_BUF0 (MMC_SD_BASE + 0x00C0U)
#define SDIO_MODE (MMC_SD_BASE + 0x00D0U)
#define SDIO_INFO1 (MMC_SD_BASE + 0x00D8U)
#define SDIO_INFO1_MASK (MMC_SD_BASE + 0x00E0U)
#define CC_EXT_MODE (MMC_SD_BASE + 0x0360U)
#define SOFT_RST (MMC_SD_BASE + 0x0380U)
#define VERSION (MMC_SD_BASE + 0x0388U)
#define HOST_MODE (MMC_SD_BASE + 0x0390U)
#define DM_CM_DTRAN_MODE (MMC_SD_BASE + 0x0820U)
#define DM_CM_DTRAN_CTRL (MMC_SD_BASE + 0x0828U)
#define DM_CM_RST (MMC_SD_BASE + 0x0830U)
#define DM_CM_INFO1 (MMC_SD_BASE + 0x0840U)
#define DM_CM_INFO1_MASK (MMC_SD_BASE + 0x0848U)
#define DM_CM_INFO2 (MMC_SD_BASE + 0x0850U)
#define DM_CM_INFO2_MASK (MMC_SD_BASE + 0x0858U)
#define DM_DTRAN_ADDR (MMC_SD_BASE + 0x0880U)
/* SD_INFO1 Registers */
#define SD_INFO1_HPIRES 0x00010000UL /* Response Reception Completion */
#define SD_INFO1_INFO10 0x00000400UL /* Indicates the SDDAT3 state */
#define SD_INFO1_INFO9 0x00000200UL /* SDDAT3 Card Insertion */
#define SD_INFO1_INFO8 0x00000100UL /* SDDAT3 Card Removal */
#define SD_INFO1_INFO7 0x00000080UL /* Write Protect */
#define SD_INFO1_INFO5 0x00000020UL /* Indicates the ISDCD state */
#define SD_INFO1_INFO4 0x00000010UL /* ISDCD Card Insertion */
#define SD_INFO1_INFO3 0x00000008UL /* ISDCD Card Removal */
#define SD_INFO1_INFO2 0x00000004UL /* Access end */
#define SD_INFO1_INFO0 0x00000001UL /* Response end */
/* SD_INFO2 Registers */
#define SD_INFO2_ILA 0x00008000UL /* Illegal Access Error */
#define SD_INFO2_CBSY 0x00004000UL /* Command Type Register Busy */
#define SD_INFO2_SCLKDIVEN 0x00002000UL
#define SD_INFO2_BWE 0x00000200UL /* SD_BUF Write Enable */
#define SD_INFO2_BRE 0x00000100UL /* SD_BUF Read Enable */
#define SD_INFO2_DAT0 0x00000080UL /* SDDAT0 */
#define SD_INFO2_ERR6 0x00000040UL /* Response Timeout */
#define SD_INFO2_ERR5 0x00000020UL /* SD_BUF Illegal Read Access */
#define SD_INFO2_ERR4 0x00000010UL /* SD_BUF Illegal Write Access */
#define SD_INFO2_ERR3 0x00000008UL /* Data Timeout */
#define SD_INFO2_ERR2 0x00000004UL /* END Error */
#define SD_INFO2_ERR1 0x00000002UL /* CRC Error */
#define SD_INFO2_ERR0 0x00000001UL /* CMD Error */
#define SD_INFO2_ALL_ERR 0x0000807FUL
#define SD_INFO2_CLEAR 0x00000800UL /* BIT11 write value should always be 1. HWM_0003 */
/* SOFT_RST */
#define SOFT_RST_SDRST 0x00000001UL
/* SD_CLK_CTRL */
#define SD_CLK_CTRL_SDCLKOFFEN 0x00000200UL
#define SD_CLK_CTRL_SCLKEN 0x00000100UL
#define SD_CLK_CTRL_CLKDIV_MASK 0x000000FFUL
#define SD_CLOCK_ENABLE 0x00000100UL
#define SD_CLOCK_DISABLE 0x00000000UL
#define SD_CLK_WRITE_MASK 0x000003FFUL
#define SD_CLK_CLKDIV_CLEAR_MASK 0xFFFFFF0FUL
/* SD_OPTION */
#define SD_OPTION_TIMEOUT_CNT_MASK 0x000000F0UL
/*
* MMC Clock Frequency
* 200MHz * 1/x = output clock
*/
#define MMC_CLK_OFF 0UL /* Clock output is disabled */
#define MMC_400KHZ 512UL /* 200MHz * 1/512 = 390 KHz */
#define MMC_20MHZ 16UL /* 200MHz * 1/16 = 12.5 MHz Normal speed mode */
#define MMC_26MHZ 8UL /* 200MHz * 1/8 = 25 MHz HS mode 26Mhz */
#define MMC_52MHZ 4UL /* 200MHz * 1/4 = 50 MHz HS mode 52Mhz */
#define MMC_100MHZ 2UL /* 200MHz * 1/2 = 100 MHz */
#define MMC_200MHZ 1UL /* 200MHz * 1/1 = 200 MHz */
#define MMC_FREQ_52MHZ 52000000UL
#define MMC_FREQ_26MHZ 26000000UL
#define MMC_FREQ_20MHZ 20000000UL
/* MMC Clock DIV */
#define MMC_SD_CLK_START 0x00000100UL /* CLOCK On */
#define MMC_SD_CLK_STOP (~0x00000100UL) /* CLOCK stop */
#define MMC_SD_CLK_DIV1 0x000000FFUL /* 1/1 */
#define MMC_SD_CLK_DIV2 0x00000000UL /* 1/2 */
#define MMC_SD_CLK_DIV4 0x00000001UL /* 1/4 */
#define MMC_SD_CLK_DIV8 0x00000002UL /* 1/8 */
#define MMC_SD_CLK_DIV16 0x00000004UL /* 1/16 */
#define MMC_SD_CLK_DIV32 0x00000008UL /* 1/32 */
#define MMC_SD_CLK_DIV64 0x00000010UL /* 1/64 */
#define MMC_SD_CLK_DIV128 0x00000020UL /* 1/128 */
#define MMC_SD_CLK_DIV256 0x00000040UL /* 1/256 */
#define MMC_SD_CLK_DIV512 0x00000080UL /* 1/512 */
/* DM_CM_DTRAN_MODE */
#define DM_CM_DTRAN_MODE_CH0 0x00000000UL /* CH0(downstream) */
#define DM_CM_DTRAN_MODE_CH1 0x00010000UL /* CH1(upstream) */
#define DM_CM_DTRAN_MODE_BIT_WIDTH 0x00000030UL
/* CC_EXT_MODE */
#define CC_EXT_MODE_DMASDRW_ENABLE 0x00000002UL /* SD_BUF Read/Write DMA Transfer */
#define CC_EXT_MODE_CLEAR 0x00001010UL /* BIT 12 & 4 always 1. */
/* DM_CM_INFO_MASK */
#define DM_CM_INFO_MASK_CLEAR 0xFFFCFFFEUL
#define DM_CM_INFO_CH0_ENABLE 0x00010001UL
#define DM_CM_INFO_CH1_ENABLE 0x00020001UL
/* DM_DTRAN_ADDR */
#define DM_DTRAN_ADDR_WRITE_MASK 0xFFFFFFF8UL
/* DM_CM_DTRAN_CTRL */
#define DM_CM_DTRAN_CTRL_START 0x00000001UL
/* SYSC Registers */
#if USE_MMC_CH == MMC_CH0
#define CPG_MSTP_MMC (BIT12) /* SDHI2/MMC0 */
#else /* USE_MMC_CH == MMC_CH0 */
#define CPG_MSTP_MMC (BIT11) /* SDHI3/MMC1 */
#endif /* USE_MMC_CH == MMC_CH0 */
#endif /* EMMC_REGISTERS_H */
@@ -0,0 +1,475 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef EMMC_STD_H
#define EMMC_STD_H
#include "emmc_hal.h"
#ifndef FALSE
#define FALSE 0U
#endif
#ifndef TRUE
#define TRUE 1U
#endif
/* 64bit registers */
#define SETR_64(r, v) (*(volatile uint64_t *)(r) = (v))
#define GETR_64(r) (*(volatile uint64_t *)(r))
/* 32bit registers */
#define SETR_32(r, v) (*(volatile uint32_t *)(r) = (v))
#define GETR_32(r) (*(volatile uint32_t *)(r))
/* 16bit registers */
#define SETR_16(r, v) (*(volatile uint16_t *)(r) = (v))
#define GETR_16(r) (*(volatile uint16_t *)(r))
/* 8bit registers */
#define SETR_8(r, v) (*(volatile uint8_t *)(r) = (v))
#define GETR_8(r) (*(volatile uint8_t *)(r))
/* CSD register Macros */
#define EMMC_GET_CID(x, y) (emmc_bit_field(mmc_drv_obj.cid_data, (x), (y)))
#define EMMC_CID_MID() (EMMC_GET_CID(127, 120))
#define EMMC_CID_CBX() (EMMC_GET_CID(113, 112))
#define EMMC_CID_OID() (EMMC_GET_CID(111, 104))
#define EMMC_CID_PNM1() (EMMC_GET_CID(103, 88))
#define EMMC_CID_PNM2() (EMMC_GET_CID(87, 56))
#define EMMC_CID_PRV() (EMMC_GET_CID(55, 48))
#define EMMC_CID_PSN() (EMMC_GET_CID(47, 16))
#define EMMC_CID_MDT() (EMMC_GET_CID(15, 8))
#define EMMC_CID_CRC() (EMMC_GET_CID(7, 1))
/* CSD register Macros */
#define EMMC_GET_CSD(x, y) (emmc_bit_field(mmc_drv_obj.csd_data, (x), (y)))
#define EMMC_CSD_CSD_STRUCTURE() (EMMC_GET_CSD(127, 126))
#define EMMC_CSD_SPEC_VARS() (EMMC_GET_CSD(125, 122))
#define EMMC_CSD_TAAC() (EMMC_GET_CSD(119, 112))
#define EMMC_CSD_NSAC() (EMMC_GET_CSD(111, 104))
#define EMMC_CSD_TRAN_SPEED() (EMMC_GET_CSD(103, 96))
#define EMMC_CSD_CCC() (EMMC_GET_CSD(95, 84))
#define EMMC_CSD_READ_BL_LEN() (EMMC_GET_CSD(83, 80))
#define EMMC_CSD_READ_BL_PARTIAL() (EMMC_GET_CSD(79, 79))
#define EMMC_CSD_WRITE_BLK_MISALIGN() (EMMC_GET_CSD(78, 78))
#define EMMC_CSD_READ_BLK_MISALIGN() (EMMC_GET_CSD(77, 77))
#define EMMC_CSD_DSR_IMP() (EMMC_GET_CSD(76, 76))
#define EMMC_CSD_C_SIZE() (EMMC_GET_CSD(73, 62))
#define EMMC_CSD_VDD_R_CURR_MIN() (EMMC_GET_CSD(61, 59))
#define EMMC_CSD_VDD_R_CURR_MAX() (EMMC_GET_CSD(58, 56))
#define EMMC_CSD_VDD_W_CURR_MIN() (EMMC_GET_CSD(55, 53))
#define EMMC_CSD_VDD_W_CURR_MAX() (EMMC_GET_CSD(52, 50))
#define EMMC_CSD_C_SIZE_MULT() (EMMC_GET_CSD(49, 47))
#define EMMC_CSD_ERASE_GRP_SIZE() (EMMC_GET_CSD(46, 42))
#define EMMC_CSD_ERASE_GRP_MULT() (EMMC_GET_CSD(41, 37))
#define EMMC_CSD_WP_GRP_SIZE() (EMMC_GET_CSD(36, 32))
#define EMMC_CSD_WP_GRP_ENABLE() (EMMC_GET_CSD(31, 31))
#define EMMC_CSD_DEFALT_ECC() (EMMC_GET_CSD(30, 29))
#define EMMC_CSD_R2W_FACTOR() (EMMC_GET_CSD(28, 26))
#define EMMC_CSD_WRITE_BL_LEN() (EMMC_GET_CSD(25, 22))
#define EMMC_CSD_WRITE_BL_PARTIAL() (EMMC_GET_CSD(21, 21))
#define EMMC_CSD_CONTENT_PROT_APP() (EMMC_GET_CSD(16, 16))
#define EMMC_CSD_FILE_FORMAT_GRP() (EMMC_GET_CSD(15, 15))
#define EMMC_CSD_COPY() (EMMC_GET_CSD(14, 14))
#define EMMC_CSD_PERM_WRITE_PROTECT() (EMMC_GET_CSD(13, 13))
#define EMMC_CSD_TMP_WRITE_PROTECT() (EMMC_GET_CSD(12, 12))
#define EMMC_CSD_FILE_FORMAT() (EMMC_GET_CSD(11, 10))
#define EMMC_CSD_ECC() (EMMC_GET_CSD(9, 8))
#define EMMC_CSD_CRC() (EMMC_GET_CSD(7, 1))
/* sector access */
#define EMMC_4B_BOUNDARY_CHECK_MASK 0x00000003
#define EMMC_SECTOR_SIZE_SHIFT 9U /* 512 = 2^9 */
#define EMMC_SECTOR_SIZE 512
#define EMMC_BLOCK_LENGTH 512
#define EMMC_BLOCK_LENGTH_DW 128
#define EMMC_BUF_SIZE_SHIFT 3U /* 8byte = 2^3 */
/* eMMC specification clock */
#define EMMC_CLOCK_SPEC_400K 400000UL /* initialize clock 400KHz */
#define EMMC_CLOCK_SPEC_20M 20000000UL /* normal speed 20MHz */
#define EMMC_CLOCK_SPEC_26M 26000000UL /* high speed 26MHz */
#define EMMC_CLOCK_SPEC_52M 52000000UL /* high speed 52MHz */
#define EMMC_CLOCK_SPEC_100M 100000000UL /* high speed 100MHz */
/* EMMC driver error code. (extended HAL_MEMCARD_RETURN) */
typedef enum {
EMMC_ERR = 0, /* unknown error */
EMMC_SUCCESS, /* OK */
EMMC_ERR_FROM_DMAC, /* DMAC allocation error */
EMMC_ERR_FROM_DMAC_TRANSFER, /* DMAC transfer error */
EMMC_ERR_CARD_STATUS_BIT, /* card status error */
EMMC_ERR_CMD_TIMEOUT, /* command timeout error */
EMMC_ERR_DATA_TIMEOUT, /* data timeout error */
EMMC_ERR_CMD_CRC, /* command CRC error */
EMMC_ERR_DATA_CRC, /* data CRC error */
EMMC_ERR_PARAM, /* parameter error */
EMMC_ERR_RESPONSE, /* response error */
EMMC_ERR_RESPONSE_BUSY, /* response busy error */
EMMC_ERR_TRANSFER, /* data transfer error */
EMMC_ERR_READ_SECTOR, /* read sector error */
EMMC_ERR_WRITE_SECTOR, /* write sector error */
EMMC_ERR_STATE, /* state error */
EMMC_ERR_TIMEOUT, /* timeout error */
EMMC_ERR_ILLEGAL_CARD, /* illegal card */
EMMC_ERR_CARD_BUSY, /* Busy state */
EMMC_ERR_CARD_STATE, /* card state error */
EMMC_ERR_SET_TRACE, /* trace information error */
EMMC_ERR_FROM_TIMER, /* Timer error */
EMMC_ERR_FORCE_TERMINATE, /* Force terminate */
EMMC_ERR_CARD_POWER, /* card power fail */
EMMC_ERR_ERASE_SECTOR, /* erase sector error */
EMMC_ERR_INFO2 /* exec cmd error info2 */
} EMMC_ERROR_CODE;
/* Function number */
#define EMMC_FUNCNO_NONE 0U
#define EMMC_FUNCNO_DRIVER_INIT 1U
#define EMMC_FUNCNO_CARD_POWER_ON 2U
#define EMMC_FUNCNO_MOUNT 3U
#define EMMC_FUNCNO_CARD_INIT 4U
#define EMMC_FUNCNO_HIGH_SPEED 5U
#define EMMC_FUNCNO_BUS_WIDTH 6U
#define EMMC_FUNCNO_MULTI_BOOT_SELECT_PARTITION 7U
#define EMMC_FUNCNO_MULTI_BOOT_READ_SECTOR 8U
#define EMMC_FUNCNO_TRANS_DATA_READ_SECTOR 9U
#define EMMC_FUNCNO_UBOOT_IMAGE_SELECT_PARTITION 10U
#define EMMC_FUNCNO_UBOOT_IMAGE_READ_SECTOR 11U
#define EMMC_FUNCNO_SET_CLOCK 12U
#define EMMC_FUNCNO_EXEC_CMD 13U
#define EMMC_FUNCNO_READ_SECTOR 14U
#define EMMC_FUNCNO_WRITE_SECTOR 15U
#define EMMC_FUNCNO_ERASE_SECTOR 16U
#define EMMC_FUNCNO_GET_PERTITION_ACCESS 17U
/*
* Response
* R1
* Type 'E' bit and bit14(must be 0). ignore bit22
*/
#define EMMC_R1_ERROR_MASK 0xFDBFE080U
/* Ignore bit23 (Not check CRC error) */
#define EMMC_R1_ERROR_MASK_WITHOUT_CRC (0xFD3FE080U)
#define EMMC_R1_STATE_MASK 0x00001E00U /* [12:9] */
#define EMMC_R1_READY 0x00000100U /* bit8 */
#define EMMC_R1_STATE_SHIFT 9
/* R4 */
#define EMMC_R4_RCA_MASK 0xFFFF0000UL
#define EMMC_R4_STATUS 0x00008000UL
/* CSD */
#define EMMC_TRANSPEED_FREQ_UNIT_MASK 0x07 /* bit[2:0] */
#define EMMC_TRANSPEED_FREQ_UNIT_SHIFT 0
#define EMMC_TRANSPEED_MULT_MASK 0x78 /* bit[6:3] */
#define EMMC_TRANSPEED_MULT_SHIFT 3
/* OCR */
#define EMMC_HOST_OCR_VALUE 0x40FF8080
#define EMMC_OCR_STATUS_BIT 0x80000000L /* Card power up status bit */
#define EMMC_OCR_ACCESS_MODE_MASK 0x60000000L /* bit[30:29] */
#define EMMC_OCR_ACCESS_MODE_SECT 0x40000000L
#define EMMC_OCR_ACCESS_MODE_BYTE 0x00000000L
/* EXT_CSD */
#define EMMC_EXT_CSD_S_CMD_SET 504
#define EMMC_EXT_CSD_INI_TIMEOUT_AP 241
#define EMMC_EXT_CSD_PWR_CL_DDR_52_360 239
#define EMMC_EXT_CSD_PWR_CL_DDR_52_195 238
#define EMMC_EXT_CSD_MIN_PERF_DDR_W_8_52 235
#define EMMC_EXT_CSD_MIN_PERF_DDR_R_8_52 234
#define EMMC_EXT_CSD_TRIM_MULT 232
#define EMMC_EXT_CSD_SEC_FEATURE_SUPPORT 231
#define EMMC_EXT_CSD_SEC_ERASE_MULT 229
#define EMMC_EXT_CSD_BOOT_INFO 228
#define EMMC_EXT_CSD_BOOT_SIZE_MULTI 226
#define EMMC_EXT_CSD_ACC_SIZE 225
#define EMMC_EXT_CSD_HC_ERASE_GRP_SIZE 224
#define EMMC_EXT_CSD_ERASE_TIMEOUT_MULT 223
#define EMMC_EXT_CSD_PEL_WR_SEC_C 222
#define EMMC_EXT_CSD_HC_WP_GRP_SIZE 221
#define EMMC_EXT_CSD_S_C_VCC 220
#define EMMC_EXT_CSD_S_C_VCCQ 219
#define EMMC_EXT_CSD_S_A_TIMEOUT 217
#define EMMC_EXT_CSD_SEC_COUNT 215
#define EMMC_EXT_CSD_MIN_PERF_W_8_52 210
#define EMMC_EXT_CSD_MIN_PERF_R_8_52 209
#define EMMC_EXT_CSD_MIN_PERF_W_8_26_4_52 208
#define EMMC_EXT_CSD_MIN_PERF_R_8_26_4_52 207
#define EMMC_EXT_CSD_MIN_PERF_W_4_26 206
#define EMMC_EXT_CSD_MIN_PERF_R_4_26 205
#define EMMC_EXT_CSD_PWR_CL_26_360 203
#define EMMC_EXT_CSD_PWR_CL_52_360 202
#define EMMC_EXT_CSD_PWR_CL_26_195 201
#define EMMC_EXT_CSD_PWR_CL_52_195 200
#define EMMC_EXT_CSD_CARD_TYPE 196
#define EMMC_EXT_CSD_CSD_STRUCTURE 194
#define EMMC_EXT_CSD_EXT_CSD_REV 192
#define EMMC_EXT_CSD_CMD_SET 191
#define EMMC_EXT_CSD_CMD_SET_REV 189
#define EMMC_EXT_CSD_POWER_CLASS 187
#define EMMC_EXT_CSD_HS_TIMING 185
#define EMMC_EXT_CSD_BUS_WIDTH 183
#define EMMC_EXT_CSD_ERASED_MEM_CONT 181
#define EMMC_EXT_CSD_PARTITION_CONFIG 179
#define EMMC_EXT_CSD_BOOT_CONFIG_PROT 178
#define EMMC_EXT_CSD_BOOT_BUS_WIDTH 177
#define EMMC_EXT_CSD_ERASE_GROUP_DEF 175
#define EMMC_EXT_CSD_BOOT_WP 173
#define EMMC_EXT_CSD_USER_WP 171
#define EMMC_EXT_CSD_FW_CONFIG 169
#define EMMC_EXT_CSD_RPMB_SIZE_MULT 168
#define EMMC_EXT_CSD_RST_n_FUNCTION 162
#define EMMC_EXT_CSD_PARTITIONING_SUPPORT 160
#define EMMC_EXT_CSD_MAX_ENH_SIZE_MULT 159
#define EMMC_EXT_CSD_PARTITIONS_ATTRIBUTE 156
#define EMMC_EXT_CSD_PARTITION_SETTING_COMPLETED 155
#define EMMC_EXT_CSD_GP_SIZE_MULT 154
#define EMMC_EXT_CSD_ENH_SIZE_MULT 142
#define EMMC_EXT_CSD_ENH_START_ADDR 139
#define EMMC_EXT_CSD_SEC_BAD_BLK_MGMNT 134
#define EMMC_EXT_CSD_CARD_TYPE_26MHZ 0x01
#define EMMC_EXT_CSD_CARD_TYPE_52MHZ 0x02
#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_12V 0x04
#define EMMC_EXT_CSD_CARD_TYPE_DDR_52MHZ_18V 0x08
#define EMMC_EXT_CSD_CARD_TYPE_52MHZ_MASK 0x0e
/* SWITCH (CMD6) argument */
#define EXTCSD_ACCESS_BYTE (BIT25 | BIT24)
#define EXTCSD_SET_BITS BIT24
#define HS_TIMING_ADD (185 << 16) /* H'b9 */
#define HS_TIMING_1 (1 << 8)
#define HS_TIMING_HS200 (2 << 8)
#define HS_TIMING_HS400 (3 << 8)
#define BUS_WIDTH_ADD (183 << 16) /* H'b7 */
#define BUS_WIDTH_1 (0 << 8)
#define BUS_WIDTH_4 (1 << 8)
#define BUS_WIDTH_8 (2 << 8)
#define BUS_WIDTH_4DDR (5 << 8)
#define BUS_WIDTH_8DDR (6 << 8)
#define EMMC_SWITCH_HS_TIMING (EXTCSD_ACCESS_BYTE | HS_TIMING_ADD |\
HS_TIMING_1) /* H'03b90100 */
#define EMMC_SWITCH_HS_TIMING_OFF (EXTCSD_ACCESS_BYTE |\
HS_TIMING_ADD) /* H'03b90000 */
#define EMMC_SWITCH_BUS_WIDTH_1 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\
BUS_WIDTH_1) /* H'03b70000 */
#define EMMC_SWITCH_BUS_WIDTH_4 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\
BUS_WIDTH_4) /* H'03b70100 */
#define EMMC_SWITCH_BUS_WIDTH_8 (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\
BUS_WIDTH_8) /* H'03b70200 */
#define EMMC_SWITCH_BUS_WIDTH_4DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\
BUS_WIDTH_4DDR) /* H'03b70500 */
#define EMMC_SWITCH_BUS_WIDTH_8DDR (EXTCSD_ACCESS_BYTE | BUS_WIDTH_ADD |\
BUS_WIDTH_8DDR) /* H'03b70600 */
/* Partition config = 0x00 */
#define EMMC_SWITCH_PARTITION_CONFIG 0x03B30000UL
#define TIMING_HIGH_SPEED 1UL
#define EMMC_BOOT_PARTITION_EN_MASK 0x38U
#define EMMC_BOOT_PARTITION_EN_SHIFT 3U
/* Bus width */
#define EMMC_BUSWIDTH_1BIT CE_CMD_SET_DATW_1BIT
#define EMMC_BUSWIDTH_4BIT CE_CMD_SET_DATW_4BIT
#define EMMC_BUSWIDTH_8BIT CE_CMD_SET_DATW_8BIT
/* for st_mmc_base */
#define EMMC_MAX_RESPONSE_LENGTH 17
#define EMMC_MAX_CID_LENGTH 16
#define EMMC_MAX_CSD_LENGTH 16
#define EMMC_MAX_EXT_CSD_LENGTH 512U
#define EMMC_RES_REG_ALIGNED 4U
#define EMMC_BUF_REG_ALIGNED 8U
/* TAAC mask */
#define TAAC_TIME_UNIT_MASK (0x07)
#define TAAC_MULTIPLIER_FACTOR_MASK (0x0F)
/* Partition id */
typedef enum {
PARTITION_ID_USER = 0x0, /* User Area */
PARTITION_ID_BOOT_1 = 0x1, /* boot partition 1 */
PARTITION_ID_BOOT_2 = 0x2, /* boot partition 2 */
PARTITION_ID_RPMB = 0x3, /* Replay Protected Memory Block */
PARTITION_ID_GP_1 = 0x4, /* General Purpose partition 1 */
PARTITION_ID_GP_2 = 0x5, /* General Purpose partition 2 */
PARTITION_ID_GP_3 = 0x6, /* General Purpose partition 3 */
PARTITION_ID_GP_4 = 0x7, /* General Purpose partition 4 */
PARTITION_ID_MASK = 0x7 /* [2:0] */
} EMMC_PARTITION_ID;
/* card state in R1 response [12:9] */
typedef enum {
EMMC_R1_STATE_IDLE = 0,
EMMC_R1_STATE_READY,
EMMC_R1_STATE_IDENT,
EMMC_R1_STATE_STBY,
EMMC_R1_STATE_TRAN,
EMMC_R1_STATE_DATA,
EMMC_R1_STATE_RCV,
EMMC_R1_STATE_PRG,
EMMC_R1_STATE_DIS,
EMMC_R1_STATE_BTST,
EMMC_R1_STATE_SLEP
} EMMC_R1_STATE;
typedef enum {
ESTATE_BEGIN = 0,
ESTATE_ISSUE_CMD,
ESTATE_NON_RESP_CMD,
ESTATE_RCV_RESP,
ESTATE_RCV_RESPONSE_BUSY,
ESTATE_CHECK_RESPONSE_COMPLETE,
ESTATE_DATA_TRANSFER,
ESTATE_DATA_TRANSFER_COMPLETE,
ESTATE_ACCESS_END,
ESTATE_TRANSFER_ERROR,
ESTATE_ERROR,
ESTATE_END
} EMMC_INT_STATE;
/* eMMC boot driver error information */
typedef struct {
uint16_t num; /* error no */
uint16_t code; /* error code */
volatile uint32_t info1; /* SD_INFO1. (hw dependent) */
volatile uint32_t info2; /* SD_INFO2. (hw dependent) */
volatile uint32_t status1; /* SD_ERR_STS1. (hw dependent) */
volatile uint32_t status2; /* SD_ERR_STS2. (hw dependent) */
volatile uint32_t dm_info1; /* DM_CM_INFO1. (hw dependent) */
volatile uint32_t dm_info2; /* DM_CM_INFO2. (hw dependent) */
} st_error_info;
/* Command information */
typedef struct {
HAL_MEMCARD_COMMAND cmd; /* Command information */
uint32_t arg; /* argument */
HAL_MEMCARD_OPERATION dir; /* direction */
uint32_t hw; /* SD_CMD register value. */
} st_command_info;
/* MMC driver base */
typedef struct {
st_error_info error_info; /* error information */
st_command_info cmd_info; /* command information */
/* for data transfer */
uint32_t *buff_address_virtual; /* Dest or Src buff */
uint32_t *buff_address_physical; /* Dest or Src buff */
HAL_MEMCARD_DATA_WIDTH bus_width; /* bus width */
uint32_t trans_size; /* transfer size for this command */
uint32_t remain_size; /* remain size for this command */
uint32_t response_length; /* response length for this command */
uint32_t sector_size; /* sector_size */
/* clock */
uint32_t base_clock; /* MMC host controller clock */
/*
* Max freq (Card Spec)[Hz]. It changes dynamically by CSD and
* EXT_CSD.
*/
uint32_t max_freq;
/* request freq [Hz] (400K, 26MHz, 52MHz, etc) */
uint32_t request_freq;
/* current MMC clock[Hz] (the closest frequency supported by HW) */
uint32_t current_freq;
/* state flag */
/* presence status of the memory card */
HAL_MEMCARD_PRESENCE_STATUS card_present;
uint32_t card_power_enable;
uint32_t clock_enable;
/* True : initialize complete. */
uint32_t initialize;
/* True : sector access, FALSE : byte access */
uint32_t access_mode;
/* True : mount complete. */
uint32_t mount;
/* True : selected card. */
uint32_t selected;
/* 0: DMA, 1:PIO */
HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode;
/* loaded ISSW image No. ISSW have copy image. */
uint32_t image_num;
/* card state */
EMMC_R1_STATE current_state;
/* True : during command processing */
volatile uint32_t during_cmd_processing;
/* True : during transfer */
volatile uint32_t during_transfer;
/* True : during transfer (DMA) */
volatile uint32_t during_dma_transfer;
/* True : occurred DMAC error */
volatile uint32_t dma_error_flag;
/* force terminate flag */
volatile uint32_t force_terminate;
/* state machine blocking flag : True or False */
volatile uint32_t state_machine_blocking;
/* True : get partition access processing */
volatile uint32_t get_partition_access_flag;
EMMC_PARTITION_ID boot_partition_en; /* Boot partition */
EMMC_PARTITION_ID partition_access; /* Current access partition */
/* timeout */
uint32_t hs_timing;
/* read and write data timeout */
uint32_t data_timeout;
/* retry */
uint32_t retries_after_fail;
/* interrupt */
volatile uint32_t int_event1; /* interrupt SD_INFO1 Event */
volatile uint32_t int_event2; /* interrupt SD_INFO2 Event */
volatile uint32_t dm_event1; /* interrupt DM_CM_INFO1 Event */
volatile uint32_t dm_event2; /* interrupt DM_CM_INFO2 Event */
/* response */
uint32_t *response; /* buffer ptr for executing command. */
uint32_t r1_card_status; /* R1 response data */
uint32_t r3_ocr; /* R3 response data */
uint32_t r4_resp; /* R4 response data */
uint32_t r5_resp; /* R5 response data */
/* True : clock mode is low. (MMC clock = Max26MHz) */
uint32_t low_clock_mode_enable;
uint32_t reserved2;
uint32_t reserved3;
uint32_t reserved4;
/* CSD registers (4byte align) */
uint8_t csd_data[EMMC_MAX_CSD_LENGTH] /* CSD */
__attribute__ ((aligned(EMMC_RES_REG_ALIGNED)));
/* CID registers (4byte align) */
uint8_t cid_data[EMMC_MAX_CID_LENGTH] /* CID */
__attribute__ ((aligned(EMMC_RES_REG_ALIGNED)));
/* EXT CSD registers (8byte align) */
uint8_t ext_csd_data[EMMC_MAX_EXT_CSD_LENGTH] /* EXT_CSD */
__attribute__ ((aligned(EMMC_BUF_REG_ALIGNED)));
/* Response registers (4byte align) */
uint8_t response_data[EMMC_MAX_RESPONSE_LENGTH] /* other response */
__attribute__ ((aligned(EMMC_RES_REG_ALIGNED)));
} st_mmc_base;
typedef int (*func) (void);
uint32_t emmc_get_csd_time(void);
#define MMC_DEBUG
#endif /* EMMC_STD_H */
@@ -0,0 +1,226 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include "emmc_config.h"
#include "emmc_def.h"
#include "emmc_hal.h"
#include "emmc_registers.h"
#include "emmc_std.h"
static const uint32_t cmd_reg_hw[EMMC_CMD_MAX + 1] = {
0x00000000, /* CMD0 */
0x00000701, /* CMD1 */
0x00000002, /* CMD2 */
0x00000003, /* CMD3 */
0x00000004, /* CMD4 */
0x00000505, /* CMD5 */
0x00000406, /* CMD6 */
0x00000007, /* CMD7 */
0x00001C08, /* CMD8 */
0x00000009, /* CMD9 */
0x0000000A, /* CMD10 */
0x00000000, /* reserved */
0x0000000C, /* CMD12 */
0x0000000D, /* CMD13 */
0x00001C0E, /* CMD14 */
0x0000000F, /* CMD15 */
0x00000010, /* CMD16 */
0x00000011, /* CMD17 */
0x00007C12, /* CMD18 */
0x00000C13, /* CMD19 */
0x00000000,
0x00001C15, /* CMD21 */
0x00000000,
0x00000017, /* CMD23 */
0x00000018, /* CMD24 */
0x00006C19, /* CMD25 */
0x00000C1A, /* CMD26 */
0x0000001B, /* CMD27 */
0x0000001C, /* CMD28 */
0x0000001D, /* CMD29 */
0x0000001E, /* CMD30 */
0x00001C1F, /* CMD31 */
0x00000000,
0x00000000,
0x00000000,
0x00000423, /* CMD35 */
0x00000424, /* CMD36 */
0x00000000,
0x00000026, /* CMD38 */
0x00000427, /* CMD39 */
0x00000428, /* CMD40(send cmd) */
0x00000000,
0x0000002A, /* CMD42 */
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000C31,
0x00000000,
0x00000000,
0x00000000,
0x00007C35,
0x00006C36,
0x00000037, /* CMD55 */
0x00000038, /* CMD56(Read) */
0x00000000,
0x00000000,
0x00000000,
0x00000000
};
uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom)
{
uint32_t value;
uint32_t index_top = (uint32_t) (15 - (top >> 3));
uint32_t index_bottom = (uint32_t) (15 - (bottom >> 3));
if (index_top == index_bottom) {
value = data[index_top];
} else if ((index_top + 1) == index_bottom) {
value =
(uint32_t) ((data[index_top] << 8) | data[index_bottom]);
} else if ((index_top + 2) == index_bottom) {
value =
(uint32_t) ((data[index_top] << 16) |
(data[index_top + 1] << 8) | data[index_top +
2]);
} else {
value =
(uint32_t) ((data[index_top] << 24) |
(data[index_top + 1] << 16) |
(data[index_top + 2] << 8) |
data[index_top + 3]);
}
value = ((value >> (bottom & 0x07)) & ((1 << (top - bottom + 1)) - 1));
return value;
}
void emmc_write_error_info(uint16_t func_no, EMMC_ERROR_CODE error_code)
{
mmc_drv_obj.error_info.num = func_no;
mmc_drv_obj.error_info.code = (uint16_t) error_code;
ERROR("BL2: emmc err:func_no=0x%x code=0x%x\n", func_no, error_code);
}
void emmc_write_error_info_func_no(uint16_t func_no)
{
mmc_drv_obj.error_info.num = func_no;
ERROR("BL2: emmc err:func_no=0x%x\n", func_no);
}
void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg)
{
/* command information */
mmc_drv_obj.cmd_info.cmd = cmd;
mmc_drv_obj.cmd_info.arg = arg;
mmc_drv_obj.cmd_info.dir = HAL_MEMCARD_READ;
mmc_drv_obj.cmd_info.hw =
cmd_reg_hw[cmd & HAL_MEMCARD_COMMAND_INDEX_MASK];
/* clear data transfer information */
mmc_drv_obj.trans_size = 0;
mmc_drv_obj.remain_size = 0;
mmc_drv_obj.buff_address_virtual = NULL;
mmc_drv_obj.buff_address_physical = NULL;
/* response information */
mmc_drv_obj.response_length = 6;
switch (mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK) {
case HAL_MEMCARD_RESPONSE_NONE:
mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data;
mmc_drv_obj.response_length = 0;
break;
case HAL_MEMCARD_RESPONSE_R1:
mmc_drv_obj.response = &mmc_drv_obj.r1_card_status;
break;
case HAL_MEMCARD_RESPONSE_R1b:
mmc_drv_obj.cmd_info.hw |= BIT10; /* bit10 = R1 busy bit */
mmc_drv_obj.response = &mmc_drv_obj.r1_card_status;
break;
case HAL_MEMCARD_RESPONSE_R2:
mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data;
mmc_drv_obj.response_length = 17;
break;
case HAL_MEMCARD_RESPONSE_R3:
mmc_drv_obj.response = &mmc_drv_obj.r3_ocr;
break;
case HAL_MEMCARD_RESPONSE_R4:
mmc_drv_obj.response = &mmc_drv_obj.r4_resp;
break;
case HAL_MEMCARD_RESPONSE_R5:
mmc_drv_obj.response = &mmc_drv_obj.r5_resp;
break;
default:
mmc_drv_obj.response = (uint32_t *) mmc_drv_obj.response_data;
break;
}
}
void emmc_make_trans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg,
uint32_t *buff_address_virtual,
uint32_t len,
HAL_MEMCARD_OPERATION dir,
HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode)
{
emmc_make_nontrans_cmd(cmd, arg); /* update common information */
/* for data transfer command */
mmc_drv_obj.cmd_info.dir = dir;
mmc_drv_obj.buff_address_virtual = buff_address_virtual;
mmc_drv_obj.buff_address_physical = buff_address_virtual;
mmc_drv_obj.trans_size = len;
mmc_drv_obj.remain_size = len;
mmc_drv_obj.transfer_mode = transfer_mode;
}
EMMC_ERROR_CODE emmc_send_idle_cmd(uint32_t arg)
{
EMMC_ERROR_CODE result;
uint32_t freq;
/* initialize state */
mmc_drv_obj.mount = FALSE;
mmc_drv_obj.selected = FALSE;
mmc_drv_obj.during_transfer = FALSE;
mmc_drv_obj.during_cmd_processing = FALSE;
mmc_drv_obj.during_dma_transfer = FALSE;
mmc_drv_obj.dma_error_flag = FALSE;
mmc_drv_obj.force_terminate = FALSE;
mmc_drv_obj.state_machine_blocking = FALSE;
mmc_drv_obj.bus_width = HAL_MEMCARD_DATA_WIDTH_1_BIT;
mmc_drv_obj.max_freq = MMC_20MHZ; /* 20MHz */
mmc_drv_obj.current_state = EMMC_R1_STATE_IDLE;
/* CMD0 (MMC clock is current frequency. if Data transfer mode, 20MHz or higher.) */
emmc_make_nontrans_cmd(CMD0_GO_IDLE_STATE, arg); /* CMD0 */
result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
if (result != EMMC_SUCCESS) {
return result;
}
/* change MMC clock(400KHz) */
freq = MMC_400KHZ;
result = emmc_set_request_mmc_clock(&freq);
if (result != EMMC_SUCCESS) {
return result;
}
return EMMC_SUCCESS;
}
@@ -0,0 +1,600 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <lib/mmio.h>
#include "cpg_registers.h"
#include "iic_dvfs.h"
#include "rcar_def.h"
#include "rcar_private.h"
#define DVFS_RETRY_MAX (2U)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0 (0x07U)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09U)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0BU)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0EU)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07U)
#define CPG_BIT_SMSTPCR9_DVFS (0x04000000U)
#define IIC_DVFS_REG_BASE (0xE60B0000U)
#define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000U)
#define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004U)
#define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008U)
#define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000CU)
#define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010U)
#define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014U)
#define IIC_DVFS_BIT_ICSR_BUSY (0x10U)
#define IIC_DVFS_BIT_ICSR_AL (0x08U)
#define IIC_DVFS_BIT_ICSR_TACK (0x04U)
#define IIC_DVFS_BIT_ICSR_WAIT (0x02U)
#define IIC_DVFS_BIT_ICSR_DTE (0x01U)
#define IIC_DVFS_BIT_ICCR_ENABLE (0x80U)
#define IIC_DVFS_SET_ICCR_START (0x94U)
#define IIC_DVFS_SET_ICCR_STOP (0x90U)
#define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94U)
#define IIC_DVFS_SET_ICCR_CHANGE (0x81U)
#define IIC_DVFS_SET_ICCR_STOP_READ (0xC0U)
#define IIC_DVFS_BIT_ICIC_TACKE (0x04U)
#define IIC_DVFS_BIT_ICIC_WAITE (0x02U)
#define IIC_DVFS_BIT_ICIC_DTEE (0x01U)
#define DVFS_READ_MODE (0x01U)
#define DVFS_WRITE_MODE (0x00U)
#define IIC_DVFS_SET_DUMMY (0x52U)
#define IIC_DVFS_SET_BUSY_LOOP (500000000U)
enum dvfs_state_t {
DVFS_START = 0,
DVFS_STOP,
DVFS_RETRANSMIT,
DVFS_READ,
DVFS_STOP_READ,
DVFS_SET_SLAVE_READ,
DVFS_SET_SLAVE,
DVFS_WRITE_ADDR,
DVFS_WRITE_DATA,
DVFS_CHANGE_SEND_TO_RECEIVE,
DVFS_DONE,
};
#define DVFS_PROCESS (1)
#define DVFS_COMPLETE (0)
#define DVFS_ERROR (-1)
#if IMAGE_BL31
#define IIC_DVFS_FUNC(__name, ...) \
static int32_t __attribute__ ((section(".system_ram"))) \
dvfs_ ##__name(__VA_ARGS__)
#define RCAR_DVFS_API(__name, ...) \
int32_t __attribute__ ((section(".system_ram"))) \
rcar_iic_dvfs_ ##__name(__VA_ARGS__)
#else
#define IIC_DVFS_FUNC(__name, ...) \
static int32_t dvfs_ ##__name(__VA_ARGS__)
#define RCAR_DVFS_API(__name, ...) \
int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__)
#endif
IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode)
{
uint8_t icsr_al = 0U, icsr_tack = 0U;
uint8_t reg, stop;
uint32_t i = 0U;
stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ :
IIC_DVFS_SET_ICCR_STOP;
reg = mmio_read_8(IIC_DVFS_REG_ICSR);
icsr_al = (reg & IIC_DVFS_BIT_ICSR_AL) == IIC_DVFS_BIT_ICSR_AL;
icsr_tack = (reg & IIC_DVFS_BIT_ICSR_TACK) == IIC_DVFS_BIT_ICSR_TACK;
if (icsr_al == 0U && icsr_tack == 0U) {
return DVFS_PROCESS;
}
if (icsr_al) {
reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL;
mmio_write_8(IIC_DVFS_REG_ICSR, reg);
if (*state == DVFS_SET_SLAVE) {
mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY);
}
do {
reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
IIC_DVFS_BIT_ICSR_WAIT;
} while (reg == 0U);
mmio_write_8(IIC_DVFS_REG_ICCR, stop);
reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, reg);
i = 0U;
do {
reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
IIC_DVFS_BIT_ICSR_BUSY;
if (reg == 0U) {
break;
}
if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
panic();
}
} while (true);
mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U);
(*err)++;
if (*err > DVFS_RETRY_MAX) {
return DVFS_ERROR;
}
*state = DVFS_START;
return DVFS_PROCESS;
}
/* icsr_tack */
mmio_write_8(IIC_DVFS_REG_ICCR, stop);
reg = mmio_read_8(IIC_DVFS_REG_ICIC);
reg &= ~(IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE);
mmio_write_8(IIC_DVFS_REG_ICIC, reg);
reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK;
mmio_write_8(IIC_DVFS_REG_ICSR, reg);
i = 0U;
while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
panic();
}
}
mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
(*err)++;
if (*err > DVFS_RETRY_MAX) {
return DVFS_ERROR;
}
*state = DVFS_START;
return DVFS_PROCESS;
}
IIC_DVFS_FUNC(start, enum dvfs_state_t *state)
{
uint8_t iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_E;
uint8_t icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_E;
int32_t result = DVFS_PROCESS;
uint32_t reg, lsi_product;
uint8_t mode;
mode = mmio_read_8(IIC_DVFS_REG_ICCR) | IIC_DVFS_BIT_ICCR_ENABLE;
mmio_write_8(IIC_DVFS_REG_ICCR, mode);
lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
if (lsi_product == PRR_PRODUCT_E3) {
goto start;
}
reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14;
switch (reg) {
case MD14_MD13_TYPE_0:
iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_0;
icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_0;
break;
case MD14_MD13_TYPE_1:
iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_1;
icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_1;
break;
case MD14_MD13_TYPE_2:
iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_2;
icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_2;
break;
default:
iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_3;
icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_3;
break;
}
start:
mmio_write_8(IIC_DVFS_REG_ICCL, iccl);
mmio_write_8(IIC_DVFS_REG_ICCH, icch);
mode = mmio_read_8(IIC_DVFS_REG_ICIC)
| IIC_DVFS_BIT_ICIC_TACKE
| IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE;
mmio_write_8(IIC_DVFS_REG_ICIC, mode);
mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_START);
*state = DVFS_SET_SLAVE;
return result;
}
IIC_DVFS_FUNC(set_slave, enum dvfs_state_t *state, uint32_t *err, uint8_t slave)
{
uint8_t mode;
int32_t result;
uint8_t address;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
if (mode != IIC_DVFS_BIT_ICSR_DTE) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
mmio_write_8(IIC_DVFS_REG_ICIC, mode);
address = slave << 1;
mmio_write_8(IIC_DVFS_REG_ICDR, address);
*state = DVFS_WRITE_ADDR;
return result;
}
IIC_DVFS_FUNC(write_addr, enum dvfs_state_t *state, uint32_t *err, uint8_t reg_addr)
{
uint8_t mode;
int32_t result;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
return result;
}
mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, mode);
*state = DVFS_WRITE_DATA;
return result;
}
IIC_DVFS_FUNC(write_data, enum dvfs_state_t *state, uint32_t *err,
uint8_t reg_data)
{
int32_t result;
uint8_t mode;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
return result;
}
mmio_write_8(IIC_DVFS_REG_ICDR, reg_data);
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, mode);
*state = DVFS_STOP;
return result;
}
IIC_DVFS_FUNC(stop, enum dvfs_state_t *state, uint32_t *err)
{
int32_t result;
uint8_t mode;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
return result;
}
mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP);
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, mode);
*state = DVFS_DONE;
return result;
}
IIC_DVFS_FUNC(done, void)
{
uint32_t i;
for (i = 0U; i < IIC_DVFS_SET_BUSY_LOOP; i++) {
if ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
continue;
}
goto done;
}
panic();
done:
mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
return DVFS_COMPLETE;
}
IIC_DVFS_FUNC(write_reg_addr_read, enum dvfs_state_t *state, uint32_t *err,
uint8_t reg_addr)
{
int32_t result;
uint8_t mode;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
return result;
}
mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, mode);
*state = DVFS_RETRANSMIT;
return result;
}
IIC_DVFS_FUNC(retransmit, enum dvfs_state_t *state, uint32_t *err)
{
int32_t result;
uint8_t mode;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
return result;
}
mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION);
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, mode);
mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
mmio_write_8(IIC_DVFS_REG_ICIC, mode);
*state = DVFS_SET_SLAVE_READ;
return result;
}
IIC_DVFS_FUNC(set_slave_read, enum dvfs_state_t *state, uint32_t *err,
uint8_t slave)
{
uint8_t address;
int32_t result;
uint8_t mode;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
if (mode != IIC_DVFS_BIT_ICSR_DTE) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
mmio_write_8(IIC_DVFS_REG_ICIC, mode);
address = ((uint8_t) (slave << 1) + DVFS_READ_MODE);
mmio_write_8(IIC_DVFS_REG_ICDR, address);
*state = DVFS_CHANGE_SEND_TO_RECEIVE;
return result;
}
IIC_DVFS_FUNC(change_send_to_receive, enum dvfs_state_t *state, uint32_t *err)
{
int32_t result;
uint8_t mode;
result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
return result;
}
mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE);
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, mode);
*state = DVFS_STOP_READ;
return result;
}
IIC_DVFS_FUNC(stop_read, enum dvfs_state_t *state, uint32_t *err)
{
int32_t result;
uint8_t mode;
result = dvfs_check_error(state, err, DVFS_READ_MODE);
if (result == DVFS_ERROR) {
return result;
}
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
return result;
}
mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ);
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
mmio_write_8(IIC_DVFS_REG_ICSR, mode);
mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
mmio_write_8(IIC_DVFS_REG_ICIC, mode);
*state = DVFS_READ;
return result;
}
IIC_DVFS_FUNC(read, enum dvfs_state_t *state, uint8_t *reg_data)
{
uint8_t mode;
mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
if (mode != IIC_DVFS_BIT_ICSR_DTE) {
return DVFS_PROCESS;
}
mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
mmio_write_8(IIC_DVFS_REG_ICIC, mode);
*reg_data = mmio_read_8(IIC_DVFS_REG_ICDR);
*state = DVFS_DONE;
return DVFS_PROCESS;
}
RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data)
{
enum dvfs_state_t state = DVFS_START;
int32_t result = DVFS_PROCESS;
uint32_t err = 0U;
mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
mmio_write_8(IIC_DVFS_REG_ICCR, 1U);
again:
switch (state) {
case DVFS_START:
result = dvfs_start(&state);
break;
case DVFS_SET_SLAVE:
result = dvfs_set_slave(&state, &err, slave);
break;
case DVFS_WRITE_ADDR:
result = dvfs_write_addr(&state, &err, reg_addr);
break;
case DVFS_WRITE_DATA:
result = dvfs_write_data(&state, &err, reg_data);
break;
case DVFS_STOP:
result = dvfs_stop(&state, &err);
break;
case DVFS_DONE:
result = dvfs_done();
break;
default:
panic();
break;
}
if (result == DVFS_PROCESS) {
goto again;
}
return result;
}
RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data)
{
enum dvfs_state_t state = DVFS_START;
int32_t result = DVFS_PROCESS;
uint32_t err = 0U;
mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
mmio_write_8(IIC_DVFS_REG_ICCR, 1U);
again:
switch (state) {
case DVFS_START:
result = dvfs_start(&state);
break;
case DVFS_SET_SLAVE:
result = dvfs_set_slave(&state, &err, slave);
break;
case DVFS_WRITE_ADDR:
result = dvfs_write_reg_addr_read(&state, &err, reg);
break;
case DVFS_RETRANSMIT:
result = dvfs_retransmit(&state, &err);
break;
case DVFS_SET_SLAVE_READ:
result = dvfs_set_slave_read(&state, &err, slave);
break;
case DVFS_CHANGE_SEND_TO_RECEIVE:
result = dvfs_change_send_to_receive(&state, &err);
break;
case DVFS_STOP_READ:
result = dvfs_stop_read(&state, &err);
break;
case DVFS_READ:
result = dvfs_read(&state, data);
break;
case DVFS_DONE:
result = dvfs_done();
break;
default:
panic();
break;
}
if (result == DVFS_PROCESS) {
goto again;
}
return result;
}
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IIC_DVFS_H
#define IIC_DVFS_H
/* PMIC slave */
#define PMIC (0x30U)
#define BKUP_MODE_CNT (0x20U)
#define DVFS_SET_VID (0x54U)
#define REG_KEEP10 (0x79U)
/* EEPROM slave */
#define EEPROM (0x50U)
#define BOARD_ID (0x70U)
int32_t rcar_iic_dvfs_receive(uint8_t slave, uint8_t reg, uint8_t *data);
int32_t rcar_iic_dvfs_send(uint8_t slave, uint8_t regr, uint8_t data);
#endif /* IIC_DVFS_H */
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IO_COMMON_H
#define IO_COMMON_H
typedef struct io_drv_spec {
size_t offset;
size_t length;
uint32_t partition;
} io_drv_spec_t;
#endif /* IO_COMMON_H */
@@ -0,0 +1,179 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <string.h>
#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_storage.h>
#include "emmc_config.h"
#include "emmc_def.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "io_common.h"
#include "io_emmcdrv.h"
#include "io_private.h"
static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)),
io_dev_info_t **dev_info);
static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info);
typedef struct {
uint32_t in_use;
uintptr_t base;
signed long long file_pos;
EMMC_PARTITION_ID partition;
} file_state_t;
static file_state_t current_file = { 0 };
static EMMC_PARTITION_ID emmcdrv_bootpartition = PARTITION_ID_USER;
static io_type_t device_type_emmcdrv(void)
{
return IO_TYPE_MEMMAP;
}
static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode,
signed long long offset)
{
if (mode != IO_SEEK_SET) {
return IO_FAIL;
}
((file_state_t *) entity->info)->file_pos = offset;
return IO_SUCCESS;
}
static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
file_state_t *fp = (file_state_t *) entity->info;
uint32_t sector_add, sector_num, emmc_dma = 0;
int32_t result = IO_SUCCESS;
sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT;
sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT;
NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n",
buffer,
current_file.partition, current_file.file_pos,
sector_add, length, sector_num);
if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) {
emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE;
}
if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num,
emmc_dma) != EMMC_SUCCESS) {
result = IO_FAIL;
}
*length_read = length;
fp->file_pos += (signed long long)length;
return result;
}
static int32_t emmcdrv_block_open(io_dev_info_t *dev_info,
const uintptr_t spec, io_entity_t *entity)
{
const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec;
if (current_file.in_use != 0U) {
WARN("mmc_block: Only one open spec at a time\n");
return IO_RESOURCES_EXHAUSTED;
}
current_file.file_pos = 0;
current_file.in_use = 1;
if (emmcdrv_bootpartition == PARTITION_ID_USER) {
emmcdrv_bootpartition = mmc_drv_obj.boot_partition_en;
if ((emmcdrv_bootpartition == PARTITION_ID_BOOT_1) ||
(emmcdrv_bootpartition == PARTITION_ID_BOOT_2)) {
current_file.partition = emmcdrv_bootpartition;
NOTICE("BL2: eMMC boot from partition %d\n",
emmcdrv_bootpartition);
goto done;
}
return IO_FAIL;
}
if ((block_spec->partition == PARTITION_ID_USER) ||
(block_spec->partition == PARTITION_ID_BOOT_1) ||
(block_spec->partition == PARTITION_ID_BOOT_2)) {
current_file.partition = block_spec->partition;
} else {
current_file.partition = emmcdrv_bootpartition;
}
done:
if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) {
return IO_FAIL;
}
entity->info = (uintptr_t) &current_file;
return IO_SUCCESS;
}
static int32_t emmcdrv_block_close(io_entity_t *entity)
{
memset((void *)&current_file, 0, sizeof(current_file));
entity->info = 0U;
return IO_SUCCESS;
}
static const io_dev_funcs_t emmcdrv_dev_funcs = {
.type = &device_type_emmcdrv,
.open = &emmcdrv_block_open,
.seek = &emmcdrv_block_seek,
.size = NULL,
.read = &emmcdrv_block_read,
.write = NULL,
.close = &emmcdrv_block_close,
.dev_init = NULL,
.dev_close = &emmcdrv_dev_close
};
static const io_dev_info_t emmcdrv_dev_info = {
.funcs = &emmcdrv_dev_funcs,
.info = (uintptr_t) 0
};
static const io_dev_connector_t emmcdrv_dev_connector = {
&emmcdrv_dev_open,
};
static int32_t emmcdrv_dev_open(const uintptr_t spec __attribute__ ((unused)),
io_dev_info_t **dev_info)
{
*dev_info = (io_dev_info_t *) &emmcdrv_dev_info;
return IO_SUCCESS;
}
static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info)
{
return IO_SUCCESS;
}
int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **dev_con)
{
int32_t rc;
rc = io_register_device(&emmcdrv_dev_info);
if (rc == IO_SUCCESS) {
*dev_con = &emmcdrv_dev_connector;
}
return rc;
}
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IO_EMMCDRV_H
#define IO_EMMCDRV_H
struct io_dev_connector;
int32_t rcar_register_io_dev_emmcdrv(const io_dev_connector_t **connector);
#endif /* IO_EMMCDRV_H */
@@ -0,0 +1,154 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <string.h>
#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_storage.h>
#include "io_common.h"
#include "io_memdrv.h"
#include "io_private.h"
#include "rcar_def.h"
extern void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len);
static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)),
io_dev_info_t **dev_info);
static int32_t memdrv_dev_close(io_dev_info_t *dev_info);
/*
* As we need to be able to keep state for seek, only one file can be open
* at a time. Make this a structure and point to the entity->info. When we
* can malloc memory we can change this to support more open files.
*/
typedef struct {
uint32_t in_use;
uintptr_t base;
signed long long file_pos;
} file_state_t;
static file_state_t current_file = { 0 };
static io_type_t device_type_memdrv(void)
{
return IO_TYPE_MEMMAP;
}
static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
io_entity_t *entity)
{
const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec;
/*
* Since we need to track open state for seek() we only allow one open
* spec at a time. When we have dynamic memory we can malloc and set
* entity->info.
*/
if (current_file.in_use != 0U) {
return IO_RESOURCES_EXHAUSTED;
}
/* File cursor offset for seek and incremental reads etc. */
current_file.base = block_spec->offset;
current_file.file_pos = 0;
current_file.in_use = 1;
entity->info = (uintptr_t) &current_file;
return IO_SUCCESS;
}
static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode,
signed long long offset)
{
if (mode != IO_SEEK_SET) {
return IO_FAIL;
}
((file_state_t *) entity->info)->file_pos = offset;
return IO_SUCCESS;
}
static int32_t memdrv_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *cnt)
{
file_state_t *fp;
fp = (file_state_t *) entity->info;
NOTICE("BL2: dst=0x%lx src=0x%llx len=%ld(0x%lx)\n",
buffer, (unsigned long long)fp->base +
(unsigned long long)fp->file_pos, length, length);
if (FLASH_MEMORY_SIZE < (fp->file_pos + (signed long long)length)) {
ERROR("BL2: check load image (source address)\n");
return IO_FAIL;
}
rcar_dma_exec(buffer, fp->base + (uintptr_t)fp->file_pos, length);
fp->file_pos += (signed long long)length;
*cnt = length;
return IO_SUCCESS;
}
static int32_t memdrv_block_close(io_entity_t *entity)
{
entity->info = 0U;
memset((void *)&current_file, 0, sizeof(current_file));
return IO_SUCCESS;
}
static const io_dev_funcs_t memdrv_dev_funcs = {
.type = &device_type_memdrv,
.open = &memdrv_block_open,
.seek = &memdrv_block_seek,
.size = NULL,
.read = &memdrv_block_read,
.write = NULL,
.close = &memdrv_block_close,
.dev_init = NULL,
.dev_close = &memdrv_dev_close,
};
static const io_dev_info_t memdrv_dev_info = {
.funcs = &memdrv_dev_funcs,
.info = 0,
};
static const io_dev_connector_t memdrv_dev_connector = {
.dev_open = &memdrv_dev_open
};
static int32_t memdrv_dev_open(const uintptr_t dev __attribute__ ((unused)),
io_dev_info_t **dev_info)
{
*dev_info = (io_dev_info_t *) &memdrv_dev_info;
return IO_SUCCESS;
}
static int32_t memdrv_dev_close(io_dev_info_t *dev_info)
{
return IO_SUCCESS;
}
int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **dev_con)
{
int32_t result;
result = io_register_device(&memdrv_dev_info);
if (result == IO_SUCCESS) {
*dev_con = &memdrv_dev_connector;
}
return result;
}
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IO_MEMDRV_H
#define IO_MEMDRV_H
struct io_dev_connector;
int32_t rcar_register_io_dev_memdrv(const io_dev_connector_t **connector);
#endif /* IO_MEMDRV_H */
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IO_PRIVATE_H
#define IO_PRIVATE_H
/*
* Return codes reported by 'io_*' APIs
* The value of fail should not overlap with define of the errno.
* The errno is in "include/lib/stdlib/sys/errno.h".
*/
#define IO_SUCCESS (0)
#define IO_FAIL (-0x81)
#define IO_NOT_SUPPORTED (-0x82)
#define IO_RESOURCES_EXHAUSTED (-0x83)
#endif /* IO_PRIVATE_H */
@@ -0,0 +1,665 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/auth/auth_mod.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_storage.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <tools_share/firmware_image_package.h>
#include <tools_share/uuid.h>
#include "io_rcar.h"
#include "io_common.h"
#include "io_private.h"
#include <platform_def.h>
extern int32_t plat_get_drv_source(uint32_t id, uintptr_t *dev,
uintptr_t *image_spec);
static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)),
io_dev_info_t **dev_info);
static int32_t rcar_dev_close(io_dev_info_t *dev_info);
typedef struct {
const int32_t name;
const uint32_t offset;
const uint32_t attr;
} plat_rcar_name_offset_t;
typedef struct {
/*
* Put position above the struct to allow {0} on static init.
* It is a workaround for a known bug in GCC
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
*/
uint32_t position;
uint32_t no_load;
uintptr_t offset;
uint32_t size;
uintptr_t dst;
uintptr_t partition; /* for eMMC */
/* RCAR_EMMC_PARTITION_BOOT_0 */
/* RCAR_EMMC_PARTITION_BOOT_1 */
/* RCAR_EMMC_PARTITION_USER */
} file_state_t;
#define RCAR_GET_FLASH_ADR(a, b) ((uint32_t)((0x40000U * (a)) + (b)))
#define RCAR_ATTR_SET_CALCADDR(a) ((a) & 0xF)
#define RCAR_ATTR_SET_ISNOLOAD(a) (((a) & 0x1) << 16U)
#define RCAR_ATTR_SET_CERTOFF(a) (((a) & 0xF) << 8U)
#define RCAR_ATTR_SET_ALL(a, b, c) ((uint32_t)(RCAR_ATTR_SET_CALCADDR(a) |\
RCAR_ATTR_SET_ISNOLOAD(b) |\
RCAR_ATTR_SET_CERTOFF(c)))
#define RCAR_ATTR_GET_CALCADDR(a) ((a) & 0xFU)
#define RCAR_ATTR_GET_ISNOLOAD(a) (((a) >> 16) & 0x1U)
#define RCAR_ATTR_GET_CERTOFF(a) ((uint32_t)(((a) >> 8) & 0xFU))
#define RCAR_MAX_BL3X_IMAGE (8U)
#define RCAR_SECTOR6_CERT_OFFSET (0x400U)
#define RCAR_SDRAM_certESS (0x43F00000U)
#define RCAR_CERT_SIZE (0x800U)
#define RCAR_CERT_INFO_SIZE_OFFSET (0x264U)
#define RCAR_CERT_INFO_DST_OFFSET (0x154U)
#define RCAR_CERT_INFO_SIZE_OFFSET1 (0x364U)
#define RCAR_CERT_INFO_DST_OFFSET1 (0x1D4U)
#define RCAR_CERT_INFO_SIZE_OFFSET2 (0x464U)
#define RCAR_CERT_INFO_DST_OFFSET2 (0x254U)
#define RCAR_CERT_LOAD (1U)
#define RCAR_FLASH_CERT_HEADER RCAR_GET_FLASH_ADR(6U, 0U)
#define RCAR_EMMC_CERT_HEADER (0x00030000U)
#define RCAR_COUNT_LOAD_BL33 (2U)
#define RCAR_COUNT_LOAD_BL33X (3U)
static const plat_rcar_name_offset_t name_offset[] = {
{BL31_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(0, 0, 0)},
/* BL3-2 is optional in the platform */
{BL32_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(1, 0, 1)},
{BL33_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(2, 0, 2)},
{BL332_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(3, 0, 3)},
{BL333_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(4, 0, 4)},
{BL334_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(5, 0, 5)},
{BL335_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(6, 0, 6)},
{BL336_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(7, 0, 7)},
{BL337_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(8, 0, 8)},
{BL338_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(9, 0, 9)},
};
#if TRUSTED_BOARD_BOOT
static const plat_rcar_name_offset_t cert_offset[] = {
/* Certificates */
{TRUSTED_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)},
{SOC_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)},
{TRUSTED_OS_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)},
{NON_TRUSTED_FW_KEY_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)},
{SOC_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 0)},
{TRUSTED_OS_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 1)},
{NON_TRUSTED_FW_CONTENT_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 2)},
{BL332_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 3)},
{BL333_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 4)},
{BL334_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 5)},
{BL335_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 6)},
{BL336_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 7)},
{BL337_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 8)},
{BL338_CERT_ID, 0U, RCAR_ATTR_SET_ALL(0, 1, 9)},
};
#endif /* TRUSTED_BOARD_BOOT */
static file_state_t current_file = { 0 };
static uintptr_t rcar_handle, rcar_spec;
static uint64_t rcar_image_header[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U };
static uint64_t rcar_image_header_prttn[RCAR_MAX_BL3X_IMAGE + 2U] = { 0U };
static uint64_t rcar_image_number = { 0U };
static uint32_t rcar_cert_load = { 0U };
static io_type_t device_type_rcar(void)
{
return IO_TYPE_FIRMWARE_IMAGE_PACKAGE;
}
int32_t rcar_get_certificate(const int32_t name, uint32_t *cert)
{
#if TRUSTED_BOARD_BOOT
int32_t i;
for (i = 0; i < ARRAY_SIZE(cert_offset); i++) {
if (name != cert_offset[i].name) {
continue;
}
*cert = RCAR_CERT_SIZE;
*cert *= RCAR_ATTR_GET_CERTOFF(cert_offset[i].attr);
*cert += RCAR_SDRAM_certESS;
return 0;
}
#endif
return -EINVAL;
}
#define MFISBTSTSR (0xE6260604U)
#define MFISBTSTSR_BOOT_PARTITION (0x00000010U)
static int32_t file_to_offset(const int32_t name, uintptr_t *offset,
uint32_t *cert, uint32_t *no_load,
uintptr_t *partition)
{
uint32_t addr;
int32_t i;
for (i = 0; i < ARRAY_SIZE(name_offset); i++) {
if (name != name_offset[i].name) {
continue;
}
addr = RCAR_ATTR_GET_CALCADDR(name_offset[i].attr);
if (rcar_image_number + 2U < addr) {
continue;
}
*offset = rcar_image_header[addr];
if (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION)
*offset += 0x800000;
*cert = RCAR_CERT_SIZE;
*cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr);
*cert += RCAR_SDRAM_certESS;
*no_load = RCAR_ATTR_GET_ISNOLOAD(name_offset[i].attr);
*partition = rcar_image_header_prttn[addr];
return IO_SUCCESS;
}
#if TRUSTED_BOARD_BOOT
for (i = 0; i < ARRAY_SIZE(cert_offset); i++) {
if (name != cert_offset[i].name) {
continue;
}
*no_load = RCAR_ATTR_GET_ISNOLOAD(cert_offset[i].attr);
*partition = 0U;
*offset = 0U;
*cert = 0U;
return IO_SUCCESS;
}
#endif
return -EINVAL;
}
#define RCAR_BOOT_KEY_CERT_NEW (0xE6300F00U)
#define RCAR_CERT_MAGIC_NUM (0xE291F358U)
void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *dst)
{
uint32_t seed, val, info_1, info_2;
uintptr_t size, dsth, dstl;
cert &= 0xFFFFFFFFU;
seed = mmio_read_32(RCAR_BOOT_KEY_CERT_NEW);
val = mmio_read_32(RCAR_BOOT_KEY_CERT_NEW + 0xC);
info_1 = (val >> 18) & 0x3U;
val = mmio_read_32(cert + 0xC);
info_2 = (val >> 21) & 0x3;
if (seed == RCAR_CERT_MAGIC_NUM) {
if (info_1 != 1) {
ERROR("BL2: Cert is invalid.\n");
*dst = 0;
*len = 0;
return;
}
if (info_2 > 2) {
ERROR("BL2: Cert is invalid.\n");
*dst = 0;
*len = 0;
return;
}
switch (info_2) {
case 2:
size = cert + RCAR_CERT_INFO_SIZE_OFFSET2;
dstl = cert + RCAR_CERT_INFO_DST_OFFSET2;
break;
case 1:
size = cert + RCAR_CERT_INFO_SIZE_OFFSET1;
dstl = cert + RCAR_CERT_INFO_DST_OFFSET1;
break;
case 0:
size = cert + RCAR_CERT_INFO_SIZE_OFFSET;
dstl = cert + RCAR_CERT_INFO_DST_OFFSET;
break;
}
*len = mmio_read_32(size) * 4U;
dsth = dstl + 4U;
*dst = ((uintptr_t) mmio_read_32(dsth) << 32) +
((uintptr_t) mmio_read_32(dstl));
return;
}
size = cert + RCAR_CERT_INFO_SIZE_OFFSET;
*len = mmio_read_32(size) * 4U;
dstl = cert + RCAR_CERT_INFO_DST_OFFSET;
dsth = dstl + 4U;
*dst = ((uintptr_t) mmio_read_32(dsth) << 32) +
((uintptr_t) mmio_read_32(dstl));
}
static int32_t check_load_area(uintptr_t dst, uintptr_t len)
{
uint32_t legacy = dst + len <= UINT32_MAX - 1 ? 1 : 0;
uintptr_t dram_start, dram_end;
uintptr_t prot_start, prot_end;
int32_t result = IO_SUCCESS;
dram_start = legacy ? DRAM1_BASE : DRAM_40BIT_BASE;
dram_end = legacy ? DRAM1_BASE + DRAM1_SIZE :
DRAM_40BIT_BASE + DRAM_40BIT_SIZE;
prot_start = legacy ? DRAM_PROTECTED_BASE : DRAM_40BIT_PROTECTED_BASE;
prot_end = prot_start + DRAM_PROTECTED_SIZE;
if (dst < dram_start || dst > dram_end - len) {
ERROR("BL2: dst address is on the protected area.\n");
result = IO_FAIL;
goto done;
}
/* load image is within SDRAM protected area */
if (dst >= prot_start && dst < prot_end) {
ERROR("BL2: dst address is on the protected area.\n");
result = IO_FAIL;
}
if (dst < prot_start && dst > prot_start - len) {
ERROR("BL2: loaded data is on the protected area.\n");
result = IO_FAIL;
}
done:
if (result == IO_FAIL) {
ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len);
}
return result;
}
static int32_t load_bl33x(void)
{
static int32_t loaded = IO_NOT_SUPPORTED;
uintptr_t dst, partition, handle;
uint32_t noload, cert, len, i;
uintptr_t offset;
int32_t rc;
size_t cnt;
const int32_t img[] = {
BL33_IMAGE_ID,
BL332_IMAGE_ID,
BL333_IMAGE_ID,
BL334_IMAGE_ID,
BL335_IMAGE_ID,
BL336_IMAGE_ID,
BL337_IMAGE_ID,
BL338_IMAGE_ID
};
if (loaded != IO_NOT_SUPPORTED) {
return loaded;
}
for (i = 1; i < rcar_image_number; i++) {
rc = file_to_offset(img[i], &offset, &cert, &noload,
&partition);
if (rc != IO_SUCCESS) {
WARN("%s: failed to get offset\n", __func__);
loaded = IO_FAIL;
return loaded;
}
rcar_read_certificate((uint64_t) cert, &len, &dst);
((io_drv_spec_t *) rcar_spec)->partition = partition;
rc = io_open(rcar_handle, rcar_spec, &handle);
if (rc != IO_SUCCESS) {
WARN("%s: Failed to open FIP (%i)\n", __func__, rc);
loaded = IO_FAIL;
return loaded;
}
rc = io_seek(handle, IO_SEEK_SET, offset);
if (rc != IO_SUCCESS) {
WARN("%s: failed to seek\n", __func__);
loaded = IO_FAIL;
return loaded;
}
rc = check_load_area(dst, len);
if (rc != IO_SUCCESS) {
WARN("%s: check load area\n", __func__);
loaded = IO_FAIL;
return loaded;
}
rc = io_read(handle, dst, len, &cnt);
if (rc != IO_SUCCESS) {
WARN("%s: failed to read\n", __func__);
loaded = IO_FAIL;
return loaded;
}
#if TRUSTED_BOARD_BOOT
rc = auth_mod_verify_img(img[i], (void *)dst, len);
if (rc != 0) {
memset((void *)dst, 0x00, len);
loaded = IO_FAIL;
return loaded;
}
#endif
io_close(handle);
}
loaded = IO_SUCCESS;
return loaded;
}
static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name)
{
static uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = {0UL};
uintptr_t handle;
ssize_t offset;
uint32_t i;
int32_t rc;
size_t cnt;
/* Obtain a reference to the image by querying the platform layer */
rc = plat_get_drv_source(name, &rcar_handle, &rcar_spec);
if (rc != IO_SUCCESS) {
WARN("Failed to obtain reference to img %ld (%i)\n", name, rc);
return IO_FAIL;
}
if (rcar_cert_load == RCAR_CERT_LOAD) {
return IO_SUCCESS;
}
rc = io_open(rcar_handle, rcar_spec, &handle);
if (rc != IO_SUCCESS) {
WARN("Failed to access img %ld (%i)\n", name, rc);
return IO_FAIL;
}
/*
* get start address list
* [0] address num
* [1] BL33-1 image address
* [2] BL33-2 image address
* [3] BL33-3 image address
* [4] BL33-4 image address
* [5] BL33-5 image address
* [6] BL33-6 image address
* [7] BL33-7 image address
* [8] BL33-8 image address
*/
offset = name == EMMC_DEV_ID ? RCAR_EMMC_CERT_HEADER :
RCAR_FLASH_CERT_HEADER;
rc = io_seek(handle, IO_SEEK_SET, offset);
if (rc != IO_SUCCESS) {
WARN("Firmware Image Package header failed to seek\n");
goto error;
}
rc = io_read(handle, (uintptr_t) &header, sizeof(header), &cnt);
if (rc != IO_SUCCESS) {
WARN("Firmware Image Package header failed to read\n");
goto error;
}
#if RCAR_BL2_DCACHE == 1
inv_dcache_range((uint64_t) header, sizeof(header));
#endif
rcar_image_number = header[0];
for (i = 0; i < rcar_image_number + 2; i++) {
rcar_image_header[i] = header[i * 2 + 1];
rcar_image_header_prttn[i] = header[i * 2 + 2];
}
if (rcar_image_number == 0 || rcar_image_number > RCAR_MAX_BL3X_IMAGE) {
WARN("Firmware Image Package header check failed.\n");
rc = IO_FAIL;
goto error;
}
rc = io_seek(handle, IO_SEEK_SET, offset + RCAR_SECTOR6_CERT_OFFSET);
if (rc != IO_SUCCESS) {
WARN("Firmware Image Package header failed to seek cert\n");
goto error;
}
rc = io_read(handle, RCAR_SDRAM_certESS,
RCAR_CERT_SIZE * (2 + rcar_image_number), &cnt);
if (rc != IO_SUCCESS) {
WARN("cert file read error.\n");
goto error;
}
#if RCAR_BL2_DCACHE == 1
inv_dcache_range(RCAR_SDRAM_certESS,
RCAR_CERT_SIZE * (2 + rcar_image_number));
#endif
rcar_cert_load = RCAR_CERT_LOAD;
error:
if (rc != IO_SUCCESS) {
rc = IO_FAIL;
}
io_close(handle);
return rc;
}
static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec,
io_entity_t *entity)
{
const io_drv_spec_t *spec = (io_drv_spec_t *) file_spec;
uintptr_t partition, offset, dst;
uint32_t noload, cert, len;
int32_t rc;
/*
* Only one file open at a time. We need to track state (ie, file
* cursor position). Since the header lives at offset zero, this entry
* should never be zero in an active file.
* Once the system supports dynamic memory allocation we will allow more
* than one open file at a time.
*/
if (current_file.offset != 0U) {
WARN("%s: Only one open file at a time.\n", __func__);
return IO_RESOURCES_EXHAUSTED;
}
rc = file_to_offset(spec->offset, &offset, &cert, &noload, &partition);
if (rc != IO_SUCCESS) {
WARN("Failed to open file name %ld (%i)\n", spec->offset, rc);
return IO_FAIL;
}
if (noload != 0U) {
current_file.offset = 1;
current_file.dst = 0;
current_file.size = 1;
current_file.position = 0;
current_file.no_load = noload;
current_file.partition = 0;
entity->info = (uintptr_t) &current_file;
return IO_SUCCESS;
}
rcar_read_certificate((uint64_t) cert, &len, &dst);
/* Baylibre: HACK */
if (spec->offset == BL31_IMAGE_ID && len < RCAR_TRUSTED_SRAM_SIZE) {
WARN("%s,%s\n", "r-car ignoring the BL31 size from certificate",
"using RCAR_TRUSTED_SRAM_SIZE instead");
len = RCAR_TRUSTED_SRAM_SIZE;
}
current_file.partition = partition;
current_file.no_load = noload;
current_file.offset = offset;
current_file.position = 0;
current_file.size = len;
current_file.dst = dst;
entity->info = (uintptr_t) &current_file;
return IO_SUCCESS;
}
static int32_t rcar_file_len(io_entity_t *entity, size_t *length)
{
*length = ((file_state_t *) entity->info)->size;
NOTICE("%s: len: 0x%08lx\n", __func__, *length);
return IO_SUCCESS;
}
static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *cnt)
{
file_state_t *fp = (file_state_t *) entity->info;
ssize_t offset = fp->offset + fp->position;
uintptr_t handle;
int32_t rc;
#ifdef SPD_NONE
static uint32_t load_bl33x_counter = 1;
#else
static uint32_t load_bl33x_counter;
#endif
if (current_file.no_load != 0U) {
*cnt = length;
return IO_SUCCESS;
}
((io_drv_spec_t *) rcar_spec)->partition = fp->partition;
rc = io_open(rcar_handle, rcar_spec, &handle);
if (rc != IO_SUCCESS) {
WARN("Failed to open FIP (%i)\n", rc);
return IO_FAIL;
}
rc = io_seek(handle, IO_SEEK_SET, offset);
if (rc != IO_SUCCESS) {
WARN("%s: failed to seek\n", __func__);
goto error;
}
if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33) {
rc = check_load_area(buffer, length);
if (rc != IO_SUCCESS) {
WARN("%s: load area err\n", __func__);
goto error;
}
}
rc = io_read(handle, buffer, length, cnt);
if (rc != IO_SUCCESS) {
WARN("Failed to read payload (%i)\n", rc);
goto error;
}
fp->position += *cnt;
io_close(handle);
load_bl33x_counter += 1;
if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33X) {
return load_bl33x();
}
return IO_SUCCESS;
error:
io_close(handle);
return IO_FAIL;
}
static int32_t rcar_file_close(io_entity_t *entity)
{
if (current_file.offset != 0U) {
memset(&current_file, 0, sizeof(current_file));
}
entity->info = 0U;
return IO_SUCCESS;
}
static const io_dev_funcs_t rcar_dev_funcs = {
.type = &device_type_rcar,
.open = &rcar_file_open,
.seek = NULL,
.size = &rcar_file_len,
.read = &rcar_file_read,
.write = NULL,
.close = &rcar_file_close,
.dev_init = &rcar_dev_init,
.dev_close = &rcar_dev_close,
};
static const io_dev_info_t rcar_dev_info = {
.funcs = &rcar_dev_funcs,
.info = (uintptr_t) 0
};
static const io_dev_connector_t rcar_dev_connector = {
.dev_open = &rcar_dev_open
};
static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)),
io_dev_info_t **dev_info)
{
*dev_info = (io_dev_info_t *) &rcar_dev_info;
return IO_SUCCESS;
}
static int32_t rcar_dev_close(io_dev_info_t *dev_info)
{
rcar_handle = 0;
rcar_spec = 0;
return IO_SUCCESS;
}
int32_t rcar_register_io_dev(const io_dev_connector_t **dev_con)
{
int32_t result;
result = io_register_device(&rcar_dev_info);
if (result == IO_SUCCESS) {
*dev_con = &rcar_dev_connector;
}
return result;
}
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IO_RCAR_H
#define IO_RCAR_H
int32_t rcar_register_io_dev(const io_dev_connector_t **dev_con);
int32_t rcar_get_certificate(const int32_t name, uint32_t *cert);
void rcar_read_certificate(uint64_t cert, uint32_t *size, uintptr_t *dest);
#endif /* IO_RCAR_H */
@@ -0,0 +1,230 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PFC_REGS_H
#define PFC_REGS_H
/* GPIO base address */
#define GPIO_BASE (0xE6050000U)
/* GPIO registers */
#define GPIO_IOINTSEL0 (GPIO_BASE + 0x0000U)
#define GPIO_INOUTSEL0 (GPIO_BASE + 0x0004U)
#define GPIO_OUTDT0 (GPIO_BASE + 0x0008U)
#define GPIO_INDT0 (GPIO_BASE + 0x000CU)
#define GPIO_INTDT0 (GPIO_BASE + 0x0010U)
#define GPIO_INTCLR0 (GPIO_BASE + 0x0014U)
#define GPIO_INTMSK0 (GPIO_BASE + 0x0018U)
#define GPIO_MSKCLR0 (GPIO_BASE + 0x001CU)
#define GPIO_POSNEG0 (GPIO_BASE + 0x0020U)
#define GPIO_EDGLEVEL0 (GPIO_BASE + 0x0024U)
#define GPIO_FILONOFF0 (GPIO_BASE + 0x0028U)
#define GPIO_INTMSKS0 (GPIO_BASE + 0x0038U)
#define GPIO_MSKCLRS0 (GPIO_BASE + 0x003CU)
#define GPIO_OUTDTSEL0 (GPIO_BASE + 0x0040U)
#define GPIO_OUTDTH0 (GPIO_BASE + 0x0044U)
#define GPIO_OUTDTL0 (GPIO_BASE + 0x0048U)
#define GPIO_BOTHEDGE0 (GPIO_BASE + 0x004CU)
#define GPIO_IOINTSEL1 (GPIO_BASE + 0x1000U)
#define GPIO_INOUTSEL1 (GPIO_BASE + 0x1004U)
#define GPIO_OUTDT1 (GPIO_BASE + 0x1008U)
#define GPIO_INDT1 (GPIO_BASE + 0x100CU)
#define GPIO_INTDT1 (GPIO_BASE + 0x1010U)
#define GPIO_INTCLR1 (GPIO_BASE + 0x1014U)
#define GPIO_INTMSK1 (GPIO_BASE + 0x1018U)
#define GPIO_MSKCLR1 (GPIO_BASE + 0x101CU)
#define GPIO_POSNEG1 (GPIO_BASE + 0x1020U)
#define GPIO_EDGLEVEL1 (GPIO_BASE + 0x1024U)
#define GPIO_FILONOFF1 (GPIO_BASE + 0x1028U)
#define GPIO_INTMSKS1 (GPIO_BASE + 0x1038U)
#define GPIO_MSKCLRS1 (GPIO_BASE + 0x103CU)
#define GPIO_OUTDTSEL1 (GPIO_BASE + 0x1040U)
#define GPIO_OUTDTH1 (GPIO_BASE + 0x1044U)
#define GPIO_OUTDTL1 (GPIO_BASE + 0x1048U)
#define GPIO_BOTHEDGE1 (GPIO_BASE + 0x104CU)
#define GPIO_IOINTSEL2 (GPIO_BASE + 0x2000U)
#define GPIO_INOUTSEL2 (GPIO_BASE + 0x2004U)
#define GPIO_OUTDT2 (GPIO_BASE + 0x2008U)
#define GPIO_INDT2 (GPIO_BASE + 0x200CU)
#define GPIO_INTDT2 (GPIO_BASE + 0x2010U)
#define GPIO_INTCLR2 (GPIO_BASE + 0x2014U)
#define GPIO_INTMSK2 (GPIO_BASE + 0x2018U)
#define GPIO_MSKCLR2 (GPIO_BASE + 0x201CU)
#define GPIO_POSNEG2 (GPIO_BASE + 0x2020U)
#define GPIO_EDGLEVEL2 (GPIO_BASE + 0x2024U)
#define GPIO_FILONOFF2 (GPIO_BASE + 0x2028U)
#define GPIO_INTMSKS2 (GPIO_BASE + 0x2038U)
#define GPIO_MSKCLRS2 (GPIO_BASE + 0x203CU)
#define GPIO_OUTDTSEL2 (GPIO_BASE + 0x2040U)
#define GPIO_OUTDTH2 (GPIO_BASE + 0x2044U)
#define GPIO_OUTDTL2 (GPIO_BASE + 0x2048U)
#define GPIO_BOTHEDGE2 (GPIO_BASE + 0x204CU)
#define GPIO_IOINTSEL3 (GPIO_BASE + 0x3000U)
#define GPIO_INOUTSEL3 (GPIO_BASE + 0x3004U)
#define GPIO_OUTDT3 (GPIO_BASE + 0x3008U)
#define GPIO_INDT3 (GPIO_BASE + 0x300CU)
#define GPIO_INTDT3 (GPIO_BASE + 0x3010U)
#define GPIO_INTCLR3 (GPIO_BASE + 0x3014U)
#define GPIO_INTMSK3 (GPIO_BASE + 0x3018U)
#define GPIO_MSKCLR3 (GPIO_BASE + 0x301CU)
#define GPIO_POSNEG3 (GPIO_BASE + 0x3020U)
#define GPIO_EDGLEVEL3 (GPIO_BASE + 0x3024U)
#define GPIO_FILONOFF3 (GPIO_BASE + 0x3028U)
#define GPIO_INTMSKS3 (GPIO_BASE + 0x3038U)
#define GPIO_MSKCLRS3 (GPIO_BASE + 0x303CU)
#define GPIO_OUTDTSEL3 (GPIO_BASE + 0x3040U)
#define GPIO_OUTDTH3 (GPIO_BASE + 0x3044U)
#define GPIO_OUTDTL3 (GPIO_BASE + 0x3048U)
#define GPIO_BOTHEDGE3 (GPIO_BASE + 0x304CU)
#define GPIO_IOINTSEL4 (GPIO_BASE + 0x4000U)
#define GPIO_INOUTSEL4 (GPIO_BASE + 0x4004U)
#define GPIO_OUTDT4 (GPIO_BASE + 0x4008U)
#define GPIO_INDT4 (GPIO_BASE + 0x400CU)
#define GPIO_INTDT4 (GPIO_BASE + 0x4010U)
#define GPIO_INTCLR4 (GPIO_BASE + 0x4014U)
#define GPIO_INTMSK4 (GPIO_BASE + 0x4018U)
#define GPIO_MSKCLR4 (GPIO_BASE + 0x401CU)
#define GPIO_POSNEG4 (GPIO_BASE + 0x4020U)
#define GPIO_EDGLEVEL4 (GPIO_BASE + 0x4024U)
#define GPIO_FILONOFF4 (GPIO_BASE + 0x4028U)
#define GPIO_INTMSKS4 (GPIO_BASE + 0x4038U)
#define GPIO_MSKCLRS4 (GPIO_BASE + 0x403CU)
#define GPIO_OUTDTSEL4 (GPIO_BASE + 0x4040U)
#define GPIO_OUTDTH4 (GPIO_BASE + 0x4044U)
#define GPIO_OUTDTL4 (GPIO_BASE + 0x4048U)
#define GPIO_BOTHEDGE4 (GPIO_BASE + 0x404CU)
#define GPIO_IOINTSEL5 (GPIO_BASE + 0x5000U)
#define GPIO_INOUTSEL5 (GPIO_BASE + 0x5004U)
#define GPIO_OUTDT5 (GPIO_BASE + 0x5008U)
#define GPIO_INDT5 (GPIO_BASE + 0x500CU)
#define GPIO_INTDT5 (GPIO_BASE + 0x5010U)
#define GPIO_INTCLR5 (GPIO_BASE + 0x5014U)
#define GPIO_INTMSK5 (GPIO_BASE + 0x5018U)
#define GPIO_MSKCLR5 (GPIO_BASE + 0x501CU)
#define GPIO_POSNEG5 (GPIO_BASE + 0x5020U)
#define GPIO_EDGLEVEL5 (GPIO_BASE + 0x5024U)
#define GPIO_FILONOFF5 (GPIO_BASE + 0x5028U)
#define GPIO_INTMSKS5 (GPIO_BASE + 0x5038U)
#define GPIO_MSKCLRS5 (GPIO_BASE + 0x503CU)
#define GPIO_OUTDTSEL5 (GPIO_BASE + 0x5040U)
#define GPIO_OUTDTH5 (GPIO_BASE + 0x5044U)
#define GPIO_OUTDTL5 (GPIO_BASE + 0x5048U)
#define GPIO_BOTHEDGE5 (GPIO_BASE + 0x504CU)
#define GPIO_IOINTSEL6 (GPIO_BASE + 0x5400U)
#define GPIO_INOUTSEL6 (GPIO_BASE + 0x5404U)
#define GPIO_OUTDT6 (GPIO_BASE + 0x5408U)
#define GPIO_INTDT6 (GPIO_BASE + 0x5410U)
#define GPIO_INTCLR6 (GPIO_BASE + 0x5414U)
#define GPIO_INTMSK6 (GPIO_BASE + 0x5418U)
#define GPIO_MSKCLR6 (GPIO_BASE + 0x541CU)
#define GPIO_POSNEG6 (GPIO_BASE + 0x5420U)
#define GPIO_EDGLEVEL6 (GPIO_BASE + 0x5424U)
#define GPIO_FILONOFF6 (GPIO_BASE + 0x5428U)
#define GPIO_INTMSKS6 (GPIO_BASE + 0x5438U)
#define GPIO_MSKCLRS6 (GPIO_BASE + 0x543CU)
#define GPIO_OUTDTSEL6 (GPIO_BASE + 0x5440U)
#define GPIO_OUTDTH6 (GPIO_BASE + 0x5444U)
#define GPIO_OUTDTL6 (GPIO_BASE + 0x5448U)
#define GPIO_BOTHEDGE6 (GPIO_BASE + 0x544CU)
#define GPIO_IOINTSEL7 (GPIO_BASE + 0x5800U)
#define GPIO_INOUTSEL7 (GPIO_BASE + 0x5804U)
#define GPIO_OUTDT7 (GPIO_BASE + 0x5808U)
#define GPIO_INDT7 (GPIO_BASE + 0x580CU)
#define GPIO_INTDT7 (GPIO_BASE + 0x5810U)
#define GPIO_INTCLR7 (GPIO_BASE + 0x5814U)
#define GPIO_INTMSK7 (GPIO_BASE + 0x5818U)
#define GPIO_MSKCLR7 (GPIO_BASE + 0x581CU)
#define GPIO_POSNEG7 (GPIO_BASE + 0x5820U)
#define GPIO_EDGLEVEL7 (GPIO_BASE + 0x5824U)
#define GPIO_FILONOFF7 (GPIO_BASE + 0x5828U)
#define GPIO_INTMSKS7 (GPIO_BASE + 0x5838U)
#define GPIO_MSKCLRS7 (GPIO_BASE + 0x583CU)
#define GPIO_OUTDTSEL7 (GPIO_BASE + 0x5840U)
#define GPIO_OUTDTH7 (GPIO_BASE + 0x5844U)
#define GPIO_OUTDTL7 (GPIO_BASE + 0x5848U)
#define GPIO_BOTHEDGE7 (GPIO_BASE + 0x584CU)
/* Pin functon base address */
#define PFC_BASE (0xE6060000U)
/* Pin functon registers */
#define PFC_PMMR (PFC_BASE + 0x0000U)
#define PFC_GPSR0 (PFC_BASE + 0x0100U)
#define PFC_GPSR1 (PFC_BASE + 0x0104U)
#define PFC_GPSR2 (PFC_BASE + 0x0108U)
#define PFC_GPSR3 (PFC_BASE + 0x010CU)
#define PFC_GPSR4 (PFC_BASE + 0x0110U)
#define PFC_GPSR5 (PFC_BASE + 0x0114U)
#define PFC_GPSR6 (PFC_BASE + 0x0118U)
#define PFC_GPSR7 (PFC_BASE + 0x011CU)
#define PFC_IPSR0 (PFC_BASE + 0x0200U)
#define PFC_IPSR1 (PFC_BASE + 0x0204U)
#define PFC_IPSR2 (PFC_BASE + 0x0208U)
#define PFC_IPSR3 (PFC_BASE + 0x020CU)
#define PFC_IPSR4 (PFC_BASE + 0x0210U)
#define PFC_IPSR5 (PFC_BASE + 0x0214U)
#define PFC_IPSR6 (PFC_BASE + 0x0218U)
#define PFC_IPSR7 (PFC_BASE + 0x021CU)
#define PFC_IPSR8 (PFC_BASE + 0x0220U)
#define PFC_IPSR9 (PFC_BASE + 0x0224U)
#define PFC_IPSR10 (PFC_BASE + 0x0228U)
#define PFC_IPSR11 (PFC_BASE + 0x022CU)
#define PFC_IPSR12 (PFC_BASE + 0x0230U)
#define PFC_IPSR13 (PFC_BASE + 0x0234U)
#define PFC_IPSR14 (PFC_BASE + 0x0238U)
#define PFC_IPSR15 (PFC_BASE + 0x023CU)
#define PFC_IPSR16 (PFC_BASE + 0x0240U)
#define PFC_IPSR17 (PFC_BASE + 0x0244U)
#define PFC_IPSR18 (PFC_BASE + 0x0248U)
#define PFC_DRVCTRL0 (PFC_BASE + 0x0300U)
#define PFC_DRVCTRL1 (PFC_BASE + 0x0304U)
#define PFC_DRVCTRL2 (PFC_BASE + 0x0308U)
#define PFC_DRVCTRL3 (PFC_BASE + 0x030CU)
#define PFC_DRVCTRL4 (PFC_BASE + 0x0310U)
#define PFC_DRVCTRL5 (PFC_BASE + 0x0314U)
#define PFC_DRVCTRL6 (PFC_BASE + 0x0318U)
#define PFC_DRVCTRL7 (PFC_BASE + 0x031CU)
#define PFC_DRVCTRL8 (PFC_BASE + 0x0320U)
#define PFC_DRVCTRL9 (PFC_BASE + 0x0324U)
#define PFC_DRVCTRL10 (PFC_BASE + 0x0328U)
#define PFC_DRVCTRL11 (PFC_BASE + 0x032CU)
#define PFC_DRVCTRL12 (PFC_BASE + 0x0330U)
#define PFC_DRVCTRL13 (PFC_BASE + 0x0334U)
#define PFC_DRVCTRL14 (PFC_BASE + 0x0338U)
#define PFC_DRVCTRL15 (PFC_BASE + 0x033CU)
#define PFC_DRVCTRL16 (PFC_BASE + 0x0340U)
#define PFC_DRVCTRL17 (PFC_BASE + 0x0344U)
#define PFC_DRVCTRL18 (PFC_BASE + 0x0348U)
#define PFC_DRVCTRL19 (PFC_BASE + 0x034CU)
#define PFC_DRVCTRL20 (PFC_BASE + 0x0350U)
#define PFC_DRVCTRL21 (PFC_BASE + 0x0354U)
#define PFC_DRVCTRL22 (PFC_BASE + 0x0358U)
#define PFC_DRVCTRL23 (PFC_BASE + 0x035CU)
#define PFC_DRVCTRL24 (PFC_BASE + 0x0360U)
#define PFC_POCCTRL0 (PFC_BASE + 0x0380U)
#define PFC_IOCTRL31 (PFC_BASE + 0x0384U)
#define PFC_POCCTRL2 (PFC_BASE + 0x0388U)
#define PFC_TDSELCTRL0 (PFC_BASE + 0x03C0U)
#define PFC_IOCTRL (PFC_BASE + 0x03E0U)
#define PFC_TSREG (PFC_BASE + 0x03E4U)
#define PFC_PUEN0 (PFC_BASE + 0x0400U)
#define PFC_PUEN1 (PFC_BASE + 0x0404U)
#define PFC_PUEN2 (PFC_BASE + 0x0408U)
#define PFC_PUEN3 (PFC_BASE + 0x040CU)
#define PFC_PUEN4 (PFC_BASE + 0x0410U)
#define PFC_PUEN5 (PFC_BASE + 0x0414U)
#define PFC_PUEN6 (PFC_BASE + 0x0418U)
#define PFC_PUD0 (PFC_BASE + 0x0440U)
#define PFC_PUD1 (PFC_BASE + 0x0444U)
#define PFC_PUD2 (PFC_BASE + 0x0448U)
#define PFC_PUD3 (PFC_BASE + 0x044CU)
#define PFC_PUD4 (PFC_BASE + 0x0450U)
#define PFC_PUD5 (PFC_BASE + 0x0454U)
#define PFC_PUD6 (PFC_BASE + 0x0458U)
#define PFC_MOD_SEL0 (PFC_BASE + 0x0500U)
#define PFC_MOD_SEL1 (PFC_BASE + 0x0504U)
#define PFC_MOD_SEL2 (PFC_BASE + 0x0508U)
#endif /* PFC_REGS_H */
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
.global rcar_pwrc_switch_stack
/*
* x0 : jump address,
* x1 : stack address,
* x2 : arg,
* x3 : stack address (temporary)
*/
func rcar_pwrc_switch_stack
/* lr to stack */
stp x29, x30, [sp,#-16]
/* change stack pointer */
mov x3, sp
mov sp, x1
/* save stack pointer */
sub sp, sp, #16
stp x0, x3, [sp]
/* data synchronization barrier */
dsb sy
/* jump to code */
mov x1, x0
mov x0, x2
blr x1
/* load stack pointer */
ldp x0, x2, [sp,#0]
/* change stack pointer */
mov sp, x2
/* return */
ldp x29, x30, [sp,#-16]
ret
endfunc rcar_pwrc_switch_stack
@@ -0,0 +1,917 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <string.h>
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <lib/bakery_lock.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include "iic_dvfs.h"
#include "micro_delay.h"
#include "pwrc.h"
#include "rcar_def.h"
#include "rcar_private.h"
#include "cpg_registers.h"
/*
* Someday there will be a generic power controller api. At the moment each
* platform has its own pwrc so just exporting functions should be acceptable.
*/
RCAR_INSTANTIATE_LOCK
#define WUP_IRQ_SHIFT (0U)
#define WUP_FIQ_SHIFT (8U)
#define WUP_CSD_SHIFT (16U)
#define BIT_SOFTRESET (1U << 15)
#define BIT_CA53_SCU (1U << 21)
#define BIT_CA57_SCU (1U << 12)
#define REQ_RESUME (1U << 1)
#define REQ_OFF (1U << 0)
#define STATUS_PWRUP (1U << 4)
#define STATUS_PWRDOWN (1U << 0)
#define STATE_CA57_CPU (27U)
#define STATE_CA53_CPU (22U)
#define MODE_L2_DOWN (0x00000002U)
#define CPU_PWR_OFF (0x00000003U)
#define RCAR_PSTR_MASK (0x00000003U)
#define ST_ALL_STANDBY (0x00003333U)
#define SYSCEXTMASK_EXTMSK0 (0x00000001U)
/* Suspend to ram */
#define DBSC4_REG_BASE (0xE6790000U)
#define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U)
#define DBSC4_REG_DBACEN (DBSC4_REG_BASE + 0x0200U)
#define DBSC4_REG_DBCMD (DBSC4_REG_BASE + 0x0208U)
#define DBSC4_REG_DBRFEN (DBSC4_REG_BASE + 0x0204U)
#define DBSC4_REG_DBWAIT (DBSC4_REG_BASE + 0x0210U)
#define DBSC4_REG_DBCALCNF (DBSC4_REG_BASE + 0x0424U)
#define DBSC4_REG_DBDFIPMSTRCNF (DBSC4_REG_BASE + 0x0520U)
#define DBSC4_REG_DBPDLK0 (DBSC4_REG_BASE + 0x0620U)
#define DBSC4_REG_DBPDRGA0 (DBSC4_REG_BASE + 0x0624U)
#define DBSC4_REG_DBPDRGD0 (DBSC4_REG_BASE + 0x0628U)
#define DBSC4_REG_DBCAM0CTRL0 (DBSC4_REG_BASE + 0x0940U)
#define DBSC4_REG_DBCAM0STAT0 (DBSC4_REG_BASE + 0x0980U)
#define DBSC4_REG_DBCAM1STAT0 (DBSC4_REG_BASE + 0x0990U)
#define DBSC4_REG_DBCAM2STAT0 (DBSC4_REG_BASE + 0x09A0U)
#define DBSC4_REG_DBCAM3STAT0 (DBSC4_REG_BASE + 0x09B0U)
#define DBSC4_BIT_DBACEN_ACCEN ((uint32_t)(1U << 0))
#define DBSC4_BIT_DBRFEN_ARFEN ((uint32_t)(1U << 0))
#define DBSC4_BIT_DBCAMxSTAT0 (0x00000001U)
#define DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN (0x00000001U)
#define DBSC4_SET_DBCMD_OPC_PRE (0x04000000U)
#define DBSC4_SET_DBCMD_OPC_SR (0x0A000000U)
#define DBSC4_SET_DBCMD_OPC_PD (0x08000000U)
#define DBSC4_SET_DBCMD_OPC_MRW (0x0E000000U)
#define DBSC4_SET_DBCMD_CH_ALL (0x00800000U)
#define DBSC4_SET_DBCMD_RANK_ALL (0x00040000U)
#define DBSC4_SET_DBCMD_ARG_ALL (0x00000010U)
#define DBSC4_SET_DBCMD_ARG_ENTER (0x00000000U)
#define DBSC4_SET_DBCMD_ARG_MRW_ODTC (0x00000B00U)
#define DBSC4_SET_DBSYSCNT0_WRITE_ENABLE (0x00001234U)
#define DBSC4_SET_DBSYSCNT0_WRITE_DISABLE (0x00000000U)
#define DBSC4_SET_DBPDLK0_PHY_ACCESS (0x0000A55AU)
#define DBSC4_SET_DBPDRGA0_ACIOCR0 (0x0000001AU)
#define DBSC4_SET_DBPDRGD0_ACIOCR0 (0x33C03C11U)
#define DBSC4_SET_DBPDRGA0_DXCCR (0x00000020U)
#define DBSC4_SET_DBPDRGD0_DXCCR (0x00181006U)
#define DBSC4_SET_DBPDRGA0_PGCR1 (0x00000003U)
#define DBSC4_SET_DBPDRGD0_PGCR1 (0x0380C600U)
#define DBSC4_SET_DBPDRGA0_ACIOCR1 (0x0000001BU)
#define DBSC4_SET_DBPDRGD0_ACIOCR1 (0xAAAAAAAAU)
#define DBSC4_SET_DBPDRGA0_ACIOCR3 (0x0000001DU)
#define DBSC4_SET_DBPDRGD0_ACIOCR3 (0xAAAAAAAAU)
#define DBSC4_SET_DBPDRGA0_ACIOCR5 (0x0000001FU)
#define DBSC4_SET_DBPDRGD0_ACIOCR5 (0x000000AAU)
#define DBSC4_SET_DBPDRGA0_DX0GCR2 (0x000000A2U)
#define DBSC4_SET_DBPDRGD0_DX0GCR2 (0xAAAA0000U)
#define DBSC4_SET_DBPDRGA0_DX1GCR2 (0x000000C2U)
#define DBSC4_SET_DBPDRGD0_DX1GCR2 (0xAAAA0000U)
#define DBSC4_SET_DBPDRGA0_DX2GCR2 (0x000000E2U)
#define DBSC4_SET_DBPDRGD0_DX2GCR2 (0xAAAA0000U)
#define DBSC4_SET_DBPDRGA0_DX3GCR2 (0x00000102U)
#define DBSC4_SET_DBPDRGD0_DX3GCR2 (0xAAAA0000U)
#define DBSC4_SET_DBPDRGA0_ZQCR (0x00000090U)
#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 (0x04058904U)
#define DBSC4_SET_DBPDRGD0_ZQCR_MD19_1 (0x04058A04U)
#define DBSC4_SET_DBPDRGA0_DX0GCR0 (0x000000A0U)
#define DBSC4_SET_DBPDRGD0_DX0GCR0 (0x7C0002E5U)
#define DBSC4_SET_DBPDRGA0_DX1GCR0 (0x000000C0U)
#define DBSC4_SET_DBPDRGD0_DX1GCR0 (0x7C0002E5U)
#define DBSC4_SET_DBPDRGA0_DX2GCR0 (0x000000E0U)
#define DBSC4_SET_DBPDRGD0_DX2GCR0 (0x7C0002E5U)
#define DBSC4_SET_DBPDRGA0_DX3GCR0 (0x00000100U)
#define DBSC4_SET_DBPDRGD0_DX3GCR0 (0x7C0002E5U)
#define DBSC4_SET_DBPDRGA0_DX0GCR1 (0x000000A1U)
#define DBSC4_SET_DBPDRGD0_DX0GCR1 (0x55550000U)
#define DBSC4_SET_DBPDRGA0_DX1GCR1 (0x000000C1U)
#define DBSC4_SET_DBPDRGD0_DX1GCR1 (0x55550000U)
#define DBSC4_SET_DBPDRGA0_DX2GCR1 (0x000000E1U)
#define DBSC4_SET_DBPDRGD0_DX2GCR1 (0x55550000U)
#define DBSC4_SET_DBPDRGA0_DX3GCR1 (0x00000101U)
#define DBSC4_SET_DBPDRGD0_DX3GCR1 (0x55550000U)
#define DBSC4_SET_DBPDRGA0_DX0GCR3 (0x000000A3U)
#define DBSC4_SET_DBPDRGD0_DX0GCR3 (0x00008484U)
#define DBSC4_SET_DBPDRGA0_DX1GCR3 (0x000000C3U)
#define DBSC4_SET_DBPDRGD0_DX1GCR3 (0x00008484U)
#define DBSC4_SET_DBPDRGA0_DX2GCR3 (0x000000E3U)
#define DBSC4_SET_DBPDRGD0_DX2GCR3 (0x00008484U)
#define DBSC4_SET_DBPDRGA0_DX3GCR3 (0x00000103U)
#define DBSC4_SET_DBPDRGD0_DX3GCR3 (0x00008484U)
#define RST_BASE (0xE6160000U)
#define RST_MODEMR (RST_BASE + 0x0060U)
#define RST_MODEMR_BIT0 (0x00000001U)
#define RCAR_CNTCR_OFF (0x00U)
#define RCAR_CNTCVL_OFF (0x08U)
#define RCAR_CNTCVU_OFF (0x0CU)
#define RCAR_CNTFID_OFF (0x20U)
#define RCAR_CNTCR_EN ((uint32_t)1U << 0U)
#define RCAR_CNTCR_FCREQ(x) ((uint32_t)(x) << 8U)
#if PMIC_ROHM_BD9571
#define BIT_BKUP_CTRL_OUT ((uint8_t)(1U << 4))
#define PMIC_BKUP_MODE_CNT (0x20U)
#define PMIC_QLLM_CNT (0x27U)
#define PMIC_RETRY_MAX (100U)
#endif /* PMIC_ROHM_BD9571 */
#define SCTLR_EL3_M_BIT ((uint32_t)1U << 0)
#define RCAR_CA53CPU_NUM_MAX (4U)
#define RCAR_CA57CPU_NUM_MAX (4U)
#define IS_A53A57(c) ((c) == RCAR_CLUSTER_A53A57)
#define IS_CA57(c) ((c) == RCAR_CLUSTER_CA57)
#define IS_CA53(c) ((c) == RCAR_CLUSTER_CA53)
#ifndef __ASSEMBLER__
IMPORT_SYM(unsigned long, __system_ram_start__, SYSTEM_RAM_START);
IMPORT_SYM(unsigned long, __system_ram_end__, SYSTEM_RAM_END);
IMPORT_SYM(unsigned long, __SRAM_COPY_START__, SRAM_COPY_START);
#endif
uint32_t rcar_pwrc_status(u_register_t mpidr)
{
uint32_t ret = 0;
uint64_t cm, cpu;
uint32_t reg;
uint32_t c;
rcar_lock_get();
c = rcar_pwrc_get_cluster();
cm = mpidr & MPIDR_CLUSTER_MASK;
if (!IS_A53A57(c) && cm != 0) {
ret = RCAR_INVALID;
goto done;
}
reg = mmio_read_32(RCAR_PRR);
cpu = mpidr & MPIDR_CPU_MASK;
if (IS_CA53(c))
if (reg & (1 << (STATE_CA53_CPU + cpu)))
ret = RCAR_INVALID;
if (IS_CA57(c))
if (reg & (1 << (STATE_CA57_CPU + cpu)))
ret = RCAR_INVALID;
done:
rcar_lock_release();
return ret;
}
static void scu_power_up(u_register_t mpidr)
{
uintptr_t reg_pwrsr, reg_cpumcr, reg_pwron, reg_pwrer;
uint32_t c, sysc_reg_bit;
uint32_t lsi_product;
uint32_t lsi_cut;
c = rcar_pwrc_get_mpidr_cluster(mpidr);
reg_cpumcr = IS_CA57(c) ? RCAR_CA57CPUCMCR : RCAR_CA53CPUCMCR;
sysc_reg_bit = IS_CA57(c) ? BIT_CA57_SCU : BIT_CA53_SCU;
reg_pwron = IS_CA57(c) ? RCAR_PWRONCR5 : RCAR_PWRONCR3;
reg_pwrer = IS_CA57(c) ? RCAR_PWRER5 : RCAR_PWRER3;
reg_pwrsr = IS_CA57(c) ? RCAR_PWRSR5 : RCAR_PWRSR3;
if ((mmio_read_32(reg_pwrsr) & STATUS_PWRDOWN) == 0)
return;
if (mmio_read_32(reg_cpumcr) != 0)
mmio_write_32(reg_cpumcr, 0);
lsi_product = mmio_read_32((uintptr_t)RCAR_PRR);
lsi_cut = lsi_product & PRR_CUT_MASK;
lsi_product &= PRR_PRODUCT_MASK;
if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) ||
lsi_product == PRR_PRODUCT_H3 ||
lsi_product == PRR_PRODUCT_M3N ||
lsi_product == PRR_PRODUCT_E3) {
mmio_setbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0);
}
mmio_setbits_32(RCAR_SYSCIER, sysc_reg_bit);
mmio_setbits_32(RCAR_SYSCIMR, sysc_reg_bit);
do {
while ((mmio_read_32(RCAR_SYSCSR) & REQ_RESUME) == 0)
;
mmio_write_32(reg_pwron, 1);
} while (mmio_read_32(reg_pwrer) & 1);
while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0)
;
mmio_write_32(RCAR_SYSCISCR, sysc_reg_bit);
if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) ||
lsi_product == PRR_PRODUCT_H3 ||
lsi_product == PRR_PRODUCT_M3N ||
lsi_product == PRR_PRODUCT_E3) {
mmio_clrbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0);
}
while ((mmio_read_32(reg_pwrsr) & STATUS_PWRUP) == 0)
;
}
void rcar_pwrc_cpuon(u_register_t mpidr)
{
uint32_t res_data, on_data;
uintptr_t res_reg, on_reg;
uint32_t limit, c;
uint64_t cpu;
rcar_lock_get();
c = rcar_pwrc_get_mpidr_cluster(mpidr);
res_reg = IS_CA53(c) ? RCAR_CA53RESCNT : RCAR_CA57RESCNT;
on_reg = IS_CA53(c) ? RCAR_CA53WUPCR : RCAR_CA57WUPCR;
limit = IS_CA53(c) ? 0x5A5A0000 : 0xA5A50000;
res_data = mmio_read_32(res_reg) | limit;
scu_power_up(mpidr);
cpu = mpidr & MPIDR_CPU_MASK;
on_data = 1 << cpu;
mmio_write_32(CPG_CPGWPR, ~on_data);
mmio_write_32(on_reg, on_data);
mmio_write_32(res_reg, res_data & (~(1 << (3 - cpu))));
rcar_lock_release();
}
void rcar_pwrc_cpuoff(u_register_t mpidr)
{
uint32_t c;
uintptr_t reg;
uint64_t cpu;
rcar_lock_get();
cpu = mpidr & MPIDR_CPU_MASK;
c = rcar_pwrc_get_mpidr_cluster(mpidr);
reg = IS_CA53(c) ? RCAR_CA53CPU0CR : RCAR_CA57CPU0CR;
if (read_mpidr_el1() != mpidr)
panic();
mmio_write_32(CPG_CPGWPR, ~CPU_PWR_OFF);
mmio_write_32(reg + cpu * 0x0010, CPU_PWR_OFF);
rcar_lock_release();
}
void rcar_pwrc_enable_interrupt_wakeup(u_register_t mpidr)
{
uint32_t c, shift_irq, shift_fiq;
uintptr_t reg;
uint64_t cpu;
rcar_lock_get();
cpu = mpidr & MPIDR_CPU_MASK;
c = rcar_pwrc_get_mpidr_cluster(mpidr);
reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57;
shift_irq = WUP_IRQ_SHIFT + cpu;
shift_fiq = WUP_FIQ_SHIFT + cpu;
mmio_clrbits_32(reg, ((uint32_t) 1 << shift_irq) |
((uint32_t) 1 << shift_fiq));
rcar_lock_release();
}
void rcar_pwrc_disable_interrupt_wakeup(u_register_t mpidr)
{
uint32_t c, shift_irq, shift_fiq;
uintptr_t reg;
uint64_t cpu;
rcar_lock_get();
cpu = mpidr & MPIDR_CPU_MASK;
c = rcar_pwrc_get_mpidr_cluster(mpidr);
reg = IS_CA53(c) ? RCAR_WUPMSKCA53 : RCAR_WUPMSKCA57;
shift_irq = WUP_IRQ_SHIFT + cpu;
shift_fiq = WUP_FIQ_SHIFT + cpu;
mmio_setbits_32(reg, ((uint32_t) 1 << shift_irq) |
((uint32_t) 1 << shift_fiq));
rcar_lock_release();
}
void rcar_pwrc_all_disable_interrupt_wakeup(void)
{
uint32_t cpu_num;
u_register_t cl, cpu, mpidr;
const uint32_t cluster[PLATFORM_CLUSTER_COUNT] = {
RCAR_CLUSTER_CA57,
RCAR_CLUSTER_CA53
};
for (cl = 0; cl < PLATFORM_CLUSTER_COUNT; cl++) {
cpu_num = rcar_pwrc_get_cpu_num(cluster[cl]);
for (cpu = 0; cpu < cpu_num; cpu++) {
mpidr = ((cl << MPIDR_AFFINITY_BITS) | cpu);
if (mpidr == rcar_boot_mpidr) {
rcar_pwrc_enable_interrupt_wakeup(mpidr);
} else {
rcar_pwrc_disable_interrupt_wakeup(mpidr);
}
}
}
}
void rcar_pwrc_clusteroff(u_register_t mpidr)
{
uint32_t c, product, cut, reg;
uintptr_t dst;
rcar_lock_get();
reg = mmio_read_32(RCAR_PRR);
product = reg & PRR_PRODUCT_MASK;
cut = reg & PRR_CUT_MASK;
c = rcar_pwrc_get_mpidr_cluster(mpidr);
dst = IS_CA53(c) ? RCAR_CA53CPUCMCR : RCAR_CA57CPUCMCR;
if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) {
goto done;
}
if (product == PRR_PRODUCT_H3 && cut <= PRR_PRODUCT_20) {
goto done;
}
/* all of the CPUs in the cluster is in the CoreStandby mode */
mmio_write_32(dst, MODE_L2_DOWN);
done:
rcar_lock_release();
}
static uint64_t rcar_pwrc_saved_cntpct_el0;
static uint32_t rcar_pwrc_saved_cntfid;
#if RCAR_SYSTEM_SUSPEND
static void rcar_pwrc_save_timer_state(void)
{
rcar_pwrc_saved_cntpct_el0 = read_cntpct_el0();
rcar_pwrc_saved_cntfid =
mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF));
}
#endif /* RCAR_SYSTEM_SUSPEND */
void rcar_pwrc_restore_timer_state(void)
{
/* Stop timer before restoring counter value */
mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), 0U);
mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVL_OFF),
(uint32_t)(rcar_pwrc_saved_cntpct_el0 & 0xFFFFFFFFU));
mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVU_OFF),
(uint32_t)(rcar_pwrc_saved_cntpct_el0 >> 32U));
mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF),
rcar_pwrc_saved_cntfid);
/* Start generic timer back */
write_cntfrq_el0((u_register_t)plat_get_syscnt_freq2());
mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF),
(RCAR_CNTCR_FCREQ(0U) | RCAR_CNTCR_EN));
}
#if !PMIC_ROHM_BD9571
void rcar_pwrc_system_reset(void)
{
mmio_write_32(RCAR_SRESCR, 0x5AA50000U | BIT_SOFTRESET);
}
#endif /* PMIC_ROHM_BD9571 */
#define RST_CA53_CPU0_BARH (0xE6160080U)
#define RST_CA53_CPU0_BARL (0xE6160084U)
#define RST_CA57_CPU0_BARH (0xE61600C0U)
#define RST_CA57_CPU0_BARL (0xE61600C4U)
void rcar_pwrc_setup(void)
{
uintptr_t rst_barh;
uintptr_t rst_barl;
uint32_t i, j;
uint64_t reset = (uint64_t) (&plat_secondary_reset) & 0xFFFFFFFF;
const uint32_t cluster[PLATFORM_CLUSTER_COUNT] = {
RCAR_CLUSTER_CA53,
RCAR_CLUSTER_CA57
};
const uintptr_t reg_barh[PLATFORM_CLUSTER_COUNT] = {
RST_CA53_CPU0_BARH,
RST_CA57_CPU0_BARH
};
const uintptr_t reg_barl[PLATFORM_CLUSTER_COUNT] = {
RST_CA53_CPU0_BARL,
RST_CA57_CPU0_BARL
};
for (i = 0; i < PLATFORM_CLUSTER_COUNT; i++) {
rst_barh = reg_barh[i];
rst_barl = reg_barl[i];
for (j = 0; j < rcar_pwrc_get_cpu_num(cluster[i]); j++) {
mmio_write_32(rst_barh, 0);
mmio_write_32(rst_barl, (uint32_t) reset);
rst_barh += 0x10;
rst_barl += 0x10;
}
}
rcar_lock_init();
}
#if RCAR_SYSTEM_SUSPEND
#define DBCAM_FLUSH(__bit) \
do { \
; \
} while (!(mmio_read_32(DBSC4_REG_DBCAM##__bit##STAT0) & DBSC4_BIT_DBCAMxSTAT0))
static void __attribute__ ((section(".system_ram")))
rcar_pwrc_set_self_refresh(void)
{
uint32_t reg = mmio_read_32(RCAR_PRR);
uint32_t cut, product;
product = reg & PRR_PRODUCT_MASK;
cut = reg & PRR_CUT_MASK;
if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) {
goto self_refresh;
}
if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) {
goto self_refresh;
}
mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE);
self_refresh:
/* DFI_PHYMSTR_ACK setting */
mmio_write_32(DBSC4_REG_DBDFIPMSTRCNF,
mmio_read_32(DBSC4_REG_DBDFIPMSTRCNF) &
(~DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN));
/* Set the Self-Refresh mode */
mmio_write_32(DBSC4_REG_DBACEN, 0);
if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20)
rcar_micro_delay(100);
else if (product == PRR_PRODUCT_H3) {
mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
DBCAM_FLUSH(0);
DBCAM_FLUSH(1);
DBCAM_FLUSH(2);
DBCAM_FLUSH(3);
mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0);
} else if (product == PRR_PRODUCT_M3) {
mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
DBCAM_FLUSH(0);
DBCAM_FLUSH(1);
mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0);
} else {
mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
DBCAM_FLUSH(0);
mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0);
}
/* Set the SDRAM calibration configuration register */
mmio_write_32(DBSC4_REG_DBCALCNF, 0);
reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL |
DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL;
mmio_write_32(DBSC4_REG_DBCMD, reg);
while (mmio_read_32(DBSC4_REG_DBWAIT))
;
/* Self-Refresh entry command */
reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL |
DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER;
mmio_write_32(DBSC4_REG_DBCMD, reg);
while (mmio_read_32(DBSC4_REG_DBWAIT))
;
/* Mode Register Write command. (ODT disabled) */
reg = DBSC4_SET_DBCMD_OPC_MRW | DBSC4_SET_DBCMD_CH_ALL |
DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_MRW_ODTC;
mmio_write_32(DBSC4_REG_DBCMD, reg);
while (mmio_read_32(DBSC4_REG_DBWAIT))
;
/* Power Down entry command */
reg = DBSC4_SET_DBCMD_OPC_PD | DBSC4_SET_DBCMD_CH_ALL |
DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER;
mmio_write_32(DBSC4_REG_DBCMD, reg);
while (mmio_read_32(DBSC4_REG_DBWAIT))
;
/* Set the auto-refresh enable register */
mmio_write_32(DBSC4_REG_DBRFEN, 0U);
rcar_micro_delay(1U);
if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30)
return;
if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20)
return;
mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE);
}
static void __attribute__ ((section(".system_ram")))
rcar_pwrc_set_self_refresh_e3(void)
{
uint32_t ddr_md;
uint32_t reg;
ddr_md = (mmio_read_32(RST_MODEMR) >> 19) & RST_MODEMR_BIT0;
/* Write enable */
mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE);
mmio_write_32(DBSC4_REG_DBACEN, 0);
DBCAM_FLUSH(0);
reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL |
DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL;
mmio_write_32(DBSC4_REG_DBCMD, reg);
while (mmio_read_32(DBSC4_REG_DBWAIT))
;
reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL |
DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER;
mmio_write_32(DBSC4_REG_DBCMD, reg);
while (mmio_read_32(DBSC4_REG_DBWAIT))
;
/*
* Set the auto-refresh enable register
* Set the ARFEN bit to 0 in the DBRFEN
*/
mmio_write_32(DBSC4_REG_DBRFEN, 0);
mmio_write_32(DBSC4_REG_DBPDLK0, DBSC4_SET_DBPDLK0_PHY_ACCESS);
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR0);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR0);
/* DDR_DXCCR */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DXCCR);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DXCCR);
/* DDR_PGCR1 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_PGCR1);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_PGCR1);
/* DDR_ACIOCR1 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR1);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR1);
/* DDR_ACIOCR3 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR3);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR3);
/* DDR_ACIOCR5 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ACIOCR5);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_ACIOCR5);
/* DDR_DX0GCR2 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR2);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR2);
/* DDR_DX1GCR2 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR2);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR2);
/* DDR_DX2GCR2 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR2);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR2);
/* DDR_DX3GCR2 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR2);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR2);
/* DDR_ZQCR */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_ZQCR);
mmio_write_32(DBSC4_REG_DBPDRGD0, ddr_md == 0 ?
DBSC4_SET_DBPDRGD0_ZQCR_MD19_0 :
DBSC4_SET_DBPDRGD0_ZQCR_MD19_1);
/* DDR_DX0GCR0 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR0);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR0);
/* DDR_DX1GCR0 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR0);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR0);
/* DDR_DX2GCR0 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR0);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR0);
/* DDR_DX3GCR0 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR0);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR0);
/* DDR_DX0GCR1 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR1);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR1);
/* DDR_DX1GCR1 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR1);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR1);
/* DDR_DX2GCR1 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR1);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR1);
/* DDR_DX3GCR1 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR1);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR1);
/* DDR_DX0GCR3 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX0GCR3);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX0GCR3);
/* DDR_DX1GCR3 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX1GCR3);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX1GCR3);
/* DDR_DX2GCR3 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX2GCR3);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX2GCR3);
/* DDR_DX3GCR3 */
mmio_write_32(DBSC4_REG_DBPDRGA0, DBSC4_SET_DBPDRGA0_DX3GCR3);
mmio_write_32(DBSC4_REG_DBPDRGD0, DBSC4_SET_DBPDRGD0_DX3GCR3);
/* Write disable */
mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE);
}
void __attribute__ ((section(".system_ram"))) __attribute__ ((noinline))
rcar_pwrc_go_suspend_to_ram(void)
{
#if PMIC_ROHM_BD9571
int32_t rc = -1, qllm = -1;
uint8_t mode;
uint32_t i;
#endif
uint32_t reg, product;
reg = mmio_read_32(RCAR_PRR);
product = reg & PRR_PRODUCT_MASK;
if (product != PRR_PRODUCT_E3)
rcar_pwrc_set_self_refresh();
else
rcar_pwrc_set_self_refresh_e3();
#if PMIC_ROHM_BD9571
/* Set QLLM Cnt Disable */
for (i = 0; (i < PMIC_RETRY_MAX) && (qllm != 0); i++)
qllm = rcar_iic_dvfs_send(PMIC, PMIC_QLLM_CNT, 0);
/* Set trigger of power down to PMIV */
for (i = 0; (i < PMIC_RETRY_MAX) && (rc != 0) && (qllm == 0); i++) {
rc = rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode);
if (rc == 0) {
mode |= BIT_BKUP_CTRL_OUT;
rc = rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode);
}
}
#endif
wfi();
while (1)
;
}
void rcar_pwrc_set_suspend_to_ram(void)
{
uintptr_t jump = (uintptr_t) &rcar_pwrc_go_suspend_to_ram;
uintptr_t stack = (uintptr_t) (DEVICE_SRAM_STACK_BASE +
DEVICE_SRAM_STACK_SIZE);
uint32_t sctlr;
rcar_pwrc_save_timer_state();
/* disable MMU */
sctlr = (uint32_t) read_sctlr_el3();
sctlr &= (uint32_t) ~SCTLR_EL3_M_BIT;
write_sctlr_el3((uint64_t) sctlr);
rcar_pwrc_switch_stack(jump, stack, NULL);
}
void rcar_pwrc_init_suspend_to_ram(void)
{
#if PMIC_ROHM_BD9571
uint8_t mode;
if (rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode))
panic();
mode &= (uint8_t) (~BIT_BKUP_CTRL_OUT);
if (rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode))
panic();
#endif
}
void rcar_pwrc_suspend_to_ram(void)
{
#if RCAR_SYSTEM_RESET_KEEPON_DDR
int32_t error;
error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, 0);
if (error) {
ERROR("Failed send KEEP10 init ret=%d\n", error);
return;
}
#endif
rcar_pwrc_set_suspend_to_ram();
}
#endif
void rcar_pwrc_code_copy_to_system_ram(void)
{
int ret __attribute__ ((unused)); /* in assert */
uint32_t attr;
struct device_sram_t {
uintptr_t base;
size_t len;
} sram = {
.base = (uintptr_t) DEVICE_SRAM_BASE,
.len = DEVICE_SRAM_SIZE,
};
struct ddr_code_t {
void *base;
size_t len;
} code = {
.base = (void *) SRAM_COPY_START,
.len = SYSTEM_RAM_END - SYSTEM_RAM_START,
};
attr = MT_MEMORY | MT_RW | MT_SECURE | MT_EXECUTE_NEVER;
ret = xlat_change_mem_attributes(sram.base, sram.len, attr);
assert(ret == 0);
memcpy((void *)sram.base, code.base, code.len);
flush_dcache_range((uint64_t) sram.base, code.len);
attr = MT_MEMORY | MT_RO | MT_SECURE | MT_EXECUTE;
ret = xlat_change_mem_attributes(sram.base, sram.len, attr);
assert(ret == 0);
/* Invalidate instruction cache */
plat_invalidate_icache();
dsb();
isb();
}
uint32_t rcar_pwrc_get_cluster(void)
{
uint32_t reg;
reg = mmio_read_32(RCAR_PRR);
if (reg & (1U << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX)))
return RCAR_CLUSTER_CA57;
if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX)))
return RCAR_CLUSTER_CA53;
return RCAR_CLUSTER_A53A57;
}
uint32_t rcar_pwrc_get_mpidr_cluster(u_register_t mpidr)
{
uint32_t c = rcar_pwrc_get_cluster();
if (IS_A53A57(c)) {
if (mpidr & MPIDR_CLUSTER_MASK)
return RCAR_CLUSTER_CA53;
return RCAR_CLUSTER_CA57;
}
return c;
}
#if RCAR_LSI == RCAR_D3
uint32_t rcar_pwrc_get_cpu_num(uint32_t c)
{
return 1;
}
#else
uint32_t rcar_pwrc_get_cpu_num(uint32_t c)
{
uint32_t reg = mmio_read_32(RCAR_PRR);
uint32_t count = 0, i;
if (IS_A53A57(c) || IS_CA53(c)) {
if (reg & (1 << (STATE_CA53_CPU + RCAR_CA53CPU_NUM_MAX)))
goto count_ca57;
for (i = 0; i < RCAR_CA53CPU_NUM_MAX; i++) {
if (reg & (1 << (STATE_CA53_CPU + i)))
continue;
count++;
}
}
count_ca57:
if (IS_A53A57(c) || IS_CA57(c)) {
if (reg & (1U << (STATE_CA57_CPU + RCAR_CA57CPU_NUM_MAX)))
goto done;
for (i = 0; i < RCAR_CA57CPU_NUM_MAX; i++) {
if (reg & (1 << (STATE_CA57_CPU + i)))
continue;
count++;
}
}
done:
return count;
}
#endif
int32_t rcar_pwrc_cpu_on_check(u_register_t mpidr)
{
uint64_t i;
uint64_t j;
uint64_t cpu_count;
uintptr_t reg_PSTR;
uint32_t status;
uint64_t my_cpu;
int32_t rtn;
uint32_t my_cluster_type;
const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = {
RCAR_CLUSTER_CA53,
RCAR_CLUSTER_CA57
};
const uintptr_t registerPSTR[PLATFORM_CLUSTER_COUNT] = {
RCAR_CA53PSTR,
RCAR_CA57PSTR
};
my_cluster_type = rcar_pwrc_get_cluster();
rtn = 0;
my_cpu = mpidr & ((uint64_t)(MPIDR_CPU_MASK));
for (i = 0U; i < ((uint64_t)(PLATFORM_CLUSTER_COUNT)); i++) {
cpu_count = rcar_pwrc_get_cpu_num(cluster_type[i]);
reg_PSTR = registerPSTR[i];
for (j = 0U; j < cpu_count; j++) {
if ((my_cluster_type != cluster_type[i]) || (my_cpu != j)) {
status = mmio_read_32(reg_PSTR) >> (j * 4U);
if ((status & 0x00000003U) == 0U) {
rtn--;
}
}
}
}
return rtn;
}
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PWRC_H
#define PWRC_H
#define PPOFFR_OFF 0x0
#define PPONR_OFF 0x4
#define PCOFFR_OFF 0x8
#define PWKUPR_OFF 0xc
#define PSYSR_OFF 0x10
#define PWKUPR_WEN (1ull << 31)
#define PSYSR_AFF_L2 (1U << 31)
#define PSYSR_AFF_L1 (1 << 30)
#define PSYSR_AFF_L0 (1 << 29)
#define PSYSR_WEN (1 << 28)
#define PSYSR_PC (1 << 27)
#define PSYSR_PP (1 << 26)
#define PSYSR_WK_SHIFT (24)
#define PSYSR_WK_MASK (0x3)
#define PSYSR_WK(x) (((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK)
#define WKUP_COLD 0x0
#define WKUP_RESET 0x1
#define WKUP_PPONR 0x2
#define WKUP_GICREQ 0x3
#define RCAR_INVALID (0xffffffffU)
#define PSYSR_INVALID 0xffffffff
#define RCAR_CLUSTER_A53A57 (0U)
#define RCAR_CLUSTER_CA53 (1U)
#define RCAR_CLUSTER_CA57 (2U)
extern u_register_t rcar_boot_mpidr;
#ifndef __ASSEMBLER__
void rcar_pwrc_disable_interrupt_wakeup(u_register_t mpidr);
void rcar_pwrc_enable_interrupt_wakeup(u_register_t mpidr);
void rcar_pwrc_all_disable_interrupt_wakeup(void);
void rcar_pwrc_clusteroff(u_register_t mpidr);
void rcar_pwrc_cpuoff(u_register_t mpidr);
void rcar_pwrc_cpuon(u_register_t mpidr);
int32_t rcar_pwrc_cpu_on_check(u_register_t mpidr);
void rcar_pwrc_setup(void);
uint32_t rcar_pwrc_get_cpu_wkr(u_register_t mpidr);
uint32_t rcar_pwrc_status(u_register_t mpidr);
uint32_t rcar_pwrc_get_cluster(void);
uint32_t rcar_pwrc_get_mpidr_cluster(u_register_t mpidr);
uint32_t rcar_pwrc_get_cpu_num(uint32_t cluster_type);
void rcar_pwrc_restore_timer_state(void);
void plat_secondary_reset(void);
void rcar_pwrc_code_copy_to_system_ram(void);
#if !PMIC_ROHM_BD9571
void rcar_pwrc_system_reset(void);
#endif
#if RCAR_SYSTEM_SUSPEND
void rcar_pwrc_go_suspend_to_ram(void);
void rcar_pwrc_set_suspend_to_ram(void);
void rcar_pwrc_init_suspend_to_ram(void);
void rcar_pwrc_suspend_to_ram(void);
#endif
extern uint32_t rcar_pwrc_switch_stack(uintptr_t jump, uintptr_t stack,
void *arg);
#endif
#endif /* PWRC_H */
@@ -0,0 +1,133 @@
/*
* Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef QOS_REG_H
#define QOS_REG_H
#define RCAR_QOS_NONE 3U
#define RCAR_QOS_TYPE_DEFAULT 0U
#define RCAR_DRAM_SPLIT_LINEAR 0U
#define RCAR_DRAM_SPLIT_4CH 1U
#define RCAR_DRAM_SPLIT_2CH 2U
#define RCAR_DRAM_SPLIT_AUTO 3U
#define RST_BASE (0xE6160000U)
#define RST_MODEMR (RST_BASE + 0x0060U)
#define DBSC_BASE 0xE6790000U
#define DBSC_DBSYSCNT0 (DBSC_BASE + 0x0100U)
#define DBSC_AXARB (DBSC_BASE + 0x0800U)
#define DBSC_DBCAM0CNF1 (DBSC_BASE + 0x0904U)
#define DBSC_DBCAM0CNF2 (DBSC_BASE + 0x0908U)
#define DBSC_DBCAM0CNF3 (DBSC_BASE + 0x090CU)
#define DBSC_DBSCHCNT0 (DBSC_BASE + 0x1000U)
#define DBSC_DBSCHCNT1 (DBSC_BASE + 0x1004U)
#define DBSC_DBSCHSZ0 (DBSC_BASE + 0x1010U)
#define DBSC_DBSCHRW0 (DBSC_BASE + 0x1020U)
#define DBSC_DBSCHRW1 (DBSC_BASE + 0x1024U)
#define DBSC_DBSCHQOS00 (DBSC_BASE + 0x1030U)
#define DBSC_DBSCHQOS01 (DBSC_BASE + 0x1034U)
#define DBSC_DBSCHQOS02 (DBSC_BASE + 0x1038U)
#define DBSC_DBSCHQOS03 (DBSC_BASE + 0x103CU)
#define DBSC_DBSCHQOS40 (DBSC_BASE + 0x1070U)
#define DBSC_DBSCHQOS41 (DBSC_BASE + 0x1074U)
#define DBSC_DBSCHQOS42 (DBSC_BASE + 0x1078U)
#define DBSC_DBSCHQOS43 (DBSC_BASE + 0x107CU)
#define DBSC_DBSCHQOS90 (DBSC_BASE + 0x10C0U)
#define DBSC_DBSCHQOS91 (DBSC_BASE + 0x10C4U)
#define DBSC_DBSCHQOS92 (DBSC_BASE + 0x10C8U)
#define DBSC_DBSCHQOS93 (DBSC_BASE + 0x10CCU)
#define DBSC_DBSCHQOS120 (DBSC_BASE + 0x10F0U)
#define DBSC_DBSCHQOS121 (DBSC_BASE + 0x10F4U)
#define DBSC_DBSCHQOS122 (DBSC_BASE + 0x10F8U)
#define DBSC_DBSCHQOS123 (DBSC_BASE + 0x10FCU)
#define DBSC_DBSCHQOS130 (DBSC_BASE + 0x1100U)
#define DBSC_DBSCHQOS131 (DBSC_BASE + 0x1104U)
#define DBSC_DBSCHQOS132 (DBSC_BASE + 0x1108U)
#define DBSC_DBSCHQOS133 (DBSC_BASE + 0x110CU)
#define DBSC_DBSCHQOS140 (DBSC_BASE + 0x1110U)
#define DBSC_DBSCHQOS141 (DBSC_BASE + 0x1114U)
#define DBSC_DBSCHQOS142 (DBSC_BASE + 0x1118U)
#define DBSC_DBSCHQOS143 (DBSC_BASE + 0x111CU)
#define DBSC_DBSCHQOS150 (DBSC_BASE + 0x1120U)
#define DBSC_DBSCHQOS151 (DBSC_BASE + 0x1124U)
#define DBSC_DBSCHQOS152 (DBSC_BASE + 0x1128U)
#define DBSC_DBSCHQOS153 (DBSC_BASE + 0x112CU)
#define DBSC_SCFCTST0 (DBSC_BASE + 0x1700U)
#define DBSC_SCFCTST1 (DBSC_BASE + 0x1708U)
#define DBSC_SCFCTST2 (DBSC_BASE + 0x170CU)
#define AXI_BASE 0xE6784000U
#define AXI_ADSPLCR0 (AXI_BASE + 0x0008U)
#define AXI_ADSPLCR1 (AXI_BASE + 0x000CU)
#define AXI_ADSPLCR2 (AXI_BASE + 0x0010U)
#define AXI_ADSPLCR3 (AXI_BASE + 0x0014U)
#define AXI_MMCR (AXI_BASE + 0x0300U)
#define ADSPLCR0_ADRMODE_DEFAULT ((uint32_t)0U << 31U)
#define ADSPLCR0_ADRMODE_GEN2 ((uint32_t)1U << 31U)
#define ADSPLCR0_SPLITSEL(x) ((uint32_t)(x) << 16U)
#define ADSPLCR0_AREA(x) ((uint32_t)(x) << 8U)
#define ADSPLCR0_SWP 0x0CU
#define AXI_TR3CR 0xE67D100CU
#define AXI_TR4CR 0xE67D1014U
#define QOS_BASE0 0xE67E0000U
#define QOSBW_FIX_QOS_BANK0 (QOS_BASE0 + 0x0000U)
#define QOSBW_FIX_QOS_BANK1 (QOS_BASE0 + 0x1000U)
#define QOSBW_BE_QOS_BANK0 (QOS_BASE0 + 0x2000U)
#define QOSBW_BE_QOS_BANK1 (QOS_BASE0 + 0x3000U)
#define QOSCTRL_SL_INIT (QOS_BASE0 + 0x8000U)
#define QOSCTRL_REF_ARS (QOS_BASE0 + 0x8004U)
#define QOSCTRL_STATQC (QOS_BASE0 + 0x8008U)
#define QOS_BASE1 0xE67F0000U
#define QOSCTRL_RAS (QOS_BASE1 + 0x0000U)
#define QOSCTRL_FIXTH (QOS_BASE1 + 0x0004U)
#define QOSCTRL_RAEN (QOS_BASE1 + 0x0018U)
#define QOSCTRL_REGGD (QOS_BASE1 + 0x0020U)
#define QOSCTRL_DANN (QOS_BASE1 + 0x0030U)
#define QOSCTRL_DANT (QOS_BASE1 + 0x0038U)
#define QOSCTRL_EC (QOS_BASE1 + 0x003CU)
#define QOSCTRL_EMS (QOS_BASE1 + 0x0040U)
#define QOSCTRL_FSS (QOS_BASE1 + 0x0048U)
#define QOSCTRL_INSFC (QOS_BASE1 + 0x0050U)
#define QOSCTRL_BERR (QOS_BASE1 + 0x0054U)
#define QOSCTRL_EARLYR (QOS_BASE1 + 0x0060U)
#define QOSCTRL_RACNT0 (QOS_BASE1 + 0x0080U)
#define QOSCTRL_STATGEN0 (QOS_BASE1 + 0x0088U)
#define GPU_ACT_GRD 0xFD820808U
#define GPU_ACT0 0xFD820800U
#define GPU_ACT1 0xFD821800U
#define GPU_ACT2 0xFD822800U
#define GPU_ACT3 0xFD823800U
#define GPU_ACT4 0xFD824800U
#define GPU_ACT5 0xFD825800U
#define GPU_ACT6 0xFD826800U
#define GPU_ACT7 0xFD827800U
#define RT_ACT0 0xFFC50800U
#define RT_ACT1 0xFFC51800U
#define CPU_ACT0 0xF1300800U
#define CPU_ACT1 0xF1340800U
#define CPU_ACT2 0xF1380800U
#define CPU_ACT3 0xF13C0800U
#define RCAR_REWT_TRAINING_DISABLE 0U
#define RCAR_REWT_TRAINING_ENABLE 1U
#define QOSWT_FIX_WTQOS_BANK0 (QOSBW_FIX_QOS_BANK0 + 0x0800U)
#define QOSWT_FIX_WTQOS_BANK1 (QOSBW_FIX_QOS_BANK1 + 0x0800U)
#define QOSWT_BE_WTQOS_BANK0 (QOSBW_BE_QOS_BANK0 + 0x0800U)
#define QOSWT_BE_WTQOS_BANK1 (QOSBW_BE_QOS_BANK1 + 0x0800U)
#define QOSWT_WTEN (QOS_BASE0 + 0x8030U)
#define QOSWT_WTREF (QOS_BASE0 + 0x8034U)
#define QOSWT_WTSET0 (QOS_BASE0 + 0x8038U)
#define QOSWT_WTSET1 (QOS_BASE0 + 0x803CU)
#endif /* QOS_REG_H */
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <lib/mmio.h>
#include "rcar_def.h"
#include "rom_api.h"
typedef uint32_t(*rom_secure_boot_api_f) (uint32_t *key, uint32_t *cert,
rom_read_flash_f pFuncReadFlash);
typedef uint32_t(*rom_get_lcs_api_f) (uint32_t *lcs);
#define OLD_API_TABLE1 (0U) /* H3 Ver.1.0/Ver.1.1 */
#define OLD_API_TABLE2 (1U) /* H3 Ver.2.0 */
#define OLD_API_TABLE3 (2U) /* M3 Ver.1.0 */
#define NEW_API_TABLE (3U) /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */
#define NEW_API_TABLE2 (4U) /* V3M WS1.0 */
#define API_TABLE_MAX (5U) /* table max */
/* Later than H3 Ver.2.0 */
static uint32_t get_table_index(void)
{
uint32_t product;
uint32_t cut_ver;
uint32_t index;
product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
cut_ver = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK;
switch (product) {
case PRR_PRODUCT_H3:
if (cut_ver == PRR_PRODUCT_10)
index = OLD_API_TABLE1;
else if (cut_ver == PRR_PRODUCT_11)
index = OLD_API_TABLE1;
else if (cut_ver == PRR_PRODUCT_20)
index = OLD_API_TABLE2;
else
/* Later than H3 Ver.2.0 */
index = NEW_API_TABLE;
break;
case PRR_PRODUCT_M3:
if (cut_ver == PRR_PRODUCT_10)
index = OLD_API_TABLE3;
else
/* M3 Ver.1.1 or later */
index = NEW_API_TABLE;
break;
case PRR_PRODUCT_V3M:
if (cut_ver == PRR_PRODUCT_10)
/* V3M WS1.0 */
index = NEW_API_TABLE2;
else
/* V3M WS2.0 or later */
index = NEW_API_TABLE;
break;
default:
index = NEW_API_TABLE;
break;
}
return index;
}
uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert,
rom_read_flash_f read_flash)
{
static const uintptr_t rom_api_table[API_TABLE_MAX] = {
0xEB10DD64U, /* H3 Ver.1.0/Ver.1.1 */
0xEB116ED4U, /* H3 Ver.2.0 */
0xEB1102FCU, /* M3 Ver.1.0 */
0xEB100180U, /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */
0xEB110128U, /* V3M WS1.0 */
};
rom_secure_boot_api_f secure_boot;
uint32_t index;
index = get_table_index();
secure_boot = (rom_secure_boot_api_f) rom_api_table[index];
return secure_boot(key, cert, read_flash);
}
uint32_t rcar_rom_get_lcs(uint32_t *lcs)
{
static const uintptr_t rom_get_lcs_table[API_TABLE_MAX] = {
0xEB10DFE0U, /* H3 Ver.1.0/Ver.1.1 */
0xEB117150U, /* H3 Ver.2.0 */
0xEB110578U, /* M3 Ver.1.0 */
0xEB10018CU, /* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */
0xEB1103A4U, /* V3M WS1.0 */
};
rom_get_lcs_api_f get_lcs;
uint32_t index;
index = get_table_index();
get_lcs = (rom_get_lcs_api_f) rom_get_lcs_table[index];
return get_lcs(lcs);
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef ROM_API_H
#define ROM_API_H
#include <stdint.h>
#define SBROM_OK (0x00000000U)
#define SBROM_ILLEGAL_INPUT_PARAM_ERR (0x0B000001U)
#define SBROM_ILLEGAL_OEM_HASH_VALUE_ERR (0x0B000008U)
#define SBROM_ILLEGAL_LCS_FOR_OPERATION_ERR (0x0B000010U)
#define SBROM_HASH_NOT_PROGRAMMED_ERR (0x0B000100U)
#define SBROM_PUB_KEY_HASH_VALIDATION_FAILURE (0xF1000006U)
#define SBROM_RSA_SIG_VERIFICATION_FAILED (0xF1000007U)
#define LCS_CM (0x0U)
#define LCS_DM (0x1U)
#define LCS_SD (0x3U)
#define LCS_SE (0x5U)
#define LCS_FA (0x7U)
typedef uint32_t(*rom_read_flash_f) (uint64_t src, uint8_t *dst, uint32_t len);
uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert,
rom_read_flash_f f);
uint32_t rcar_rom_get_lcs(uint32_t *lcs);
#endif /* ROM_API_H */
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <string.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include "cpg_registers.h"
#include "rcar_def.h"
#include "rcar_private.h"
#include "rpc_registers.h"
#define MSTPSR9_RPC_BIT (0x00020000U)
#define RPC_CMNCR_MD_BIT (0x80000000U)
#define RPC_PHYCNT_CAL BIT(31)
#define RPC_PHYCNT_STRTIM_M3V1 (0x6 << 15UL)
#define RPC_PHYCNT_STRTIM (0x7 << 15UL)
static void rpc_enable(void)
{
/* Enable clock supply to RPC. */
mstpcr_write(CPG_SMSTPCR9, CPG_MSTPSR9, MSTPSR9_RPC_BIT);
}
static void rpc_setup(void)
{
uint32_t product, cut, reg, phy_strtim;
if (mmio_read_32(RPC_CMNCR) & RPC_CMNCR_MD_BIT)
mmio_clrbits_32(RPC_CMNCR, RPC_CMNCR_MD_BIT);
product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK;
if ((product == PRR_PRODUCT_M3) && (cut < PRR_PRODUCT_30))
phy_strtim = RPC_PHYCNT_STRTIM_M3V1;
else
phy_strtim = RPC_PHYCNT_STRTIM;
reg = mmio_read_32(RPC_PHYCNT);
reg &= ~RPC_PHYCNT_STRTIM;
reg |= phy_strtim;
mmio_write_32(RPC_PHYCNT, reg);
reg |= RPC_PHYCNT_CAL;
mmio_write_32(RPC_PHYCNT, reg);
}
void rcar_rpc_init(void)
{
rpc_enable();
rpc_setup();
}
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RPC_REGISTERS_H
#define RPC_REGISTERS_H
#define RPC_BASE (0xEE200000U)
#define RPC_CMNCR (RPC_BASE + 0x0000U)
#define RPC_SSLDR (RPC_BASE + 0x0004U)
#define RPC_DRCR (RPC_BASE + 0x000CU)
#define RPC_DRCMR (RPC_BASE + 0x0010U)
#define RPC_DRENR (RPC_BASE + 0x001CU)
#define RPC_SMCR (RPC_BASE + 0x0020U)
#define RPC_SMCMR (RPC_BASE + 0x0024U)
#define RPC_SMENR (RPC_BASE + 0x0030U)
#define RPC_CMNSR (RPC_BASE + 0x0048U)
#define RPC_DRDMCR (RPC_BASE + 0x0058U)
#define RPC_DRDRENR (RPC_BASE + 0x005CU)
#define RPC_PHYCNT (RPC_BASE + 0x007CU)
#define RPC_PHYINT (RPC_BASE + 0x0088U)
#endif /* RPC_REGISTERS_H */
@@ -0,0 +1,341 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <console_macros.S>
#include <drivers/renesas/rcar/console/console.h>
#define SCIF_INTERNAL_CLK 0
#define SCIF_EXTARNAL_CLK 1
#define SCIF_CLK SCIF_INTERNAL_CLK
/* product register */
#define PRR (0xFFF00044)
#define PRR_PRODUCT_MASK (0x00007F00)
#define PRR_CUT_MASK (0x000000FF)
#define PRR_PRODUCT_H3_VER_10 (0x00004F00)
#define PRR_PRODUCT_E3 (0x00005700)
#define PRR_PRODUCT_D3 (0x00005800)
/* module stop */
#define CPG_BASE (0xE6150000)
#define CPG_SMSTPCR2 (0x0138)
#define CPG_SMSTPCR3 (0x013C)
#define CPG_MSTPSR2 (0x0040)
#define CPG_MSTPSR3 (0x0048)
#define MSTP207 (1 << 7)
#define MSTP310 (1 << 10)
#define CPG_CPGWPR (0x0900)
/* scif */
#define SCIF0_BASE (0xE6E60000)
#define SCIF2_BASE (0xE6E88000)
#define SCIF_SCSMR (0x00)
#define SCIF_SCBRR (0x04)
#define SCIF_SCSCR (0x08)
#define SCIF_SCFTDR (0x0C)
#define SCIF_SCFSR (0x10)
#define SCIF_SCFRDR (0x14)
#define SCIF_SCFCR (0x18)
#define SCIF_SCFDR (0x1C)
#define SCIF_SCSPTR (0x20)
#define SCIF_SCLSR (0x24)
#define SCIF_DL (0x30)
#define SCIF_CKS (0x34)
#if RCAR_LSI == RCAR_V3M
#define SCIF_BASE SCIF0_BASE
#define CPG_SMSTPCR CPG_SMSTPCR2
#define CPG_MSTPSR CPG_MSTPSR2
#define MSTP MSTP207
#else
#define SCIF_BASE SCIF2_BASE
#define CPG_SMSTPCR CPG_SMSTPCR3
#define CPG_MSTPSR CPG_MSTPSR3
#define MSTP MSTP310
#endif
/* mode pin */
#define RST_MODEMR (0xE6160060)
#define MODEMR_MD12 (0x00001000)
#define SCSMR_CA_MASK (1 << 7)
#define SCSMR_CA_ASYNC (0x0000)
#define SCSMR_CHR_MASK (1 << 6)
#define SCSMR_CHR_8 (0x0000)
#define SCSMR_PE_MASK (1 << 5)
#define SCSMR_PE_DIS (0x0000)
#define SCSMR_STOP_MASK (1 << 3)
#define SCSMR_STOP_1 (0x0000)
#define SCSMR_CKS_MASK (3 << 0)
#define SCSMR_CKS_DIV1 (0x0000)
#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \
SCSMR_CHR_8 + \
SCSMR_PE_DIS + \
SCSMR_STOP_1 + \
SCSMR_CKS_DIV1)
#define SCBRR_115200BPS (17)
#define SCBRR_115200BPS_D3_SSCG (16)
#define SCBRR_115200BPS_E3_SSCG (15)
#define SCBRR_230400BPS (8)
#define SCSCR_TE_MASK (1 << 5)
#define SCSCR_TE_DIS (0x0000)
#define SCSCR_TE_EN (0x0020)
#define SCSCR_RE_MASK (1 << 4)
#define SCSCR_RE_DIS (0x0000)
#define SCSCR_RE_EN (0x0010)
#define SCSCR_CKE_MASK (3 << 0)
#define SCSCR_CKE_INT (0x0000)
#define SCSCR_CKE_BRG (0x0002)
#if SCIF_CLK == SCIF_EXTARNAL_CLK
#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG)
#else
#define SCFSR_TEND_MASK (1 << 6)
#define SCFSR_TEND_TRANS_END (0x0040)
#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT)
#endif
#define SCFSR_INIT_DATA (0x0000)
#define SCFCR_TTRG_MASK (3 << 4)
#define SCFCR_TTRG_8 (0x0000)
#define SCFCR_TTRG_0 (0x0030)
#define SCFCR_TFRST_MASK (1 << 2)
#define SCFCR_TFRST_DIS (0x0000)
#define SCFCR_TFRST_EN (0x0004)
#define SCFCR_RFRS_MASK (1 << 1)
#define SCFCR_RFRS_DIS (0x0000)
#define SCFCR_RFRS_EN (0x0002)
#define SCFCR_INIT_DATA (SCFCR_TTRG_8)
#define SCFDR_T_MASK (0x1f << 8)
#define DL_INIT_DATA (8)
#define CKS_CKS_DIV_MASK (1 << 15)
#define CKS_CKS_DIV_CLK (0x0000)
#define CKS_XIN_MASK (1 << 14)
#define CKS_XIN_SCIF_CLK (0x0000)
#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK)
.globl console_rcar_register
.globl console_rcar_init
.globl console_rcar_putc
.globl console_rcar_flush
/*
* -----------------------------------------------
* int console_rcar_register(
* uintptr_t base, uint32_t clk, uint32_t baud,
* console_t *console)
* Function to initialize and register a new rcar
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
* x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
*/
func console_rcar_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
str x0, [x6, #CONSOLE_T_BASE]
bl console_rcar_init
mov x0, x6
mov x30, x7
finish_console_register rcar, putc=1, getc=0, flush=1
register_fail:
ret x7
endfunc console_rcar_register
/*
* int console_rcar_init(unsigned long base_addr,
* unsigned int uart_clk, unsigned int baud_rate)
* Function to initialize the console without a
* C Runtime to print debug information. This
* function will be accessed by console_rcar_register
* and crash reporting.
* In: x0 - console base address
* w1 - Uart clock in Hz
* w2 - Baud rate
* Out: return 1 on success
* Clobber list : x1, x2
*/
func console_rcar_init
ldr x0, =CPG_BASE
ldr w1, [x0, #CPG_SMSTPCR]
and w1, w1, #~MSTP
mvn w2, w1
str w2, [x0, #CPG_CPGWPR]
str w1, [x0, #CPG_SMSTPCR]
5:
ldr w1, [x0, #CPG_MSTPSR]
and w1, w1, #MSTP
cbnz w1, 5b
ldr x0, =SCIF_BASE
/* Clear bits TE and RE in SCSCR to 0 */
mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS)
strh w1, [x0, #SCIF_SCSCR]
/* Set bits TFRST and RFRST in SCFCR to 1 */
ldrh w1, [x0, #SCIF_SCFCR]
orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN)
strh w1, [x0, #SCIF_SCFCR]
/*
* Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER
* in SCLSR, then clear them to 0
*/
mov w1, #SCFSR_INIT_DATA
strh w1, [x0, #SCIF_SCFSR]
mov w1, #0
strh w1, [x0, #SCIF_SCLSR]
/* Set bits CKE[1:0] in SCSCR */
ldrh w1, [x0, #SCIF_SCSCR]
and w1, w1, #~SCSCR_CKE_MASK
mov w2, #SCSCR_CKE_INT_CLK
orr w1, w1, w2
strh w1, [x0, #SCIF_SCSCR]
/* Set data transfer format in SCSMR */
mov w1, #SCSMR_INIT_DATA
strh w1, [x0, #SCIF_SCSMR]
/* Set value in SCBRR */
#if SCIF_CLK == SCIF_INTERNAL_CLK
ldr x1, =PRR
ldr w1, [x1]
and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK)
mov w2, #PRR_PRODUCT_H3_VER_10
cmp w1, w2
beq 3f
and w1, w1, #PRR_PRODUCT_MASK
mov w2, #PRR_PRODUCT_D3
cmp w1, w2
beq 5f
and w1, w1, #PRR_PRODUCT_MASK
mov w2, #PRR_PRODUCT_E3
cmp w1, w2
bne 4f
/* When SSCG(MD12) on (E3) */
ldr x1, =RST_MODEMR
ldr w1, [x1]
and w1, w1, #MODEMR_MD12
mov w2, #MODEMR_MD12
cmp w1, w2
bne 4f
/* When SSCG(MD12) on (E3) */
mov w1, #SCBRR_115200BPS_E3_SSCG
b 2f
5:
/* In case of D3 */
ldr x1, =RST_MODEMR
ldr w1, [x1]
and w1, w1, #MODEMR_MD12
mov w2, #MODEMR_MD12
cmp w1, w2
bne 4f
/* When SSCG(MD12) on (D3) */
mov w1, #SCBRR_115200BPS_D3_SSCG
b 2f
4:
/* In case of H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */
mov w1, #SCBRR_115200BPS
b 2f
3:
mov w1, #SCBRR_230400BPS
2:
strb w1, [x0, SCIF_SCBRR]
#else
mov w1, #DL_INIT_DATA
strh w1, [x0, #SCIF_DL]
mov w1, #CKS_INIT_DATA
strh w1, [x0, #SCIF_CKS]
#endif
/* 1-bit interval elapsed */
mov w1, #100
1:
subs w1, w1, #1
cbnz w1, 1b
/*
* Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
* Clear bits FRST and RFRST to 0
*/
mov w1, #SCFCR_INIT_DATA
strh w1, [x0, #SCIF_SCFCR]
/* Set bits TE and RE in SCSCR to 1 */
ldrh w1, [x0, #SCIF_SCSCR]
orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN)
strh w1, [x0, #SCIF_SCSCR]
mov x0, #1
ret
endfunc console_rcar_init
/*
* int console_rcar_putc(int c, unsigned int base_addr)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
* x1 - pointer to console_t structure
* Out : return -1 on error else return character.
* Clobber list : x2
*/
func console_rcar_putc
ldr x1, =SCIF_BASE
cmp w0, #0xA
/* Prepend '\r' to '\n' */
bne 2f
1:
/* Check if the transmit FIFO is full */
ldrh w2, [x1, #SCIF_SCFDR]
ubfx w2, w2, #8, #5
cmp w2, #16
bcs 1b
mov w2, #0x0D
strb w2, [x1, #SCIF_SCFTDR]
2:
/* Check if the transmit FIFO is full */
ldrh w2, [x1, #SCIF_SCFDR]
ubfx w2, w2, #8, #5
cmp w2, #16
bcs 2b
strb w0, [x1, #SCIF_SCFTDR]
/* Clear TEND flag */
ldrh w2, [x1, #SCIF_SCFSR]
and w2, w2, #~SCFSR_TEND_MASK
strh w2, [x1, #SCIF_SCFSR]
ret
endfunc console_rcar_putc
/*
* void console_rcar_flush(void)
* Function to force a write of all buffered
* data that hasn't been output. It returns void
* Clobber list : x0, x1
*/
func console_rcar_flush
ldr x0, =SCIF_BASE
1:
/* Check TEND flag */
ldrh w1, [x0, #SCIF_SCFSR]
and w1, w1, #SCFSR_TEND_MASK
cmp w1, #SCFSR_TEND_TRANS_END
bne 1b
ldr x0, =SCIF_BASE
ldrh w1, [x0, #SCIF_SCSCR]
and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN)
strh w1, [x0, #SCIF_SCSCR]
ret
endfunc console_rcar_flush
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/gicv2.h>
#include <lib/mmio.h>
#include "rcar_def.h"
extern void gicd_set_icenabler(uintptr_t base, unsigned int id);
#define RST_BASE (0xE6160000U)
#define RST_WDTRSTCR (RST_BASE + 0x0054U)
#define SWDT_BASE (0xE6030000U)
#define SWDT_WTCNT (SWDT_BASE + 0x0000U)
#define SWDT_WTCSRA (SWDT_BASE + 0x0004U)
#define SWDT_WTCSRB (SWDT_BASE + 0x0008U)
#define SWDT_GICD_BASE (0xF1010000U)
#define SWDT_GICC_BASE (0xF1020000U)
#define SWDT_GICD_CTLR (SWDT_GICD_BASE + 0x0000U)
#define SWDT_GICD_IGROUPR (SWDT_GICD_BASE + 0x0080U)
#define SWDT_GICD_ISPRIORITYR (SWDT_GICD_BASE + 0x0400U)
#define SWDT_GICC_CTLR (SWDT_GICC_BASE + 0x0000U)
#define SWDT_GICC_PMR (SWDT_GICC_BASE + 0x0004U)
#define SWDT_GICD_ITARGETSR (SWDT_GICD_BASE + 0x0800U)
#define IGROUPR_NUM (16U)
#define ISPRIORITY_NUM (128U)
#define ITARGET_MASK (0x03U)
#define WDTRSTCR_UPPER_BYTE (0xA55A0000U)
#define WTCSRA_UPPER_BYTE (0xA5A5A500U)
#define WTCSRB_UPPER_BYTE (0xA5A5A500U)
#define WTCNT_UPPER_BYTE (0x5A5A0000U)
#define WTCNT_RESET_VALUE (0xF488U)
#define WTCSRA_BIT_CKS (0x0007U)
#define WTCSRB_BIT_CKS (0x003FU)
#define SWDT_RSTMSK (1U << 1U)
#define WTCSRA_WOVFE (1U << 3U)
#define WTCSRA_WRFLG (1U << 5U)
#define SWDT_ENABLE (1U << 7U)
#define WDTRSTCR_MASK_ALL (0x0000FFFFU)
#define WTCSRA_MASK_ALL (0x000000FFU)
#define WTCNT_INIT_DATA (WTCNT_UPPER_BYTE + WTCNT_RESET_VALUE)
#define WTCSRA_INIT_DATA (WTCSRA_UPPER_BYTE + 0x0FU)
#define WTCSRB_INIT_DATA (WTCSRB_UPPER_BYTE + 0x21U)
#if RCAR_LSI == RCAR_D3
#define WTCNT_COUNT_8p13k (0x10000U - 40760U)
#else
#define WTCNT_COUNT_8p13k (0x10000U - 40687U)
#endif
#define WTCNT_COUNT_8p13k_H3VER10 (0x10000U - 20343U)
#define WTCNT_COUNT_8p22k (0x10000U - 41115U)
#define WTCNT_COUNT_7p81k (0x10000U - 39062U)
#define WTCSRA_CKS_DIV16 (0x00000002U)
static void swdt_disable(void)
{
uint32_t rmsk;
rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL;
rmsk |= SWDT_RSTMSK;
mmio_write_32(RST_WDTRSTCR, WDTRSTCR_UPPER_BYTE | rmsk);
mmio_write_32(SWDT_WTCNT, WTCNT_INIT_DATA);
mmio_write_32(SWDT_WTCSRA, WTCSRA_INIT_DATA);
mmio_write_32(SWDT_WTCSRB, WTCSRB_INIT_DATA);
/* Set the interrupt clear enable register */
gicd_set_icenabler(RCAR_GICD_BASE, ARM_IRQ_SEC_WDT);
}
void rcar_swdt_init(void)
{
uint32_t rmsk, sr;
#if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RCAR_D3) && (RCAR_LSI != RZ_G2E)
uint32_t reg, val, product_cut, chk_data;
reg = mmio_read_32(RCAR_PRR);
product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
reg = mmio_read_32(RCAR_MODEMR);
chk_data = reg & CHECK_MD13_MD14;
#endif
/* stop watchdog */
if (mmio_read_32(SWDT_WTCSRA) & SWDT_ENABLE)
mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE);
mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE |
WTCSRA_WOVFE | WTCSRA_CKS_DIV16);
#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E)
mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k);
#elif (RCAR_LSI == RCAR_D3)
mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_8p13k);
#else
val = WTCNT_UPPER_BYTE;
switch (chk_data) {
case MD14_MD13_TYPE_0:
case MD14_MD13_TYPE_2:
val |= WTCNT_COUNT_8p13k;
break;
case MD14_MD13_TYPE_1:
val |= WTCNT_COUNT_8p22k;
break;
case MD14_MD13_TYPE_3:
val |= product_cut == (PRR_PRODUCT_H3 | PRR_PRODUCT_10) ?
WTCNT_COUNT_8p13k_H3VER10 : WTCNT_COUNT_8p13k;
break;
default:
ERROR("MODEMR ERROR value = %x\n", chk_data);
panic();
break;
}
mmio_write_32(SWDT_WTCNT, val);
#endif
rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL;
rmsk |= SWDT_RSTMSK | WDTRSTCR_UPPER_BYTE;
mmio_write_32(RST_WDTRSTCR, rmsk);
while ((mmio_read_8(SWDT_WTCSRA) & WTCSRA_WRFLG) != 0U)
;
/* Start the System WatchDog Timer */
sr = mmio_read_32(SWDT_WTCSRA) & WTCSRA_MASK_ALL;
mmio_write_32(SWDT_WTCSRA, (WTCSRA_UPPER_BYTE | sr | SWDT_ENABLE));
}
void rcar_swdt_release(void)
{
uintptr_t itarget = SWDT_GICD_ITARGETSR +
(ARM_IRQ_SEC_WDT & ~ITARGET_MASK);
uint32_t i;
/* Disable FIQ interrupt */
write_daifset(DAIF_FIQ_BIT);
/* FIQ interrupts are not taken to EL3 */
write_scr_el3(read_scr_el3() & ~SCR_FIQ_BIT);
swdt_disable();
gicv2_cpuif_disable();
for (i = 0; i < IGROUPR_NUM; i++)
mmio_write_32(SWDT_GICD_IGROUPR + i * 4, 0U);
for (i = 0; i < ISPRIORITY_NUM; i++)
mmio_write_32(SWDT_GICD_ISPRIORITYR + i * 4, 0U);
mmio_write_32(itarget, 0U);
mmio_write_32(SWDT_GICD_CTLR, 0U);
mmio_write_32(SWDT_GICC_CTLR, 0U);
mmio_write_32(SWDT_GICC_PMR, 0U);
}
void rcar_swdt_exec(uint64_t p)
{
gicv2_end_of_interrupt(ARM_IRQ_SEC_WDT);
rcar_swdt_release();
ERROR("\n");
ERROR("System WDT overflow, occurred address is %p\n", (void *)p);
panic();
}