diff options
Diffstat (limited to 'drivers')
205 files changed, 31044 insertions, 3442 deletions
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c index 13437fec8..e98b16fdb 100644 --- a/drivers/allwinner/axp/common.c +++ b/drivers/allwinner/axp/common.c @@ -105,6 +105,25 @@ static bool should_enable_regulator(const void *fdt, int node) return false; } +static bool board_uses_usb0_host_mode(const void *fdt) +{ + int node, length; + const char *prop; + + node = fdt_node_offset_by_compatible(fdt, -1, + "allwinner,sun8i-a33-musb"); + if (node < 0) { + return false; + } + + prop = fdt_getprop(fdt, node, "dr_mode", &length); + if (!prop) { + return false; + } + + return !strncmp(prop, "host", length); +} + void axp_setup_regulators(const void *fdt) { int node; @@ -121,7 +140,8 @@ void axp_setup_regulators(const void *fdt) } /* This applies to AXP803 only. */ - if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) { + if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL) && + board_uses_usb0_host_mode(fdt)) { axp_clrbits(0x8f, BIT(4)); axp_setbits(0x30, BIT(2)); INFO("PMIC: Enabling DRIVEVBUS\n"); diff --git a/drivers/allwinner/sunxi_msgbox.c b/drivers/allwinner/sunxi_msgbox.c new file mode 100644 index 000000000..cc4a6ffcb --- /dev/null +++ b/drivers/allwinner/sunxi_msgbox.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stdbool.h> + +#include <drivers/delay_timer.h> +#include <lib/bakery_lock.h> +#include <lib/mmio.h> +#include <lib/utils_def.h> + +#include <sunxi_mmap.h> + +#define REMOTE_IRQ_EN_REG 0x0040 +#define REMOTE_IRQ_STAT_REG 0x0050 +#define LOCAL_IRQ_EN_REG 0x0060 +#define LOCAL_IRQ_STAT_REG 0x0070 + +#define RX_IRQ(n) BIT(0 + 2 * (n)) +#define TX_IRQ(n) BIT(1 + 2 * (n)) + +#define FIFO_STAT_REG(n) (0x0100 + 0x4 * (n)) +#define FIFO_STAT_MASK GENMASK(0, 0) + +#define MSG_STAT_REG(n) (0x0140 + 0x4 * (n)) +#define MSG_STAT_MASK GENMASK(2, 0) + +#define MSG_DATA_REG(n) (0x0180 + 0x4 * (n)) + +#define RX_CHAN 1 +#define TX_CHAN 0 + +#define MHU_MAX_SLOT_ID 31 + +#define MHU_TIMEOUT_DELAY 10 +#define MHU_TIMEOUT_ITERS 10000 + +static DEFINE_BAKERY_LOCK(mhu_secure_message_lock); + +static bool sunxi_msgbox_last_tx_done(unsigned int chan) +{ + uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + REMOTE_IRQ_STAT_REG); + + return (stat & RX_IRQ(chan)) == 0U; +} + +static bool sunxi_msgbox_peek_data(unsigned int chan) +{ + uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_STAT_REG(chan)); + + return (stat & MSG_STAT_MASK) != 0U; +} + +void mhu_secure_message_start(unsigned int slot_id __unused) +{ + uint32_t timeout = MHU_TIMEOUT_ITERS; + + bakery_lock_get(&mhu_secure_message_lock); + + /* Wait for all previous messages to be acknowledged. */ + while (!sunxi_msgbox_last_tx_done(TX_CHAN) && --timeout) + udelay(MHU_TIMEOUT_DELAY); +} + +void mhu_secure_message_send(unsigned int slot_id) +{ + mmio_write_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(TX_CHAN), BIT(slot_id)); +} + +uint32_t mhu_secure_message_wait(void) +{ + uint32_t timeout = MHU_TIMEOUT_ITERS; + uint32_t msg = 0; + + /* Wait for a message from the SCP. */ + while (!sunxi_msgbox_peek_data(RX_CHAN) && --timeout) + udelay(MHU_TIMEOUT_DELAY); + + /* Return the most recent message in the FIFO. */ + while (sunxi_msgbox_peek_data(RX_CHAN)) + msg = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(RX_CHAN)); + + return msg; +} + +void mhu_secure_message_end(unsigned int slot_id) +{ + /* Acknowledge a response by clearing the IRQ status. */ + mmio_write_32(SUNXI_MSGBOX_BASE + LOCAL_IRQ_STAT_REG, RX_IRQ(RX_CHAN)); + + bakery_lock_release(&mhu_secure_message_lock); +} diff --git a/drivers/amlogic/console/aarch64/meson_console.S b/drivers/amlogic/console/aarch64/meson_console.S index e645cbab8..6d0a2d62e 100644 --- a/drivers/amlogic/console/aarch64/meson_console.S +++ b/drivers/amlogic/console/aarch64/meson_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -46,14 +46,14 @@ /* ----------------------------------------------- * int console_meson_register(uintptr_t base, * uint32_t clk, uint32_t baud, - * console_meson_t *console); + * console_t *console); * Function to initialize and register a new MESON * 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_meson_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -62,7 +62,7 @@ func console_meson_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_MESON_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_meson_init cbz x0, register_fail @@ -128,7 +128,7 @@ init_fail: endfunc console_meson_init /* -------------------------------------------------------- - * int console_meson_putc(int c, console_meson_t *console) + * int console_meson_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 @@ -142,7 +142,7 @@ func console_meson_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_MESON_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_meson_core_putc endfunc console_meson_putc @@ -179,7 +179,7 @@ func console_meson_core_putc endfunc console_meson_core_putc /* --------------------------------------------- - * int console_meson_getc(console_meson_t *console) + * int console_meson_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -193,7 +193,7 @@ func console_meson_getc cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_MESON_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_meson_core_getc endfunc console_meson_getc @@ -224,11 +224,11 @@ func console_meson_core_getc endfunc console_meson_core_getc /* --------------------------------------------- - * int console_meson_flush(console_meson_t *console) + * void console_meson_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -237,16 +237,16 @@ func console_meson_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_MESON_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_meson_core_flush endfunc console_meson_flush /* --------------------------------------------- - * int console_meson_core_flush(uintptr_t base_addr) + * void console_meson_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -258,6 +258,5 @@ func console_meson_core_flush /* Wait until the transmit FIFO is empty */ 1: ldr w1, [x0, #MESON_STATUS_OFFSET] tbz w1, #MESON_STATUS_TX_EMPTY_BIT, 1b - mov w0, #0 ret endfunc console_meson_core_flush diff --git a/drivers/arm/cci/cci.c b/drivers/arm/cci/cci.c index a139f6cc7..2adfe1718 100644 --- a/drivers/arm/cci/cci.c +++ b/drivers/arm/cci/cci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -52,11 +52,11 @@ static bool validate_cci_map(const int *map) return false; } - if ((valid_cci_map & (1U << slave_if_id)) != 0U) { + if ((valid_cci_map & (1UL << slave_if_id)) != 0U) { ERROR("Multiple masters are assigned same slave interface ID\n"); return false; } - valid_cci_map |= 1U << slave_if_id; + valid_cci_map |= 1UL << slave_if_id; } if (valid_cci_map == 0U) { diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c index d0c5abc7c..5b13250bc 100644 --- a/drivers/arm/ccn/ccn.c +++ b/drivers/arm/ccn/ccn.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> -#include <errno.h> #include <stdbool.h> #include <arch.h> diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c index 885874272..c51f3b1d7 100644 --- a/drivers/arm/css/mhu/css_mhu_doorbell.c +++ b/drivers/arm/css/mhu/css_mhu_doorbell.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,11 +20,13 @@ void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) { + uintptr_t mhuv2_base = plat_info->db_reg_addr & MHU_V2_FRAME_BASE_MASK; + /* wake receiver */ - MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_ACCESS_REQUEST(mhuv2_base); /* wait for receiver to acknowledge its ready */ - while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) + while (MHU_V2_IS_ACCESS_READY(mhuv2_base) == 0) ; MHU_RING_DOORBELL(plat_info->db_reg_addr, @@ -32,7 +34,7 @@ void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) plat_info->db_preserve_mask); /* clear the access request for the receiver */ - MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); + MHU_V2_CLEAR_REQUEST(mhuv2_base); return; } diff --git a/drivers/arm/css/scp/css_bom_bootloader.c b/drivers/arm/css/scp/css_bom_bootloader.c index 1fc1270ba..74121b487 100644 --- a/drivers/arm/css/scp/css_bom_bootloader.c +++ b/drivers/arm/css/scp/css_bom_bootloader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,13 +51,13 @@ typedef struct { * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 * usually resides except when ARM_BL31_IN_DRAM is * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and - * the tb_fw_config. + * the fw_config. */ CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); -CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); -CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); +CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); static void scp_boot_message_start(void) { diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c index b945cda78..aeb7eda30 100644 --- a/drivers/arm/css/scp/css_pm_scmi.c +++ b/drivers/arm/css/scp/css_pm_scmi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -63,17 +63,45 @@ typedef enum { } scmi_power_state_t; /* - * The global handle for invoking the SCMI driver APIs after the driver + * The global handles for invoking the SCMI driver APIs after the driver * has been initialized. */ -static void *scmi_handle; +static void *scmi_handles[PLAT_ARM_SCMI_CHANNEL_COUNT]; -/* The SCMI channel global object */ -static scmi_channel_t channel; +/* The global SCMI channels array */ +static scmi_channel_t scmi_channels[PLAT_ARM_SCMI_CHANNEL_COUNT]; +/* + * Channel ID for the default SCMI channel. + * The default channel is used to issue SYSTEM level SCMI requests and is + * initialized to the channel which has the boot cpu as its resource. + */ +static uint32_t default_scmi_channel_id; + +/* + * TODO: Allow use of channel specific lock instead of using a single lock for + * all the channels. + */ ARM_SCMI_INSTANTIATE_LOCK; /* + * Function to obtain the SCMI Domain ID and SCMI Channel number from the linear + * core position. The SCMI Channel number is encoded in the upper 16 bits and + * the Domain ID is encoded in the lower 16 bits in each entry of the mapping + * array exported by the platform. + */ +static void css_scp_core_pos_to_scmi_channel(unsigned int core_pos, + unsigned int *scmi_domain_id, unsigned int *scmi_channel_id) +{ + unsigned int composite_id; + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[core_pos]; + + *scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); + *scmi_domain_id = GET_SCMI_DOMAIN_ID(composite_id); +} + +/* * Helper function to suspend a CPU power domain and its parent power domains * if applicable. */ @@ -87,10 +115,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) /* Check if power down at system power domain level is requested */ if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) { - /* Issue SCMI command for SYSTEM_SUSPEND */ - ret = scmi_sys_pwr_state_set(scmi_handle, - SCMI_SYS_PWR_FORCEFUL_REQ, - SCMI_SYS_PWR_SUSPEND); + /* Issue SCMI command for SYSTEM_SUSPEND on all SCMI channels */ + ret = scmi_sys_pwr_state_set( + scmi_handles[default_scmi_channel_id], + SCMI_SYS_PWR_FORCEFUL_REQ, SCMI_SYS_PWR_SUSPEND); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI system power domain suspend return 0x%x unexpected\n", ret); @@ -99,7 +127,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) return; } #if !HW_ASSISTED_COHERENCY - unsigned int lvl; + unsigned int lvl, channel_id, domain_id; uint32_t scmi_pwr_state = 0; /* * If we reach here, then assert that power down at system power domain @@ -127,9 +155,10 @@ void css_scp_suspend(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", @@ -145,7 +174,7 @@ void css_scp_suspend(const struct psci_power_state *target_state) */ void css_scp_off(const struct psci_power_state *target_state) { - unsigned int lvl = 0; + unsigned int lvl = 0, channel_id, domain_id; int ret; uint32_t scmi_pwr_state = 0; @@ -168,10 +197,10 @@ void css_scp_off(const struct psci_power_state *target_state) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); - + css_scp_core_pos_to_scmi_channel(plat_my_core_pos(), + &domain_id, &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -185,8 +214,8 @@ void css_scp_off(const struct psci_power_state *target_state) */ void css_scp_on(u_register_t mpidr) { - unsigned int lvl = 0; - int core_pos, ret; + unsigned int lvl = 0, channel_id, core_pos, domain_id; + int ret; uint32_t scmi_pwr_state = 0; for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) @@ -195,14 +224,13 @@ void css_scp_on(u_register_t mpidr) SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - core_pos = plat_core_pos_by_mpidr(mpidr); - assert((core_pos >= 0) && - (((unsigned int)core_pos) < PLATFORM_CORE_COUNT)); - - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[core_pos], - scmi_pwr_state); + core_pos = (unsigned int)plat_core_pos_by_mpidr(mpidr); + assert(core_pos < PLATFORM_CORE_COUNT); + css_scp_core_pos_to_scmi_channel(core_pos, &domain_id, + &channel_id); + ret = scmi_pwr_state_set(scmi_handles[channel_id], + domain_id, scmi_pwr_state); if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { ERROR("SCMI set power state command return 0x%x unexpected\n", ret); @@ -216,8 +244,9 @@ void css_scp_on(u_register_t mpidr) */ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) { - int ret, cpu_idx; + int ret; uint32_t scmi_pwr_state = 0, lvl_state; + unsigned int channel_id, cpu_idx, domain_id; /* We don't support get power state at the system power domain level */ if ((power_level > PLAT_MAX_PWR_LVL) || @@ -227,12 +256,12 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) return PSCI_E_INVALID_PARAMS; } - cpu_idx = plat_core_pos_by_mpidr(mpidr); - assert(cpu_idx > -1); + cpu_idx = (unsigned int)plat_core_pos_by_mpidr(mpidr); + assert(cpu_idx < PLATFORM_CORE_COUNT); - ret = scmi_pwr_state_get(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx], - &scmi_pwr_state); + css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id); + ret = scmi_pwr_state_get(scmi_handles[channel_id], + domain_id, &scmi_pwr_state); if (ret != SCMI_E_SUCCESS) { WARN("SCMI get power state command return 0x%x unexpected\n", @@ -271,7 +300,7 @@ void __dead2 css_scp_system_off(int state) * Issue SCMI command. First issue a graceful * request and if that fails force the request. */ - ret = scmi_sys_pwr_state_set(scmi_handle, + ret = scmi_sys_pwr_state_set(scmi_handles[default_scmi_channel_id], SCMI_SYS_PWR_FORCEFUL_REQ, state); @@ -325,17 +354,28 @@ static int scmi_ap_core_init(scmi_channel_t *ch) void __init plat_arm_pwrc_setup(void) { - channel.info = plat_css_get_scmi_info(); - channel.lock = ARM_SCMI_LOCK_GET_INSTANCE; - scmi_handle = scmi_init(&channel); - if (scmi_handle == NULL) { - ERROR("SCMI Initialization failed\n"); - panic(); - } - if (scmi_ap_core_init(&channel) < 0) { - ERROR("SCMI AP core protocol initialization failed\n"); - panic(); + unsigned int composite_id, idx; + + for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) { + INFO("Initializing driver on Channel %d\n", idx); + + scmi_channels[idx].info = plat_css_get_scmi_info(idx); + scmi_channels[idx].lock = ARM_SCMI_LOCK_GET_INSTANCE; + scmi_handles[idx] = scmi_init(&scmi_channels[idx]); + + if (scmi_handles[idx] == NULL) { + ERROR("SCMI Initialization failed on channel %d\n", idx); + panic(); + } + + if (scmi_ap_core_init(&scmi_channels[idx]) < 0) { + ERROR("SCMI AP core protocol initialization failed\n"); + panic(); + } } + + composite_id = plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()]; + default_scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id); } /****************************************************************************** @@ -347,6 +387,7 @@ const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops) { uint32_t msg_attr; int ret; + void *scmi_handle = scmi_handles[default_scmi_channel_id]; assert(scmi_handle); @@ -411,14 +452,17 @@ int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie) #if PROGRAMMABLE_RESET_ADDRESS void plat_arm_program_trusted_mailbox(uintptr_t address) { - int ret; + int ret, i; - assert(scmi_handle); - ret = scmi_ap_core_set_reset_addr(scmi_handle, address, - SCMI_AP_CORE_LOCK_ATTR); - if (ret != SCMI_E_SUCCESS) { - ERROR("CSS: Failed to program reset address: %d\n", ret); - panic(); + for (i = 0; i < PLAT_ARM_SCMI_CHANNEL_COUNT; i++) { + assert(scmi_handles[i]); + + ret = scmi_ap_core_set_reset_addr(scmi_handles[i], address, + SCMI_AP_CORE_LOCK_ATTR); + if (ret != SCMI_E_SUCCESS) { + ERROR("CSS: Failed to program reset address: %d\n", ret); + panic(); + } } } #endif diff --git a/drivers/arm/css/scpi/css_scpi.c b/drivers/arm/css/scpi/css_scpi.c index c56b7c41b..416356bf2 100644 --- a/drivers/arm/css/scpi/css_scpi.c +++ b/drivers/arm/css/scpi/css_scpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,7 +51,7 @@ static void scpi_secure_message_send(size_t payload_size) mhu_secure_message_send(SCPI_MHU_SLOT_ID); } -static void scpi_secure_message_receive(scpi_cmd_t *cmd) +static int scpi_secure_message_receive(scpi_cmd_t *cmd) { uint32_t mhu_status; @@ -63,7 +63,7 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd) if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", mhu_status); - panic(); + return -1; } /* @@ -74,6 +74,8 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd) dmbld(); memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); + + return 0; } static void scpi_secure_message_end(void) @@ -84,14 +86,19 @@ static void scpi_secure_message_end(void) int scpi_wait_ready(void) { scpi_cmd_t scpi_cmd; + int rc; VERBOSE("Waiting for SCP_READY command...\n"); /* Get a message from the SCP */ scpi_secure_message_start(); - scpi_secure_message_receive(&scpi_cmd); + rc = scpi_secure_message_receive(&scpi_cmd); scpi_secure_message_end(); + /* If no message was received, don't send a response */ + if (rc != 0) + return rc; + /* We are expecting 'SCP Ready', produce correct error if it's not */ scpi_status_t status = SCP_OK; if (scpi_cmd.id != SCPI_CMD_SCP_READY) { @@ -209,7 +216,8 @@ int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, * Send message and wait for SCP's response */ scpi_secure_message_send(0); - scpi_secure_message_receive(&response); + if (scpi_secure_message_receive(&response) != 0) + goto exit; if (response.status != SCP_OK) goto exit; @@ -254,7 +262,9 @@ uint32_t scpi_sys_power_state(scpi_system_state_t system_state) *payload_addr = system_state & 0xff; scpi_secure_message_send(sizeof(*payload_addr)); - scpi_secure_message_receive(&response); + /* If no response is received, fill in an error status */ + if (scpi_secure_message_receive(&response) != 0) + response.status = SCP_E_TIMEOUT; scpi_secure_message_end(); diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c index 38b2f6719..bf6405f7f 100644 --- a/drivers/arm/gic/common/gic_common.c +++ b/drivers/arm/gic/common/gic_common.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#pragma message __FILE__ " is deprecated, use gicv2.mk instead" + #include <assert.h> #include <drivers/arm/gic_common.h> diff --git a/drivers/arm/gic/v2/gicdv2_helpers.c b/drivers/arm/gic/v2/gicdv2_helpers.c new file mode 100644 index 000000000..db9ba87c4 --- /dev/null +++ b/drivers/arm/gic/v2/gicdv2_helpers.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <drivers/arm/gic_common.h> +#include <lib/mmio.h> + +#include "../common/gic_common_private.h" + +/******************************************************************************* + * GIC Distributor interface accessors for reading entire registers + ******************************************************************************/ +/* + * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt + * `id`, 32 interrupt ids at a time. + */ +unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> IGROUPR_SHIFT; + + return mmio_read_32(base + GICD_IGROUPR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ISENABLER corresponding to the + * interrupt `id`, 32 interrupt ids at a time. + */ +unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ISENABLER_SHIFT; + + return mmio_read_32(base + GICD_ISENABLER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICENABLER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICENABLER_SHIFT; + + return mmio_read_32(base + GICD_ICENABLER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ISPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ISPENDR_SHIFT; + + return mmio_read_32(base + GICD_ISPENDR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICPENDR_SHIFT; + + return mmio_read_32(base + GICD_ICPENDR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ISACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ISACTIVER_SHIFT; + + return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICACTIVER_SHIFT; + + return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupt IDs at a time. + */ +unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor ICGFR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> ICFGR_SHIFT; + + return mmio_read_32(base + GICD_ICFGR + (n << 2)); +} + +/* + * Accessor to read the GIC Distributor NSACR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> NSACR_SHIFT; + + return mmio_read_32(base + GICD_NSACR + (n << 2)); +} + +/******************************************************************************* + * GIC Distributor interface accessors for writing entire registers + ******************************************************************************/ +/* + * Accessor to write the GIC Distributor IGROUPR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> IGROUPR_SHIFT; + + mmio_write_32(base + GICD_IGROUPR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ISENABLER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ISENABLER_SHIFT; + + mmio_write_32(base + GICD_ISENABLER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICENABLER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICENABLER_SHIFT; + + mmio_write_32(base + GICD_ICENABLER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ISPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ISPENDR_SHIFT; + + mmio_write_32(base + GICD_ISPENDR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICPENDR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICPENDR_SHIFT; + + mmio_write_32(base + GICD_ICPENDR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ISACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ISACTIVER_SHIFT; + + mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICACTIVER corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICACTIVER_SHIFT; + + mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupt IDs at a time. + */ +void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor ICFGR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> ICFGR_SHIFT; + + mmio_write_32(base + GICD_ICFGR + (n << 2), val); +} + +/* + * Accessor to write the GIC Distributor NSACR corresponding to the + * interrupt `id`, 16 interrupt IDs at a time. + */ +void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> NSACR_SHIFT; + + mmio_write_32(base + GICD_NSACR + (n << 2), val); +} + +/******************************************************************************* + * GIC Distributor functions for accessing the GIC registers + * corresponding to a single interrupt ID. These functions use bitwise + * operations or appropriate register accesses to modify or return + * the bit-field corresponding the single interrupt ID. + ******************************************************************************/ +unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicd_read_igroupr(base, id); + + return (reg_val >> bit_num) & 0x1U; +} + +void gicd_set_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicd_read_igroupr(base, id); + + gicd_write_igroupr(base, id, reg_val | (1U << bit_num)); +} + +void gicd_clr_igroupr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicd_read_igroupr(base, id); + + gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num)); +} + +void gicd_set_isenabler(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); + + gicd_write_isenabler(base, id, (1U << bit_num)); +} + +void gicd_set_icenabler(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); + + gicd_write_icenabler(base, id, (1U << bit_num)); +} + +void gicd_set_ispendr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); + + gicd_write_ispendr(base, id, (1U << bit_num)); +} + +void gicd_set_icpendr(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); + + gicd_write_icpendr(base, id, (1U << bit_num)); +} + +unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); + unsigned int reg_val = gicd_read_isactiver(base, id); + + return (reg_val >> bit_num) & 0x1U; +} + +void gicd_set_isactiver(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); + + gicd_write_isactiver(base, id, (1U << bit_num)); +} + +void gicd_set_icactiver(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U); + + gicd_write_icactiver(base, id, (1U << bit_num)); +} + +void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + uint8_t val = pri & GIC_PRI_MASK; + + mmio_write_8(base + GICD_IPRIORITYR + id, val); +} + +void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1; + + uint32_t reg_val = gicd_read_icfgr(base, id); + + /* Clear the field, and insert required configuration */ + reg_val &= ~(GIC_CFG_MASK << bit_shift); + reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); + + gicd_write_icfgr(base, id, reg_val); +} diff --git a/drivers/arm/gic/v2/gicv2.mk b/drivers/arm/gic/v2/gicv2.mk new file mode 100644 index 000000000..49996bb51 --- /dev/null +++ b/drivers/arm/gic/v2/gicv2.mk @@ -0,0 +1,15 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# No support for extended PPI and SPI range +GIC_EXT_INTID := 0 + +GICV2_SOURCES += drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/arm/gic/v2/gicdv2_helpers.c + +# Set GICv2 build option +$(eval $(call add_define,GIC_EXT_INTID))
\ No newline at end of file diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c index 6739a782c..751316c03 100644 --- a/drivers/arm/gic/v2/gicv2_helpers.c +++ b/drivers/arm/gic/v2/gicv2_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,7 +7,6 @@ #include <assert.h> #include <arch.h> -#include <arch_helpers.h> #include <common/debug.h> #include <common/interrupt_props.h> #include <drivers/arm/gic_common.h> diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index c5bced00d..939d09718 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -247,6 +247,15 @@ void gicv2_end_of_interrupt(unsigned int id) assert(driver_data != NULL); assert(driver_data->gicc_base != 0U); + /* + * Ensure the write to peripheral registers are *complete* before the write + * to GIC_EOIR. + * + * Note: The completion gurantee depends on various factors of system design + * and the barrier is the best core can do by which execution of further + * instructions waits till the barrier is alive. + */ + dsbishst(); gicc_write_EOIR(driver_data->gicc_base, id); } @@ -287,8 +296,8 @@ void gicv2_set_pe_target_mask(unsigned int proc_num) assert(driver_data != NULL); assert(driver_data->gicd_base != 0U); assert(driver_data->target_masks != NULL); - assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); - assert((unsigned int)proc_num < driver_data->target_masks_num); + assert(proc_num < GICV2_MAX_TARGET_PE); + assert(proc_num < driver_data->target_masks_num); /* Return if the target mask is already populated */ if (driver_data->target_masks[proc_num] != 0U) @@ -413,7 +422,8 @@ void gicv2_raise_sgi(int sgi_num, int proc_num) unsigned int sgir_val, target; assert(driver_data != NULL); - assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); + assert(proc_num >= 0); + assert(proc_num < (int)GICV2_MAX_TARGET_PE); assert(driver_data->gicd_base != 0U); /* @@ -421,7 +431,7 @@ void gicv2_raise_sgi(int sgi_num, int proc_num) * should be valid. */ assert(driver_data->target_masks != NULL); - assert((unsigned int)proc_num < driver_data->target_masks_num); + assert(proc_num < (int)driver_data->target_masks_num); /* Don't raise SGI if the mask hasn't been populated */ target = driver_data->target_masks[proc_num]; @@ -457,8 +467,9 @@ void gicv2_set_spi_routing(unsigned int id, int proc_num) * should be valid. */ assert(driver_data->target_masks != NULL); - assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); - assert((unsigned int)proc_num < driver_data->target_masks_num); + assert(proc_num < (int)GICV2_MAX_TARGET_PE); + assert(driver_data->target_masks_num < INT_MAX); + assert(proc_num < (int)driver_data->target_masks_num); if (proc_num < 0) { /* Target all PEs */ diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c new file mode 100644 index 000000000..6e106babf --- /dev/null +++ b/drivers/arm/gic/v3/gic-x00.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Driver for GIC-500 and GIC-600 specific features. This driver only + * overrides APIs that are different to those generic ones in GICv3 + * driver. + * + * GIC-600 supports independently power-gating redistributor interface. + */ + +#include <assert.h> + +#include <arch_helpers.h> +#include <drivers/arm/gicv3.h> + +#include "gicv3_private.h" + +/* GIC-600 specific register offsets */ +#define GICR_PWRR 0x24U +#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b) +#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) +#define IIDR_MODEL_ARM_GIC_CLAYTON U(0x0400043b) + +/* GICR_PWRR fields */ +#define PWRR_RDPD_SHIFT 0 +#define PWRR_RDAG_SHIFT 1 +#define PWRR_RDGPD_SHIFT 2 +#define PWRR_RDGPO_SHIFT 3 + +#define PWRR_RDPD (1U << PWRR_RDPD_SHIFT) +#define PWRR_RDAG (1U << PWRR_RDAG_SHIFT) +#define PWRR_RDGPD (1U << PWRR_RDGPD_SHIFT) +#define PWRR_RDGPO (1U << PWRR_RDGPO_SHIFT) + +/* + * Values to write to GICR_PWRR register to power redistributor + * for operating through the core (GICR_PWRR.RDAG = 0) + */ +#define PWRR_ON (0U << PWRR_RDPD_SHIFT) +#define PWRR_OFF (1U << PWRR_RDPD_SHIFT) + +#if GICV3_SUPPORT_GIC600 + +/* GIC-600/Clayton specific accessor functions */ +static void gicr_write_pwrr(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_PWRR, val); +} + +static uint32_t gicr_read_pwrr(uintptr_t base) +{ + return mmio_read_32(base + GICR_PWRR); +} + +static void gicr_wait_group_not_in_transit(uintptr_t base) +{ + uint32_t pwrr; + + do { + pwrr = gicr_read_pwrr(base); + + /* Check group not transitioning: RDGPD == RDGPO */ + } while (((pwrr & PWRR_RDGPD) >> PWRR_RDGPD_SHIFT) != + ((pwrr & PWRR_RDGPO) >> PWRR_RDGPO_SHIFT)); +} + +static void gic600_pwr_on(uintptr_t base) +{ + do { /* Wait until group not transitioning */ + gicr_wait_group_not_in_transit(base); + + /* Power on redistributor */ + gicr_write_pwrr(base, PWRR_ON); + + /* + * Wait until the power on state is reflected. + * If RDPD == 0 then powered on. + */ + } while ((gicr_read_pwrr(base) & PWRR_RDPD) != PWRR_ON); +} + +static void gic600_pwr_off(uintptr_t base) +{ + /* Wait until group not transitioning */ + gicr_wait_group_not_in_transit(base); + + /* Power off redistributor */ + gicr_write_pwrr(base, PWRR_OFF); + + /* + * If this is the last man, turning this redistributor frame off will + * result in the group itself being powered off and RDGPD = 1. + * In that case, wait as long as it's in transition, or has aborted + * the transition altogether for any reason. + */ + if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0U) { + /* Wait until group not transitioning */ + gicr_wait_group_not_in_transit(base); + } +} + +static uintptr_t get_gicr_base(unsigned int proc_num) +{ + uintptr_t gicr_base; + + assert(gicv3_driver_data != NULL); + assert(proc_num < gicv3_driver_data->rdistif_num); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); + + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + assert(gicr_base != 0UL); + + return gicr_base; +} + +static bool gicv3_redists_need_power_mgmt(uintptr_t gicr_base) +{ + uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR); + + /* + * The Arm GIC-600 and GIC-Clayton models have their redistributors + * powered down at reset. + */ + return (((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) || + ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600AE) || + ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON)); +} + +#endif /* GICV3_SUPPORT_GIC600 */ + +void gicv3_distif_pre_save(unsigned int proc_num) +{ + arm_gicv3_distif_pre_save(proc_num); +} + +void gicv3_distif_post_restore(unsigned int proc_num) +{ + arm_gicv3_distif_post_restore(proc_num); +} + +/* + * Power off GIC-600 redistributor (if configured and detected) + */ +void gicv3_rdistif_off(unsigned int proc_num) +{ +#if GICV3_SUPPORT_GIC600 + uintptr_t gicr_base = get_gicr_base(proc_num); + + /* Attempt to power redistributor off */ + if (gicv3_redists_need_power_mgmt(gicr_base)) { + gic600_pwr_off(gicr_base); + } +#endif +} + +/* + * Power on GIC-600 redistributor (if configured and detected) + */ +void gicv3_rdistif_on(unsigned int proc_num) +{ +#if GICV3_SUPPORT_GIC600 + uintptr_t gicr_base = get_gicr_base(proc_num); + + /* Power redistributor on */ + if (gicv3_redists_need_power_mgmt(gicr_base)) { + gic600_pwr_on(gicr_base); + } +#endif +} diff --git a/drivers/arm/gic/v3/gic500.c b/drivers/arm/gic/v3/gic500.c deleted file mode 100644 index f03e33f86..000000000 --- a/drivers/arm/gic/v3/gic500.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Driver for GIC500-specific features. This driver only overrides APIs that are - * different to those generic ones in GICv3 driver. - */ -#include "gicv3_private.h" - -void gicv3_distif_pre_save(unsigned int proc_num) -{ - arm_gicv3_distif_pre_save(proc_num); -} - -void gicv3_distif_post_restore(unsigned int proc_num) -{ - arm_gicv3_distif_post_restore(proc_num); -} - diff --git a/drivers/arm/gic/v3/gic600.c b/drivers/arm/gic/v3/gic600.c deleted file mode 100644 index 59652da63..000000000 --- a/drivers/arm/gic/v3/gic600.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Driver for GIC-600 specific features. This driver only overrides - * APIs that are different to those generic ones in GICv3 driver. - * - * GIC-600 supports independently power-gating redistributor interface. - */ - -#include <assert.h> - -#include <arch_helpers.h> -#include <drivers/arm/gicv3.h> - -#include "gicv3_private.h" - -/* GIC-600 specific register offsets */ -#define GICR_PWRR 0x24 - -/* GICR_PWRR fields */ -#define PWRR_RDPD_SHIFT 0 -#define PWRR_RDAG_SHIFT 1 -#define PWRR_RDGPD_SHIFT 2 -#define PWRR_RDGPO_SHIFT 3 - -#define PWRR_RDPD (1 << PWRR_RDPD_SHIFT) -#define PWRR_RDAG (1 << PWRR_RDAG_SHIFT) -#define PWRR_RDGPD (1 << PWRR_RDGPD_SHIFT) -#define PWRR_RDGPO (1 << PWRR_RDGPO_SHIFT) - -/* - * Values to write to GICR_PWRR register to power redistributor - * for operating through the core (GICR_PWRR.RDAG = 0) - */ -#define PWRR_ON (0 << PWRR_RDPD_SHIFT) -#define PWRR_OFF (1 << PWRR_RDPD_SHIFT) - -/* GIC-600 specific accessor functions */ -static void gicr_write_pwrr(uintptr_t base, unsigned int val) -{ - mmio_write_32(base + GICR_PWRR, val); -} - -static uint32_t gicr_read_pwrr(uintptr_t base) -{ - return mmio_read_32(base + GICR_PWRR); -} - -static void gicr_wait_group_not_in_transit(uintptr_t base) -{ - /* Check group not transitioning: RDGPD == RDGPO */ - while (((gicr_read_pwrr(base) & PWRR_RDGPD) >> PWRR_RDGPD_SHIFT) != - ((gicr_read_pwrr(base) & PWRR_RDGPO) >> PWRR_RDGPO_SHIFT)) - ; -} - -static void gic600_pwr_on(uintptr_t base) -{ - do { /* Wait until group not transitioning */ - gicr_wait_group_not_in_transit(base); - - /* Power on redistributor */ - gicr_write_pwrr(base, PWRR_ON); - - /* - * Wait until the power on state is reflected. - * If RDPD == 0 then powered on. - */ - } while ((gicr_read_pwrr(base) & PWRR_RDPD) != PWRR_ON); -} - -static void gic600_pwr_off(uintptr_t base) -{ - /* Wait until group not transitioning */ - gicr_wait_group_not_in_transit(base); - - /* Power off redistributor */ - gicr_write_pwrr(base, PWRR_OFF); - - /* - * If this is the last man, turning this redistributor frame off will - * result in the group itself being powered off and RDGPD = 1. - * In that case, wait as long as it's in transition, or has aborted - * the transition altogether for any reason. - */ - if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0) { - /* Wait until group not transitioning */ - gicr_wait_group_not_in_transit(base); - } -} - -void gicv3_distif_pre_save(unsigned int proc_num) -{ - arm_gicv3_distif_pre_save(proc_num); -} - -void gicv3_distif_post_restore(unsigned int proc_num) -{ - arm_gicv3_distif_post_restore(proc_num); -} - -/* - * Power off GIC-600 redistributor - */ -void gicv3_rdistif_off(unsigned int proc_num) -{ - uintptr_t gicr_base; - - assert(gicv3_driver_data); - assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); - - gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - assert(gicr_base); - - /* Attempt to power redistributor off */ - gic600_pwr_off(gicr_base); -} - -/* - * Power on GIC-600 redistributor - */ -void gicv3_rdistif_on(unsigned int proc_num) -{ - uintptr_t gicr_base; - - assert(gicv3_driver_data); - assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); - - gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - assert(gicr_base); - - /* Power redistributor on */ - gic600_pwr_on(gicr_base); -} diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h index b0217b6d4..fe4134cba 100644 --- a/drivers/arm/gic/v3/gic600_multichip_private.h +++ b/drivers/arm/gic/v3/gic600_multichip_private.h @@ -24,11 +24,21 @@ /* GIC600 GICD multichip related shifts */ #define GICD_CHIPRx_ADDR_SHIFT 16 -#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 10 -#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 5 #define GICD_CHIPSR_RTS_SHIFT 4 #define GICD_DCHIPR_RT_OWNER_SHIFT 4 +/* + * If GIC v4 extension is enabled, then use SPI macros specific to GIC-Clayton. + * Other shifts and mask remains same between GIC-600 and GIC-Clayton. + */ +#if GIC_ENABLE_V4_EXTN +#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 9 +#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 3 +#else +#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 10 +#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 5 +#endif + #define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0) #define GICD_CHIPSR_RTS_STATE_UPDATING U(1) #define GICD_CHIPSR_RTS_STATE_CONSISTENT U(2) diff --git a/drivers/arm/gic/v3/gicdv3_helpers.c b/drivers/arm/gic/v3/gicdv3_helpers.c new file mode 100644 index 000000000..987be69e7 --- /dev/null +++ b/drivers/arm/gic/v3/gicdv3_helpers.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include "gicv3_private.h" + +/******************************************************************************* + * GIC Distributor functions for accessing the GIC registers + * corresponding to a single interrupt ID. These functions use bitwise + * operations or appropriate register accesses to modify or return + * the bit-field corresponding the single interrupt ID. + ******************************************************************************/ + +/* + * Accessors to set the bits corresponding to interrupt ID + * in GIC Distributor ICFGR and ICFGRE. + */ +void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_shift = BIT_NUM(ICFG, id) << 1U; + + /* Clear the field, and insert required configuration */ + mmio_clrsetbits_32(base + GICD_OFFSET(ICFG, id), + (uint32_t)GIC_CFG_MASK << bit_shift, + (cfg & GIC_CFG_MASK) << bit_shift); +} + +/* + * Accessors to get/set/clear the bit corresponding to interrupt ID + * in GIC Distributor IGROUPR and IGROUPRE. + */ +unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) +{ + return GICD_GET_BIT(IGROUP, base, id); +} + +void gicd_set_igroupr(uintptr_t base, unsigned int id) +{ + GICD_SET_BIT(IGROUP, base, id); +} + +void gicd_clr_igroupr(uintptr_t base, unsigned int id) +{ + GICD_CLR_BIT(IGROUP, base, id); +} + +/* + * Accessors to get/set/clear the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR and IGRPMODRE. + */ +unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICD_GET_BIT(IGRPMOD, base, id); +} + +void gicd_set_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_SET_BIT(IGRPMOD, base, id); +} + +void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_CLR_BIT(IGRPMOD, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ICENABLER and ICENABLERE. + */ +void gicd_set_icenabler(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ICENABLE, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ICPENDR and ICPENDRE. + */ +void gicd_set_icpendr(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ICPEND, base, id); +} + +/* + * Accessors to get/set the bit corresponding to interrupt ID + * in GIC Distributor ISACTIVER and ISACTIVERE. + */ +unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id) +{ + return GICD_GET_BIT(ISACTIVE, base, id); +} + +void gicd_set_isactiver(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ISACTIVE, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ISENABLER and ISENABLERE. + */ +void gicd_set_isenabler(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ISENABLE, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor ISPENDR and ISPENDRE. + */ +void gicd_set_ispendr(uintptr_t base, unsigned int id) +{ + GICD_WRITE_BIT(ISPEND, base, id); +} + +/* + * Accessors to set the bit corresponding to interrupt ID + * in GIC Distributor IPRIORITYR and IPRIORITYRE. + */ +void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + GICD_WRITE_8(IPRIORITY, base, id, (uint8_t)(pri & GIC_PRI_MASK)); +} + +/******************************************************************************* + * GIC Distributor interface accessors for reading/writing entire registers + ******************************************************************************/ + +/* + * Accessors to read/write the GIC Distributor ICGFR and ICGFRE + * corresponding to the interrupt ID, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) +{ + return GICD_READ(ICFG, base, id); +} + +void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ICFG, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor IGROUPR and IGROUPRE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IGROUP, base, id); +} + +void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(IGROUP, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor IGRPMODR and IGRPMODRE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IGRPMOD, base, id); +} + +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(IGRPMOD, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor IPRIORITYR and IPRIORITYRE + * corresponding to the interrupt ID, 4 interrupt IDs at a time. + */ +unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IPRIORITY, base, id); +} + +void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(IPRIORITY, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor ISACTIVER and ISACTIVERE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) +{ + return GICD_READ(ISACTIVE, base, id); +} + +void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ISACTIVE, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor ISENABLER and ISENABLERE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) +{ + return GICD_READ(ISENABLE, base, id); +} + +void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ISENABLE, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor ISPENDR and ISPENDRE + * corresponding to the interrupt ID, 32 interrupt IDs at a time. + */ +unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) +{ + return GICD_READ(ISPEND, base, id); +} + +void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(ISPEND, base, id, val); +} + +/* + * Accessors to read/write the GIC Distributor NSACR and NSACRE + * corresponding to the interrupt ID, 16 interrupt IDs at a time. + */ +unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) +{ + return GICD_READ(NSAC, base, id); +} + +void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICD_WRITE(NSAC, base, id, val); +} diff --git a/drivers/arm/gic/v3/gicrv3_helpers.c b/drivers/arm/gic/v3/gicrv3_helpers.c new file mode 100644 index 000000000..3004054ee --- /dev/null +++ b/drivers/arm/gic/v3/gicrv3_helpers.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <common/debug.h> +#include <common/interrupt_props.h> +#include <drivers/arm/gicv3.h> +#include "gicv3_private.h" + +/******************************************************************************* + * GIC Redistributor functions + * Note: The raw register values correspond to multiple interrupt `id`s and + * the number of interrupt `id`s involved depends on the register accessed. + ******************************************************************************/ + +/* + * Accessors to read/write the GIC Redistributor IPRIORITYR and IPRIORITYRE + * register corresponding to the interrupt `id`, 4 interrupts IDs at a time. + */ +unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) +{ + return GICR_READ(IPRIORITY, base, id); +} + +void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + GICR_WRITE(IPRIORITY, base, id, val); +} + +/* + * Accessor to set the byte corresponding to interrupt `id` + * in GIC Redistributor IPRIORITYR and IPRIORITYRE. + */ +void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + GICR_WRITE_8(IPRIORITY, base, id, (uint8_t)(pri & GIC_PRI_MASK)); +} + +/* + * Accessors to get/set/clear the bit corresponding to interrupt `id` + * from GIC Redistributor IGROUPR0 and IGROUPRE + */ +unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id) +{ + return GICR_GET_BIT(IGROUP, base, id); +} + +void gicr_set_igroupr(uintptr_t base, unsigned int id) +{ + GICR_SET_BIT(IGROUP, base, id); +} + +void gicr_clr_igroupr(uintptr_t base, unsigned int id) +{ + GICR_CLR_BIT(IGROUP, base, id); +} + +/* + * Accessors to get/set/clear the bit corresponding to interrupt `id` + * from GIC Redistributor IGRPMODR0 and IGRPMODRE + */ +unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICR_GET_BIT(IGRPMOD, base, id); +} + +void gicr_set_igrpmodr(uintptr_t base, unsigned int id) +{ + GICR_SET_BIT(IGRPMOD, base, id); +} + +void gicr_clr_igrpmodr(uintptr_t base, unsigned int id) +{ + GICR_CLR_BIT(IGRPMOD, base, id); +} + +/* + * Accessor to write the bit corresponding to interrupt `id` + * in GIC Redistributor ISENABLER0 and ISENABLERE + */ +void gicr_set_isenabler(uintptr_t base, unsigned int id) +{ + GICR_WRITE_BIT(ISENABLE, base, id); +} + +/* + * Accessor to write the bit corresponding to interrupt `id` + * in GIC Redistributor ICENABLER0 and ICENABLERE + */ +void gicr_set_icenabler(uintptr_t base, unsigned int id) +{ + GICR_WRITE_BIT(ICENABLE, base, id); +} + +/* + * Accessor to get the bit corresponding to interrupt `id` + * in GIC Redistributor ISACTIVER0 and ISACTIVERE + */ +unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id) +{ + return GICR_GET_BIT(ISACTIVE, base, id); +} + +/* + * Accessor to clear the bit corresponding to interrupt `id` + * in GIC Redistributor ICPENDR0 and ICPENDRE + */ +void gicr_set_icpendr(uintptr_t base, unsigned int id) +{ + GICR_WRITE_BIT(ICPEND, base, id); +} + +/* + * Accessor to write the bit corresponding to interrupt `id` + * in GIC Redistributor ISPENDR0 and ISPENDRE + */ +void gicr_set_ispendr(uintptr_t base, unsigned int id) +{ + GICR_WRITE_BIT(ISPEND, base, id); +} + +/* + * Accessor to set the bit fields corresponding to interrupt `id` + * in GIC Redistributor ICFGR0, ICFGR1 and ICFGRE + */ +void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_shift = BIT_NUM(ICFG, id) << 1U; + + /* Clear the field, and insert required configuration */ + mmio_clrsetbits_32(base + GICR_OFFSET(ICFG, id), + (uint32_t)GIC_CFG_MASK << bit_shift, + (cfg & GIC_CFG_MASK) << bit_shift); +} diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk new file mode 100644 index 000000000..a2fc16f9c --- /dev/null +++ b/drivers/arm/gic/v3/gicv3.mk @@ -0,0 +1,38 @@ +# +# Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Default configuration values +GICV3_SUPPORT_GIC600 ?= 0 +GICV3_IMPL_GIC600_MULTICHIP ?= 0 +GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0 +GIC_ENABLE_V4_EXTN ?= 0 +GIC_EXT_INTID ?= 0 + +GICV3_SOURCES += drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c + +ifeq (${GICV3_OVERRIDE_DISTIF_PWR_OPS}, 0) +GICV3_SOURCES += drivers/arm/gic/v3/arm_gicv3_common.c +endif + +GICV3_SOURCES += drivers/arm/gic/v3/gic-x00.c +ifeq (${GICV3_IMPL_GIC600_MULTICHIP}, 1) +GICV3_SOURCES += drivers/arm/gic/v3/gic600_multichip.c +endif + +# Set GIC-600 support +$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600)) +$(eval $(call add_define,GICV3_SUPPORT_GIC600)) + +# Set GICv4 extension +$(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN)) +$(eval $(call add_define,GIC_ENABLE_V4_EXTN)) + +# Set support for extended PPI and SPI range +$(eval $(call assert_boolean,GIC_EXT_INTID)) +$(eval $(call add_define,GIC_EXT_INTID)) diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 710532e3c..ff346f9df 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,263 +15,6 @@ #include "../common/gic_common_private.h" #include "gicv3_private.h" -/* - * Accessor to read the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. - */ -unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int n = id >> IGRPMODR_SHIFT; - - return mmio_read_32(base + GICD_IGRPMODR + (n << 2)); -} - -/* - * Accessor to write the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. - */ -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) -{ - unsigned int n = id >> IGRPMODR_SHIFT; - - mmio_write_32(base + GICD_IGRPMODR + (n << 2), val); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -void gicd_set_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - gicd_write_igrpmodr(base, id, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - gicd_write_igrpmodr(base, id, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to read the GIC Re-distributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); -} - -/* - * Accessor to write the GIC Re-distributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Re-distributor IGROUPR0. - */ -unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor IGROUPR0. - */ -void gicr_set_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Re-distributor IGROUPR0. - */ -void gicr_clr_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Re-distributor IGRPMODR0. - */ -unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor IGRPMODR0. - */ -void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Re-distributor IGRPMODR0. - */ -void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor ISENABLER0. - */ -void gicr_set_isenabler0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); - - gicr_write_isenabler0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ICENABLER0. - */ -void gicr_set_icenabler0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); - - gicr_write_icenabler0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ISACTIVER0. - */ -unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); - unsigned int reg_val = gicr_read_isactiver0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to clear the bit corresponding to interrupt ID in GIC Re-distributor - * ICPENDRR0. - */ -void gicr_set_icpendr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); - - gicr_write_icpendr0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ISPENDR0. - */ -void gicr_set_ispendr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); - - gicr_write_ispendr0(base, (1U << bit_num)); -} - -/* - * Accessor to set the byte corresponding to interrupt ID - * in GIC Re-distributor IPRIORITYR. - */ -void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) -{ - uint8_t val = pri & GIC_PRI_MASK; - - mmio_write_8(base + GICR_IPRIORITYR + id, val); -} - -/* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Re-distributor ICFGR0. - */ -void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) -{ - /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr0(base); - - /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr0(base, reg_val); -} - -/* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Re-distributor ICFGR1. - */ -void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) -{ - /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr1(base); - - /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr1(base, reg_val); -} - /****************************************************************************** * This function marks the core as awake in the re-distributor and * ensures that the interface is active. @@ -288,11 +31,10 @@ void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT); /* Wait till the WAKER_CA_BIT changes to 0 */ - while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U) - ; + while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U) { + } } - /****************************************************************************** * This function marks the core as asleep in the re-distributor and ensures * that the interface is quiescent. @@ -303,11 +45,10 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base) gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT); /* Wait till the WAKER_CA_BIT changes to 1 */ - while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U) - ; + while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U) { + } } - /******************************************************************************* * This function probes the Redistributor frames when the driver is initialised * and saves their base addresses. These base addresses are used later to @@ -342,47 +83,78 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, TYPER_PROC_NUM_MASK; } - if (proc_num < rdistif_num) + if (proc_num < rdistif_num) { rdistif_base_addrs[proc_num] = rdistif_base; + } rdistif_base += (1U << GICR_PCPUBASE_SHIFT); } while ((typer_val & TYPER_LAST_BIT) == 0U); } /******************************************************************************* - * Helper function to configure the default attributes of SPIs. + * Helper function to configure the default attributes of (E)SPIs. ******************************************************************************/ void gicv3_spis_config_defaults(uintptr_t gicd_base) { - unsigned int index, num_ints; + unsigned int i, num_ints; +#if GIC_EXT_INTID + unsigned int num_eints; +#endif + unsigned int typer_reg = gicd_read_typer(gicd_base); + + /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ + num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; + + /* Treat all (E)SPIs as G1NS by default. We do 32 at a time. */ + for (i = MIN_SPI_ID; i < num_ints; i += (1U << IGROUPR_SHIFT)) { + gicd_write_igroupr(gicd_base, i, ~0U); + } - num_ints = gicd_read_typer(gicd_base); - num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1U) << 5; +#if GIC_EXT_INTID + /* Check if extended SPI range is implemented */ + if ((typer_reg & TYPER_ESPI) != 0U) { + /* + * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 + */ + num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & + TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID - 1; - /* - * Treat all SPIs as G1NS by default. The number of interrupts is - * calculated as 32 * (IT_LINES + 1). We do 32 at a time. - */ - for (index = MIN_SPI_ID; index < num_ints; index += 32U) - gicd_write_igroupr(gicd_base, index, ~0U); + for (i = MIN_ESPI_ID; i < num_eints; + i += (1U << IGROUPR_SHIFT)) { + gicd_write_igroupr(gicd_base, i, ~0U); + } + } else { + num_eints = 0U; + } +#endif - /* Setup the default SPI priorities doing four at a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 4U) - gicd_write_ipriorityr(gicd_base, - index, - GICD_IPRIORITYR_DEF_VAL); + /* Setup the default (E)SPI priorities doing four at a time */ + for (i = MIN_SPI_ID; i < num_ints; i += (1U << IPRIORITYR_SHIFT)) { + gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL); + } +#if GIC_EXT_INTID + for (i = MIN_ESPI_ID; i < num_eints; + i += (1U << IPRIORITYR_SHIFT)) { + gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL); + } +#endif /* - * Treat all SPIs as level triggered by default, write 16 at - * a time + * Treat all (E)SPIs as level triggered by default, write 16 at a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 16U) - gicd_write_icfgr(gicd_base, index, 0U); + for (i = MIN_SPI_ID; i < num_ints; i += (1U << ICFGR_SHIFT)) { + gicd_write_icfgr(gicd_base, i, 0U); + } + +#if GIC_EXT_INTID + for (i = MIN_ESPI_ID; i < num_eints; i += (1U << ICFGR_SHIFT)) { + gicd_write_icfgr(gicd_base, i, 0U); + } +#endif } /******************************************************************************* - * Helper function to configure properties of secure SPIs + * Helper function to configure properties of secure (E)SPIs ******************************************************************************/ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, const interrupt_prop_t *interrupt_props, @@ -394,80 +166,108 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, unsigned int ctlr_enable = 0U; /* Make sure there's a valid property array */ - if (interrupt_props_num > 0U) + if (interrupt_props_num > 0U) { assert(interrupt_props != NULL); + } for (i = 0U; i < interrupt_props_num; i++) { current_prop = &interrupt_props[i]; - if (current_prop->intr_num < MIN_SPI_ID) + unsigned int intr_num = current_prop->intr_num; + + /* Skip SGI, (E)PPI and LPI interrupts */ + if (!IS_SPI(intr_num)) { continue; + } /* Configure this interrupt as a secure interrupt */ - gicd_clr_igroupr(gicd_base, current_prop->intr_num); + gicd_clr_igroupr(gicd_base, intr_num); /* Configure this interrupt as G0 or a G1S interrupt */ assert((current_prop->intr_grp == INTR_GROUP0) || (current_prop->intr_grp == INTR_GROUP1S)); + if (current_prop->intr_grp == INTR_GROUP1S) { - gicd_set_igrpmodr(gicd_base, current_prop->intr_num); + gicd_set_igrpmodr(gicd_base, intr_num); ctlr_enable |= CTLR_ENABLE_G1S_BIT; } else { - gicd_clr_igrpmodr(gicd_base, current_prop->intr_num); + gicd_clr_igrpmodr(gicd_base, intr_num); ctlr_enable |= CTLR_ENABLE_G0_BIT; } /* Set interrupt configuration */ - gicd_set_icfgr(gicd_base, current_prop->intr_num, - current_prop->intr_cfg); + gicd_set_icfgr(gicd_base, intr_num, current_prop->intr_cfg); /* Set the priority of this interrupt */ - gicd_set_ipriorityr(gicd_base, current_prop->intr_num, - current_prop->intr_pri); + gicd_set_ipriorityr(gicd_base, intr_num, + current_prop->intr_pri); - /* Target SPIs to the primary CPU */ + /* Target (E)SPIs to the primary CPU */ gic_affinity_val = gicd_irouter_val_from_mpidr(read_mpidr(), 0U); - gicd_write_irouter(gicd_base, current_prop->intr_num, - gic_affinity_val); + gicd_write_irouter(gicd_base, intr_num, + gic_affinity_val); /* Enable this interrupt */ - gicd_set_isenabler(gicd_base, current_prop->intr_num); + gicd_set_isenabler(gicd_base, intr_num); } return ctlr_enable; } /******************************************************************************* - * Helper function to configure the default attributes of SPIs. + * Helper function to configure the default attributes of (E)SPIs ******************************************************************************/ void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base) { - unsigned int index; - + unsigned int i, ppi_regs_num, regs_num; + +#if GIC_EXT_INTID + /* Calculate number of PPI registers */ + ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >> + TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1; + /* All other values except PPInum [0-2] are reserved */ + if (ppi_regs_num > 3U) { + ppi_regs_num = 1U; + } +#else + ppi_regs_num = 1U; +#endif /* - * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a - * more scalable approach as it avoids clearing the enable bits in the - * GICD_CTLR + * Disable all SGIs (imp. def.)/(E)PPIs before configuring them. + * This is a more scalable approach as it avoids clearing + * the enable bits in the GICD_CTLR. */ - gicr_write_icenabler0(gicr_base, ~0U); + for (i = 0U; i < ppi_regs_num; ++i) { + gicr_write_icenabler(gicr_base, i, ~0U); + } + + /* Wait for pending writes to GICR_ICENABLER */ gicr_wait_for_pending_write(gicr_base); - /* Treat all SGIs/PPIs as G1NS by default. */ - gicr_write_igroupr0(gicr_base, ~0U); + /* 32 interrupt IDs per GICR_IGROUPR register */ + for (i = 0U; i < ppi_regs_num; ++i) { + /* Treat all SGIs/(E)PPIs as G1NS by default */ + gicr_write_igroupr(gicr_base, i, ~0U); + } - /* Setup the default PPI/SGI priorities doing four at a time */ - for (index = 0U; index < MIN_SPI_ID; index += 4U) - gicr_write_ipriorityr(gicr_base, - index, - GICD_IPRIORITYR_DEF_VAL); + /* 4 interrupt IDs per GICR_IPRIORITYR register */ + regs_num = ppi_regs_num << 3; + for (i = 0U; i < regs_num; ++i) { + /* Setup the default (E)PPI/SGI priorities doing 4 at a time */ + gicr_write_ipriorityr(gicr_base, i, GICD_IPRIORITYR_DEF_VAL); + } - /* Configure all PPIs as level triggered by default */ - gicr_write_icfgr1(gicr_base, 0U); + /* 16 interrupt IDs per GICR_ICFGR register */ + regs_num = ppi_regs_num << 1; + for (i = (MIN_PPI_ID >> ICFGR_SHIFT); i < regs_num; ++i) { + /* Configure all (E)PPIs as level triggered by default */ + gicr_write_icfgr(gicr_base, i, 0U); + } } /******************************************************************************* - * Helper function to configure properties of secure G0 and G1S PPIs and SGIs. + * Helper function to configure properties of secure G0 and G1S (E)PPIs and SGIs ******************************************************************************/ unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, const interrupt_prop_t *interrupt_props, @@ -478,46 +278,81 @@ unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, unsigned int ctlr_enable = 0U; /* Make sure there's a valid property array */ - if (interrupt_props_num > 0U) + if (interrupt_props_num > 0U) { assert(interrupt_props != NULL); + } for (i = 0U; i < interrupt_props_num; i++) { current_prop = &interrupt_props[i]; - if (current_prop->intr_num >= MIN_SPI_ID) + unsigned int intr_num = current_prop->intr_num; + + /* Skip (E)SPI interrupt */ + if (!IS_SGI_PPI(intr_num)) { continue; + } /* Configure this interrupt as a secure interrupt */ - gicr_clr_igroupr0(gicr_base, current_prop->intr_num); + gicr_clr_igroupr(gicr_base, intr_num); /* Configure this interrupt as G0 or a G1S interrupt */ assert((current_prop->intr_grp == INTR_GROUP0) || - (current_prop->intr_grp == INTR_GROUP1S)); + (current_prop->intr_grp == INTR_GROUP1S)); + if (current_prop->intr_grp == INTR_GROUP1S) { - gicr_set_igrpmodr0(gicr_base, current_prop->intr_num); + gicr_set_igrpmodr(gicr_base, intr_num); ctlr_enable |= CTLR_ENABLE_G1S_BIT; } else { - gicr_clr_igrpmodr0(gicr_base, current_prop->intr_num); + gicr_clr_igrpmodr(gicr_base, intr_num); ctlr_enable |= CTLR_ENABLE_G0_BIT; } /* Set the priority of this interrupt */ - gicr_set_ipriorityr(gicr_base, current_prop->intr_num, - current_prop->intr_pri); + gicr_set_ipriorityr(gicr_base, intr_num, + current_prop->intr_pri); /* - * Set interrupt configuration for PPIs. Configuration for SGIs - * are ignored. + * Set interrupt configuration for (E)PPIs. + * Configurations for SGIs 0-15 are ignored. */ - if ((current_prop->intr_num >= MIN_PPI_ID) && - (current_prop->intr_num < MIN_SPI_ID)) { - gicr_set_icfgr1(gicr_base, current_prop->intr_num, + if (intr_num >= MIN_PPI_ID) { + gicr_set_icfgr(gicr_base, intr_num, current_prop->intr_cfg); } /* Enable this interrupt */ - gicr_set_isenabler0(gicr_base, current_prop->intr_num); + gicr_set_isenabler(gicr_base, intr_num); } return ctlr_enable; } + +/** + * gicv3_rdistif_get_number_frames() - determine size of GICv3 GICR region + * @gicr_frame: base address of the GICR region to check + * + * This iterates over the GICR_TYPER registers of multiple GICR frames in + * a GICR region, to find the instance which has the LAST bit set. For most + * systems this corresponds to the number of cores handled by a redistributor, + * but there could be disabled cores among them. + * It assumes that each GICR region is fully accessible (till the LAST bit + * marks the end of the region). + * If a platform has multiple GICR regions, this function would need to be + * called multiple times, providing the respective GICR base address each time. + * + * Return: number of valid GICR frames (at least 1, up to PLATFORM_CORE_COUNT) + ******************************************************************************/ +unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame) +{ + uintptr_t rdistif_base = gicr_frame; + unsigned int count; + + for (count = 1; count < PLATFORM_CORE_COUNT; count++) { + if ((gicr_read_typer(rdistif_base) & TYPER_LAST_BIT) != 0U) { + break; + } + rdistif_base += (1U << GICR_PCPUBASE_SHIFT); + } + + return count; +} diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index a672b18f3..22efd458d 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -31,26 +31,62 @@ static spinlock_t gic_lock; #pragma weak gicv3_rdistif_off #pragma weak gicv3_rdistif_on +/* Check interrupt ID for SGI/(E)PPI and (E)SPIs */ +static bool is_sgi_ppi(unsigned int id); + +/* + * Helper macros to save and restore GICR and GICD registers + * corresponding to their numbers to and from the context + */ +#define RESTORE_GICR_REG(base, ctx, name, i) \ + gicr_write_##name((base), (i), (ctx)->gicr_##name[(i)]) + +#define SAVE_GICR_REG(base, ctx, name, i) \ + (ctx)->gicr_##name[(i)] = gicr_read_##name((base), (i)) /* Helper macros to save and restore GICD registers to and from the context */ #define RESTORE_GICD_REGS(base, ctx, intr_num, reg, REG) \ do { \ - for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \ - int_id += (1U << REG##_SHIFT)) { \ - gicd_write_##reg(base, int_id, \ - ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT]); \ + for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + gicd_write_##reg((base), int_id, \ + (ctx)->gicd_##reg[(int_id - MIN_SPI_ID) >> \ + REG##R_SHIFT]); \ } \ } while (false) #define SAVE_GICD_REGS(base, ctx, intr_num, reg, REG) \ do { \ - for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \ - int_id += (1U << REG##_SHIFT)) { \ - ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT] =\ - gicd_read_##reg(base, int_id); \ + for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + (ctx)->gicd_##reg[(int_id - MIN_SPI_ID) >> \ + REG##R_SHIFT] = gicd_read_##reg((base), int_id); \ } \ } while (false) +#if GIC_EXT_INTID +#define RESTORE_GICD_EREGS(base, ctx, intr_num, reg, REG) \ + do { \ + for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + gicd_write_##reg((base), int_id, \ + (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - MIN_SPI_ID))\ + >> REG##R_SHIFT]); \ + } \ + } while (false) + +#define SAVE_GICD_EREGS(base, ctx, intr_num, reg, REG) \ + do { \ + for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\ + int_id += (1U << REG##R_SHIFT)) { \ + (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - MIN_SPI_ID))\ + >> REG##R_SHIFT] = gicd_read_##reg((base), int_id);\ + } \ + } while (false) +#else +#define SAVE_GICD_EREGS(base, ctx, intr_num, reg, REG) +#define RESTORE_GICD_EREGS(base, ctx, intr_num, reg, REG) +#endif /* GIC_EXT_INTID */ /******************************************************************************* * This function initialises the ARM GICv3 driver in EL3 with provided platform @@ -80,12 +116,20 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)) != 0U); #endif /* !__aarch64__ */ - /* The GIC version should be 3.0 */ gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); gic_version >>= PIDR2_ARCH_REV_SHIFT; gic_version &= PIDR2_ARCH_REV_MASK; - assert(gic_version == ARCH_REV_GICV3); + /* Check GIC version */ +#if GIC_ENABLE_V4_EXTN + assert(gic_version == ARCH_REV_GICV4); + + /* GICv4 supports Direct Virtual LPI injection */ + assert((gicd_read_typer(plat_driver_data->gicd_base) + & TYPER_DVIS) != 0); +#else + assert(gic_version == ARCH_REV_GICV3); +#endif /* * Find out whether the GIC supports the GICv2 compatibility mode. * The ARE_S bit resets to 0 if supported @@ -129,11 +173,9 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) flush_dcache_range((uintptr_t)gicv3_driver_data, sizeof(*gicv3_driver_data)); #endif - - INFO("GICv3 with%s legacy support detected." - " ARM GICv3 driver initialized in EL3\n", - (gicv2_compat == 0U) ? "" : "out"); - + INFO("GICv%u with%s legacy support detected.\n", gic_version, + (gicv2_compat == 0U) ? "" : "out"); + INFO("ARM GICv%u driver initialized in EL3\n", gic_version); } /******************************************************************************* @@ -142,7 +184,7 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) ******************************************************************************/ void __init gicv3_distif_init(void) { - unsigned int bitmap = 0; + unsigned int bitmap; assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); @@ -164,7 +206,7 @@ void __init gicv3_distif_init(void) gicd_set_ctlr(gicv3_driver_data->gicd_base, CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE); - /* Set the default attribute of all SPIs */ + /* Set the default attribute of all (E)SPIs */ gicv3_spis_config_defaults(gicv3_driver_data->gicd_base); bitmap = gicv3_secure_spis_config_props( @@ -172,7 +214,7 @@ void __init gicv3_distif_init(void) gicv3_driver_data->interrupt_props, gicv3_driver_data->interrupt_props_num); - /* Enable the secure SPIs now that they have been configured */ + /* Enable the secure (E)SPIs now that they have been configured */ gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE); } @@ -184,7 +226,7 @@ void __init gicv3_distif_init(void) void gicv3_rdistif_init(unsigned int proc_num) { uintptr_t gicr_base; - unsigned int bitmap = 0U; + unsigned int bitmap; uint32_t ctlr; assert(gicv3_driver_data != NULL); @@ -203,7 +245,7 @@ void gicv3_rdistif_init(unsigned int proc_num) gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; assert(gicr_base != 0U); - /* Set the default attribute of all SGIs and PPIs */ + /* Set the default attribute of all SGIs and (E)PPIs */ gicv3_ppi_sgi_config_defaults(gicr_base); bitmap = gicv3_secure_ppi_sgi_config_props(gicr_base, @@ -211,8 +253,9 @@ void gicv3_rdistif_init(unsigned int proc_num) gicv3_driver_data->interrupt_props_num); /* Enable interrupt groups as required, if not already */ - if ((ctlr & bitmap) != bitmap) + if ((ctlr & bitmap) != bitmap) { gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE); + } } /******************************************************************************* @@ -220,12 +263,10 @@ void gicv3_rdistif_init(unsigned int proc_num) ******************************************************************************/ void gicv3_rdistif_off(unsigned int proc_num) { - return; } void gicv3_rdistif_on(unsigned int proc_num) { - return; } /******************************************************************************* @@ -342,8 +383,9 @@ unsigned int gicv3_get_pending_interrupt_id(void) * If the ID is special identifier corresponding to G1S or G1NS * interrupt, then read the highest pending group 1 interrupt. */ - if ((id == PENDING_G1S_INTID) || (id == PENDING_G1NS_INTID)) + if ((id == PENDING_G1S_INTID) || (id == PENDING_G1NS_INTID)) { return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK; + } return id; } @@ -373,8 +415,7 @@ unsigned int gicv3_get_pending_interrupt_type(void) * INTR_GROUP1NS: The interrupt type is a Secure Group 1 non secure * interrupt. ******************************************************************************/ -unsigned int gicv3_get_interrupt_type(unsigned int id, - unsigned int proc_num) +unsigned int gicv3_get_interrupt_type(unsigned int id, unsigned int proc_num) { unsigned int igroup, grpmodr; uintptr_t gicr_base; @@ -387,15 +428,19 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, assert(proc_num < gicv3_driver_data->rdistif_num); /* All LPI interrupts are Group 1 non secure */ - if (id >= MIN_LPI_ID) + if (id >= MIN_LPI_ID) { return INTR_GROUP1NS; + } - if (id < MIN_SPI_ID) { + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */ assert(gicv3_driver_data->rdistif_base_addrs != NULL); gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - igroup = gicr_get_igroupr0(gicr_base, id); - grpmodr = gicr_get_igrpmodr0(gicr_base, id); + igroup = gicr_get_igroupr(gicr_base, id); + grpmodr = gicr_get_igrpmodr(gicr_base, id); } else { + /* SPIs: 32-1019, ESPIs: 4096-5119 */ assert(gicv3_driver_data->gicd_base != 0U); igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id); grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id); @@ -405,12 +450,14 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, * If the IGROUP bit is set, then it is a Group 1 Non secure * interrupt */ - if (igroup != 0U) + if (igroup != 0U) { return INTR_GROUP1NS; + } /* If the GRPMOD bit is set, then it is a Group 1 Secure interrupt */ - if (grpmodr != 0U) + if (grpmodr != 0U) { return INTR_GROUP1S; + } /* Else it is a Group 0 Secure interrupt */ return INTR_GROUP0; @@ -427,7 +474,8 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, * * This function must be invoked after the GIC CPU interface is disabled. *****************************************************************************/ -void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx) +void gicv3_its_save_disable(uintptr_t gits_base, + gicv3_its_ctx_t * const its_ctx) { unsigned int i; @@ -439,8 +487,7 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx its_ctx->gits_ctlr = gits_read_ctlr(gits_base); /* Disable the ITS */ - gits_write_ctlr(gits_base, its_ctx->gits_ctlr & - (~GITS_CTLR_ENABLED_BIT)); + gits_write_ctlr(gits_base, its_ctx->gits_ctlr & ~GITS_CTLR_ENABLED_BIT); /* Wait for quiescent state */ gits_wait_for_quiescent_bit(gits_base); @@ -448,8 +495,9 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx its_ctx->gits_cbaser = gits_read_cbaser(gits_base); its_ctx->gits_cwriter = gits_read_cwriter(gits_base); - for (i = 0; i < ARRAY_SIZE(its_ctx->gits_baser); i++) + for (i = 0U; i < ARRAY_SIZE(its_ctx->gits_baser); i++) { its_ctx->gits_baser[i] = gits_read_baser(gits_base, i); + } } /***************************************************************************** @@ -460,7 +508,8 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx * * This must be invoked before the GIC CPU interface is enabled. *****************************************************************************/ -void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx) +void gicv3_its_restore(uintptr_t gits_base, + const gicv3_its_ctx_t * const its_ctx) { unsigned int i; @@ -476,22 +525,23 @@ void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ct gits_write_cbaser(gits_base, its_ctx->gits_cbaser); gits_write_cwriter(gits_base, its_ctx->gits_cwriter); - for (i = 0; i < ARRAY_SIZE(its_ctx->gits_baser); i++) + for (i = 0U; i < ARRAY_SIZE(its_ctx->gits_baser); i++) { gits_write_baser(gits_base, i, its_ctx->gits_baser[i]); + } /* Restore the ITS CTLR but leave the ITS disabled */ - gits_write_ctlr(gits_base, its_ctx->gits_ctlr & - (~GITS_CTLR_ENABLED_BIT)); + gits_write_ctlr(gits_base, its_ctx->gits_ctlr & ~GITS_CTLR_ENABLED_BIT); } /***************************************************************************** * Function to save the GIC Redistributor register context. This function * must be invoked after CPU interface disable and prior to Distributor save. *****************************************************************************/ -void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ctx) +void gicv3_rdistif_save(unsigned int proc_num, + gicv3_redist_ctx_t * const rdist_ctx) { uintptr_t gicr_base; - unsigned int int_id; + unsigned int i, ppi_regs_num, regs_num; assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); @@ -501,6 +551,17 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; +#if GIC_EXT_INTID + /* Calculate number of PPI registers */ + ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >> + TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1; + /* All other values except PPInum [0-2] are reserved */ + if (ppi_regs_num > 3U) { + ppi_regs_num = 1U; + } +#else + ppi_regs_num = 1U; +#endif /* * Wait for any write to GICR_CTLR to complete before trying to save any * state. @@ -512,20 +573,29 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ rdist_ctx->gicr_propbaser = gicr_read_propbaser(gicr_base); rdist_ctx->gicr_pendbaser = gicr_read_pendbaser(gicr_base); - rdist_ctx->gicr_igroupr0 = gicr_read_igroupr0(gicr_base); - rdist_ctx->gicr_isenabler0 = gicr_read_isenabler0(gicr_base); - rdist_ctx->gicr_ispendr0 = gicr_read_ispendr0(gicr_base); - rdist_ctx->gicr_isactiver0 = gicr_read_isactiver0(gicr_base); - rdist_ctx->gicr_icfgr0 = gicr_read_icfgr0(gicr_base); - rdist_ctx->gicr_icfgr1 = gicr_read_icfgr1(gicr_base); - rdist_ctx->gicr_igrpmodr0 = gicr_read_igrpmodr0(gicr_base); - rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base); - for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM; - int_id += (1U << IPRIORITYR_SHIFT)) { - rdist_ctx->gicr_ipriorityr[(int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT] = - gicr_read_ipriorityr(gicr_base, int_id); + /* 32 interrupt IDs per register */ + for (i = 0U; i < ppi_regs_num; ++i) { + SAVE_GICR_REG(gicr_base, rdist_ctx, igroupr, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, isenabler, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, ispendr, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, isactiver, i); + SAVE_GICR_REG(gicr_base, rdist_ctx, igrpmodr, i); } + /* 16 interrupt IDs per GICR_ICFGR register */ + regs_num = ppi_regs_num << 1; + for (i = 0U; i < regs_num; ++i) { + SAVE_GICR_REG(gicr_base, rdist_ctx, icfgr, i); + } + + rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base); + + /* 4 interrupt IDs per GICR_IPRIORITYR register */ + regs_num = ppi_regs_num << 3; + for (i = 0U; i < regs_num; ++i) { + rdist_ctx->gicr_ipriorityr[i] = + gicr_ipriorityr_read(gicr_base, i); + } /* * Call the pre-save hook that implements the IMP DEF sequence that may @@ -546,7 +616,7 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, const gicv3_redist_ctx_t * const rdist_ctx) { uintptr_t gicr_base; - unsigned int int_id; + unsigned int i, ppi_regs_num, regs_num; assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); @@ -556,6 +626,17 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; +#if GIC_EXT_INTID + /* Calculate number of PPI registers */ + ppi_regs_num = (unsigned int)((gicr_read_typer(gicr_base) >> + TYPER_PPI_NUM_SHIFT) & TYPER_PPI_NUM_MASK) + 1; + /* All other values except PPInum [0-2] are reserved */ + if (ppi_regs_num > 3U) { + ppi_regs_num = 1U; + } +#else + ppi_regs_num = 1U; +#endif /* Power on redistributor */ gicv3_rdistif_on(proc_num); @@ -567,11 +648,14 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, gicv3_distif_post_restore(proc_num); /* - * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a - * more scalable approach as it avoids clearing the enable bits in the - * GICD_CTLR + * Disable all SGIs (imp. def.)/(E)PPIs before configuring them. + * This is a more scalable approach as it avoids clearing the enable + * bits in the GICD_CTLR. */ - gicr_write_icenabler0(gicr_base, ~0U); + for (i = 0U; i < ppi_regs_num; ++i) { + gicr_write_icenabler(gicr_base, i, ~0U); + } + /* Wait for pending writes to GICR_ICENABLER */ gicr_wait_for_pending_write(gicr_base); @@ -586,30 +670,45 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, gicr_write_propbaser(gicr_base, rdist_ctx->gicr_propbaser); gicr_write_pendbaser(gicr_base, rdist_ctx->gicr_pendbaser); - gicr_write_igroupr0(gicr_base, rdist_ctx->gicr_igroupr0); + /* 32 interrupt IDs per register */ + for (i = 0U; i < ppi_regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, igroupr, i); + RESTORE_GICR_REG(gicr_base, rdist_ctx, igrpmodr, i); + } + + /* 4 interrupt IDs per GICR_IPRIORITYR register */ + regs_num = ppi_regs_num << 3; + for (i = 0U; i < regs_num; ++i) { + gicr_ipriorityr_write(gicr_base, i, + rdist_ctx->gicr_ipriorityr[i]); + } - for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM; - int_id += (1U << IPRIORITYR_SHIFT)) { - gicr_write_ipriorityr(gicr_base, int_id, - rdist_ctx->gicr_ipriorityr[ - (int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT]); + /* 16 interrupt IDs per GICR_ICFGR register */ + regs_num = ppi_regs_num << 1; + for (i = 0U; i < regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, icfgr, i); } - gicr_write_icfgr0(gicr_base, rdist_ctx->gicr_icfgr0); - gicr_write_icfgr1(gicr_base, rdist_ctx->gicr_icfgr1); - gicr_write_igrpmodr0(gicr_base, rdist_ctx->gicr_igrpmodr0); gicr_write_nsacr(gicr_base, rdist_ctx->gicr_nsacr); - /* Restore after group and priorities are set */ - gicr_write_ispendr0(gicr_base, rdist_ctx->gicr_ispendr0); - gicr_write_isactiver0(gicr_base, rdist_ctx->gicr_isactiver0); + /* Restore after group and priorities are set. + * 32 interrupt IDs per register + */ + for (i = 0U; i < ppi_regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, ispendr, i); + RESTORE_GICR_REG(gicr_base, rdist_ctx, isactiver, i); + } /* * Wait for all writes to the Distributor to complete before enabling - * the SGI and PPIs. + * the SGI and (E)PPIs. */ gicr_wait_for_upstream_pending_write(gicr_base); - gicr_write_isenabler0(gicr_base, rdist_ctx->gicr_isenabler0); + + /* 32 interrupt IDs per GICR_ISENABLER register */ + for (i = 0U; i < ppi_regs_num; ++i) { + RESTORE_GICR_REG(gicr_base, rdist_ctx, isenabler, i); + } /* * Restore GICR_CTLR.Enable_LPIs bit and wait for pending writes in case @@ -627,7 +726,10 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, *****************************************************************************/ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) { - unsigned int num_ints; + unsigned int typer_reg, num_ints; +#if GIC_EXT_INTID + unsigned int num_eints; +#endif assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); @@ -636,14 +738,28 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) uintptr_t gicd_base = gicv3_driver_data->gicd_base; - num_ints = gicd_read_typer(gicd_base); - num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1U) << 5; + typer_reg = gicd_read_typer(gicd_base); + + /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ + num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; /* Filter out special INTIDs 1020-1023 */ - if (num_ints > (MAX_SPI_ID + 1U)) + if (num_ints > (MAX_SPI_ID + 1U)) { num_ints = MAX_SPI_ID + 1U; + } +#if GIC_EXT_INTID + /* Check if extended SPI range is implemented */ + if ((typer_reg & TYPER_ESPI) != 0U) { + /* + * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 + */ + num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & + TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID - 1; + } else { + num_eints = 0U; + } +#endif /* Wait for pending write to complete */ gicd_wait_for_pending_write(gicd_base); @@ -651,31 +767,58 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) dist_ctx->gicd_ctlr = gicd_read_ctlr(gicd_base); /* Save GICD_IGROUPR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUP); + + /* Save GICD_IGROUPRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igroupr, IGROUP); /* Save GICD_ISENABLER for INT_IDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLER); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLE); + + /* Save GICD_ISENABLERE for INT_IDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isenabler, ISENABLE); /* Save GICD_ISPENDR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPENDR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPEND); + + /* Save GICD_ISPENDRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ispendr, ISPEND); /* Save GICD_ISACTIVER for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVER); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVE); + + /* Save GICD_ISACTIVERE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isactiver, ISACTIVE); /* Save GICD_IPRIORITYR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITYR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITY); + + /* Save GICD_IPRIORITYRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ipriorityr, IPRIORITY); /* Save GICD_ICFGR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFGR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFG); + + /* Save GICD_ICFGRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, icfgr, ICFG); /* Save GICD_IGRPMODR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMODR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMOD); + + /* Save GICD_IGRPMODRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igrpmodr, IGRPMOD); /* Save GICD_NSACR for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSACR); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSAC); + + /* Save GICD_NSACRE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, nsacr, NSAC); /* Save GICD_IROUTER for INTIDs 32 - 1019 */ - SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTER); + SAVE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTE); + + /* Save GICD_IROUTERE for INTIDs 4096 - 5119 */ + SAVE_GICD_EREGS(gicd_base, dist_ctx, num_eints, irouter, IROUTE); /* * GICD_ITARGETSR<n> and GICD_SPENDSGIR<n> are RAZ/WI when @@ -693,7 +836,10 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) *****************************************************************************/ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) { - unsigned int num_ints = 0U; + unsigned int typer_reg, num_ints; +#if GIC_EXT_INTID + unsigned int num_eints; +#endif assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); @@ -716,50 +862,90 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) /* Set the ARE_S and ARE_NS bit now that interrupts have been disabled */ gicd_set_ctlr(gicd_base, CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE); - num_ints = gicd_read_typer(gicd_base); - num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1U) << 5; + typer_reg = gicd_read_typer(gicd_base); + + /* Maximum SPI INTID is 32 * (GICD_TYPER.ITLinesNumber + 1) - 1 */ + num_ints = ((typer_reg & TYPER_IT_LINES_NO_MASK) + 1U) << 5; /* Filter out special INTIDs 1020-1023 */ - if (num_ints > (MAX_SPI_ID + 1U)) + if (num_ints > (MAX_SPI_ID + 1U)) { num_ints = MAX_SPI_ID + 1U; + } +#if GIC_EXT_INTID + /* Check if extended SPI range is implemented */ + if ((typer_reg & TYPER_ESPI) != 0U) { + /* + * Maximum ESPI INTID is 32 * (GICD_TYPER.ESPI_range + 1) + 4095 + */ + num_eints = ((((typer_reg >> TYPER_ESPI_RANGE_SHIFT) & + TYPER_ESPI_RANGE_MASK) + 1U) << 5) + MIN_ESPI_ID - 1; + } else { + num_eints = 0U; + } +#endif /* Restore GICD_IGROUPR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUP); + + /* Restore GICD_IGROUPRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igroupr, IGROUP); /* Restore GICD_IPRIORITYR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITYR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ipriorityr, IPRIORITY); + + /* Restore GICD_IPRIORITYRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ipriorityr, IPRIORITY); /* Restore GICD_ICFGR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFGR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, icfgr, ICFG); + + /* Restore GICD_ICFGRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, icfgr, ICFG); /* Restore GICD_IGRPMODR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMODR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igrpmodr, IGRPMOD); + + /* Restore GICD_IGRPMODRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, igrpmodr, IGRPMOD); /* Restore GICD_NSACR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSACR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, nsacr, NSAC); + + /* Restore GICD_NSACRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, nsacr, NSAC); /* Restore GICD_IROUTER for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTER); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, irouter, IROUTE); + + /* Restore GICD_IROUTERE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, irouter, IROUTE); /* - * Restore ISENABLER, ISPENDR and ISACTIVER after the interrupts are - * configured. + * Restore ISENABLER(E), ISPENDR(E) and ISACTIVER(E) after + * the interrupts are configured. */ /* Restore GICD_ISENABLER for INT_IDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLER); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isenabler, ISENABLE); + + /* Restore GICD_ISENABLERE for INT_IDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isenabler, ISENABLE); /* Restore GICD_ISPENDR for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPENDR); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, ispendr, ISPEND); + + /* Restore GICD_ISPENDRE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, ispendr, ISPEND); /* Restore GICD_ISACTIVER for INTIDs 32 - 1019 */ - RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVER); + RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, isactiver, ISACTIVE); + + /* Restore GICD_ISACTIVERE for INTIDs 4096 - 5119 */ + RESTORE_GICD_EREGS(gicd_base, dist_ctx, num_eints, isactiver, ISACTIVE); /* Restore the GICD_CTLR */ gicd_write_ctlr(gicd_base, dist_ctx->gicd_ctlr); gicd_wait_for_pending_write(gicd_base); - } /******************************************************************************* @@ -774,28 +960,25 @@ unsigned int gicv3_get_running_priority(void) /******************************************************************************* * This function checks if the interrupt identified by id is active (whether the * state is either active, or active and pending). The proc_num is used if the - * interrupt is SGI or PPI and programs the corresponding Redistributor + * interrupt is SGI or (E)PPI and programs the corresponding Redistributor * interface. ******************************************************************************/ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num) { - unsigned int value; - assert(gicv3_driver_data != NULL); assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - value = gicr_get_isactiver0( - gicv3_driver_data->rdistif_base_addrs[proc_num], id); - } else { - value = gicd_get_isactiver(gicv3_driver_data->gicd_base, id); + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + return gicr_get_isactiver( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } - return value; + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ + return gicd_get_isactiver(gicv3_driver_data->gicd_base, id); } /******************************************************************************* @@ -809,19 +992,20 @@ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num) assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); /* * Ensure that any shared variable updates depending on out of band * interrupt trigger are observed before enabling interrupt. */ dsbishst(); - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_isenabler0( - gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_isenabler( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_isenabler(gicv3_driver_data->gicd_base, id); } } @@ -837,22 +1021,23 @@ void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num) assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); /* * Disable interrupt, and ensure that any shared variable updates * depending on out of band interrupt trigger are observed afterwards. */ - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_icenabler0( - gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_icenabler( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); /* Write to clear enable requires waiting for pending writes */ gicr_wait_for_pending_write( - gicv3_driver_data->rdistif_base_addrs[proc_num]); + gicv3_driver_data->rdistif_base_addrs[proc_num]); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_icenabler(gicv3_driver_data->gicd_base, id); /* Write to clear enable requires waiting for pending writes */ @@ -875,19 +1060,21 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs != NULL); - assert(id <= MAX_SPI_ID); - if (id < MIN_SPI_ID) { + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; gicr_set_ipriorityr(gicr_base, id, priority); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_ipriorityr(gicv3_driver_data->gicd_base, id, priority); } } /******************************************************************************* * This function assigns group for the interrupt identified by id. The proc_num - * is used if the interrupt is SGI or PPI, and programs the corresponding + * is used if the interrupt is SGI or (E)PPI, and programs the corresponding * Redistributor interface. The group can be any of GICV3_INTR_GROUP* ******************************************************************************/ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, @@ -919,29 +1106,26 @@ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, break; } - if (id < MIN_SPI_ID) { + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; - if (igroup) - gicr_set_igroupr0(gicr_base, id); - else - gicr_clr_igroupr0(gicr_base, id); - - if (grpmod) - gicr_set_igrpmodr0(gicr_base, id); - else - gicr_clr_igrpmodr0(gicr_base, id); + + igroup ? gicr_set_igroupr(gicr_base, id) : + gicr_clr_igroupr(gicr_base, id); + grpmod ? gicr_set_igrpmodr(gicr_base, id) : + gicr_clr_igrpmodr(gicr_base, id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ + /* Serialize read-modify-write to Distributor registers */ spin_lock(&gic_lock); - if (igroup) - gicd_set_igroupr(gicv3_driver_data->gicd_base, id); - else - gicd_clr_igroupr(gicv3_driver_data->gicd_base, id); - - if (grpmod) - gicd_set_igrpmodr(gicv3_driver_data->gicd_base, id); - else - gicd_clr_igrpmodr(gicv3_driver_data->gicd_base, id); + + igroup ? gicd_set_igroupr(gicv3_driver_data->gicd_base, id) : + gicd_clr_igroupr(gicv3_driver_data->gicd_base, id); + grpmod ? gicd_set_igrpmodr(gicv3_driver_data->gicd_base, id) : + gicd_clr_igrpmodr(gicv3_driver_data->gicd_base, id); + spin_unlock(&gic_lock); } } @@ -986,7 +1170,7 @@ void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target) } /******************************************************************************* - * This function sets the interrupt routing for the given SPI interrupt id. + * This function sets the interrupt routing for the given (E)SPI interrupt id. * The interrupt routing is specified in routing mode and mpidr. * * The routing mode can be either of: @@ -1005,7 +1189,8 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr assert(gicv3_driver_data->gicd_base != 0U); assert((irm == GICV3_IRM_ANY) || (irm == GICV3_IRM_PE)); - assert((id >= MIN_SPI_ID) && (id <= MAX_SPI_ID)); + + assert(IS_SPI(id)); aff = gicd_irouter_val_from_mpidr(mpidr, irm); gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff); @@ -1025,7 +1210,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr /******************************************************************************* * This function clears the pending status of an interrupt identified by id. - * The proc_num is used if the interrupt is SGI or PPI, and programs the + * The proc_num is used if the interrupt is SGI or (E)PPI, and programs the * corresponding Redistributor interface. ******************************************************************************/ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num) @@ -1039,13 +1224,17 @@ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num) * Clear pending interrupt, and ensure that any shared variable updates * depending on out of band interrupt trigger are observed afterwards. */ - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_icpendr0(gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_icpendr( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_icpendr(gicv3_driver_data->gicd_base, id); } + dsbishst(); } @@ -1066,11 +1255,14 @@ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num) * interrupt trigger are observed before setting interrupt pending. */ dsbishst(); - if (id < MIN_SPI_ID) { - /* For SGIs and PPIs */ - gicr_set_ispendr0(gicv3_driver_data->rdistif_base_addrs[proc_num], - id); + + /* Check interrupt ID */ + if (is_sgi_ppi(id)) { + /* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */ + gicr_set_ispendr( + gicv3_driver_data->rdistif_base_addrs[proc_num], id); } else { + /* For SPIs: 32-1019 and ESPIs: 4096-5119 */ gicd_set_ispendr(gicv3_driver_data->gicd_base, id); } } @@ -1083,7 +1275,7 @@ unsigned int gicv3_set_pmr(unsigned int mask) { unsigned int old_mask; - old_mask = (uint32_t) read_icc_pmr_el1(); + old_mask = (unsigned int)read_icc_pmr_el1(); /* * Order memory updates w.r.t. PMR write, and ensure they're visible @@ -1130,15 +1322,17 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) mpidr = mpidr_from_gicr_typer(typer_val); proc_num = gicv3_driver_data->mpidr_to_core_pos(mpidr); } else { - proc_num = (unsigned int)(typer_val >> TYPER_PROC_NUM_SHIFT) & - TYPER_PROC_NUM_MASK; + proc_num = (unsigned int)(typer_val >> + TYPER_PROC_NUM_SHIFT) & TYPER_PROC_NUM_MASK; } if (proc_num == proc_self) { /* The base address doesn't need to be initialized on * every warm boot. */ - if (gicv3_driver_data->rdistif_base_addrs[proc_num] != 0U) + if (gicv3_driver_data->rdistif_base_addrs[proc_num] + != 0U) { return 0; + } gicv3_driver_data->rdistif_base_addrs[proc_num] = rdistif_base; gicr_frame_found = true; @@ -1147,8 +1341,9 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) rdistif_base += (uintptr_t)(ULL(1) << GICR_PCPUBASE_SHIFT); } while ((typer_val & TYPER_LAST_BIT) == 0U); - if (!gicr_frame_found) + if (!gicr_frame_found) { return -1; + } /* * Flush the driver data to ensure coherency. This is @@ -1164,3 +1359,23 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) #endif return 0; /* Found matching GICR frame */ } + +/****************************************************************************** + * This function checks the interrupt ID and returns true for SGIs and (E)PPIs + * and false for (E)SPIs IDs. + *****************************************************************************/ +static bool is_sgi_ppi(unsigned int id) +{ + /* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */ + if (IS_SGI_PPI(id)) { + return true; + } + + /* SPIs: 32-1019, ESPIs: 4096-5119 */ + if (IS_SPI(id)) { + return false; + } + + assert(false); + panic(); +} diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 327a9a149..c5d027da2 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,6 +24,144 @@ #define RWP_TRUE U(1) #define RWP_FALSE U(0) +/* Calculate GIC register bit number corresponding to its interrupt ID */ +#define BIT_NUM(REG, id) \ + ((id) & ((1U << REG##R_SHIFT) - 1U)) + +/* + * Calculate 8, 32 and 64-bit GICD register offset + * corresponding to its interrupt ID + */ +#if GIC_EXT_INTID + /* GICv3.1 */ +#define GICD_OFFSET_8(REG, id) \ + (((id) <= MAX_SPI_ID) ? \ + GICD_##REG##R + (uintptr_t)(id) : \ + GICD_##REG##RE + (uintptr_t)(id) - MIN_ESPI_ID) + +#define GICD_OFFSET(REG, id) \ + (((id) <= MAX_SPI_ID) ? \ + GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \ + GICD_##REG##RE + ((((uintptr_t)(id) - MIN_ESPI_ID) >> \ + REG##R_SHIFT) << 2)) + +#define GICD_OFFSET_64(REG, id) \ + (((id) <= MAX_SPI_ID) ? \ + GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3) : \ + GICD_##REG##RE + (((uintptr_t)(id) - MIN_ESPI_ID) << 3)) + +#else /* GICv3 */ +#define GICD_OFFSET_8(REG, id) \ + (GICD_##REG##R + (uintptr_t)(id)) + +#define GICD_OFFSET(REG, id) \ + (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2)) + +#define GICD_OFFSET_64(REG, id) \ + (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3)) +#endif /* GIC_EXT_INTID */ + +/* + * Read/Write 8, 32 and 64-bit GIC Distributor register + * corresponding to its interrupt ID + */ +#define GICD_READ(REG, base, id) \ + mmio_read_32((base) + GICD_OFFSET(REG, (id))) + +#define GICD_READ_64(REG, base, id) \ + mmio_read_64((base) + GICD_OFFSET_64(REG, (id))) + +#define GICD_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val)) + +#define GICD_WRITE(REG, base, id, val) \ + mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val)) + +#define GICD_WRITE_64(REG, base, id, val) \ + mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val)) + +/* + * Bit operations on GIC Distributor register corresponding + * to its interrupt ID + */ +/* Get bit in GIC Distributor register */ +#define GICD_GET_BIT(REG, base, id) \ + ((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >> \ + BIT_NUM(REG, (id))) & 1U) + +/* Set bit in GIC Distributor register */ +#define GICD_SET_BIT(REG, base, id) \ + mmio_setbits_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Clear bit in GIC Distributor register */ +#define GICD_CLR_BIT(REG, base, id) \ + mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Write bit in GIC Distributor register */ +#define GICD_WRITE_BIT(REG, base, id) \ + mmio_write_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* + * Calculate 8 and 32-bit GICR register offset + * corresponding to its interrupt ID + */ +#if GIC_EXT_INTID + /* GICv3.1 */ +#define GICR_OFFSET_8(REG, id) \ + (((id) <= MAX_PPI_ID) ? \ + GICR_##REG##R + (uintptr_t)(id) : \ + GICR_##REG##R + (uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID)) + +#define GICR_OFFSET(REG, id) \ + (((id) <= MAX_PPI_ID) ? \ + GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \ + GICR_##REG##R + ((((uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID))\ + >> REG##R_SHIFT) << 2)) +#else /* GICv3 */ +#define GICR_OFFSET_8(REG, id) \ + (GICR_##REG##R + (uintptr_t)(id)) + +#define GICR_OFFSET(REG, id) \ + (GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2)) +#endif /* GIC_EXT_INTID */ + +/* Read/Write GIC Redistributor register corresponding to its interrupt ID */ +#define GICR_READ(REG, base, id) \ + mmio_read_32((base) + GICR_OFFSET(REG, (id))) + +#define GICR_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICR_OFFSET_8(REG, (id)), (val)) + +#define GICR_WRITE(REG, base, id, val) \ + mmio_write_32((base) + GICR_OFFSET(REG, (id)), (val)) + +/* + * Bit operations on GIC Redistributor register + * corresponding to its interrupt ID + */ +/* Get bit in GIC Redistributor register */ +#define GICR_GET_BIT(REG, base, id) \ + ((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >> \ + BIT_NUM(REG, (id))) & 1U) + +/* Write bit in GIC Redistributor register */ +#define GICR_WRITE_BIT(REG, base, id) \ + mmio_write_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Set bit in GIC Redistributor register */ +#define GICR_SET_BIT(REG, base, id) \ + mmio_setbits_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Clear bit in GIC Redistributor register */ +#define GICR_CLR_BIT(REG, base, id) \ + mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + /* * Macro to convert an mpidr to a value suitable for programming into a * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant @@ -75,22 +213,21 @@ void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); * the bit-field corresponding the single interrupt ID. ******************************************************************************/ unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id); -unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id); -unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id); -unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id); +unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id); +unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id); +unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id); void gicd_set_igrpmodr(uintptr_t base, unsigned int id); -void gicr_set_igrpmodr0(uintptr_t base, unsigned int id); -void gicr_set_isenabler0(uintptr_t base, unsigned int id); -void gicr_set_icenabler0(uintptr_t base, unsigned int id); -void gicr_set_ispendr0(uintptr_t base, unsigned int id); -void gicr_set_icpendr0(uintptr_t base, unsigned int id); -void gicr_set_igroupr0(uintptr_t base, unsigned int id); +void gicr_set_igrpmodr(uintptr_t base, unsigned int id); +void gicr_set_isenabler(uintptr_t base, unsigned int id); +void gicr_set_icenabler(uintptr_t base, unsigned int id); +void gicr_set_ispendr(uintptr_t base, unsigned int id); +void gicr_set_icpendr(uintptr_t base, unsigned int id); +void gicr_set_igroupr(uintptr_t base, unsigned int id); void gicd_clr_igrpmodr(uintptr_t base, unsigned int id); -void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id); -void gicr_clr_igroupr0(uintptr_t base, unsigned int id); +void gicr_clr_igrpmodr(uintptr_t base, unsigned int id); +void gicr_clr_igroupr(uintptr_t base, unsigned int id); void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri); -void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg); -void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg); +void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg); /******************************************************************************* * Private GICv3 helper function prototypes @@ -114,34 +251,34 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); * GIC Distributor interface accessors ******************************************************************************/ /* - * Wait for updates to : + * Wait for updates to: * GICD_CTLR[2:0] - the Group Enables - * GICD_CTLR[5:4] - the ARE bits - * GICD_ICENABLERn - the clearing of enable state for SPIs + * GICD_CTLR[7:4] - the ARE bits, E1NWF bit and DS bit + * GICD_ICENABLER<n> - the clearing of enable state for SPIs */ static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) { - while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) - ; + while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) { + } } -static inline unsigned int gicd_read_pidr2(uintptr_t base) +static inline uint32_t gicd_read_pidr2(uintptr_t base) { return mmio_read_32(base + GICD_PIDR2_GICV3); } -static inline unsigned long long gicd_read_irouter(uintptr_t base, unsigned int id) +static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id) { assert(id >= MIN_SPI_ID); - return mmio_read_64(base + GICD_IROUTER + (id << 3)); + return GICD_READ_64(IROUTE, base, id); } static inline void gicd_write_irouter(uintptr_t base, unsigned int id, - unsigned long long affinity) + uint64_t affinity) { assert(id >= MIN_SPI_ID); - mmio_write_64(base + GICD_IROUTER + (id << 3), affinity); + GICD_WRITE_64(IROUTE, base, id, affinity); } static inline void gicd_clr_ctlr(uintptr_t base, @@ -149,8 +286,9 @@ static inline void gicd_clr_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap); - if (rwp != 0U) + if (rwp != 0U) { gicd_wait_for_pending_write(base); + } } static inline void gicd_set_ctlr(uintptr_t base, @@ -158,8 +296,9 @@ static inline void gicd_set_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap); - if (rwp != 0U) + if (rwp != 0U) { gicd_wait_for_pending_write(base); + } } /******************************************************************************* @@ -175,38 +314,39 @@ static inline void gicr_write_ctlr(uintptr_t base, uint32_t val) mmio_write_32(base + GICR_CTLR, val); } -static inline unsigned long long gicr_read_typer(uintptr_t base) +static inline uint64_t gicr_read_typer(uintptr_t base) { return mmio_read_64(base + GICR_TYPER); } -static inline unsigned int gicr_read_waker(uintptr_t base) +static inline uint32_t gicr_read_waker(uintptr_t base) { return mmio_read_32(base + GICR_WAKER); } -static inline void gicr_write_waker(uintptr_t base, unsigned int val) +static inline void gicr_write_waker(uintptr_t base, uint32_t val) { mmio_write_32(base + GICR_WAKER, val); } /* - * Wait for updates to : + * Wait for updates to: * GICR_ICENABLER0 * GICR_CTLR.DPG1S * GICR_CTLR.DPG1NS * GICR_CTLR.DPG0 + * GICR_CTLR, which clears EnableLPIs from 1 to 0 */ static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) { - while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) - ; + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) { + } } static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base) { - while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) - ; + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) { + } } /* Private implementation of Distributor power control hooks */ @@ -214,10 +354,14 @@ void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num); void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); /******************************************************************************* - * GIC Re-distributor functions for accessing entire registers. + * GIC Redistributor functions for accessing entire registers. * Note: The raw register values correspond to multiple interrupt IDs and * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ + +/* + * Accessors to read/write GIC Redistributor ICENABLER0 register + */ static inline unsigned int gicr_read_icenabler0(uintptr_t base) { return mmio_read_32(base + GICR_ICENABLER0); @@ -228,41 +372,110 @@ static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val) mmio_write_32(base + GICR_ICENABLER0, val); } -static inline unsigned int gicr_read_isenabler0(uintptr_t base) +/* + * Accessors to read/write GIC Redistributor ICENABLER0 and ICENABLERE + * register corresponding to its number + */ +static inline unsigned int gicr_read_icenabler(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_ISENABLER0); + return mmio_read_32(base + GICR_ICENABLER + (reg_num << 2)); +} + +static inline void gicr_write_icenabler(uintptr_t base, unsigned int reg_num, + unsigned int val) +{ + mmio_write_32(base + GICR_ICENABLER + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 registers + */ +static inline unsigned int gicr_read_icfgr0(uintptr_t base) +{ + return mmio_read_32(base + GICR_ICFGR0); +} + +static inline unsigned int gicr_read_icfgr1(uintptr_t base) +{ + return mmio_read_32(base + GICR_ICFGR1); +} + +static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ICFGR0, val); +} + +static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ICFGR1, val); +} + +/* + * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_icfgr(uintptr_t base, unsigned int reg_num) +{ + return mmio_read_32(base + GICR_ICFGR + (reg_num << 2)); +} + +static inline void gicr_write_icfgr(uintptr_t base, unsigned int reg_num, + unsigned int val) +{ + mmio_write_32(base + GICR_ICFGR + (reg_num << 2), val); +} + +/* + * Accessor to write GIC Redistributor ICPENDR0 register + */ static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val) { mmio_write_32(base + GICR_ICPENDR0, val); } -static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val) +/* + * Accessor to write GIC Redistributor ICPENDR0 and ICPENDRE + * register corresponding to its number + */ +static inline void gicr_write_icpendr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_ISENABLER0, val); + mmio_write_32(base + GICR_ICPENDR + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor IGROUPR0 register + */ static inline unsigned int gicr_read_igroupr0(uintptr_t base) { return mmio_read_32(base + GICR_IGROUPR0); } -static inline unsigned int gicr_read_ispendr0(uintptr_t base) +static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val) { - return mmio_read_32(base + GICR_ISPENDR0); + mmio_write_32(base + GICR_IGROUPR0, val); } -static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val) +/* + * Accessors to read/write GIC Redistributor IGROUPR0 and IGROUPRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_igroupr(uintptr_t base, + unsigned int reg_num) { - mmio_write_32(base + GICR_ISPENDR0, val); + return mmio_read_32(base + GICR_IGROUPR + (reg_num << 2)); } -static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val) +static inline void gicr_write_igroupr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_IGROUPR0, val); + mmio_write_32(base + GICR_IGROUPR + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor IGRPMODR0 register + */ static inline unsigned int gicr_read_igrpmodr0(uintptr_t base) { return mmio_read_32(base + GICR_IGRPMODR0); @@ -273,16 +486,41 @@ static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val) mmio_write_32(base + GICR_IGRPMODR0, val); } -static inline unsigned int gicr_read_nsacr(uintptr_t base) +/* + * Accessors to read/write GIC Redistributor IGRPMODR0 and IGRPMODRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_igrpmodr(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_NSACR); + return mmio_read_32(base + GICR_IGRPMODR + (reg_num << 2)); } -static inline void gicr_write_nsacr(uintptr_t base, unsigned int val) +static inline void gicr_write_igrpmodr(uintptr_t base, unsigned int reg_num, + unsigned int val) { - mmio_write_32(base + GICR_NSACR, val); + mmio_write_32(base + GICR_IGRPMODR + (reg_num << 2), val); +} + +/* + * Accessors to read/write the GIC Redistributor IPRIORITYR(E) register + * corresponding to its number, 4 interrupts IDs at a time. + */ +static inline unsigned int gicr_ipriorityr_read(uintptr_t base, + unsigned int reg_num) +{ + return mmio_read_32(base + GICR_IPRIORITYR + (reg_num << 2)); +} + +static inline void gicr_ipriorityr_write(uintptr_t base, unsigned int reg_num, + unsigned int val) +{ + mmio_write_32(base + GICR_IPRIORITYR + (reg_num << 2), val); } +/* + * Accessors to read/write GIC Redistributor ISACTIVER0 register + */ static inline unsigned int gicr_read_isactiver0(uintptr_t base) { return mmio_read_32(base + GICR_ISACTIVER0); @@ -293,26 +531,96 @@ static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val) mmio_write_32(base + GICR_ISACTIVER0, val); } -static inline unsigned int gicr_read_icfgr0(uintptr_t base) +/* + * Accessors to read/write GIC Redistributor ISACTIVER0 and ISACTIVERE + * register corresponding to its number + */ +static inline unsigned int gicr_read_isactiver(uintptr_t base, + unsigned int reg_num) { - return mmio_read_32(base + GICR_ICFGR0); + return mmio_read_32(base + GICR_ISACTIVER + (reg_num << 2)); } -static inline unsigned int gicr_read_icfgr1(uintptr_t base) +static inline void gicr_write_isactiver(uintptr_t base, unsigned int reg_num, + unsigned int val) { - return mmio_read_32(base + GICR_ICFGR1); + mmio_write_32(base + GICR_ISACTIVER + (reg_num << 2), val); } -static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val) +/* + * Accessors to read/write GIC Redistributor ISENABLER0 register + */ +static inline unsigned int gicr_read_isenabler0(uintptr_t base) { - mmio_write_32(base + GICR_ICFGR0, val); + return mmio_read_32(base + GICR_ISENABLER0); } -static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) +static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val) { - mmio_write_32(base + GICR_ICFGR1, val); + mmio_write_32(base + GICR_ISENABLER0, val); +} + +/* + * Accessors to read/write GIC Redistributor ISENABLER0 and ISENABLERE + * register corresponding to its number + */ +static inline unsigned int gicr_read_isenabler(uintptr_t base, + unsigned int reg_num) +{ + return mmio_read_32(base + GICR_ISENABLER + (reg_num << 2)); +} + +static inline void gicr_write_isenabler(uintptr_t base, unsigned int reg_num, + unsigned int val) +{ + mmio_write_32(base + GICR_ISENABLER + (reg_num << 2), val); +} + +/* + * Accessors to read/write GIC Redistributor ISPENDR0 register + */ +static inline unsigned int gicr_read_ispendr0(uintptr_t base) +{ + return mmio_read_32(base + GICR_ISPENDR0); +} + +static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_ISPENDR0, val); +} + +/* + * Accessors to read/write GIC Redistributor ISPENDR0 and ISPENDRE + * register corresponding to its number + */ +static inline unsigned int gicr_read_ispendr(uintptr_t base, + unsigned int reg_num) +{ + return mmio_read_32(base + GICR_ISPENDR + (reg_num << 2)); } +static inline void gicr_write_ispendr(uintptr_t base, unsigned int reg_num, + unsigned int val) +{ + mmio_write_32(base + GICR_ISPENDR + (reg_num << 2), val); +} + +/* + * Accessors to read/write GIC Redistributor NSACR register + */ +static inline unsigned int gicr_read_nsacr(uintptr_t base) +{ + return mmio_read_32(base + GICR_NSACR); +} + +static inline void gicr_write_nsacr(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICR_NSACR, val); +} + +/* + * Accessors to read/write GIC Redistributor PROPBASER register + */ static inline uint64_t gicr_read_propbaser(uintptr_t base) { return mmio_read_64(base + GICR_PROPBASER); @@ -323,6 +631,9 @@ static inline void gicr_write_propbaser(uintptr_t base, uint64_t val) mmio_write_64(base + GICR_PROPBASER, val); } +/* + * Accessors to read/write GIC Redistributor PENDBASER register + */ static inline uint64_t gicr_read_pendbaser(uintptr_t base) { return mmio_read_64(base + GICR_PENDBASER); @@ -341,7 +652,7 @@ static inline uint32_t gits_read_ctlr(uintptr_t base) return mmio_read_32(base + GITS_CTLR); } -static inline void gits_write_ctlr(uintptr_t base, unsigned int val) +static inline void gits_write_ctlr(uintptr_t base, uint32_t val) { mmio_write_32(base + GITS_CTLR, val); } @@ -366,13 +677,15 @@ static inline void gits_write_cwriter(uintptr_t base, uint64_t val) mmio_write_64(base + GITS_CWRITER, val); } -static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id) +static inline uint64_t gits_read_baser(uintptr_t base, + unsigned int its_table_id) { assert(its_table_id < 8U); return mmio_read_64(base + GITS_BASER + (8U * its_table_id)); } -static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val) +static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, + uint64_t val) { assert(its_table_id < 8U); mmio_write_64(base + GITS_BASER + (8U * its_table_id), val); @@ -384,9 +697,8 @@ static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, u static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base) { assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U); - while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) - ; + while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) { + } } - #endif /* GICV3_PRIVATE_H */ diff --git a/drivers/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S index 05c8250dc..9caeb0c69 100644 --- a/drivers/arm/pl011/aarch32/pl011_console.S +++ b/drivers/arm/pl011/aarch32/pl011_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -91,14 +91,14 @@ endfunc console_pl011_core_init /* ------------------------------------------------------- * int console_pl011_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_pl011_t *console); + * console_t *console); * Function to initialize and register a new PL011 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: r0 - UART register base address * r1 - UART clock in Hz * r2 - Baud rate - * r3 - pointer to empty console_pl011_t struct + * r3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : r0, r1, r2 * ------------------------------------------------------- @@ -108,7 +108,7 @@ func console_pl011_register mov r4, r3 cmp r4, #0 beq register_fail - str r0, [r4, #CONSOLE_T_PL011_BASE] + str r0, [r4, #CONSOLE_T_BASE] bl console_pl011_core_init cmp r0, #0 @@ -159,7 +159,7 @@ putc_error: endfunc console_pl011_core_putc /* -------------------------------------------------------- - * int console_pl011_putc(int c, console_pl011_t *console) + * int console_pl011_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: r0 - character to be printed @@ -173,7 +173,7 @@ func console_pl011_putc cmp r1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r1, [r1, #CONSOLE_T_PL011_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] b console_pl011_core_putc endfunc console_pl011_putc @@ -203,7 +203,7 @@ getc_error: endfunc console_pl011_core_getc /* ------------------------------------------------ - * int console_pl011_getc(console_pl011_t *console) + * int console_pl011_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -217,22 +217,24 @@ func console_pl011_getc cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_PL011_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_pl011_core_getc endfunc console_pl011_getc /* --------------------------------------------- - * int console_core_flush(uintptr_t base_addr) + * void console_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void * Clobber list : r0, r1 * --------------------------------------------- */ func console_pl011_core_flush +#if ENABLE_ASSERTIONS cmp r0, #0 - beq flush_error + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ 1: /* Loop while the transmit FIFO is busy */ @@ -240,19 +242,15 @@ func console_pl011_core_flush tst r1, #PL011_UARTFR_BUSY bne 1b - mov r0, #0 - bx lr -flush_error: - mov r0, #-1 bx lr endfunc console_pl011_core_flush /* --------------------------------------------- - * int console_pl011_flush(console_pl011_t *console) + * void console_pl011_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void * Clobber list: r0, r1 * --------------------------------------------- */ @@ -261,6 +259,6 @@ func console_pl011_flush cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_PL011_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_pl011_core_flush endfunc console_pl011_flush diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S index 04de99fbc..861d2ed22 100644 --- a/drivers/arm/pl011/aarch64/pl011_console.S +++ b/drivers/arm/pl011/aarch64/pl011_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -80,14 +80,14 @@ endfunc console_pl011_core_init /* ----------------------------------------------- * int console_pl011_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_pl011_t *console); + * console_t *console); * Function to initialize and register a new PL011 * 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_pl011_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -96,7 +96,7 @@ func console_pl011_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_PL011_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_pl011_core_init cbz x0, register_fail @@ -143,7 +143,7 @@ func console_pl011_core_putc endfunc console_pl011_core_putc /* -------------------------------------------------------- - * int console_pl011_putc(int c, console_pl011_t *console) + * int console_pl011_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 @@ -157,7 +157,7 @@ func console_pl011_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_PL011_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_pl011_core_putc endfunc console_pl011_putc @@ -189,7 +189,7 @@ no_char: endfunc console_pl011_core_getc /* --------------------------------------------- - * int console_pl011_getc(console_pl011_t *console) + * int console_pl011_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -203,16 +203,16 @@ func console_pl011_getc cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_PL011_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_pl011_core_getc endfunc console_pl011_getc /* --------------------------------------------- - * int console_pl011_core_flush(uintptr_t base_addr) + * void console_pl011_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -225,17 +225,15 @@ func console_pl011_core_flush /* Loop until the transmit FIFO is empty */ ldr w1, [x0, #UARTFR] tbnz w1, #PL011_UARTFR_BUSY_BIT, 1b - - mov w0, #0 ret endfunc console_pl011_core_flush /* --------------------------------------------- - * int console_pl011_flush(console_pl011_t *console) + * void console_pl011_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void * Clobber list : x0, x1 * --------------------------------------------- */ @@ -244,6 +242,6 @@ func console_pl011_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_PL011_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_pl011_core_flush endfunc console_pl011_flush diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c index 50d670139..95a5e7f77 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -91,9 +91,9 @@ static void _tzc400_set_gate_keeper(uintptr_t base, open_status = get_gate_keeper_os(base); if (val != 0) - open_status |= (1U << filter); + open_status |= (1UL << filter); else - open_status &= ~(1U << filter); + open_status &= ~(1UL << filter); _tzc400_write_gate_keeper(base, (open_status & GATE_KEEPER_OR_MASK) << GATE_KEEPER_OR_SHIFT); diff --git a/drivers/arm/tzc/tzc_common_private.h b/drivers/arm/tzc/tzc_common_private.h index c800536f3..1d99077ad 100644 --- a/drivers/arm/tzc/tzc_common_private.h +++ b/drivers/arm/tzc/tzc_common_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,13 +30,13 @@ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \ (uint32_t)region_base); \ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \ (uint32_t)(region_base >> 32)); \ } @@ -48,15 +48,15 @@ unsigned long long region_top) \ { \ mmio_write_32(base + \ - TZC_REGION_OFFSET \ - (TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + TZC_REGION_OFFSET( \ + TZC_##macro_name##_REGION_SIZE, \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \ (uint32_t)region_top); \ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \ (uint32_t)(region_top >> 32)); \ } @@ -70,7 +70,7 @@ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ attr); \ } @@ -84,7 +84,7 @@ mmio_write_32(base + \ TZC_REGION_OFFSET( \ TZC_##macro_name##_REGION_SIZE, \ - region_no) + \ + (u_register_t)region_no) + \ TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \ val); \ } diff --git a/drivers/arm/tzc/tzc_dmc620.c b/drivers/arm/tzc/tzc_dmc620.c index 64ec5abee..7e307ee50 100644 --- a/drivers/arm/tzc/tzc_dmc620.c +++ b/drivers/arm/tzc/tzc_dmc620.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,7 +17,7 @@ /* Helper macro for getting dmc_base addr of a dmc_inst */ #define DMC_BASE(plat_data, dmc_inst) \ - ((uintptr_t)(plat_data->dmc_base[dmc_inst])) + ((uintptr_t)((plat_data)->dmc_base[(dmc_inst)])) /* Pointer to the tzc_dmc620_config_data structure populated by the platform */ static const tzc_dmc620_config_data_t *g_plat_config_data; @@ -31,8 +31,7 @@ static const tzc_dmc620_config_data_t *g_plat_config_data; static void tzc_dmc620_validate_plat_driver_data( const tzc_dmc620_driver_data_t *plat_driver_data) { - uint8_t dmc_inst, dmc_count; - unsigned int dmc_id; + unsigned int dmc_inst, dmc_count, dmc_id; uintptr_t base; assert(plat_driver_data != NULL); @@ -59,7 +58,7 @@ static void tzc_dmc620_configure_region(int region_no, { uint32_t min_31_00, min_47_32; uint32_t max_31_00, max_47_32; - uint8_t dmc_inst, dmc_count; + unsigned int dmc_inst, dmc_count; uintptr_t base; const tzc_dmc620_driver_data_t *plat_driver_data; @@ -67,19 +66,19 @@ static void tzc_dmc620_configure_region(int region_no, assert(plat_driver_data != NULL); /* Do range checks on regions. */ - assert((region_no >= 0U) && (region_no <= DMC620_ACC_ADDR_COUNT)); + assert((region_no >= 0) && (region_no <= DMC620_ACC_ADDR_COUNT)); /* region_base and (region_top + 1) must be 4KB aligned */ assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U); dmc_count = plat_driver_data->dmc_count; for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) { - min_31_00 = (region_base & MASK_31_16) | sec_attr; - min_47_32 = (region_base & MASK_47_32) - >> DMC620_ACC_ADDR_WIDTH; - max_31_00 = (region_top & MASK_31_16); - max_47_32 = (region_top & MASK_47_32) - >> DMC620_ACC_ADDR_WIDTH; + min_31_00 = (uint32_t)((region_base & MASK_31_16) | sec_attr); + min_47_32 = (uint32_t)((region_base & MASK_47_32) + >> DMC620_ACC_ADDR_WIDTH); + max_31_00 = (uint32_t)(region_top & MASK_31_16); + max_47_32 = (uint32_t)((region_top & MASK_47_32) + >> DMC620_ACC_ADDR_WIDTH); /* Extract the base address of the DMC-620 instance */ base = DMC_BASE(plat_driver_data, dmc_inst); @@ -100,7 +99,7 @@ static void tzc_dmc620_configure_region(int region_no, */ static void tzc_dmc620_set_action(void) { - uint8_t dmc_inst, dmc_count; + unsigned int dmc_inst, dmc_count; uintptr_t base; const tzc_dmc620_driver_data_t *plat_driver_data; @@ -123,7 +122,7 @@ static void tzc_dmc620_set_action(void) */ static void tzc_dmc620_verify_complete(void) { - uint8_t dmc_inst, dmc_count; + unsigned int dmc_inst, dmc_count; uintptr_t base; const tzc_dmc620_driver_data_t *plat_driver_data; @@ -133,8 +132,9 @@ static void tzc_dmc620_verify_complete(void) /* Extract the base address of the DMC-620 instance */ base = DMC_BASE(plat_driver_data, dmc_inst); while ((mmio_read_32(base + DMC620_MEMC_STATUS) & - DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO) + DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO) { continue; + } } } @@ -145,7 +145,7 @@ static void tzc_dmc620_verify_complete(void) */ void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data) { - int i; + uint8_t i; /* Check if valid pointer is passed */ assert(plat_config_data != NULL); @@ -164,11 +164,12 @@ void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data) g_plat_config_data = plat_config_data; INFO("Configuring DMC-620 TZC settings\n"); - for (i = 0U; i < g_plat_config_data->acc_addr_count; i++) + for (i = 0U; i < g_plat_config_data->acc_addr_count; i++) { tzc_dmc620_configure_region(i, g_plat_config_data->plat_acc_addr_data[i].region_base, g_plat_config_data->plat_acc_addr_data[i].region_top, g_plat_config_data->plat_acc_addr_data[i].sec_attr); + } tzc_dmc620_set_action(); tzc_dmc620_verify_complete(); diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c index 3fb2d1a48..91ee1bea9 100644 --- a/drivers/auth/auth_mod.c +++ b/drivers/auth/auth_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ #include <drivers/auth/auth_mod.h> #include <drivers/auth/crypto_mod.h> #include <drivers/auth/img_parser_mod.h> +#include <lib/fconf/fconf_tbbr_getter.h> #include <plat/common/platform.h> /* ASN.1 tags */ @@ -302,9 +303,8 @@ int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id) const auth_img_desc_t *img_desc = NULL; assert(parent_id != NULL); - /* Get the image descriptor */ - img_desc = cot_desc_ptr[img_id]; + img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); /* Check if the image has no parent (ROT) */ if (img_desc->parent == NULL) { @@ -353,7 +353,7 @@ int auth_mod_verify_img(unsigned int img_id, int rc, i; /* Get the image descriptor from the chain of trust */ - img_desc = cot_desc_ptr[img_id]; + img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); /* Ask the parser to check the image integrity */ rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len); diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c index 110c5045f..c63ff080f 100644 --- a/drivers/auth/crypto_mod.c +++ b/drivers/auth/crypto_mod.c @@ -124,3 +124,35 @@ int crypto_mod_calc_hash(unsigned int alg, void *data_ptr, return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output); } #endif /* MEASURED_BOOT */ + +/* + * Authenticated decryption of data + * + * Parameters: + * + * dec_algo: authenticated decryption algorithm + * data_ptr, len: data to be decrypted (inout param) + * key, key_len, key_flags: symmetric decryption key + * iv, iv_len: initialization vector + * tag, tag_len: authentication tag + */ +int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, + size_t len, const void *key, unsigned int key_len, + unsigned int key_flags, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len) +{ + assert(crypto_lib_desc.auth_decrypt != NULL); + assert(data_ptr != NULL); + assert(len != 0U); + assert(key != NULL); + assert(key_len != 0U); + assert(iv != NULL); + assert((iv_len != 0U) && (iv_len <= CRYPTO_MAX_IV_SIZE)); + assert(tag != NULL); + assert((tag_len != 0U) && (tag_len <= CRYPTO_MAX_TAG_SIZE)); + + return crypto_lib_desc.auth_decrypt(dec_algo, data_ptr, len, key, + key_len, key_flags, iv, iv_len, tag, + tag_len); +} diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c index 25eb6bcb6..c7ee36fa7 100644 --- a/drivers/auth/cryptocell/712/cryptocell_crypto.c +++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,6 +22,7 @@ #include <lib/utils.h> #include <mbedtls/oid.h> +#include <mbedtls/x509.h> #define LIB_NAME "CryptoCell 712 SBROM" #define RSA_SALT_LEN 32 @@ -301,5 +302,5 @@ static int verify_hash(void *data_ptr, unsigned int data_len, /* * Register crypto library descriptor */ -REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL); diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c new file mode 100644 index 000000000..5f390a226 --- /dev/null +++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stddef.h> +#include <string.h> + +#include <drivers/arm/cryptocell/713/bsv_api.h> +#include <drivers/arm/cryptocell/713/bsv_crypto_asym_api.h> +#include <drivers/auth/crypto_mod.h> + +#include <mbedtls/oid.h> + +#define LIB_NAME "CryptoCell 713 SBROM" +#define RSA_SALT_LEN 32 +#define RSA_EXPONENT 65537 + +/* + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + * + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm, + * maskGenAlgorithm [1] MaskGenAlgorithm, + * saltLength [2] INTEGER, + * trailerField [3] TrailerField DEFAULT trailerFieldBC + * } + */ + +/* + * Initialize the library and export the descriptor + */ +static void init(void) +{ + CCError_t ret; + uint32_t lcs; + + /* Initialize CC SBROM */ + ret = CC_BsvInit((uintptr_t)PLAT_CRYPTOCELL_BASE); + if (ret != CC_OK) { + ERROR("CryptoCell CC_BsvInit() error %x\n", ret); + panic(); + } + + /* Initialize lifecycle state */ + ret = CC_BsvGetAndInitLcs((uintptr_t)PLAT_CRYPTOCELL_BASE, &lcs); + if (ret != CC_OK) { + ERROR("CryptoCell CC_BsvGetAndInitLcs() error %x\n", ret); + panic(); + } +} + +/* + * Verify a signature. + * + * Parameters are passed using the DER encoding format following the ASN.1 + * structures detailed above. + */ +static int verify_signature(void *data_ptr, unsigned int data_len, + void *sig_ptr, unsigned int sig_len, + void *sig_alg, unsigned int sig_alg_len, + void *pk_ptr, unsigned int pk_len) +{ + CCError_t error; + CCBsvNBuff_t NBuff; + CCBsvSignature_t signature; + int rc, exp; + mbedtls_asn1_buf sig_oid, alg_oid, params; + mbedtls_md_type_t md_alg; + mbedtls_pk_type_t pk_alg; + mbedtls_pk_rsassa_pss_options pss_opts; + size_t len; + uint8_t *p, *end; + CCHashResult_t digest; + CCBool_t is_verified; + /* This is a rather large array, we don't want it on stack */ + static uint32_t workspace[BSV_RSA_WORKSPACE_MIN_SIZE]; + + /* Verify the signature algorithm */ + /* Get pointers to signature OID and parameters */ + p = sig_alg; + end = p + sig_alg_len; + rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, ¶ms); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + /* Get the actual signature algorithm (MD + PK) */ + rc = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + /* The CryptoCell only supports RSASSA-PSS signature */ + if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE) + return CRYPTO_ERR_SIGNATURE; + + /* Verify the RSASSA-PSS params */ + /* The trailer field is verified to be 0xBC internally by this API */ + rc = mbedtls_x509_get_rsassa_pss_params(¶ms, &md_alg, + &pss_opts.mgf1_hash_id, + &pss_opts.expected_salt_len); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + /* The CryptoCell only supports SHA256 as hash algorithm */ + if (md_alg != MBEDTLS_MD_SHA256 || + pss_opts.mgf1_hash_id != MBEDTLS_MD_SHA256) + return CRYPTO_ERR_SIGNATURE; + + if (pss_opts.expected_salt_len != RSA_SALT_LEN) + return CRYPTO_ERR_SIGNATURE; + + /* Parse the public key */ + p = pk_ptr; + end = p + pk_len; + rc = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + end = p + len; + rc = mbedtls_asn1_get_alg_null(&p, end, &alg_oid); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0) + return CRYPTO_ERR_SIGNATURE; + + if (pk_alg != MBEDTLS_PK_RSA) + return CRYPTO_ERR_SIGNATURE; + + rc = mbedtls_asn1_get_bitstring_null(&p, end, &len); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + rc = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (*p == 0) { + p++; len--; + } + if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end)) + return CRYPTO_ERR_SIGNATURE; + + /* + * Copy N from certificate. + */ + memcpy(NBuff, p, BSV_CERT_RSA_KEY_SIZE_IN_BYTES); + + /* Verify the RSA exponent */ + p += len; + rc = mbedtls_asn1_get_int(&p, end, &exp); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (exp != RSA_EXPONENT) + return CRYPTO_ERR_SIGNATURE; + + /* Get the signature (bitstring) */ + p = sig_ptr; + end = p + sig_len; + rc = mbedtls_asn1_get_bitstring_null(&p, end, &len); + if (rc != 0) + return CRYPTO_ERR_SIGNATURE; + + if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end)) + return CRYPTO_ERR_SIGNATURE; + + /* + * Copy the signature (in BE format) + */ + memcpy((uint8_t *)signature, p, BSV_CERT_RSA_KEY_SIZE_IN_BYTES); + + error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE, + data_ptr, data_len, digest); + if (error != CC_OK) + return CRYPTO_ERR_SIGNATURE; + + /* Verify the signature */ + error = CC_BsvRsaPssVerify((uintptr_t)PLAT_CRYPTOCELL_BASE, NBuff, + NULL, signature, digest, workspace, + BSV_RSA_WORKSPACE_MIN_SIZE, &is_verified); + if ((error != CC_OK) || (is_verified != CC_TRUE)) + return CRYPTO_ERR_SIGNATURE; + + /* Signature verification success */ + return CRYPTO_SUCCESS; +} + +/* + * Match a hash + * + * Digest info is passed in DER format following the ASN.1 structure detailed + * above. + */ +static int verify_hash(void *data_ptr, unsigned int data_len, + void *digest_info_ptr, unsigned int digest_info_len) +{ + mbedtls_asn1_buf hash_oid, params; + mbedtls_md_type_t md_alg; + uint8_t *p, *end, *hash; + CCHashResult_t pubKeyHash; + size_t len; + int rc; + CCError_t error; + + /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */ + p = digest_info_ptr; + end = p + digest_info_len; + rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE); + if (rc != 0) + return CRYPTO_ERR_HASH; + + /* Get the hash algorithm */ + rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); + if (rc != 0) + return CRYPTO_ERR_HASH; + + rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); + if (rc != 0) + return CRYPTO_ERR_HASH; + /* Verify that hash algorithm is SHA256 */ + if (md_alg != MBEDTLS_MD_SHA256) + return CRYPTO_ERR_HASH; + + /* Hash should be octet string type */ + rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); + if (rc != 0) + return CRYPTO_ERR_HASH; + + /* Length of hash must match the algorithm's size */ + if (len != HASH_RESULT_SIZE_IN_BYTES) + return CRYPTO_ERR_HASH; + + hash = p; + error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE, data_ptr, + data_len, pubKeyHash); + if (error != CC_OK) + return CRYPTO_ERR_HASH; + + rc = memcmp(pubKeyHash, hash, HASH_RESULT_SIZE_IN_BYTES); + if (rc != 0) + return CRYPTO_ERR_HASH; + + return CRYPTO_SUCCESS; +} + +/* + * Register crypto library descriptor + */ +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL); diff --git a/drivers/auth/cryptocell/713/cryptocell_plat_helpers.c b/drivers/auth/cryptocell/713/cryptocell_plat_helpers.c new file mode 100644 index 000000000..17e12807c --- /dev/null +++ b/drivers/auth/cryptocell/713/cryptocell_plat_helpers.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stddef.h> +#include <string.h> + +#include <plat/common/platform.h> +#include <tools_share/tbbr_oid.h> + +#include <lib/libc/endian.h> +#include <drivers/arm/cryptocell/713/bsv_api.h> +#include <drivers/arm/cryptocell/713/bsv_error.h> + +/* + * Return the ROTPK hash + * + * Return: 0 = success, Otherwise = error + */ +int cc_get_rotpk_hash(unsigned char *dst, unsigned int len, unsigned int *flags) +{ + CCError_t error; + uint32_t lcs; + int i; + uint32_t *key = (uint32_t *)dst; + + assert(dst != NULL); + assert(len >= HASH_RESULT_SIZE_IN_WORDS); + assert(flags != NULL); + + error = CC_BsvLcsGet(PLAT_CRYPTOCELL_BASE, &lcs); + if (error != CC_OK) + return 1; + + if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) || (lcs == CC_BSV_RMA_LCS)) { + *flags = ROTPK_NOT_DEPLOYED; + return 0; + } + + error = CC_BsvPubKeyHashGet(PLAT_CRYPTOCELL_BASE, + CC_SB_HASH_BOOT_KEY_256B, + key, HASH_RESULT_SIZE_IN_WORDS); + + if (error == CC_BSV_HASH_NOT_PROGRAMMED_ERR) { + *flags = ROTPK_NOT_DEPLOYED; + return 0; + } + + if (error == CC_OK) { + + /* Keys are stored in OTP in little-endian format */ + for (i = 0; i < HASH_RESULT_SIZE_IN_WORDS; i++) + key[i] = le32toh(key[i]); + + *flags = ROTPK_IS_HASH; + return 0; + } + + return 1; +} + +/* + * Return the non-volatile counter value stored in the platform. The cookie + * specifies the OID of the counter in the certificate. + * + * Return: 0 = success, Otherwise = error + */ +int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) +{ + CCError_t error = CC_FAIL; + + if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionGet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_TRUSTED, nv_ctr); + } else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionGet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_NON_TRUSTED, nv_ctr); + } + + return (error != CC_OK); +} + +/* + * Store a new non-volatile counter value in the counter specified by the OID + * in the cookie. This function is not expected to be called if the Lifecycle + * state is RMA as the values in the certificate are expected to always match + * the nvcounter values. But if called when the LCS is RMA, the underlying + * helper functions will return success but without updating the counter. + * + * Return: 0 = success, Otherwise = error + */ +int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) +{ + CCError_t error = CC_FAIL; + + if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionSet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_TRUSTED, nv_ctr); + } else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { + error = CC_BsvSwVersionSet(PLAT_CRYPTOCELL_BASE, + CC_SW_VERSION_NON_TRUSTED, nv_ctr); + } + + return (error != CC_OK); +} + diff --git a/drivers/auth/cryptocell/cryptocell_crypto.mk b/drivers/auth/cryptocell/cryptocell_crypto.mk index 2fc4ddb11..db390471f 100644 --- a/drivers/auth/cryptocell/cryptocell_crypto.mk +++ b/drivers/auth/cryptocell/cryptocell_crypto.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -22,6 +22,8 @@ endif CRYPTOCELL_VERSION ?= 712 ifeq (${CRYPTOCELL_VERSION},712) CCSBROM_LIB_FILENAME := cc_712sbromx509 +else ifeq (${CRYPTOCELL_VERSION},713) + CCSBROM_LIB_FILENAME := cc_713bsv else $(error Error: CRYPTOCELL_VERSION set to invalid version) endif diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/dualroot/cot.c index 6dd4ae252..e1e47bca0 100644 --- a/drivers/auth/tbbr/tbbr_cot.c +++ b/drivers/auth/dualroot/cot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,43 +7,16 @@ #include <stddef.h> #include <platform_def.h> -#include <drivers/auth/mbedtls/mbedtls_config.h> +#include <drivers/auth/mbedtls/mbedtls_config.h> #include <drivers/auth/auth_mod.h> -#if USE_TBBR_DEFS -#include <tools_share/tbbr_oid.h> -#else -#include <platform_oid.h> -#endif - - -/* - * Maximum key and hash sizes (in DER format) - */ -#if TF_MBEDTLS_USE_RSA -#if TF_MBEDTLS_KEY_SIZE == 1024 -#define PK_DER_LEN 162 -#elif TF_MBEDTLS_KEY_SIZE == 2048 -#define PK_DER_LEN 294 -#elif TF_MBEDTLS_KEY_SIZE == 3072 -#define PK_DER_LEN 422 -#elif TF_MBEDTLS_KEY_SIZE == 4096 -#define PK_DER_LEN 550 -#else -#error "Invalid value for TF_MBEDTLS_KEY_SIZE" -#endif -#else -#define PK_DER_LEN 294 -#endif - -#define HASH_DER_LEN 83 +#include <tools_share/dualroot_oid.h> /* - * The platform must allocate buffers to store the authentication parameters - * extracted from the certificates. In this case, because of the way the CoT is - * established, we can reuse some of the buffers on different stages + * Allocate static buffers to store the authentication parameters extracted from + * the certificates. */ - +static unsigned char fw_config_hash_buf[HASH_DER_LEN]; static unsigned char tb_fw_hash_buf[HASH_DER_LEN]; static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char hw_config_hash_buf[HASH_DER_LEN]; @@ -55,20 +28,22 @@ static unsigned char soc_fw_hash_buf[HASH_DER_LEN]; static unsigned char tos_fw_hash_buf[HASH_DER_LEN]; static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN]; static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; -static unsigned char trusted_world_pk_buf[PK_DER_LEN]; -static unsigned char non_trusted_world_pk_buf[PK_DER_LEN]; -static unsigned char content_pk_buf[PK_DER_LEN]; static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; +#if defined(SPD_spmd) +static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN]; +#endif /* SPD_spmd */ + +static unsigned char trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char content_pk_buf[PK_DER_LEN]; #endif /* - * Parameter type descriptors + * Parameter type descriptors. */ static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID); - static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_PUB_KEY, 0); static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( @@ -78,13 +53,14 @@ static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_RAW_DATA, 0); - static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID); static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); +static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FW_CONFIG_HASH_OID); #ifdef IMAGE_BL1 static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID); @@ -97,18 +73,18 @@ static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC( #ifdef IMAGE_BL2 static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID); + static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID); -static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID); static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID); static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID); static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID); -static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC( - AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, PROT_PK_OID); + static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, SCP_FW_HASH_OID); static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC( @@ -127,13 +103,28 @@ static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID); static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC( AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID); - +#if defined(SPD_spmd) +static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG1_HASH_OID); +static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG2_HASH_OID); +static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG3_HASH_OID); +static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG4_HASH_OID); +static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG5_HASH_OID); +static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG6_HASH_OID); +static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG7_HASH_OID); +static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG8_HASH_OID); +#endif /* SPD_spmd */ #endif /* IMAGE_BL2 */ - /* - * BL2 - */ +/* BL2 */ static const auth_img_desc_t trusted_boot_fw_cert = { .img_id = TRUSTED_BOOT_FW_CERT_ID, .img_type = IMG_CERT, @@ -177,9 +168,17 @@ static const auth_img_desc_t trusted_boot_fw_cert = { .ptr = (void *)hw_config_hash_buf, .len = (unsigned int)HASH_DER_LEN } + }, + [3] = { + .type_desc = &fw_config_hash, + .data = { + .ptr = (void *)fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } } } - }; +}; + #ifdef IMAGE_BL1 static const auth_img_desc_t bl2_image = { .img_id = BL2_IMAGE_ID, @@ -196,6 +195,7 @@ static const auth_img_desc_t bl2_image = { } }; #endif /* IMAGE_BL1 */ + /* HW Config */ static const auth_img_desc_t hw_config = { .img_id = HW_CONFIG_ID, @@ -211,6 +211,7 @@ static const auth_img_desc_t hw_config = { } } }; + /* TB FW Config */ #ifdef IMAGE_BL1 static const auth_img_desc_t tb_fw_config = { @@ -227,11 +228,26 @@ static const auth_img_desc_t tb_fw_config = { } } }; + +static const auth_img_desc_t fw_config = { + .img_id = FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &fw_config_hash + } + } + } +}; + #endif /* IMAGE_BL1 */ + #ifdef IMAGE_BL2 -/* - * Trusted key certificate - */ +/* Trusted key certificate */ static const auth_img_desc_t trusted_key_cert = { .img_id = TRUSTED_KEY_CERT_ID, .img_type = IMG_CERT, @@ -262,18 +278,10 @@ static const auth_img_desc_t trusted_key_cert = { .len = (unsigned int)PK_DER_LEN } }, - [1] = { - .type_desc = &non_trusted_world_pk, - .data = { - .ptr = (void *)non_trusted_world_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - } } }; -/* - * SCP Firmware - */ + +/* SCP Firmware */ static const auth_img_desc_t scp_fw_key_cert = { .img_id = SCP_FW_KEY_CERT_ID, .img_type = IMG_CERT, @@ -306,6 +314,7 @@ static const auth_img_desc_t scp_fw_key_cert = { } } }; + static const auth_img_desc_t scp_fw_content_cert = { .img_id = SCP_FW_CONTENT_CERT_ID, .img_type = IMG_CERT, @@ -338,6 +347,7 @@ static const auth_img_desc_t scp_fw_content_cert = { } } }; + static const auth_img_desc_t scp_bl2_image = { .img_id = SCP_BL2_IMAGE_ID, .img_type = IMG_RAW, @@ -352,9 +362,8 @@ static const auth_img_desc_t scp_bl2_image = { } } }; -/* - * SoC Firmware - */ + +/* SoC Firmware */ static const auth_img_desc_t soc_fw_key_cert = { .img_id = SOC_FW_KEY_CERT_ID, .img_type = IMG_CERT, @@ -387,6 +396,7 @@ static const auth_img_desc_t soc_fw_key_cert = { } } }; + static const auth_img_desc_t soc_fw_content_cert = { .img_id = SOC_FW_CONTENT_CERT_ID, .img_type = IMG_CERT, @@ -426,6 +436,7 @@ static const auth_img_desc_t soc_fw_content_cert = { } } }; + static const auth_img_desc_t bl31_image = { .img_id = BL31_IMAGE_ID, .img_type = IMG_RAW, @@ -440,6 +451,7 @@ static const auth_img_desc_t bl31_image = { } } }; + /* SOC FW Config */ static const auth_img_desc_t soc_fw_config = { .img_id = SOC_FW_CONFIG_ID, @@ -455,9 +467,8 @@ static const auth_img_desc_t soc_fw_config = { } } }; -/* - * Trusted OS Firmware - */ + +/* Trusted OS Firmware */ static const auth_img_desc_t trusted_os_fw_key_cert = { .img_id = TRUSTED_OS_FW_KEY_CERT_ID, .img_type = IMG_CERT, @@ -490,6 +501,7 @@ static const auth_img_desc_t trusted_os_fw_key_cert = { } } }; + static const auth_img_desc_t trusted_os_fw_content_cert = { .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID, .img_type = IMG_CERT, @@ -543,6 +555,7 @@ static const auth_img_desc_t trusted_os_fw_content_cert = { } } }; + static const auth_img_desc_t bl32_image = { .img_id = BL32_IMAGE_ID, .img_type = IMG_RAW, @@ -557,6 +570,7 @@ static const auth_img_desc_t bl32_image = { } } }; + static const auth_img_desc_t bl32_extra1_image = { .img_id = BL32_EXTRA1_IMAGE_ID, .img_type = IMG_RAW, @@ -571,6 +585,7 @@ static const auth_img_desc_t bl32_extra1_image = { } } }; + static const auth_img_desc_t bl32_extra2_image = { .img_id = BL32_EXTRA2_IMAGE_ID, .img_type = IMG_RAW, @@ -585,6 +600,7 @@ static const auth_img_desc_t bl32_extra2_image = { } } }; + /* TOS FW Config */ static const auth_img_desc_t tos_fw_config = { .img_id = TOS_FW_CONFIG_ID, @@ -600,50 +616,17 @@ static const auth_img_desc_t tos_fw_config = { } } }; -/* - * Non-Trusted Firmware - */ -static const auth_img_desc_t non_trusted_fw_key_cert = { - .img_id = NON_TRUSTED_FW_KEY_CERT_ID, - .img_type = IMG_CERT, - .parent = &trusted_key_cert, - .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { - [0] = { - .type = AUTH_METHOD_SIG, - .param.sig = { - .pk = &non_trusted_world_pk, - .sig = &sig, - .alg = &sig_alg, - .data = &raw_data - } - }, - [1] = { - .type = AUTH_METHOD_NV_CTR, - .param.nv_ctr = { - .cert_nv_ctr = &non_trusted_nv_ctr, - .plat_nv_ctr = &non_trusted_nv_ctr - } - } - }, - .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { - [0] = { - .type_desc = &nt_fw_content_pk, - .data = { - .ptr = (void *)content_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - } - } -}; + +/* Non-Trusted Firmware */ static const auth_img_desc_t non_trusted_fw_content_cert = { .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID, .img_type = IMG_CERT, - .parent = &non_trusted_fw_key_cert, + .parent = NULL, /* Root certificate. */ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { [0] = { .type = AUTH_METHOD_SIG, .param.sig = { - .pk = &nt_fw_content_pk, + .pk = &prot_pk, .sig = &sig, .alg = &sig_alg, .data = &raw_data @@ -674,6 +657,7 @@ static const auth_img_desc_t non_trusted_fw_content_cert = { } } }; + static const auth_img_desc_t bl33_image = { .img_id = BL33_IMAGE_ID, .img_type = IMG_RAW, @@ -688,6 +672,7 @@ static const auth_img_desc_t bl33_image = { } } }; + /* NT FW Config */ static const auth_img_desc_t nt_fw_config = { .img_id = NT_FW_CONFIG_ID, @@ -703,10 +688,133 @@ static const auth_img_desc_t nt_fw_config = { } } }; -#else /* IMAGE_BL2 */ + /* - * FWU auth descriptor. + * Secure Partitions */ +#if defined(SPD_spmd) +static const auth_img_desc_t sip_sp_content_cert = { + .img_id = SIP_SP_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &sp_pkg1_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[0], + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &sp_pkg2_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[1], + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &sp_pkg3_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[2], + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &sp_pkg4_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[3], + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +DEFINE_SIP_SP_PKG(1); +DEFINE_SIP_SP_PKG(2); +DEFINE_SIP_SP_PKG(3); +DEFINE_SIP_SP_PKG(4); + +static const auth_img_desc_t plat_sp_content_cert = { + .img_id = PLAT_SP_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &prot_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &sp_pkg5_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[4], + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &sp_pkg6_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[5], + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &sp_pkg7_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[6], + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &sp_pkg8_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[7], + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +DEFINE_PLAT_SP_PKG(5); +DEFINE_PLAT_SP_PKG(6); +DEFINE_PLAT_SP_PKG(7); +DEFINE_PLAT_SP_PKG(8); +#endif /* SPD_spmd */ + +#else /* IMAGE_BL2 */ + +/* FWU auth descriptor */ static const auth_img_desc_t fwu_cert = { .img_id = FWU_CERT_ID, .img_type = IMG_CERT, @@ -746,9 +854,8 @@ static const auth_img_desc_t fwu_cert = { } } }; -/* - * SCP_BL2U - */ + +/* SCP_BL2U */ static const auth_img_desc_t scp_bl2u_image = { .img_id = SCP_BL2U_IMAGE_ID, .img_type = IMG_RAW, @@ -763,9 +870,8 @@ static const auth_img_desc_t scp_bl2u_image = { } } }; -/* - * BL2U - */ + +/* BL2U */ static const auth_img_desc_t bl2u_image = { .img_id = BL2U_IMAGE_ID, .img_type = IMG_RAW, @@ -780,9 +886,8 @@ static const auth_img_desc_t bl2u_image = { } } }; -/* - * NS_BL2U - */ + +/* NS_BL2U */ static const auth_img_desc_t ns_bl2u_image = { .img_id = NS_BL2U_IMAGE_ID, .img_type = IMG_RAW, @@ -793,21 +898,22 @@ static const auth_img_desc_t ns_bl2u_image = { .param.hash = { .data = &raw_data, .hash = &ns_bl2u_hash - } } } - }; + } +}; #endif /* IMAGE_BL2 */ + /* - * TBBR Chain of trust definition + * Chain of trust definition */ - #ifdef IMAGE_BL1 static const auth_img_desc_t * const cot_desc[] = { [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, [BL2_IMAGE_ID] = &bl2_image, [HW_CONFIG_ID] = &hw_config, [TB_FW_CONFIG_ID] = &tb_fw_config, + [FW_CONFIG_ID] = &fw_config, [FWU_CERT_ID] = &fwu_cert, [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, [BL2U_IMAGE_ID] = &bl2u_image, @@ -831,10 +937,21 @@ static const auth_img_desc_t * const cot_desc[] = { [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, [TOS_FW_CONFIG_ID] = &tos_fw_config, - [NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert, [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, [BL33_IMAGE_ID] = &bl33_image, [NT_FW_CONFIG_ID] = &nt_fw_config, +#if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert, + [PLAT_SP_CONTENT_CERT_ID] = &plat_sp_content_cert, + [SP_PKG1_ID] = &sp_pkg1, + [SP_PKG2_ID] = &sp_pkg2, + [SP_PKG3_ID] = &sp_pkg3, + [SP_PKG4_ID] = &sp_pkg4, + [SP_PKG5_ID] = &sp_pkg5, + [SP_PKG6_ID] = &sp_pkg6, + [SP_PKG7_ID] = &sp_pkg7, + [SP_PKG8_ID] = &sp_pkg8, +#endif }; #endif diff --git a/drivers/auth/img_parser_mod.c b/drivers/auth/img_parser_mod.c index c4688f867..535695d82 100644 --- a/drivers/auth/img_parser_mod.c +++ b/drivers/auth/img_parser_mod.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> -#include <errno.h> #include <limits.h> #include <stdint.h> #include <string.h> diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk index 4b8301541..53ebe30b6 100644 --- a/drivers/auth/mbedtls/mbedtls_common.mk +++ b/drivers/auth/mbedtls/mbedtls_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -23,15 +23,18 @@ MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \ + aes.c \ asn1parse.c \ asn1write.c \ + cipher.c \ + cipher_wrap.c \ memory_buffer_alloc.c \ oid.c \ platform.c \ platform_util.c \ bignum.c \ + gcm.c \ md.c \ - md_wrap.c \ pk.c \ pk_wrap.c \ pkparse.c \ @@ -72,7 +75,7 @@ endif ifeq (${HASH_ALG}, sha384) TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384 else ifeq (${HASH_ALG}, sha512) - TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512 + TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512 else TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256 endif @@ -87,11 +90,20 @@ else $(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS") endif -# Needs to be set to drive mbed TLS configuration correctly -$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID)) -$(eval $(call add_define,TF_MBEDTLS_KEY_SIZE)) -$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID)) +ifeq (${DECRYPTION_SUPPORT}, aes_gcm) + TF_MBEDTLS_USE_AES_GCM := 1 +else + TF_MBEDTLS_USE_AES_GCM := 0 +endif +# Needs to be set to drive mbed TLS configuration correctly +$(eval $(call add_defines,\ + $(sort \ + TF_MBEDTLS_KEY_ALG_ID \ + TF_MBEDTLS_KEY_SIZE \ + TF_MBEDTLS_HASH_ALG_ID \ + TF_MBEDTLS_USE_AES_GCM \ +))) $(eval $(call MAKE_LIB,mbedtls)) diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c index 04fbc648b..6d6efb503 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.c +++ b/drivers/auth/mbedtls/mbedtls_crypto.c @@ -4,19 +4,23 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> #include <stddef.h> #include <string.h> /* mbed TLS headers */ +#include <mbedtls/gcm.h> #include <mbedtls/md.h> #include <mbedtls/memory_buffer_alloc.h> #include <mbedtls/oid.h> #include <mbedtls/platform.h> +#include <mbedtls/x509.h> #include <common/debug.h> #include <drivers/auth/crypto_mod.h> #include <drivers/auth/mbedtls/mbedtls_common.h> #include <drivers/auth/mbedtls/mbedtls_config.h> +#include <plat/common/platform.h> #define LIB_NAME "mbed TLS" @@ -226,11 +230,121 @@ int calc_hash(unsigned int alg, void *data_ptr, } #endif /* MEASURED_BOOT */ +#if TF_MBEDTLS_USE_AES_GCM +/* + * Stack based buffer allocation for decryption operation. It could + * be configured to balance stack usage vs execution speed. + */ +#define DEC_OP_BUF_SIZE 128 + +static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, + unsigned int key_len, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len) +{ + mbedtls_gcm_context ctx; + mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; + unsigned char buf[DEC_OP_BUF_SIZE]; + unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE]; + unsigned char *pt = data_ptr; + size_t dec_len; + int diff, i, rc; + + mbedtls_gcm_init(&ctx); + + rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + while (len > 0) { + dec_len = MIN(sizeof(buf), len); + + rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + memcpy(pt, buf, dec_len); + pt += dec_len; + len -= dec_len; + } + + rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf)); + if (rc != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + /* Check tag in "constant-time" */ + for (diff = 0, i = 0; i < tag_len; i++) + diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i]; + + if (diff != 0) { + rc = CRYPTO_ERR_DECRYPTION; + goto exit_gcm; + } + + /* GCM decryption success */ + rc = CRYPTO_SUCCESS; + +exit_gcm: + mbedtls_gcm_free(&ctx); + return rc; +} + +/* + * Authenticated decryption of an image + */ +static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, + size_t len, const void *key, unsigned int key_len, + unsigned int key_flags, const void *iv, + unsigned int iv_len, const void *tag, + unsigned int tag_len) +{ + int rc; + + assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); + + switch (dec_algo) { + case CRYPTO_GCM_DECRYPT: + rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, + tag, tag_len); + if (rc != 0) + return rc; + break; + default: + return CRYPTO_ERR_DECRYPTION; + } + + return CRYPTO_SUCCESS; +} +#endif /* TF_MBEDTLS_USE_AES_GCM */ + /* * Register crypto library descriptor */ #if MEASURED_BOOT -REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash); +#if TF_MBEDTLS_USE_AES_GCM +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, + auth_decrypt); +#else +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, + NULL); +#endif +#else /* MEASURED_BOOT */ +#if TF_MBEDTLS_USE_AES_GCM +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, + auth_decrypt); #else -REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); +REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL); +#endif #endif /* MEASURED_BOOT */ diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c new file mode 100644 index 000000000..e4c92213a --- /dev/null +++ b/drivers/auth/tbbr/tbbr_cot_bl1.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> + +#include <platform_def.h> +#include <drivers/auth/mbedtls/mbedtls_config.h> + +#include <drivers/auth/auth_mod.h> +#include <drivers/auth/tbbr_cot_common.h> +#if USE_TBBR_DEFS +#include <tools_share/tbbr_oid.h> +#else +#include <platform_oid.h> +#endif + +static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID); +static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID); +static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FWU_HASH_OID); + +static const auth_img_desc_t bl2_image = { + .img_id = BL2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tb_fw_hash + } + } + } +}; + +/* + * FWU auth descriptor. + */ +static const auth_img_desc_t fwu_cert = { + .img_id = FWU_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &subject_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &scp_bl2u_hash, + .data = { + .ptr = (void *)scp_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &bl2u_hash, + .data = { + .ptr = (void *)tb_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &ns_bl2u_hash, + .data = { + .ptr = (void *)nt_world_bl_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +/* + * SCP_BL2U + */ +static const auth_img_desc_t scp_bl2u_image = { + .img_id = SCP_BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &scp_bl2u_hash + } + } + } +}; +/* + * BL2U + */ +static const auth_img_desc_t bl2u_image = { + .img_id = BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &bl2u_hash + } + } + } +}; +/* + * NS_BL2U + */ +static const auth_img_desc_t ns_bl2u_image = { + .img_id = NS_BL2U_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &fwu_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ns_bl2u_hash + } + } + } +}; +/* + * TB_FW_CONFIG + */ +static const auth_img_desc_t tb_fw_config = { + .img_id = TB_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tb_fw_config_hash + } + } + } +}; + +static const auth_img_desc_t fw_config = { + .img_id = FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &fw_config_hash + } + } + } +}; + +/* + * TBBR Chain of trust definition + */ +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, + [BL2_IMAGE_ID] = &bl2_image, + [HW_CONFIG_ID] = &hw_config, + [TB_FW_CONFIG_ID] = &tb_fw_config, + [FW_CONFIG_ID] = &fw_config, + [FWU_CERT_ID] = &fwu_cert, + [SCP_BL2U_IMAGE_ID] = &scp_bl2u_image, + [BL2U_IMAGE_ID] = &bl2u_image, + [NS_BL2U_IMAGE_ID] = &ns_bl2u_image +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c new file mode 100644 index 000000000..65a0478ab --- /dev/null +++ b/drivers/auth/tbbr/tbbr_cot_bl2.c @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> + +#include <platform_def.h> +#include <drivers/auth/mbedtls/mbedtls_config.h> + +#include <drivers/auth/auth_mod.h> +#include <drivers/auth/tbbr_cot_common.h> +#if USE_TBBR_DEFS +#include <tools_share/tbbr_oid.h> +#else +#include <platform_oid.h> +#endif + +static unsigned char soc_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; +static unsigned char trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char non_trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char content_pk_buf[PK_DER_LEN]; +static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; +#if defined(SPD_spmd) +static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN]; +#endif /* SPD_spmd */ + +static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID); +static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SCP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID); +static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID); +static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID); +static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID); +static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID); +#if defined(SPD_spmd) +static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG1_HASH_OID); +static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG2_HASH_OID); +static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG3_HASH_OID); +static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG4_HASH_OID); +static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG5_HASH_OID); +static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG6_HASH_OID); +static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG7_HASH_OID); +static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG8_HASH_OID); +#endif /* SPD_spmd */ + +/* + * Trusted key certificate + */ +static const auth_img_desc_t trusted_key_cert = { + .img_id = TRUSTED_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &subject_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &trusted_world_pk, + .data = { + .ptr = (void *)trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + }, + [1] = { + .type_desc = &non_trusted_world_pk, + .data = { + .ptr = (void *)non_trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +/* + * SCP Firmware + */ +static const auth_img_desc_t scp_fw_key_cert = { + .img_id = SCP_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &scp_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t scp_fw_content_cert = { + .img_id = SCP_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &scp_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &scp_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &scp_fw_hash, + .data = { + .ptr = (void *)scp_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t scp_bl2_image = { + .img_id = SCP_BL2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &scp_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &scp_fw_hash + } + } + } +}; +/* + * SoC Firmware + */ +static const auth_img_desc_t soc_fw_key_cert = { + .img_id = SOC_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &soc_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t soc_fw_content_cert = { + .img_id = SOC_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &soc_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &soc_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &soc_fw_hash, + .data = { + .ptr = (void *)soc_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &soc_fw_config_hash, + .data = { + .ptr = (void *)soc_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl31_image = { + .img_id = BL31_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &soc_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &soc_fw_hash + } + } + } +}; +/* SOC FW Config */ +static const auth_img_desc_t soc_fw_config = { + .img_id = SOC_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &soc_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &soc_fw_config_hash + } + } + } +}; +/* + * Trusted OS Firmware + */ +static const auth_img_desc_t trusted_os_fw_key_cert = { + .img_id = TRUSTED_OS_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &tos_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t trusted_os_fw_content_cert = { + .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_os_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &tos_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &tos_fw_hash, + .data = { + .ptr = (void *)tos_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tos_fw_extra1_hash, + .data = { + .ptr = (void *)tos_fw_extra1_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &tos_fw_extra2_hash, + .data = { + .ptr = (void *)tos_fw_extra2_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &tos_fw_config_hash, + .data = { + .ptr = (void *)tos_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra1_image = { + .img_id = BL32_EXTRA1_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_extra1_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra2_image = { + .img_id = BL32_EXTRA2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_extra2_hash + } + } + } +}; +/* TOS FW Config */ +static const auth_img_desc_t tos_fw_config = { + .img_id = TOS_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_config_hash + } + } + } +}; +/* + * Non-Trusted Firmware + */ +static const auth_img_desc_t non_trusted_fw_key_cert = { + .img_id = NON_TRUSTED_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t non_trusted_fw_content_cert = { + .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &non_trusted_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &nt_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_world_bl_hash, + .data = { + .ptr = (void *)nt_world_bl_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &nt_fw_config_hash, + .data = { + .ptr = (void *)nt_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl33_image = { + .img_id = BL33_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &non_trusted_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &nt_world_bl_hash + } + } + } +}; +/* NT FW Config */ +static const auth_img_desc_t nt_fw_config = { + .img_id = NT_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &non_trusted_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &nt_fw_config_hash + } + } + } +}; +/* Secure Partitions */ +#if defined(SPD_spmd) +static const auth_img_desc_t sip_sp_content_cert = { + .img_id = SIP_SP_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &sp_pkg1_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[0], + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &sp_pkg2_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[1], + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &sp_pkg3_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[2], + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &sp_pkg4_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[3], + .len = (unsigned int)HASH_DER_LEN + } + }, + [4] = { + .type_desc = &sp_pkg5_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[4], + .len = (unsigned int)HASH_DER_LEN + } + }, + [5] = { + .type_desc = &sp_pkg6_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[5], + .len = (unsigned int)HASH_DER_LEN + } + }, + [6] = { + .type_desc = &sp_pkg7_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[6], + .len = (unsigned int)HASH_DER_LEN + } + }, + [7] = { + .type_desc = &sp_pkg8_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[7], + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +DEFINE_SIP_SP_PKG(1); +DEFINE_SIP_SP_PKG(2); +DEFINE_SIP_SP_PKG(3); +DEFINE_SIP_SP_PKG(4); +DEFINE_SIP_SP_PKG(5); +DEFINE_SIP_SP_PKG(6); +DEFINE_SIP_SP_PKG(7); +DEFINE_SIP_SP_PKG(8); +#endif /* SPD_spmd */ + +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, + [HW_CONFIG_ID] = &hw_config, + [TRUSTED_KEY_CERT_ID] = &trusted_key_cert, + [SCP_FW_KEY_CERT_ID] = &scp_fw_key_cert, + [SCP_FW_CONTENT_CERT_ID] = &scp_fw_content_cert, + [SCP_BL2_IMAGE_ID] = &scp_bl2_image, + [SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert, + [SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert, + [BL31_IMAGE_ID] = &bl31_image, + [SOC_FW_CONFIG_ID] = &soc_fw_config, + [TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert, + [BL32_IMAGE_ID] = &bl32_image, + [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, + [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, + [TOS_FW_CONFIG_ID] = &tos_fw_config, + [NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, + [BL33_IMAGE_ID] = &bl33_image, + [NT_FW_CONFIG_ID] = &nt_fw_config, +#if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert, + [SP_PKG1_ID] = &sp_pkg1, + [SP_PKG2_ID] = &sp_pkg2, + [SP_PKG3_ID] = &sp_pkg3, + [SP_PKG4_ID] = &sp_pkg4, + [SP_PKG5_ID] = &sp_pkg5, + [SP_PKG6_ID] = &sp_pkg6, + [SP_PKG7_ID] = &sp_pkg7, + [SP_PKG8_ID] = &sp_pkg8, +#endif +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c new file mode 100644 index 000000000..ff3f22de1 --- /dev/null +++ b/drivers/auth/tbbr/tbbr_cot_common.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> + +#include <platform_def.h> +#include <drivers/auth/mbedtls/mbedtls_config.h> + +#include <drivers/auth/auth_mod.h> +#include <drivers/auth/tbbr_cot_common.h> +#if USE_TBBR_DEFS +#include <tools_share/tbbr_oid.h> +#else +#include <platform_oid.h> +#endif + +/* + * The platform must allocate buffers to store the authentication parameters + * extracted from the certificates. In this case, because of the way the CoT is + * established, we can reuse some of the buffers on different stages + */ + +static unsigned char fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char hw_config_hash_buf[HASH_DER_LEN]; +unsigned char tb_fw_hash_buf[HASH_DER_LEN]; +unsigned char scp_fw_hash_buf[HASH_DER_LEN]; +unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; + +/* + * common Parameter type descriptors across BL1 and BL2 + */ +auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID); +auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, 0); +auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG, 0); +auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG_ALG, 0); +auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_RAW_DATA, 0); + +/* common hash used across BL1 and BL2 */ +auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID); +auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID); +auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, FW_CONFIG_HASH_OID); +static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, HW_CONFIG_HASH_OID); + +/* trusted_boot_fw_cert */ +const auth_img_desc_t trusted_boot_fw_cert = { + .img_id = TRUSTED_BOOT_FW_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &subject_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &tb_fw_hash, + .data = { + .ptr = (void *)tb_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tb_fw_config_hash, + .data = { + .ptr = (void *)tb_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &hw_config_hash, + .data = { + .ptr = (void *)hw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &fw_config_hash, + .data = { + .ptr = (void *)fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +/* HW Config */ +const auth_img_desc_t hw_config = { + .img_id = HW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_boot_fw_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &hw_config_hash + } + } + } +}; diff --git a/drivers/brcm/chimp.c b/drivers/brcm/chimp.c new file mode 100644 index 000000000..81767bb5b --- /dev/null +++ b/drivers/brcm/chimp.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> + +#include <drivers/delay_timer.h> + +#include <chimp.h> +#include <chimp_nv_defs.h> + +#define CHIMP_DEFAULT_STARTUP_ADDR 0xb4300000 + +/* ChiMP's view of APE scratchpad memory for fastboot */ +#define CHIMP_FASTBOOT_ADDR 0x61000000 + +#define CHIMP_PREPARE_ACCESS_WINDOW(addr) \ + (\ + mmio_write_32(\ + NIC400_NITRO_CHIMP_S_IDM_IO_CONTROL_DIRECT, \ + addr & 0xffc00000)\ + ) +#define CHIMP_INDIRECT_TGT_ADDR(addr) \ + (CHIMP_INDIRECT_BASE + (addr & CHIMP_INDIRECT_ADDR_MASK)) + +#define CHIMP_CTRL_ADDR(x) (CHIMP_REG_CTRL_BASE + x) + +/* For non-PAXC builds */ +#ifndef CHIMP_FB1_ENTRY +#define CHIMP_FB1_ENTRY 0 +#endif + +#define CHIMP_DBG VERBOSE + +void bcm_chimp_write(uintptr_t addr, uint32_t value) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + mmio_write_32(CHIMP_INDIRECT_TGT_ADDR(addr), value); +} + +uint32_t bcm_chimp_read(uintptr_t addr) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + return mmio_read_32(CHIMP_INDIRECT_TGT_ADDR(addr)); +} + +void bcm_chimp_clrbits(uintptr_t addr, uint32_t bits) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + mmio_clrbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits); +} + +void bcm_chimp_setbits(uintptr_t addr, uint32_t bits) +{ + CHIMP_PREPARE_ACCESS_WINDOW(addr); + mmio_setbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits); +} + +int bcm_chimp_is_nic_mode(void) +{ + uint32_t val; + + /* Check if ChiMP straps are set */ + val = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW); + val &= CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK; + + return val == CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK; +} + +void bcm_chimp_fru_prog_done(bool is_done) +{ + uint32_t val; + + val = is_done ? (1 << CHIMP_FRU_PROG_DONE_BIT) : 0; + bcm_chimp_setbits(CHIMP_REG_ECO_RESERVED, val); +} + +int bcm_chimp_handshake_done(void) +{ + uint32_t value; + + value = bcm_chimp_read(CHIMP_REG_ECO_RESERVED); + value &= (1 << CHIMP_FLASH_ACCESS_DONE_BIT); + + return value != 0; +} + +int bcm_chimp_wait_handshake(void) +{ + uint32_t timeout = CHIMP_HANDSHAKE_TIMEOUT_MS; + uint32_t status; + + INFO("Waiting for ChiMP handshake...\n"); + do { + if (bcm_chimp_handshake_done()) + break; + /* No need to wait if ChiMP reported an error */ + status = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG); + if (status & CHIMP_ERROR_MASK) { + ERROR("ChiMP error 0x%x. Wait aborted\n", status); + break; + } + mdelay(1); + } while (--timeout); + + if (!bcm_chimp_handshake_done()) { + if (timeout == 0) { + WARN("Timeout waiting for ChiMP handshake\n"); + } + } else { + INFO("Got handshake from ChiMP!\n"); + } + + return bcm_chimp_handshake_done(); +} + +uint32_t bcm_chimp_read_ctrl(uint32_t offset) +{ + return bcm_chimp_read(CHIMP_CTRL_ADDR(offset)); +} + +static int bcm_chimp_nitro_reset(void) +{ + uint32_t timeout; + + /* Perform tasks done by M0 in NIC mode */ + CHIMP_DBG("Taking Nitro out of reset\n"); + mmio_setbits_32(CDRU_MISC_RESET_CONTROL, + /* MHB_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_MHB_RESET_N_R) | + /* PCI_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R) | + /* PM_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_PM_RESET_N_R) | + /* NIC_RESET_N */ + (1 << CDRU_MISC_RESET_CONTROL__CDRU_NITRO_RESET_N_R) + ); + + /* Wait until Nitro is out of reset */ + timeout = NIC_RESET_RELEASE_TIMEOUT_US; + do { + uint32_t value; + + value = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG); + if ((value & CHIMP_BPE_MODE_ID_MASK) == + CHIMP_BPE_MODE_ID_PATTERN) + break; + udelay(1); + } while (--timeout); + + if (timeout == 0) { + ERROR("NIC reset release timed out\n"); + return -1; + } + + return 0; +} + +static void bcm_nitro_secure_mode_enable(void) +{ + mmio_setbits_32(CDRU_NITRO_CONTROL, + (1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_MODE_R) | + (1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_OVERRIDE_R)); + mmio_write_32(NITRO_TZPC_TZPCDECPROT0clr, + /* NITRO_TZPC */ + 1 << NITRO_TZPC_TZPCDECPROT0clr__DECPROT0_chimp_m_clr_R); +} + +static int bcm_chimp_reset_and_initial_setup(void) +{ + + int err; + uint32_t handshake_reg; + + err = bcm_chimp_nitro_reset(); + if (err) + return err; + + /* Enable Nitro secure mode */ + bcm_nitro_secure_mode_enable(); + + /* Force ChiMP back into reset */ + bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG), + 1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R); + + handshake_reg = (1 << SR_IN_SMARTNIC_MODE_BIT); + + /* Get OTP secure Chimp boot status */ + if (mmio_read_32(CRMU_OTP_STATUS) & (1 << CRMU_OTP_STATUS_BIT)) + handshake_reg |= (1 << SR_CHIMP_SECURE_BOOT_BIT); + + bcm_chimp_write(CHIMP_REG_ECO_RESERVED, handshake_reg); + + CHIMP_DBG("ChiMP reset and initial handshake parameters set\n"); + + return 0; +} + +static void bcm_nitro_chimp_release_reset(void) +{ + bcm_chimp_clrbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG), + 1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R); + + CHIMP_DBG("Nitro Reset Released\n"); +} + +static void bcm_chimp_set_fastboot(int mode) +{ + uint32_t fb_entry; + + /* 1. Enable fastboot */ + bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG), + (1 << CHIMP_FAST_BOOT_MODE_BIT)); + fb_entry = CHIMP_FASTBOOT_ADDR | mode; + if (mode == CHIMP_FASTBOOT_JUMP_IN_PLACE) + fb_entry = CHIMP_FB1_ENTRY; + /* 2. Write startup address and mode */ + INFO("Setting fastboot type %d entry to 0x%x\n", mode, fb_entry); + bcm_chimp_write( + CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_FSTBOOT_PTR_REG), + fb_entry); +} + +#ifndef CHIMPFW_USE_SIDELOAD +static void bcm_chimp_load_fw_from_spi(uintptr_t spi_addr, size_t size) +{ + uintptr_t ape_scpad; + uintptr_t dest; + size_t bytes_left; + + ape_scpad = CHIMP_REG_CHIMP_APE_SCPAD; + dest = CHIMP_INDIRECT_TGT_ADDR(CHIMP_REG_CHIMP_APE_SCPAD); + bytes_left = size; + + while (bytes_left) { + uint32_t delta; + + delta = bytes_left > CHIMP_WINDOW_SIZE ? + bytes_left - CHIMP_WINDOW_SIZE : bytes_left; + CHIMP_PREPARE_ACCESS_WINDOW(ape_scpad); + INFO("Transferring %d byte(s) from 0x%lx to 0x%lx\n", + delta, spi_addr, dest); + /* + * This single memcpy call takes significant amount of time + * on Palladium. Be patient + */ + memcpy((void *)dest, (void *)spi_addr, delta); + bytes_left -= delta; + INFO("Transferred %d byte(s) from 0x%lx to 0x%lx (%lu%%)\n", + delta, spi_addr, dest, + ((size - bytes_left) * 100)/size); + spi_addr += delta; + dest += delta; + ape_scpad += delta; + } +} + +static int bcm_chimp_find_fw_in_spi(uintptr_t *addr, size_t *size) +{ + int i; + bnxnvm_master_block_header_t *master_block_hdr; + bnxnvm_directory_block_header_t *dir_block_hdr; + bnxnvm_directory_entry_t *dir_entry; + int found; + + found = 0; + + /* Read the master block */ + master_block_hdr = + (bnxnvm_master_block_header_t *)(uintptr_t)QSPI_BASE_ADDR; + if (master_block_hdr->sig != BNXNVM_MASTER_BLOCK_SIG) { + WARN("Invalid masterblock 0x%x (expected 0x%x)\n", + master_block_hdr->sig, + BNXNVM_MASTER_BLOCK_SIG); + return -NV_NOT_NVRAM; + } + if ((master_block_hdr->block_size > NV_MAX_BLOCK_SIZE) || + (master_block_hdr->directory_offset >= + master_block_hdr->nvram_size)) { + WARN("Invalid masterblock block size 0x%x or directory offset 0x%x\n", + master_block_hdr->block_size, + master_block_hdr->directory_offset); + return -NV_BAD_MB; + } + + /* Skip to the Directory block start */ + dir_block_hdr = + (bnxnvm_directory_block_header_t *) + ((uintptr_t)QSPI_BASE_ADDR + + master_block_hdr->directory_offset); + if (dir_block_hdr->sig != BNXNVM_DIRECTORY_BLOCK_SIG) { + WARN("Invalid directory header 0x%x (expected 0x%x)\n", + dir_block_hdr->sig, + BNXNVM_DIRECTORY_BLOCK_SIG); + return -NV_BAD_DIR_HEADER; + } + + /* Locate the firmware */ + for (i = 0; i < dir_block_hdr->entries; i++) { + *addr = ((uintptr_t)dir_block_hdr + dir_block_hdr->length + + i * dir_block_hdr->entry_length); + dir_entry = (bnxnvm_directory_entry_t *)(*addr); + if ((dir_entry->type == BNX_DIR_TYPE_BOOTCODE) || + (dir_entry->type == BNX_DIR_TYPE_BOOTCODE_2)) { + found = 1; + break; + } + } + + if (!found) + return -NV_FW_NOT_FOUND; + + *addr = QSPI_BASE_ADDR + dir_entry->item_location; + *size = dir_entry->data_length; + + INFO("Found chimp firmware at 0x%lx, size %lu byte(s)\n", + *addr, *size); + + return NV_OK; +} +#endif + +int bcm_chimp_initiate_fastboot(int fastboot_type) +{ + int err; + + if ((fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) && + (fastboot_type <= CHIMP_FASTBOOT_JUMP_DECOMPRESS)) { + CHIMP_DBG("Initiating ChiMP fastboot type %d\n", fastboot_type); + } + + /* + * If we are here, M0 did not setup Nitro because NIC mode + * strap was not present + */ + err = bcm_chimp_reset_and_initial_setup(); + if (err) + return err; + + if (fastboot_type > CHIMP_FASTBOOT_JUMP_DECOMPRESS) { + WARN("ChiMP setup deferred\n"); + return -1; + } + + if (fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) { + + if ((fastboot_type == CHIMP_FASTBOOT_JUMP_IN_PLACE) && + (CHIMP_FB1_ENTRY == 0)) { + ERROR("Missing ESAL entry point for fastboot type 1.\n" + "Fastboot failed\n"); + return -1; + } + + /* + * TODO: We need to think of the way to load the ChiMP fw. + * This could be SPI, NAND, etc. + * For now we temporarily stick to the SPI load unless + * CHIMPFW_USE_SIDELOAD is defined. Note that for the SPI NVRAM + * image we need to parse directory and get the image. + * When we load image from other media there is no need to + * parse because fw image can be directly placed into the APE's + * scratchpad. + * For sideload method we simply reset the ChiMP, set bpe_reg + * to do fastboot with the type we define, and release from + * reset so that ROM loader would initiate fastboot immediately + */ +#ifndef CHIMPFW_USE_SIDELOAD + { + uintptr_t spi_addr; + size_t size; + + err = bcm_chimp_find_fw_in_spi(&spi_addr, &size); + if (!err) { + INFO("Loading ChiMP firmware, addr 0x%lx, size %lu byte(s)\n", + spi_addr, size); + bcm_chimp_load_fw_from_spi(spi_addr, size); + } else { + ERROR("Error %d ChiMP firmware not in NVRAM directory!\n", + err); + } + } +#else + INFO("Skip ChiMP QSPI fastboot type %d due to sideload requested\n", + fastboot_type); +#endif + if (!err) { + INFO("Instruct ChiMP to fastboot\n"); + bcm_chimp_set_fastboot(fastboot_type); + INFO("Fastboot mode set\n"); + } + } + + bcm_nitro_chimp_release_reset(); + + return err; +} diff --git a/drivers/brcm/emmc/emmc_chal_sd.c b/drivers/brcm/emmc/emmc_chal_sd.c new file mode 100644 index 000000000..34d761c73 --- /dev/null +++ b/drivers/brcm/emmc/emmc_chal_sd.c @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <string.h> + +#include <lib/mmio.h> + +#include <platform_def.h> + +#include "bcm_emmc.h" +#include "emmc_chal_types.h" +#include "emmc_chal_sd.h" +#include "emmc_pboot_hal_memory_drv.h" + +extern void emmc_soft_reset(void); + +#define SD_VDD_WINDOW_1_6_TO_1_7 0x00000010 // 1.6 V to 1.7 Volts +#define SD_VDD_WINDOW_1_7_TO_1_8 0x00000020 // 1.7 V to 1.8 Volts +#define SD_VDD_WINDOW_1_8_TO_1_9 0x00000040 // 1.8 V to 1.9 Volts +#define SD_VDD_WINDOW_1_9_TO_2_0 0x00000080 // 1.9 V to 2.0 Volts +#define SD_VDD_WINDOW_2_0_TO_2_1 0x00000100 // 2.0 V to 2.1 Volts +#define SD_VDD_WINDOW_2_1_TO_2_2 0x00000200 // 2.1 V to 2.2 Volts +#define SD_VDD_WINDOW_2_2_TO_2_3 0x00000400 // 2.2 V to 2.3 Volts +#define SD_VDD_WINDOW_2_3_TO_2_4 0x00000800 // 2.3 V to 2.4 Volts +#define SD_VDD_WINDOW_2_4_TO_2_5 0x00001000 // 2.4 V to 2.5 Volts +#define SD_VDD_WINDOW_2_5_TO_2_6 0x00002000 // 2.5 V to 2.6 Volts +#define SD_VDD_WINDOW_2_6_TO_2_7 0x00004000 // 2.6 V to 2.7 Volts +#define SD_VDD_WINDOW_2_7_TO_2_8 0x00008000 // 2.7 V to 2.8 Volts +#define SD_VDD_WINDOW_2_8_TO_2_9 0x00010000 // 2.8 V to 2.9 Volts +#define SD_VDD_WINDOW_2_9_TO_3_0 0x00020000 // 2.9 V to 3.0 Volts +#define SD_VDD_WINDOW_3_0_TO_3_1 0x00040000 // 3.0 V to 3.1 Volts +#define SD_VDD_WINDOW_3_1_TO_3_2 0x00080000 // 3.1 V to 3.2 Volts +#define SD_VDD_WINDOW_3_2_TO_3_3 0x00100000 // 3.2 V to 3.3 Volts +#define SD_VDD_WINDOW_3_3_TO_3_4 0x00200000 // 3.3 V to 3.4 Volts +#define SD_VDD_WINDOW_3_4_TO_3_5 0x00400000 // 3.4 V to 3.5 Volts +#define SD_VDD_WINDOW_3_5_TO_3_6 0x00800000 // 3.5 V to 3.6 Volts + +#define SD_VDD_WINDOW_1_6_TO_2_6 (SD_VDD_WINDOW_1_6_TO_1_7 | \ + SD_VDD_WINDOW_1_7_TO_1_8 | \ + SD_VDD_WINDOW_1_8_TO_1_9 | \ + SD_VDD_WINDOW_1_9_TO_2_0 | \ + SD_VDD_WINDOW_2_0_TO_2_1 | \ + SD_VDD_WINDOW_2_1_TO_2_2 | \ + SD_VDD_WINDOW_2_2_TO_2_3 | \ + SD_VDD_WINDOW_2_3_TO_2_4 | \ + SD_VDD_WINDOW_2_4_TO_2_5 | \ + SD_VDD_WINDOW_2_5_TO_2_6) + +#define SD_VDD_WINDOW_2_6_TO_3_2 (SD_VDD_WINDOW_2_6_TO_2_7 | \ + SD_VDD_WINDOW_2_7_TO_2_8 | \ + SD_VDD_WINDOW_2_8_TO_2_9 | \ + SD_VDD_WINDOW_2_9_TO_3_0 | \ + SD_VDD_WINDOW_3_0_TO_3_1 | \ + SD_VDD_WINDOW_3_1_TO_3_2) + +#define SD_VDD_WINDOW_3_2_TO_3_6 (SD_VDD_WINDOW_3_2_TO_3_3 | \ + SD_VDD_WINDOW_3_3_TO_3_4 | \ + SD_VDD_WINDOW_3_4_TO_3_5 | \ + SD_VDD_WINDOW_3_5_TO_3_6) + + +static int32_t chal_sd_set_power(struct sd_dev *handle, + uint32_t voltage, uint32_t state); + +static void chal_sd_set_dma_boundary(struct sd_dev *handle, uint32_t boundary); + +static int32_t chal_sd_setup_handler(struct sd_dev *handle, + uint32_t sdBbase, uint32_t hostBase); + +/* + * Configure host controller pwr settings, + * to match voltage requirements by SD Card + */ +static int32_t chal_sd_set_power(struct sd_dev *handle, + uint32_t voltage, uint32_t state) +{ + int32_t rc, rval = SD_FAIL; + uint32_t time = 0; + + if (handle == NULL) + return SD_INVALID_HANDLE; + + mmio_clrsetbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, + (SD4_EMMC_TOP_CTRL_SDVSELVDD1_MASK | + SD4_EMMC_TOP_CTRL_SDPWR_MASK), + (voltage << 9)); + + /* + * Long delay is required here in emulation. Without this, the initial + * commands sent to the eMMC card timeout. We don't know if this + * delay is necessary with silicon, leaving in for safety. + * It is observed that 403ms on emulation system and as per the clock + * calculations it is expected to complete with in 1ms on chip + */ + do { + rc = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET); + + if ((rc & SD4_EMMC_TOP_INTR_CRDINS_MASK) == + SD4_EMMC_TOP_INTR_CRDINS_MASK) + break; + + mdelay(1); + } while (time++ < EMMC_CARD_DETECT_TIMEOUT_MS); + + if (time >= EMMC_CARD_DETECT_TIMEOUT_MS) { + ERROR("EMMC: Card insert event detection timeout\n"); + return rval; + } + + VERBOSE("EMMC: Card detection delay: %dms\n", time); + + if (state) + mmio_setbits_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL_OFFSET, + SD4_EMMC_TOP_CTRL_SDPWR_MASK); + + /* dummy write & ack to verify if the sdio is ready to send commads */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_ARG_OFFSET, 0); + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CMD_OFFSET, 0); + + /* + * 63ms observed on emulation system, As per clock calculations + * it will complete < 1ms on chip. + */ + time = 0; + do { + rc = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET); + + if (rc & SD4_EMMC_TOP_INTR_ERRIRQ_MASK) + break; + + if ((rc & SD4_EMMC_TOP_INTR_CMDDONE_MASK) == + SD4_EMMC_TOP_INTR_CMDDONE_MASK) + break; + + mdelay(1); + } while (time++ < EMMC_CMD_TIMEOUT_MS); + + if (time >= EMMC_CMD_TIMEOUT_MS) { + WARN("%s %d Initial dummy command timeout is happened\n", + __func__, __LINE__); + return rval; + } + + VERBOSE("EMMC: Dummy Command delay: %dms\n", time); + + return SD_OK; +} + +/* + * Configure DMA Boundaries + */ +static void chal_sd_set_dma_boundary(struct sd_dev *handle, uint32_t boundary) +{ + if (handle == NULL) + return; + + mmio_clrsetbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BLOCK_OFFSET, + SD4_EMMC_TOP_BLOCK_HSBS_MASK, boundary); +} + +static int32_t chal_sd_setup_handler(struct sd_dev *handle, uint32_t sdBase, + uint32_t hostBase) +{ + if (handle == NULL) + return SD_INVALID_HANDLE; + + handle->ctrl.sdRegBaseAddr = sdBase; + handle->ctrl.hostRegBaseAddr = hostBase; + handle->ctrl.present = 0; + handle->ctrl.rca = 0; + handle->ctrl.blkGapEnable = 0; + handle->ctrl.cmdStatus = 0; + + return SD_OK; +} + +/* + * Initialize SD Host controller + */ +int32_t chal_sd_init(CHAL_HANDLE *sd_handle) +{ + uint32_t cap_val_l = 0; + uint32_t ctl_val, voltage; + uint32_t timeout_val; + struct sd_dev *handle; + uint32_t reg_val; + int32_t rval = SD_FAIL; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + /* + * Set SDIO Host Controller capabilities register + */ + EMMC_TRACE("Set Host Controller Capabilities register\n"); + + reg_val = 0; + reg_val |= (1 << ICFG_SDIO0_CAP0__SLOT_TYPE_R); + reg_val |= (0 << ICFG_SDIO0_CAP0__INT_MODE_R); + reg_val |= (0 << ICFG_SDIO0_CAP0__SYS_BUS_64BIT_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__VOLTAGE_1P8V_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__VOLTAGE_3P0V_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__VOLTAGE_3P3V_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__SUSPEND_RESUME_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__SDMA_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__HIGH_SPEED_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__ADMA2_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__EXTENDED_MEDIA_R); + reg_val |= (2 << ICFG_SDIO0_CAP0__MAX_BLOCK_LEN_R); + reg_val |= (0xd0 << ICFG_SDIO0_CAP0__BASE_CLK_FREQ_R); + reg_val |= (1 << ICFG_SDIO0_CAP0__TIMEOUT_UNIT_R); + reg_val |= (0x30 << ICFG_SDIO0_CAP0__TIMEOUT_CLK_FREQ_R); + + mmio_write_32(ICFG_SDIO0_CAP0, reg_val); + + reg_val = 0; + reg_val |= (1 << ICFG_SDIO0_CAP1__SPI_BLOCK_MODE_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__SPI_MODE_R); + reg_val |= (0 << ICFG_SDIO0_CAP1__CLK_MULT_R); + reg_val |= (0 << ICFG_SDIO0_CAP1__RETUNING_MODE_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__TUNE_SDR50_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__TIME_RETUNE_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DRIVER_D_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DRIVER_C_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DRIVER_A_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__DDR50_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__SDR104_R); + reg_val |= (1 << ICFG_SDIO0_CAP1__SDR50_R); + + mmio_write_32(ICFG_SDIO0_CAP1, reg_val); + + /* Reset the SDIO controller */ + chal_sd_stop(); + + /* Turn on SD clock */ + chal_sd_set_clock(sd_handle, + chal_sd_freq_2_div_ctrl_setting(INIT_CLK_FREQ), 1); + + /* program data time out value to the max */ + timeout_val = SD_HOST_CORE_TIMEOUT; + + ctl_val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + ctl_val |= ((timeout_val & 0xf) << SD4_EMMC_TOP_CTRL1_DTCNT_SHIFT); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + ctl_val); + + /* enable all interrupt status */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN1_OFFSET, + 0); + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN2_OFFSET, + 0); + + SD_US_DELAY(100); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN1_OFFSET, + SD_NOR_INTERRUPTS | SD_ERR_INTERRUPTS); + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_INTREN2_OFFSET, + SD_NOR_INTERRUPTS | SD_ERR_INTERRUPTS); + + /* Select SD bus voltage */ + cap_val_l = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CAPABILITIES1_OFFSET); + handle->cfg.voltage = 0; + voltage = 0x7; + + if (cap_val_l & SD4_EMMC_TOP_CAPABILITIES1_V33_MASK) { + handle->cfg.voltage |= SD_VDD_WINDOW_3_3_TO_3_4; + voltage = 0x7; + } else if (cap_val_l & SD4_EMMC_TOP_CAPABILITIES1_V3_MASK) { + handle->cfg.voltage |= SD_VDD_WINDOW_3_0_TO_3_1; + voltage = 0x6; + } else if (cap_val_l & SD4_EMMC_TOP_CAPABILITIES1_V18_MASK) { + handle->cfg.voltage |= SD_VDD_WINDOW_1_8_TO_1_9; + voltage = 0x5; + } + + rval = chal_sd_set_power(handle, voltage, SD4_EMMC_TOP_CTRL_SDPWR_MASK); + + ctl_val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_HCVERSIRQ_OFFSET); + handle->ctrl.version = ((ctl_val >> 16) & 0xFF); + + return rval; +} + +void chal_sd_set_speed(CHAL_HANDLE *sd_handle, uint32_t speed) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return; + + handle = (struct sd_dev *) sd_handle; + + if (speed) { + EMMC_TRACE("enable HighSpeed\n"); + mmio_setbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, + SD4_EMMC_TOP_CTRL_HSEN_MASK); + } else { + EMMC_TRACE("disable HighSpeed\n"); + mmio_clrbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, + SD4_EMMC_TOP_CTRL_HSEN_MASK); + } +} + +int32_t chal_sd_stop(void) +{ + uintptr_t idm_rst_ctrl_addr = EMMC_IDM_RESET_CTRL_ADDR; + + /* Configure IO pins */ + emmc_soft_reset(); + + /* Reset the SDIO controller */ + mmio_write_32(idm_rst_ctrl_addr, 1); + SD_US_DELAY(100); + mmio_write_32(idm_rst_ctrl_addr, 0); + SD_US_DELAY(100); + + return SD_OK; +} + +/* + * Check if host supports specified capability + * returns -ve val on error, 0 if capability not supported else 1. + */ +int32_t chal_sd_check_cap(CHAL_HANDLE *sd_handle, uint32_t caps) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (caps & mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CAPABILITIES1_OFFSET)) + return 1; + else + return 0; +} + +int32_t chal_sd_start(CHAL_HANDLE *sd_handle, + uint32_t mode, uint32_t sd_base, uint32_t host_base) +{ + + struct sd_dev *handle; + int32_t rval = SD_FAIL; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + handle->cfg.mode = SD_PIO_MODE; /* set to PIO mode first for init */ + handle->cfg.dma = SD_DMA_OFF; + + chal_sd_setup_handler(handle, sd_base, host_base); + + /* init and start hw */ + rval = chal_sd_init(sd_handle); + if (rval != SD_OK) + return rval; + + chal_sd_clear_pending_irq(sd_handle); + + handle->ctrl.eventList = 0; + handle->cfg.mode = mode; + + return SD_OK; +} + +/* + * Function to check 8bits of err generated from auto CMD12 + */ +int32_t chal_sd_get_atuo12_error(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + return (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_ERRSTAT_OFFSET) & 0xFF); +} + +/* + * Read present state register + */ +uint32_t chal_sd_get_present_status(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + return mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_PSTATE_OFFSET); +} + +/* + * Set SD bus width + */ +int32_t chal_sd_config_bus_width(CHAL_HANDLE *sd_handle, int32_t width) +{ + uint32_t ctl_val; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + ctl_val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET); + + switch (width) { +#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT + case SD_BUS_DATA_WIDTH_8BIT: + ctl_val &= ~SD_BUS_DATA_WIDTH_4BIT; + ctl_val |= SD_BUS_DATA_WIDTH_8BIT; + break; +#endif + case SD_BUS_DATA_WIDTH_4BIT: + ctl_val &= ~SD_BUS_DATA_WIDTH_8BIT; + ctl_val |= SD_BUS_DATA_WIDTH_4BIT; + break; + case SD_BUS_DATA_WIDTH_1BIT: + ctl_val &= ~(SD_BUS_DATA_WIDTH_4BIT | SD_BUS_DATA_WIDTH_8BIT); + break; + default: + return SD_INV_DATA_WIDTH; + }; + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL_OFFSET, + ctl_val); + + return SD_OK; +} + +/* + * Function to enable or disable DMA control. + */ +int32_t chal_sd_set_dma(CHAL_HANDLE *sd_handle, uint32_t mode) +{ + uint32_t val; + struct sd_dev *handle; + int32_t rc; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + if (mode) { + rc = chal_sd_check_cap(sd_handle, + SD4_EMMC_TOP_CAPABILITIES1_SDMA_MASK | + SD4_EMMC_TOP_CAPABILITIES1_ADMA2_MASK); + if (rc < 0) + return rc; + + if (rc) { + + handle->cfg.dma = mode; + val = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET); + val &= ~(SD4_EMMC_TOP_CTRL_DMASEL_MASK); + val |= handle->cfg.dma - 1; + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL_OFFSET, val); + return SD_OK; + } + } + handle->cfg.dma = 0; + + return SD_FAIL; +} + +/* + * Get current DMA address. + * Called only when there is no data transaction activity. + */ +uintptr_t chal_sd_get_dma_addr(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (handle->cfg.dma == SD_DMA_OFF) + return 0; + + return (uintptr_t)mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_SYSADDR_OFFSET); +} + +int32_t chal_sd_send_cmd(CHAL_HANDLE *sd_handle, uint32_t cmd_idx, + uint32_t argument, uint32_t options) +{ + uint32_t cmd_mode_reg = 0; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + EMMC_TRACE("%s %d cmd:%d argReg:%x options:%x\n", + __func__, __LINE__, cmd_idx, argument, options); + + /* Configure the value for command and mode registers */ + cmd_mode_reg = (cmd_idx << 24) | options; + + /* + * 1. Write block size reg & block count reg, + * this is done in the tx or rx setup + */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_BLOCK_OFFSET, + handle->ctrl.blkReg); + + /* 2. Write argument reg */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_ARG_OFFSET, + argument); + handle->ctrl.argReg = argument; + + /* + * 3. Write transfer mode reg & command reg, check the DMA bit which is + * set before this function call if it is selected. + */ + if (cmd_idx == 24 || cmd_idx == 25 || cmd_idx == 18 || cmd_idx == 17 || + cmd_idx == 42 || cmd_idx == 51 || cmd_idx == 53) + cmd_mode_reg |= ((handle->cfg.dma) ? 1 : 0); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CMD_OFFSET, + cmd_mode_reg); + + handle->ctrl.cmdIndex = cmd_idx; + + return SD_OK; +} + +int32_t chal_sd_set_dma_addr(CHAL_HANDLE *sd_handle, uintptr_t address) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (handle->cfg.dma == SD_DMA_OFF) + return SD_FAIL; + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_SYSADDR_OFFSET, + address); + return SD_OK; +} + +uint32_t chal_sd_freq_2_div_ctrl_setting(uint32_t desired_freq) +{ + /* + * Divider control setting represents 1/2 of the actual divider value. + * + * DesiredFreq = BaseClockFreq / (2 * div_ctrl_setting) + * + * ==> div_ctrl_setting = BaseClockFreq / (2 * DesiredFreq) + */ + uint32_t div_ctrl_setting; + uint32_t actual_freq; + + assert(desired_freq != 0); + + /* Special case, 0 = divider of 1. */ + if (desired_freq >= BASE_CLK_FREQ) + return 0; + + /* Normal case, desired_freq < BASE_CLK_FREQ */ + div_ctrl_setting = BASE_CLK_FREQ / (2 * desired_freq); + + actual_freq = BASE_CLK_FREQ / (2 * div_ctrl_setting); + + if (actual_freq > desired_freq) { + /* + * Division does not result in exact freqency match. + * Make sure resulting frequency does not exceed requested freq. + */ + div_ctrl_setting++; + } + + return div_ctrl_setting; +} + +int32_t chal_sd_set_clock(CHAL_HANDLE *sd_handle, uint32_t div_ctrl_setting, + uint32_t on) +{ + uint32_t value; + struct sd_dev *handle; + uint32_t time; + uint32_t clk_sel_high_byte = 0xFF & (div_ctrl_setting >> 8); + uint32_t clk_sel_low_byte = 0xFF & div_ctrl_setting; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + EMMC_TRACE("set_clock(div_ctrl_setting=%d,on=%d)\n", + div_ctrl_setting, on); + + handle = (struct sd_dev *) sd_handle; + + /* Read control register content. */ + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + + /* Disable Clock */ + value &= ~(SD4_EMMC_TOP_CTRL1_SDCLKEN_MASK); + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + value); + + /* Clear bits of interest. */ + value &= ~(SD4_EMMC_TOP_CTRL1_SDCLKSEL_MASK | + SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_MASK); + + /* Set bits of interest to new value. */ + value |= (SD4_EMMC_TOP_CTRL1_SDCLKSEL_MASK & + (clk_sel_low_byte << SD4_EMMC_TOP_CTRL1_SDCLKSEL_SHIFT)); + value |= (SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_MASK & + (clk_sel_high_byte << SD4_EMMC_TOP_CTRL1_SDCLKSEL_UP_SHIFT)); + value |= SD4_EMMC_TOP_CTRL1_ICLKEN_MASK; + + /* Write updated value back to control register. */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + value); + + time = 0; + do { + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + + if ((value & SD4_EMMC_TOP_CTRL1_ICLKSTB_MASK) == + SD4_EMMC_TOP_CTRL1_ICLKSTB_MASK) + break; + + mdelay(1); + } while (time++ < EMMC_CLOCK_SETTING_TIMEOUT_MS); + + if (time >= EMMC_CLOCK_SETTING_TIMEOUT_MS) + WARN("%s %d clock settings timeout happenedi (%dms)\n", + __func__, __LINE__, time); + + VERBOSE("EMMC: clock settings delay: %dms\n", time); + + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + + if (on) + value |= SD4_EMMC_TOP_CTRL1_SDCLKEN_MASK; + + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + value); + + return SD_OK; +} + +/* + * function to setup DMA buffer and data length, calculates block + * size and the number of blocks to be transferred and return + * the DMA buffer address. + */ +int32_t chal_sd_setup_xfer(CHAL_HANDLE *sd_handle, + uint8_t *data, uint32_t length, int32_t dir) +{ + uint32_t blocks = 0; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + if (length <= handle->cfg.blockSize) { + handle->ctrl.blkReg = length | handle->cfg.dmaBoundary; + } else { + blocks = length / handle->cfg.blockSize; + handle->ctrl.blkReg = (blocks << 16) | handle->cfg.blockSize | + handle->cfg.dmaBoundary; + } + + if (handle->cfg.dma != SD_DMA_OFF) { + /* For DMA target address setting, physical address should be used */ + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_SYSADDR_OFFSET, + (uintptr_t)data); + } + + return SD_OK; +} + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +/* + * function to write one block data directly to the + * host controller's FIFO which is 1K uint8_t or + * 2K uint8_t in size. + * It is used in Non-DMA mode for data transmission. + */ +int32_t chal_sd_write_buffer(CHAL_HANDLE *sd_handle, uint32_t length, + uint8_t *data) +{ + uint32_t i, leftOver = 0, blockSize, size, value = 0; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + blockSize = handle->cfg.blockSize; + + if (length == 0) + return SD_OK; + + /* PIO mode, push into fifo word by word */ + if (length >= blockSize) { + size = blockSize; + } else { + size = ((length >> 2) << 2); + leftOver = length % 4; + } + + for (i = 0; i < size; i += 4) { + value = *(uint32_t *)(data + i); + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET, value); + } +/* + * BUG ALERT: + * This implementation has TWO issues that must be addressed before you + * can safely INCLUDE_EMMC_DRIVER_WRITE_CODE. + * + * (1) For the last leftOver bytes, driver writes full word, which means + * some of the eMMC content (i.e. "4 - leftOver" will be erroneously + * overwritten). + * (2) eMMC is a block device. What happens when less than a full block of + * data is submitted??? + */ + if (leftOver > 0) { + value = ((*(uint32_t *)(data + i)) << (4 - leftOver)); + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET, value); + } + + return SD_OK; +} +#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */ + +/* + * Function to read maximal one block data directly + * from the data port of the host controller (FIFO). It is used + * in Non-DMA mode for data transmission. + */ +int32_t chal_sd_read_buffer(CHAL_HANDLE *sd_handle, uint32_t length, + uint8_t *data) +{ + uint32_t i, size, leftOver, blockSize, value; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + value = 0; + + blockSize = handle->cfg.blockSize; + + /* PIO mode, extract fifo word by word */ + if (length >= blockSize) { + size = blockSize; + leftOver = 0; + } else { + leftOver = length % 4; + size = ((length >> 2) << 2); + } + + for (i = 0; i < size; i += 4) { + value = + mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET); + memcpy((void *)(data + i), &value, sizeof(uint32_t)); + } + + if (leftOver > 0) { + value = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET); + + /* + * Copy remaining non-full word bytes. + * (We run ARM as Little Endian) + */ + uint8_t j = 0; + + for (j = 0; j < leftOver; j++) { + data[i + j] = (value >> (j * 8)) & 0xFF; + } + } + + return SD_OK; +} + +/* + * Resets both DAT or CMD line. + */ +int32_t chal_sd_reset_line(CHAL_HANDLE *sd_handle, uint32_t line) +{ + uint32_t control, flag; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + flag = SD4_EMMC_TOP_CTRL1_CMDRST_MASK | SD4_EMMC_TOP_CTRL1_DATRST_MASK; + + if (flag != (line | flag)) + return SD_FAIL; + + control = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + control |= line; + mmio_write_32(handle->ctrl.sdRegBaseAddr + SD4_EMMC_TOP_CTRL1_OFFSET, + control); + + /* reset CMD and DATA line should always work, no need to timed out */ + do { + control = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_CTRL1_OFFSET); + } while (control & line); + + return SD_OK; +} + +/* + * Function to be called once a SD command is done to read + * back it's response data. + */ +int32_t chal_sd_get_response(CHAL_HANDLE *sd_handle, uint32_t *resp) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + resp[0] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP0_OFFSET); + resp[1] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP2_OFFSET); + resp[2] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP4_OFFSET); + resp[3] = mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_RESP6_OFFSET); + + return SD_OK; +} + +/* + * The function is called to clean all the pending interrupts. + */ +int32_t chal_sd_clear_pending_irq(CHAL_HANDLE *sd_handle) +{ + uint32_t status = SD_OK; + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *)sd_handle; + + /* Make sure clean all interrupts */ + do { + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET, 0xFFFFFFFF); + SD_US_DELAY(10); + } while (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET)); + + return status; +} + +/* + * The function returns interrupt status register value. + */ +int32_t chal_sd_get_irq_status(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + return (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET)); +} + +/* + * The function clears interrupt(s) specified in the mask. + */ +int32_t chal_sd_clear_irq(CHAL_HANDLE *sd_handle, uint32_t mask) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + /* Make sure clean masked interrupts */ + do { + mmio_write_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET, mask); + SD_US_DELAY(10); + } while (mask & + mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTR_OFFSET)); + + return SD_OK; +} + +/* + * Description: The function configures the SD host controller. + */ +int32_t chal_sd_config(CHAL_HANDLE *sd_handle, uint32_t speed, uint32_t retry, + uint32_t boundary, uint32_t blkSize, uint32_t dma) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return SD_INVALID_HANDLE; + + handle = (struct sd_dev *) sd_handle; + + handle->cfg.speedMode = speed; + handle->cfg.retryLimit = retry; + handle->cfg.dmaBoundary = boundary; + handle->cfg.blockSize = blkSize; + + chal_sd_set_dma(sd_handle, dma); + SD_US_DELAY(100); + chal_sd_set_dma_boundary(handle, boundary); + SD_US_DELAY(100); + + chal_sd_set_speed(sd_handle, speed); + + SD_US_DELAY(100); + return SD_OK; +} + +/* + * Cleans up HC FIFO. + */ +void chal_sd_dump_fifo(CHAL_HANDLE *sd_handle) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return; + + handle = (struct sd_dev *)sd_handle; + + /* in case there still data in the host buffer */ + while (mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_PSTATE_OFFSET) & 0x800) { + mmio_read_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_BUFDAT_OFFSET); + }; +} + +/* + * Enable or disable a SD interrupt signal. + */ +void chal_sd_set_irq_signal(CHAL_HANDLE *sd_handle, uint32_t mask, + uint32_t state) +{ + struct sd_dev *handle; + + if (sd_handle == NULL) + return; + + handle = (struct sd_dev *)sd_handle; + + if (state) + mmio_setbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTREN2_OFFSET, mask); + else + mmio_clrbits_32(handle->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_INTREN2_OFFSET, mask); +} diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c new file mode 100644 index 000000000..d6ad4bc9c --- /dev/null +++ b/drivers/brcm/emmc/emmc_csl_sdcard.c @@ -0,0 +1,1087 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdlib.h> +#include <string.h> +#include <stddef.h> + +#include <arch_helpers.h> +#include <lib/mmio.h> + +#include "bcm_emmc.h" +#include "emmc_chal_types.h" +#include "emmc_csl_sdprot.h" +#include "emmc_chal_sd.h" +#include "emmc_csl_sdcmd.h" +#include "emmc_csl_sd.h" +#include "emmc_pboot_hal_memory_drv.h" + +#define SD_CARD_BUSY 0x80000000 +#define SD_CARD_RETRY_LIMIT 1000 +#define SD_CARD_HIGH_SPEED_PS 13 +#define SD_CHK_HIGH_SPEED_MODE 0x00FFFFF1 +#define SD_SET_HIGH_SPEED_MODE 0x80FFFFF1 +#define SD_MMC_ENABLE_HIGH_SPEED 0x03b90100 //0x03b90103 +#define SD_MMC_8BIT_MODE 0x03b70200 +#define SD_MMC_4BIT_MODE 0x03b70100 +#define SD_MMC_1BIT_MODE 0x03b70000 + +#define SD_MMC_BOOT_8BIT_MODE 0x03b10200 +#define SD_MMC_BOOT_4BIT_MODE 0x03b10100 +#define SD_MMC_BOOT_1BIT_MODE 0x03b10000 +#define SDIO_HW_EMMC_EXT_CSD_BOOT_CNF 0X03B30000 + +#ifdef USE_EMMC_FIP_TOC_CACHE +/* + * Cache size mirrors the size of the global eMMC temp buffer + * which is used for non-image body reads such as headers, ToC etc. + */ +#define CACHE_SIZE ((EMMC_BLOCK_SIZE) * 2) +#define PARTITION_BLOCK_ADDR ((PLAT_FIP_ATTEMPT_OFFSET)/(EMMC_BLOCK_SIZE)) + +static uint32_t cached_partition_block; +static uint8_t cached_block[CACHE_SIZE]; +#endif + +static int set_card_data_width(struct sd_handle *handle, int width); +static int abort_err(struct sd_handle *handle); +static int err_recovery(struct sd_handle *handle, uint32_t errors); +static int xfer_data(struct sd_handle *handle, uint32_t mode, uint32_t addr, + uint32_t length, uint8_t *base); + +int set_boot_config(struct sd_handle *handle, uint32_t config) +{ + return mmc_cmd6(handle, SDIO_HW_EMMC_EXT_CSD_BOOT_CNF | config); +} + +void process_csd_mmc_speed(struct sd_handle *handle, uint32_t csd_mmc_speed) +{ + uint32_t div_ctrl_setting; + + /* CSD field TRAN_SPEED: + * Bits [2:0] 0 = 100 KHz + * 1 = 1 MHz + * 2 = 10 MHz + * 3 = 100 MHz + * 4...7 Reserved. + * Bits [6:3] 0 = Reserved + * 1 = 1.0 + * 2 = 1.2 + * 3 = 1.3 + * 4 = 1.5 + * 5 = 2.0 + * 6 = 2.6 + * 7 = 3.0 + * 8 = 3.5 + * 9 = 4.0 + * A = 4.5 + * B = 5.2 + * C = 5.5 + * D = 6.0 + * E = 7.0 + * F = 8.0 + * For cards supporting version 4.0, 4.1, and 4.2 of the standard, + * the value shall be 20 MHz (0x2A). + * For cards supporting version 4.3 , the value shall be 26 MHz (0x32) + */ + + switch (csd_mmc_speed & 0x7F) { + case 0x2A: + EMMC_TRACE("Speeding up eMMC clock to 20MHz\n"); + div_ctrl_setting = + chal_sd_freq_2_div_ctrl_setting(20 * 1000 * 1000); + break; + case 0x32: + EMMC_TRACE("Speeding up eMMC clock to 26MHz\n"); + div_ctrl_setting = + chal_sd_freq_2_div_ctrl_setting(26 * 1000 * 1000); + break; + default: + /* Unknown */ + return; + } + + chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 0); + + chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 1); + + SD_US_DELAY(1000); +} + + +/* + * The function changes SD/SDIO/MMC card data width if + * the card support configurable data width. The host controller + * and the card has to be in the same bus data width. + */ +int set_card_data_width(struct sd_handle *handle, int width) +{ + uint32_t data_width = 0; + int is_valid_arg = 1; + int rc = SD_FAIL; + char *bitwidth_str = " "; + char *result_str = "failed"; + + switch (width) { +#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT + case SD_BUS_DATA_WIDTH_8BIT: + data_width = SD_MMC_8BIT_MODE; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "8_BIT"; +#endif + break; +#endif + case SD_BUS_DATA_WIDTH_4BIT: + data_width = SD_MMC_4BIT_MODE; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "4_BIT"; +#endif + break; + + case SD_BUS_DATA_WIDTH_1BIT: + data_width = SD_MMC_1BIT_MODE; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "1_BIT"; +#endif + break; + + default: + is_valid_arg = 0; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + bitwidth_str = "unknown"; +#endif + break; + } + + if (is_valid_arg) { + rc = mmc_cmd6(handle, data_width); + if (rc == SD_OK) { +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + result_str = "succeeded"; +#endif + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + width); + } else { +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + result_str = "failed"; +#endif + } + } else { + rc = SD_FAIL; +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE + result_str = "ignored"; +#endif + } + + VERBOSE("SDIO Data Width(%s) %s.\n", bitwidth_str, result_str); + + return rc; +} + + +/* + * Error handling routine. Does abort data + * transmission if error is found. + */ +static int abort_err(struct sd_handle *handle) +{ + uint32_t present, options, event, rel = 0; + struct sd_resp cmdRsp; + + handle->device->ctrl.argReg = 0; + handle->device->ctrl.cmdIndex = SD_CMD_STOP_TRANSMISSION; + + options = (SD_CMD_STOP_TRANSMISSION << 24) | + (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + chal_sd_send_cmd((CHAL_HANDLE *) handle->device, + handle->device->ctrl.cmdIndex, + handle->device->ctrl.argReg, options); + + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_CMDDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (event & SD_CMD_ERROR_INT) { + rel = SD_ERROR_NON_RECOVERABLE; + } else { + if (event & SD_DAT_TIMEOUT) { + return SD_ERROR_NON_RECOVERABLE; + } + + chal_sd_get_response((CHAL_HANDLE *) handle->device, + (uint32_t *)&cmdRsp); + + process_cmd_response(handle, handle->device->ctrl.cmdIndex, + cmdRsp.data.r2.rsp1, cmdRsp.data.r2.rsp2, + cmdRsp.data.r2.rsp3, cmdRsp.data.r2.rsp4, + &cmdRsp); + + SD_US_DELAY(2000); + + present = + chal_sd_get_present_status((CHAL_HANDLE *) handle->device); + + if ((present & 0x00F00000) == 0x00F00000) + rel = SD_ERROR_RECOVERABLE; + else + rel = SD_ERROR_NON_RECOVERABLE; + } + + return rel; +} + + +/* + * The function handles real data transmission on both DMA and + * none DMA mode, In None DMA mode the data transfer starts + * when the command is sent to the card, data has to be written + * into the host contollers buffer at this time one block + * at a time. + * In DMA mode, the real data transfer is done by the DMA engine + * and this functions just waits for the data transfer to complete. + * + */ +int process_data_xfer(struct sd_handle *handle, uint8_t *buffer, uint32_t addr, + uint32_t length, int dir) +{ + if (dir == SD_XFER_HOST_TO_CARD) { +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + if (handle->device->cfg.dma == SD_DMA_OFF) { + /* + * In NON DMA mode, the real data xfer starts from here + */ + if (write_buffer(handle, length, buffer)) + return SD_WRITE_ERROR; + } else { + wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus == SD_OK) + return SD_OK; + + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_WRITE_ERROR; + } +#else + return SD_WRITE_ERROR; +#endif + } else { /* SD_XFER_CARD_TO_HOST */ + + if (handle->device->cfg.dma == SD_DMA_OFF) { + /* In NON DMA mode, the real data + * transfer starts from here + */ + if (read_buffer(handle, length, buffer)) + return SD_READ_ERROR; + + } else { /* for DMA mode */ + + /* + * once the data transmission is done + * copy data to the host buffer. + */ + wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus == SD_OK) + return SD_OK; + + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_READ_ERROR; + } + } + return SD_OK; +} + + +/* + * The function sets block size for the next SD/SDIO/MMC + * card read/write command. + */ +int select_blk_sz(struct sd_handle *handle, uint16_t size) +{ + return sd_cmd16(handle, size); +} + + +/* + * The function initalizes the SD/SDIO/MMC/CEATA and detects + * the card according to the flag of detection. + * Once this function is called, the card is put into ready state + * so application can do data transfer to and from the card. + */ +int init_card(struct sd_handle *handle, int detection) +{ + /* + * After Reset, eMMC comes up in 1 Bit Data Width by default. + * Set host side to match. + */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_1BIT); + +#ifdef USE_EMMC_FIP_TOC_CACHE + cached_partition_block = 0; +#endif + handle->device->ctrl.present = 0; /* init card present to be no card */ + + init_mmc_card(handle); + + handle->device->ctrl.present = 1; /* card is detected */ + + /* switch the data width back */ + if (handle->card->type != SD_CARD_MMC) + return SD_FAIL; + + /* + * Dynamically set Data Width to highest supported value. + * Try different data width settings (highest to lowest). + * Verify each setting by reading EXT_CSD and comparing + * against the EXT_CSD contents previously read in call to + * init_mmc_card() earlier. Stop at first verified data width + * setting. + */ + { +#define EXT_CSD_PROPERTIES_SECTION_START_INDEX 192 +#define EXT_CSD_PROPERTIES_SECTION_END_INDEX 511 + uint8_t buffer[EXT_CSD_SIZE]; +#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT + /* Try 8 Bit Data Width */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_8BIT); + if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_8BIT)) && + (!mmc_cmd8(handle, buffer)) && + (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX], + &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]), + EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1))) + + return SD_OK; +#endif + /* Fall back to 4 Bit Data Width */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_4BIT); + if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_4BIT)) && + (!mmc_cmd8(handle, buffer)) && + (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX], + &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]), + EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1))) + + return SD_OK; + + /* Fall back to 1 Bit Data Width */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_1BIT); + /* Just use 1 Bit Data Width then. */ + if (!set_card_data_width(handle, SD_BUS_DATA_WIDTH_1BIT)) + return SD_OK; + + } + return SD_CARD_INIT_ERROR; +} + + +/* + * The function handles MMC/CEATA card initalization. + */ +int init_mmc_card(struct sd_handle *handle) +{ + uint32_t ocr = 0, newOcr, rc, limit = 0; + uint32_t cmd1_option = 0x40300000; + uint32_t sec_count; + + handle->card->type = SD_CARD_MMC; + + do { + SD_US_DELAY(1000); + newOcr = 0; + ocr = 0; + rc = sd_cmd1(handle, cmd1_option, &newOcr); + limit++; + + if (rc == SD_OK) + ocr = newOcr; + + } while (((ocr & SD_CARD_BUSY) == 0) && (limit < SD_CARD_RETRY_LIMIT)); + + if (limit >= SD_CARD_RETRY_LIMIT) { + handle->card->type = SD_CARD_UNKNOWN; + EMMC_TRACE("CMD1 Timeout: Device is not ready\n"); + return SD_CARD_UNKNOWN; + } + + /* Save the ocr register */ + handle->device->ctrl.ocr = ocr; + + /* Ready State */ + rc = sd_cmd2(handle); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + + rc = sd_cmd3(handle); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + /* read CSD */ + rc = sd_cmd9(handle, &emmc_global_vars_ptr->cardData); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + + /* Increase clock frequency according to what the card advertises */ + EMMC_TRACE("From CSD... cardData.csd.mmc.speed = 0x%X\n", + emmc_global_vars_ptr->cardData.csd.mmc.speed); + process_csd_mmc_speed(handle, + emmc_global_vars_ptr->cardData.csd.mmc.speed); + + /* goto transfer mode */ + rc = sd_cmd7(handle, handle->device->ctrl.rca); + if (rc != SD_OK) { + handle->card->type = SD_CARD_UNKNOWN; + return SD_CARD_UNKNOWN; + } + + rc = mmc_cmd8(handle, emmc_global_buf_ptr->u.Ext_CSD_storage); + if (rc == SD_OK) { + /* calcul real capacity */ + sec_count = emmc_global_buf_ptr->u.Ext_CSD_storage[212] | + emmc_global_buf_ptr->u.Ext_CSD_storage[213] << 8 | + emmc_global_buf_ptr->u.Ext_CSD_storage[214] << 16 | + emmc_global_buf_ptr->u.Ext_CSD_storage[215] << 24; + + EMMC_TRACE("Device density = %ldMBytes\n", + handle->card->size / (1024 * 1024)); + + if (sec_count > 0) { + handle->card->size = (uint64_t)sec_count * 512; + + EMMC_TRACE("Updated Device density = %ldMBytes\n", + handle->card->size / (1024 * 1024)); + } + + if (sec_count > (2u * 1024 * 1024 * 1024) / 512) { + handle->device->ctrl.ocr |= SD_CARD_HIGH_CAPACITY; + handle->device->cfg.blockSize = 512; + } + + if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + EMMC_TRACE("Sector addressing\n"); + else + EMMC_TRACE("Byte addressing\n"); + + EMMC_TRACE("Ext_CSD_storage[162]: 0x%02X Ext_CSD_storage[179]: 0x%02X\n", + emmc_global_buf_ptr->u.Ext_CSD_storage[162], + emmc_global_buf_ptr->u.Ext_CSD_storage[179]); + } + + return handle->card->type; +} + + +/* + * The function send reset command to the card. + * The card will be in ready status after the reset. + */ +int reset_card(struct sd_handle *handle) +{ + int res = SD_OK; + + /* on reset, card's RCA should return to 0 */ + handle->device->ctrl.rca = 0; + + res = sd_cmd0(handle); + + if (res != SD_OK) + return SD_RESET_ERROR; + + return res; +} + + +/* + * The function sends command to the card and starts + * data transmission. + */ +static int xfer_data(struct sd_handle *handle, + uint32_t mode, + uint32_t addr, uint32_t length, uint8_t *base) +{ + int rc = SD_OK; + + VERBOSE("XFER: dest: 0x%llx, addr: 0x%x, size: 0x%x bytes\n", + (uint64_t)base, addr, length); + + if ((length / handle->device->cfg.blockSize) > 1) { + if (mode == SD_OP_READ) { + inv_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd18(handle, addr, length, base); + } else { +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + flush_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd25(handle, addr, length, base); +#else + rc = SD_DATA_XFER_ERROR; +#endif + } + } else { + if (mode == SD_OP_READ) { + inv_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd17(handle, addr, + handle->device->cfg.blockSize, base); + } else { +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + flush_dcache_range((uintptr_t)base, (uint64_t)length); + rc = sd_cmd24(handle, addr, + handle->device->cfg.blockSize, base); +#else + rc = SD_DATA_XFER_ERROR; +#endif + } + } + + if (rc != SD_OK) + return SD_DATA_XFER_ERROR; + + return SD_OK; +} + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +int erase_card(struct sd_handle *handle, uint32_t addr, uint32_t blocks) +{ + uint32_t end_addr; + + INFO("ERASE: addr: 0x%x, num of sectors: 0x%x\n", addr, blocks); + + if (sd_cmd35(handle, addr) != SD_OK) + return SD_FAIL; + + end_addr = addr + blocks - 1; + if (sd_cmd36(handle, end_addr) != SD_OK) + return SD_FAIL; + + if (sd_cmd38(handle) != SD_OK) + return SD_FAIL; + + return SD_OK; +} +#endif + +/* + * The function reads block data from a card. + */ +#ifdef USE_EMMC_FIP_TOC_CACHE +int read_block(struct sd_handle *handle, + uint8_t *dst, uint32_t addr, uint32_t len) +{ + int rel = SD_OK; + + /* + * Avoid doing repeated reads of the partition block + * by caching. + */ + if (cached_partition_block && + addr == PARTITION_BLOCK_ADDR && + len == CACHE_SIZE) { + memcpy(dst, cached_block, len); + } else { + rel = xfer_data(handle, SD_OP_READ, addr, len, dst); + + if (len == CACHE_SIZE && addr == PARTITION_BLOCK_ADDR) { + cached_partition_block = 1; + memcpy(cached_block, dst, len); + } + } + + return rel; +} +#else +int read_block(struct sd_handle *handle, + uint8_t *dst, uint32_t addr, uint32_t len) +{ + return xfer_data(handle, SD_OP_READ, addr, len, dst); +} +#endif + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + +/* + * The function writes block data to a card. + */ +int write_block(struct sd_handle *handle, + uint8_t *src, uint32_t addr, uint32_t len) +{ + int rel = SD_OK; + + /* + * Current HC has problem to get response of cmd16 after cmd12, + * the delay is necessary to sure the next cmd16 will not be timed out. + * The delay has to be at least 4 ms. + * The code removed cmd16 and use cmd13 to get card status before + * sending cmd18 or cmd25 to make sure the card is ready and thus + * no need to have delay here. + */ + + rel = xfer_data(handle, SD_OP_WRITE, addr, len, src); + + EMMC_TRACE("wr_blk addr:0x%08X src:0x%08X len:0x%08X result:%d\n", + addr, src, len, rel); + + return rel; +} + + +/* + * The function is called to write one block data directly to + * a card's data buffer. + * it is used in Non-DMA mode for card data transmission. + */ +int write_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data) +{ + uint32_t rem, blockSize, event; + uint8_t *pData = data; + + blockSize = handle->device->cfg.blockSize; + rem = length; + + if (rem == 0) + return SD_OK; + + while (rem > 0) { + + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_BWRDY_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_WRITE_ERROR; + } + + if (rem >= blockSize) + chal_sd_write_buffer((CHAL_HANDLE *) handle->device, + blockSize, pData); + else + chal_sd_write_buffer((CHAL_HANDLE *) handle->device, + rem, pData); + + if (rem > blockSize) { + rem -= blockSize; + pData += blockSize; + } else { + pData += rem; + rem = 0; + } + } + + if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) != + SD4_EMMC_TOP_INTR_TXDONE_MASK) { + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus != SD_OK) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_WRITE_ERROR; + } + } else { + handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK; + } + + return SD_OK; +} +#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */ + + +/* + * The function is called to read maximal one block data + * directly from a card + * It is used in Non-DMA mode for card data transmission. + */ +int read_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data) +{ + uint32_t rem, blockSize, event = 0; + uint8_t *pData = data; + + blockSize = handle->device->cfg.blockSize; + rem = length; + + if (rem == 0) + return SD_OK; + + while (rem > 0) { + event = wait_for_event(handle, + SD4_EMMC_TOP_INTR_BRRDY_MASK | + SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_READ_ERROR; + } + + if (rem >= blockSize) + chal_sd_read_buffer((CHAL_HANDLE *) handle->device, + blockSize, pData); + else + chal_sd_read_buffer((CHAL_HANDLE *) handle->device, rem, + pData); + + if (rem > blockSize) { + rem -= blockSize; + pData += blockSize; + } else { + pData += rem; + rem = 0; + } + } + + /* In case, there are extra data in the SD FIFO, just dump them. */ + chal_sd_dump_fifo((CHAL_HANDLE *) handle->device); + + if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) != + SD4_EMMC_TOP_INTR_TXDONE_MASK) { + event = wait_for_event(handle, SD4_EMMC_TOP_INTR_TXDONE_MASK, + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus) { + check_error(handle, handle->device->ctrl.cmdStatus); + return SD_READ_ERROR; + } + } else { + handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK; + } + + return SD_OK; +} + + +/* + * Error handling routine. + * The function just reset the DAT + * and CMD line if an error occures during data transmission. + */ +int check_error(struct sd_handle *handle, uint32_t ints) +{ + uint32_t rel; + + chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, + SD_ERR_INTERRUPTS, 0); + + if (ints & SD4_EMMC_TOP_INTR_CMDERROR_MASK) { + + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_CMDRST_MASK); + rel = abort_err(handle); + + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_DATRST_MASK); + chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, + SD_ERR_INTERRUPTS, 1); + + return (rel == SD_ERROR_NON_RECOVERABLE) ? + SD_ERROR_NON_RECOVERABLE : SD_ERROR_RECOVERABLE; + } else { + rel = err_recovery(handle, ints); + } + + chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device, + SD_ERR_INTERRUPTS, 1); + + return rel; +} + + +/* + * Error recovery routine. + * Try to recover from the error. + */ +static int err_recovery(struct sd_handle *handle, uint32_t errors) +{ + uint32_t rel = 0; + + /* + * In case of timeout error, the cmd line and data line maybe + * still active or stuck at atcitve so it is needed to reset + * either data line or cmd line to make sure a new cmd can be sent. + */ + + if (errors & SD_CMD_ERROR_INT) + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_CMDRST_MASK); + + if (errors & SD_DAT_ERROR_INT) + chal_sd_reset_line((CHAL_HANDLE *) handle->device, + SD4_EMMC_TOP_CTRL1_DATRST_MASK); + + /* Abort transaction by sending out stop command */ + if ((handle->device->ctrl.cmdIndex == 18) || + (handle->device->ctrl.cmdIndex == 25)) + rel = abort_err(handle); + + return rel; +} + + +/* + * The function is called to read one block data directly from a card. + * It is used in Non-DMA mode for card data transmission. + */ +int process_cmd_response(struct sd_handle *handle, + uint32_t cmdIndex, + uint32_t rsp0, + uint32_t rsp1, + uint32_t rsp2, uint32_t rsp3, struct sd_resp *resp) +{ + int result = SD_OK; + + /* R6 */ + uint32_t rca = (rsp0 >> 16) & 0xffff; + uint32_t cardStatus = rsp0; + + /* R4 */ + uint32_t cBit = (rsp0 >> 31) & 0x1; + uint32_t funcs = (rsp0 >> 28) & 0x7; + uint32_t memPresent = (rsp0 >> 27) & 0x1; + + resp->r1 = 0x3f; + resp->cardStatus = cardStatus; + + if (cmdIndex == SD_CMD_IO_SEND_OP_COND) { + resp->data.r4.cardReady = cBit; + resp->data.r4.funcs = funcs; + resp->data.r4.memPresent = memPresent; + resp->data.r4.ocr = cardStatus; + } + + if (cmdIndex == SD_CMD_MMC_SET_RCA) { + resp->data.r6.rca = rca; + resp->data.r6.cardStatus = cardStatus & 0xFFFF; + } + + if (cmdIndex == SD_CMD_SELECT_DESELECT_CARD) { + resp->data.r7.rca = rca; + } + + if (cmdIndex == SD_CMD_IO_RW_DIRECT) { + if (((rsp0 >> 16) & 0xffff) != 0) + result = SD_CMD_ERR_INVALID_RESPONSE; + + resp->data.r5.data = rsp0 & 0xff; + } + + if (cmdIndex == SD_CMD_IO_RW_EXTENDED) { + if (((rsp0 >> 16) & 0xffff) != 0) + result = SD_CMD_ERR_INVALID_RESPONSE; + + resp->data.r5.data = rsp0 & 0xff; + } + + if (cmdIndex == SD_ACMD_SD_SEND_OP_COND || + cmdIndex == SD_CMD_SEND_OPCOND) + resp->data.r3.ocr = cardStatus; + + if (cmdIndex == SD_CMD_SEND_CSD || + cmdIndex == SD_CMD_SEND_CID || + cmdIndex == SD_CMD_ALL_SEND_CID) { + resp->data.r2.rsp4 = rsp3; + resp->data.r2.rsp3 = rsp2; + resp->data.r2.rsp2 = rsp1; + resp->data.r2.rsp1 = rsp0; + } + + if ((cmdIndex == SD_CMD_READ_EXT_CSD) && + (handle->card->type == SD_CARD_SD)) { + if ((resp->cardStatus & 0xAA) != 0xAA) { + result = SD_CMD_ERR_INVALID_RESPONSE; + } + } + + return result; +} + + +/* + * The function sets DMA buffer and data length, process + * block size and the number of blocks to be transferred. + * It returns the DMA buffer address. + * It copies dma data from user buffer to the DMA buffer + * if the operation is to write data to the SD card. + */ +void data_xfer_setup(struct sd_handle *handle, uint8_t *data, uint32_t length, + int dir) +{ + chal_sd_setup_xfer((CHAL_HANDLE *)handle->device, data, length, dir); +} + + +/* + * The function does soft reset the host SD controller. After + * the function call all host controller's register are reset + * to default vallue; + * + * Note This function only resets the host controller it does not + * reset the controller's handler. + */ +int reset_host_ctrl(struct sd_handle *handle) +{ + chal_sd_stop(); + + return SD_OK; +} + +static void pstate_log(struct sd_handle *handle) +{ + ERROR("PSTATE: 0x%x\n", mmio_read_32 + (handle->device->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_PSTATE_SD4_OFFSET)); + ERROR("ERRSTAT: 0x%x\n", mmio_read_32 + (handle->device->ctrl.sdRegBaseAddr + + SD4_EMMC_TOP_ERRSTAT_OFFSET)); +} + +/* + * The function waits for one or a group of interrupts specified + * by mask. The function returns if any one the interrupt status + * is set. If interrupt mode is not enabled then it will poll + * the interrupt status register until a interrupt status is set + * an error interrupt happens. If interrupt mode is enabled then + * this function should be called after the interrupt + * is received by ISR routine. + */ +uint32_t wait_for_event(struct sd_handle *handle, + uint32_t mask, uint32_t retry) +{ + uint32_t regval, cmd12, time = 0; + + handle->device->ctrl.cmdStatus = 0; /* no error */ + EMMC_TRACE("%s %d mask:0x%x timeout:%d irq_status:0x%x\n", + __func__, __LINE__, mask, retry, + chal_sd_get_irq_status((CHAL_HANDLE *)handle->device)); + + /* Polling mode */ + do { + regval = chal_sd_get_irq_status((CHAL_HANDLE *)handle->device); + + if (regval & SD4_EMMC_TOP_INTR_DMAIRQ_MASK) { + chal_sd_set_dma_addr((CHAL_HANDLE *)handle->device, + (uintptr_t) + chal_sd_get_dma_addr((CHAL_HANDLE *) + handle->device)); + chal_sd_clear_irq((CHAL_HANDLE *)handle->device, + SD4_EMMC_TOP_INTR_DMAIRQ_MASK); + } + + if (time++ > retry) { + ERROR("EMMC: No response (cmd%d) after %dus.\n", + handle->device->ctrl.cmdIndex, + time * EMMC_WFE_RETRY_DELAY_US); + handle->device->ctrl.cmdStatus = SD_CMD_MISSING; + pstate_log(handle); + ERROR("EMMC: INT[0x%x]\n", regval); + break; + } + + if (regval & SD4_EMMC_TOP_INTR_CTOERR_MASK) { + ERROR("EMMC: Cmd%d timeout INT[0x%x]\n", + handle->device->ctrl.cmdIndex, regval); + handle->device->ctrl.cmdStatus = + SD4_EMMC_TOP_INTR_CTOERR_MASK; + pstate_log(handle); + break; + } + if (regval & SD_CMD_ERROR_FLAGS) { + ERROR("EMMC: Cmd%d error INT[0x%x]\n", + handle->device->ctrl.cmdIndex, regval); + handle->device->ctrl.cmdStatus = SD_CMD_ERROR_FLAGS; + pstate_log(handle); + break; + } + + cmd12 = chal_sd_get_atuo12_error((CHAL_HANDLE *)handle->device); + if (cmd12) { + ERROR("EMMC: Cmd%d auto cmd12 err:0x%x\n", + handle->device->ctrl.cmdIndex, cmd12); + handle->device->ctrl.cmdStatus = cmd12; + pstate_log(handle); + break; + } + + if (SD_DATA_ERROR_FLAGS & regval) { + ERROR("EMMC: Data for cmd%d error, INT[0x%x]\n", + handle->device->ctrl.cmdIndex, regval); + handle->device->ctrl.cmdStatus = + (SD_DATA_ERROR_FLAGS & regval); + pstate_log(handle); + break; + } + + if ((regval & mask) == 0) + udelay(EMMC_WFE_RETRY_DELAY_US); + + } while ((regval & mask) == 0); + + /* clear the interrupt since it is processed */ + chal_sd_clear_irq((CHAL_HANDLE *)handle->device, (regval & mask)); + + return (regval & mask); +} + +int32_t set_config(struct sd_handle *handle, uint32_t speed, uint32_t retry, + uint32_t dma, uint32_t dmaBound, uint32_t blkSize, + uint32_t wfe_retry) +{ + int32_t rel = 0; + + if (handle == NULL) + return SD_FAIL; + + handle->device->cfg.wfe_retry = wfe_retry; + + rel = chal_sd_config((CHAL_HANDLE *)handle->device, speed, retry, + dmaBound, blkSize, dma); + return rel; + +} + +int mmc_cmd1(struct sd_handle *handle) +{ + uint32_t newOcr, res; + uint32_t cmd1_option = MMC_OCR_OP_VOLT | MMC_OCR_SECTOR_ACCESS_MODE; + + /* + * After Reset, eMMC comes up in 1 Bit Data Width by default. + * Set host side to match. + */ + chal_sd_config_bus_width((CHAL_HANDLE *) handle->device, + SD_BUS_DATA_WIDTH_1BIT); + +#ifdef USE_EMMC_FIP_TOC_CACHE + cached_partition_block = 0; +#endif + handle->device->ctrl.present = 0; /* init card present to be no card */ + + handle->card->type = SD_CARD_MMC; + + res = sd_cmd1(handle, cmd1_option, &newOcr); + + if (res != SD_OK) { + EMMC_TRACE("CMD1 Timeout: Device is not ready\n"); + res = SD_CARD_UNKNOWN; + } + return res; +} diff --git a/drivers/brcm/emmc/emmc_csl_sdcmd.c b/drivers/brcm/emmc/emmc_csl_sdcmd.c new file mode 100644 index 000000000..c62886cf6 --- /dev/null +++ b/drivers/brcm/emmc/emmc_csl_sdcmd.c @@ -0,0 +1,842 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdlib.h> +#include <stddef.h> + +#include "bcm_emmc.h" +#include "emmc_chal_types.h" +#include "emmc_chal_sd.h" +#include "emmc_csl_sdprot.h" +#include "emmc_csl_sdcmd.h" +#include "emmc_csl_sd.h" +#include "emmc_chal_sd.h" +#include "emmc_pboot_hal_memory_drv.h" + +int sd_cmd0(struct sd_handle *handle) +{ + int res; + uint32_t argument = 0x0; /* Go to IDLE state. */ + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_GO_IDLE_STATE, argument, 0, NULL); + + if (res == SD_OK) { + /* Clear all other interrupts */ + chal_sd_clear_irq((void *)handle->device, 0xffffffff); + } + + return res; +} + +int sd_cmd1(struct sd_handle *handle, uint32_t ocr, uint32_t *ocr_output) +{ + int res; + uint32_t options; + struct sd_resp resp; + + options = SD_CMDR_RSP_TYPE_R3_4 << SD_CMDR_RSP_TYPE_S; + + if (ocr_output == NULL) { + EMMC_TRACE("Invalid args\n"); + return SD_FAIL; + } + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SEND_OPCOND, ocr, options, &resp); + + if (res == SD_OK) + *ocr_output = resp.data.r3.ocr; + + return res; +} + +int sd_cmd2(struct sd_handle *handle) +{ + uint32_t options; + struct sd_resp resp; + + /* send cmd and parse result */ + options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S; + + return send_cmd(handle, SD_CMD_ALL_SEND_CID, 0, options, &resp); +} + +int sd_cmd3(struct sd_handle *handle) +{ + int res; + uint32_t options = 0; + uint32_t argument; + struct sd_resp resp; + + /* use non zero and non 0x1 value for rca */ + handle->device->ctrl.rca = 0x5; + argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_MMC_SET_RCA, argument, options, &resp); + + if (res != SD_OK) + handle->device->ctrl.rca = 0; + + return res; +} + +int sd_cmd7(struct sd_handle *handle, uint32_t rca) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + argument = (rca << SD_CMD7_ARG_RCA_SHIFT); + + /* + * Response to CMD7 is: + * R1 while selectiing from Stand-By State to Transfer State + * R1b while selecting from Disconnected State to Programming State. + * + * In this driver, we only issue a CMD7 once, to go to transfer mode + * during init_mmc_card(). + */ + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SELECT_DESELECT_CARD, argument, options, + &resp); + + if (res == SD_OK) + /* Clear all other interrupts */ + chal_sd_clear_irq((void *)handle->device, 0xffffffff); + + return res; +} + + +/* + * CMD8 Get CSD_EXT + */ +int mmc_cmd8(struct sd_handle *handle, uint8_t *extCsdReg) +{ + uint32_t res, options; + struct sd_resp resp; + + data_xfer_setup(handle, extCsdReg, CEATA_EXT_CSDBLOCK_SIZE, + SD_XFER_CARD_TO_HOST); + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_READ_EXT_CSD, 0, options, &resp); + + if (res == SD_OK) + res = process_data_xfer(handle, extCsdReg, 0, + CEATA_EXT_CSDBLOCK_SIZE, + SD_XFER_CARD_TO_HOST); + + return res; +} + +int sd_cmd9(struct sd_handle *handle, struct sd_card_data *card) +{ + int res; + uint32_t argument, options, iBlkNum, multiFactor = 1; + uint32_t maxReadBlockLen = 1, maxWriteBlockLen = 1; + struct sd_resp resp; + + argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT; + + options = SD_CMDR_RSP_TYPE_R2 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SEND_CSD, argument, options, &resp); + + if (res != SD_OK) + return res; + + if (handle->card->type == SD_CARD_MMC) { + card->csd.mmc.structure = (resp.data.r2.rsp4 >> 22) & 0x3; + card->csd.mmc.csdSpecVer = (resp.data.r2.rsp4 >> 18) & 0x0f; + card->csd.mmc.taac = (resp.data.r2.rsp4 >> 8) & 0xff; + card->csd.mmc.nsac = resp.data.r2.rsp4 & 0xff; + card->csd.mmc.speed = resp.data.r2.rsp3 >> 24; + card->csd.mmc.classes = (resp.data.r2.rsp3 >> 12) & 0xfff; + card->csd.mmc.rdBlkLen = (resp.data.r2.rsp3 >> 8) & 0xf; + card->csd.mmc.rdBlkPartial = (resp.data.r2.rsp3 >> 7) & 0x01; + card->csd.mmc.wrBlkMisalign = (resp.data.r2.rsp3 >> 6) & 0x1; + card->csd.mmc.rdBlkMisalign = (resp.data.r2.rsp3 >> 5) & 0x1; + card->csd.mmc.dsr = (resp.data.r2.rsp2 >> 4) & 0x01; + card->csd.mmc.size = + ((resp.data.r2.rsp3 & 0x3) << 10) + + ((resp.data.r2.rsp2 >> 22) & 0x3ff); + card->csd.mmc.vddRdCurrMin = (resp.data.r2.rsp2 >> 19) & 0x7; + card->csd.mmc.vddRdCurrMax = (resp.data.r2.rsp2 >> 16) & 0x7; + card->csd.mmc.vddWrCurrMin = (resp.data.r2.rsp2 >> 13) & 0x7; + card->csd.mmc.vddWrCurrMax = (resp.data.r2.rsp2 >> 10) & 0x7; + card->csd.mmc.devSizeMulti = (resp.data.r2.rsp2 >> 7) & 0x7; + card->csd.mmc.eraseGrpSize = (resp.data.r2.rsp2 >> 2) & 0x1f; + card->csd.mmc.eraseGrpSizeMulti = + ((resp.data.r2.rsp2 & 0x3) << 3) + + ((resp.data.r2.rsp1 >> 29) & 0x7); + card->csd.mmc.wrProtGroupSize = + ((resp.data.r2.rsp1 >> 24) & 0x1f); + card->csd.mmc.wrProtGroupEnable = + (resp.data.r2.rsp1 >> 23) & 0x1; + card->csd.mmc.manuDefEcc = (resp.data.r2.rsp1 >> 21) & 0x3; + card->csd.mmc.wrSpeedFactor = (resp.data.r2.rsp1 >> 18) & 0x7; + card->csd.mmc.wrBlkLen = (resp.data.r2.rsp1 >> 14) & 0xf; + card->csd.mmc.wrBlkPartial = (resp.data.r2.rsp1 >> 13) & 0x1; + card->csd.mmc.protAppl = (resp.data.r2.rsp1 >> 8) & 0x1; + card->csd.mmc.copyFlag = (resp.data.r2.rsp1 >> 7) & 0x1; + card->csd.mmc.permWrProt = (resp.data.r2.rsp1 >> 6) & 0x1; + card->csd.mmc.tmpWrProt = (resp.data.r2.rsp1 >> 5) & 0x1; + card->csd.mmc.fileFormat = (resp.data.r2.rsp1 >> 4) & 0x03; + card->csd.mmc.eccCode = resp.data.r2.rsp1 & 0x03; + maxReadBlockLen <<= card->csd.mmc.rdBlkLen; + maxWriteBlockLen <<= card->csd.mmc.wrBlkLen; + + iBlkNum = card->csd.mmc.size + 1; + multiFactor = (1 << (card->csd.mmc.devSizeMulti + 2)); + + handle->card->size = + iBlkNum * multiFactor * (1 << card->csd.mmc.rdBlkLen); + } + + handle->card->maxRdBlkLen = maxReadBlockLen; + handle->card->maxWtBlkLen = maxWriteBlockLen; + + if (handle->card->size < 0xA00000) { + /* + * 10MB Too small size mean, cmd9 response is wrong, + * Use default value 1G + */ + handle->card->size = 0x40000000; + handle->card->maxRdBlkLen = 512; + handle->card->maxWtBlkLen = 512; + } + + if ((handle->card->maxRdBlkLen > 512) || + (handle->card->maxWtBlkLen > 512)) { + handle->card->maxRdBlkLen = 512; + handle->card->maxWtBlkLen = 512; + } else if ((handle->card->maxRdBlkLen == 0) || + (handle->card->maxWtBlkLen == 0)) { + handle->card->maxRdBlkLen = 512; + handle->card->maxWtBlkLen = 512; + } + + handle->device->cfg.blockSize = handle->card->maxRdBlkLen; + + return res; +} + +int sd_cmd13(struct sd_handle *handle, uint32_t *status) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + argument = handle->device->ctrl.rca << SD_CMD7_ARG_RCA_SHIFT; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SEND_STATUS, argument, options, &resp); + + if (res == SD_OK) { + *status = resp.cardStatus; + } + + return res; +} + +int sd_cmd16(struct sd_handle *handle, uint32_t length) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + argument = length; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd13 failed before cmd16: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd16\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + + } while (1); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_SET_BLOCKLEN, argument, options, &resp); + + return res; +} + +int sd_cmd17(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd17: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd17\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST); + + /* send cmd and parse result */ + argument = addr; + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + res = send_cmd(handle, SD_CMD_READ_SINGLE_BLOCK, argument, options, + &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST); + + return res; +} + +int sd_cmd18(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd18: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd18\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_CARD_TO_HOST); + + argument = addr; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_DTDS_MASK | + SD4_EMMC_TOP_CMD_MSBS_MASK | SD4_EMMC_TOP_CMD_CCHK_EN_MASK | + SD4_EMMC_TOP_CMD_BCEN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK | + BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_READ_MULTIPLE_BLOCK, argument, options, + &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_CARD_TO_HOST); + + return res; +} + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +static int card_sts_resp(struct sd_handle *handle, uint32_t *status) +{ + int res; + uint32_t ntry = 0; + + do { + res = sd_cmd13(handle, status); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd35: rca 0x%0x, return %d\n", + handle->device->ctrl.rca, res); + return res; + } + + if (*status & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd35\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + } while (1); + + return SD_OK; +} + +int sd_cmd35(struct sd_handle *handle, uint32_t start) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + res = card_sts_resp(handle, &resp.cardStatus); + if (res != SD_OK) + return res; + + argument = start; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_ERASE_GROUP_START, + argument, options, &resp); + + if (res != SD_OK) + return res; + + return res; +} + +int sd_cmd36(struct sd_handle *handle, uint32_t end) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + res = card_sts_resp(handle, &resp.cardStatus); + if (res != SD_OK) + return res; + + argument = end; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_ERASE_GROUP_END, + argument, options, &resp); + + if (res != SD_OK) + return res; + + return res; +} + +int sd_cmd38(struct sd_handle *handle) +{ + int res; + uint32_t argument, options; + struct sd_resp resp; + + res = card_sts_resp(handle, &resp.cardStatus); + if (res != SD_OK) + return res; + + argument = 0; + + options = (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_ERASE, argument, options, &resp); + + if (res != SD_OK) + return res; + + return res; +} +#endif + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE + +int sd_cmd24(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd24: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, &resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd24\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD); + + argument = addr; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK; + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_WRITE_BLOCK, argument, options, &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD); + + return res; +} + +int sd_cmd25(struct sd_handle *handle, + uint32_t addr, uint32_t len, uint8_t *buffer) +{ + int res = SD_OK; + uint32_t argument, options, ntry; + struct sd_resp resp; + + ntry = 0; + do { + res = sd_cmd13(handle, &resp.cardStatus); + if (res != SD_OK) { + EMMC_TRACE( + "cmd 13 failed before cmd25: rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, &resp.cardStatus); + return res; + } + + if (resp.cardStatus & 0x100) + break; + + EMMC_TRACE("cmd13 rsp:0x%08x before cmd25\n", resp.cardStatus); + + if (ntry > handle->device->cfg.retryLimit) { + EMMC_TRACE("cmd13 retry reach limit %d\n", + handle->device->cfg.retryLimit); + return SD_CMD_TIMEOUT; + } + + ntry++; + EMMC_TRACE("cmd13 retry %d\n", ntry); + + SD_US_DELAY(1000); + } while (1); + + data_xfer_setup(handle, buffer, len, SD_XFER_HOST_TO_CARD); + + argument = addr; + + options = SD_CMDR_RSP_TYPE_R1_5_6 << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_DPS_MASK | SD4_EMMC_TOP_CMD_MSBS_MASK | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_BCEN_MASK | + SD4_EMMC_TOP_CMD_CRC_EN_MASK | + BIT(SD4_EMMC_TOP_CMD_ACMDEN_SHIFT); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_CMD_WRITE_MULTIPLE_BLOCK, + argument, options, &resp); + + if (res != SD_OK) + return res; + + res = process_data_xfer(handle, buffer, addr, len, SD_XFER_HOST_TO_CARD); + + return res; +} +#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */ + +int mmc_cmd6(struct sd_handle *handle, uint32_t argument) +{ + int res; + uint32_t options; + struct sd_resp resp; + + options = SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S | + SD4_EMMC_TOP_CMD_CCHK_EN_MASK | SD4_EMMC_TOP_CMD_CRC_EN_MASK; + + EMMC_TRACE("Sending CMD6 with argument 0x%X\n", argument); + + /* send cmd and parse result */ + res = send_cmd(handle, SD_ACMD_SET_BUS_WIDTH, argument, options, &resp); + + /* + * For R1b type response: + * controller issues a COMMAND COMPLETE interrupt when the R1 + * response is received, + * then controller monitors DAT0 for busy status, + * controller issues a TRANSFER COMPLETE interrupt when busy signal + * clears. + */ + wait_for_event(handle, + SD4_EMMC_TOP_INTR_TXDONE_MASK | SD_ERR_INTERRUPTS, + handle->device->cfg.wfe_retry); + + if (res == SD_OK) { + /* Check result of Cmd6 using Cmd13 to check card status */ + + /* Check status using Cmd13 */ + res = sd_cmd13(handle, &resp.cardStatus); + + if (res == SD_OK) { + /* Check bit 7 (SWITCH_ERROR) in card status */ + if ((resp.cardStatus & 0x80) != 0) { + EMMC_TRACE("cmd6 failed: SWITCH_ERROR\n"); + res = SD_FAIL; + } + } else { + EMMC_TRACE("cmd13 failed after cmd6: "); + EMMC_TRACE("rca 0x%0x, return %d, response 0x%0x\n", + handle->device->ctrl.rca, res, resp.cardStatus); + } + } + + return res; +} + + +#define SD_BUSY_CHECK 0x00203000 +#define DAT0_LEVEL_MASK 0x100000 /* bit20 in PSTATE */ +#define DEV_BUSY_TIMEOUT 600000 /* 60 Sec : 600000 * 100us */ + +int send_cmd(struct sd_handle *handle, uint32_t cmdIndex, uint32_t argument, + uint32_t options, struct sd_resp *resp) +{ + int status = SD_OK; + uint32_t event = 0, present, timeout = 0, retry = 0, mask = 3; + uint32_t temp_resp[4]; + + if (handle == NULL) { + EMMC_TRACE("Invalid handle for cmd%d\n", cmdIndex); + return SD_INVALID_HANDLE; + } + + mask = (SD_BUSY_CHECK & options) ? 3 : 1; + +RETRY_WRITE_CMD: + do { + /* Make sure it is ok to send command */ + present = + chal_sd_get_present_status((CHAL_HANDLE *) handle->device); + timeout++; + + if (present & mask) + SD_US_DELAY(1000); + else + break; + + } while (timeout < EMMC_BUSY_CMD_TIMEOUT_MS); + + if (timeout >= EMMC_BUSY_CMD_TIMEOUT_MS) { + status = SD_CMD_MISSING; + EMMC_TRACE("cmd%d timedout %dms\n", cmdIndex, timeout); + } + + /* Reset both DAT and CMD line if only of them are stuck */ + if (present & mask) + check_error(handle, SD4_EMMC_TOP_INTR_CMDERROR_MASK); + + handle->device->ctrl.argReg = argument; + chal_sd_send_cmd((CHAL_HANDLE *) handle->device, cmdIndex, + handle->device->ctrl.argReg, options); + + handle->device->ctrl.cmdIndex = cmdIndex; + + event = wait_for_event(handle, + (SD4_EMMC_TOP_INTR_CMDDONE_MASK | + SD_ERR_INTERRUPTS), + handle->device->cfg.wfe_retry); + + if (handle->device->ctrl.cmdStatus == SD_CMD_MISSING) { + retry++; + + if (retry >= handle->device->cfg.retryLimit) { + status = SD_CMD_MISSING; + EMMC_TRACE("cmd%d retry reaches the limit %d\n", + cmdIndex, retry); + } else { + /* reset both DAT & CMD line if one of them is stuck */ + present = chal_sd_get_present_status((CHAL_HANDLE *) + handle->device); + + if (present & mask) + check_error(handle, + SD4_EMMC_TOP_INTR_CMDERROR_MASK); + + EMMC_TRACE("cmd%d retry %d PSTATE[0x%08x]\n", + cmdIndex, retry, + chal_sd_get_present_status((CHAL_HANDLE *) + handle->device)); + goto RETRY_WRITE_CMD; + } + } + + if (handle->device->ctrl.cmdStatus == SD_OK) { + if (resp != NULL) { + status = + chal_sd_get_response((CHAL_HANDLE *) handle->device, + temp_resp); + process_cmd_response(handle, + handle->device->ctrl.cmdIndex, + temp_resp[0], temp_resp[1], + temp_resp[2], temp_resp[3], resp); + } + + /* Check Device busy after CMD */ + if ((cmdIndex == 5) || (cmdIndex == 6) || (cmdIndex == 7) || + (cmdIndex == 28) || (cmdIndex == 29) || (cmdIndex == 38)) { + + timeout = 0; + do { + present = + chal_sd_get_present_status((CHAL_HANDLE *) + handle->device); + + timeout++; + + /* Dat[0]:bit20 low means device busy */ + if ((present & DAT0_LEVEL_MASK) == 0) { + EMMC_TRACE("Device busy: "); + EMMC_TRACE( + "cmd%d arg:0x%08x: PSTATE[0x%08x]\n", + cmdIndex, argument, present); + SD_US_DELAY(100); + } else { + break; + } + } while (timeout < DEV_BUSY_TIMEOUT); + } + } else if (handle->device->ctrl.cmdStatus && + handle->device->ctrl.cmdStatus != SD_CMD_MISSING) { + retry++; + status = check_error(handle, handle->device->ctrl.cmdStatus); + + EMMC_TRACE( + "cmd%d error: cmdStatus:0x%08x error_status:0x%08x\n", + cmdIndex, handle->device->ctrl.cmdStatus, status); + + if ((handle->device->ctrl.cmdIndex == 1) || + (handle->device->ctrl.cmdIndex == 5)) { + status = event; + } else if ((handle->device->ctrl.cmdIndex == 7) || + (handle->device->ctrl.cmdIndex == 41)) { + status = event; + } else if ((status == SD_ERROR_RECOVERABLE) && + (retry < handle->device->cfg.retryLimit)) { + EMMC_TRACE("cmd%d recoverable error ", cmdIndex); + EMMC_TRACE("retry %d PSTATE[0x%08x].\n", retry, + chal_sd_get_present_status((CHAL_HANDLE *) + handle->device)); + goto RETRY_WRITE_CMD; + } else { + EMMC_TRACE("cmd%d retry reaches the limit %d\n", + cmdIndex, retry); + status = event; + } + } + + handle->device->ctrl.blkReg = 0; + /* clear error status for next command */ + handle->device->ctrl.cmdStatus = 0; + + return status; +} diff --git a/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c new file mode 100644 index 000000000..68f93e75e --- /dev/null +++ b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c @@ -0,0 +1,621 @@ +/* + * Copyright (c) 2016 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> + +#include <emmc_api.h> +#include <cmn_plat_util.h> + +#define MAX_CMD_RETRY 10 + +#if EMMC_USE_DMA +#define USE_DMA 1 +#else +#define USE_DMA 0 +#endif + +struct emmc_global_buffer emmc_global_buf; +struct emmc_global_buffer *emmc_global_buf_ptr = &emmc_global_buf; + +struct emmc_global_vars emmc_global_vars; +struct emmc_global_vars *emmc_global_vars_ptr = &emmc_global_vars; + +static struct sd_handle *sdio_gethandle(void); +static uint32_t sdio_idle(struct sd_handle *p_sdhandle); + +static uint32_t sdio_read(struct sd_handle *p_sdhandle, + uintptr_t mem_addr, + uintptr_t storage_addr, + size_t storage_size, + size_t bytes_to_read); + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +static uint32_t sdio_write(struct sd_handle *p_sdhandle, + uintptr_t mem_addr, + uintptr_t data_addr, + size_t bytes_to_write); +#endif + +static struct sd_handle *sdio_init(void); +static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle); + +static void init_globals(void) +{ + memset((void *)emmc_global_buf_ptr, 0, sizeof(*emmc_global_buf_ptr)); + memset((void *)emmc_global_vars_ptr, 0, sizeof(*emmc_global_vars_ptr)); +} + +/* + * This function is used to change partition + */ +uint32_t emmc_partition_select(uint32_t partition) +{ + int rc; + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 0; + } + + switch (partition) { + case EMMC_BOOT_PARTITION1: + rc = set_boot_config(sd_handle, + SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT1); + EMMC_TRACE( + "Change to Boot Partition 1 result:%d (0 means SD_OK)\n", + rc); + break; + + case EMMC_BOOT_PARTITION2: + rc = set_boot_config(sd_handle, + SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT2); + EMMC_TRACE( + "Change to Boot Partition 2 result:%d (0 means SD_OK)\n", + rc); + break; + + case EMMC_USE_CURRENT_PARTITION: + rc = SD_OK; + EMMC_TRACE("Stay on current partition"); + break; + + case EMMC_USER_AREA: + default: + rc = set_boot_config(sd_handle, + SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_USER); + EMMC_TRACE("Change to User area result:%d (0 means SD_OK)\n", + rc); + break; + + } + return (rc == SD_OK); +} + +/* + * Initialize emmc controller for eMMC + * Returns 0 on fail condition + */ +uint32_t bcm_emmc_init(bool card_rdy_only) +{ + struct sd_handle *p_sdhandle; + uint32_t result = 0; + + EMMC_TRACE("Enter emmc_controller_init()\n"); + + /* If eMMC is already initialized, skip init */ + if (emmc_global_vars_ptr->init_done) + return 1; + + init_globals(); + + p_sdhandle = sdio_init(); + + if (p_sdhandle == NULL) { + ERROR("eMMC init failed"); + return result; + } + + if (card_rdy_only) { + /* Put the card in Ready state, Not complete init */ + result = bcm_emmc_card_ready_state(p_sdhandle); + return !result; + } + + if (sdio_idle(p_sdhandle) == EMMC_BOOT_OK) { + set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, USE_DMA, + SD_DMA_BOUNDARY_256K, EMMC_BLOCK_SIZE, + EMMC_WFE_RETRY); + + if (!select_blk_sz(p_sdhandle, + p_sdhandle->device->cfg.blockSize)) { + emmc_global_vars_ptr->init_done = 1; + result = 1; + } else { + ERROR("Select Block Size failed\n"); + } + } else { + ERROR("eMMC init failed"); + } + + /* Initialization is failed, so deinit HW setting */ + if (result == 0) + emmc_deinit(); + + return result; +} + +/* + * Function to de-init SDIO controller for eMMC + */ +void emmc_deinit(void) +{ + emmc_global_vars_ptr->init_done = 0; + emmc_global_vars_ptr->sdHandle.card = 0; + emmc_global_vars_ptr->sdHandle.device = 0; +} + +/* + * Read eMMC memory + * Returns read_size + */ +uint32_t emmc_read(uintptr_t mem_addr, uintptr_t storage_addr, + size_t storage_size, size_t bytes_to_read) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 0; + } + + return sdio_read(sdio_gethandle(), mem_addr, storage_addr, + storage_size, bytes_to_read); +} + +#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE +#define EXT_CSD_ERASE_GRP_SIZE 224 + +static int emmc_block_erase(uintptr_t mem_addr, size_t blocks) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + ERROR("eMMC init is not done"); + return -1; + } + + return erase_card(sdio_gethandle(), mem_addr, blocks); +} + +int emmc_erase(uintptr_t mem_addr, size_t num_of_blocks, uint32_t partition) +{ + int err = 0; + size_t block_count = 0, blocks = 0; + size_t erase_group = 0; + + erase_group = + emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_ERASE_GRP_SIZE]*1024; + + INFO("eMMC Erase Group Size=0x%lx\n", erase_group); + + emmc_partition_select(partition); + + while (block_count < num_of_blocks) { + blocks = ((num_of_blocks - block_count) > erase_group) ? + erase_group : (num_of_blocks - block_count); + err = emmc_block_erase(mem_addr + block_count, blocks); + if (err) + break; + + block_count += blocks; + } + + if (err == 0) + INFO("eMMC Erase of partition %d successful\n", partition); + else + ERROR("eMMC Erase of partition %d Failed(%i)\n", partition, err); + + return err; +} +#endif + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +/* + * Write to eMMC memory + * Returns written_size + */ +uint32_t emmc_write(uintptr_t mem_addr, uintptr_t data_addr, + size_t bytes_to_write) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 0; + } + + return sdio_write(sd_handle, mem_addr, data_addr, bytes_to_write); +} +#endif + +/* + * Send SDIO Cmd + * Return 0 for pass condition + */ +uint32_t send_sdio_cmd(uint32_t cmdIndex, uint32_t argument, + uint32_t options, struct sd_resp *resp) +{ + struct sd_handle *sd_handle = sdio_gethandle(); + + if (sd_handle->device == 0) { + EMMC_TRACE("eMMC init is not done"); + return 1; + } + + return send_cmd(sd_handle, cmdIndex, argument, options, resp); +} + + +/* + * This function return SDIO handle + */ +struct sd_handle *sdio_gethandle(void) +{ + return &emmc_global_vars_ptr->sdHandle; +} + +/* + * Initialize SDIO controller + */ +struct sd_handle *sdio_init(void) +{ + uint32_t SDIO_base; + struct sd_handle *p_sdhandle = &emmc_global_vars_ptr->sdHandle; + + SDIO_base = EMMC_CTRL_REGS_BASE_ADDR; + + if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR) + EMMC_TRACE(" ---> for SDIO 0 Controller\n\n"); + + memset(p_sdhandle, 0, sizeof(struct sd_handle)); + + p_sdhandle->device = &emmc_global_vars_ptr->sdDevice; + p_sdhandle->card = &emmc_global_vars_ptr->sdCard; + + memset(p_sdhandle->device, 0, sizeof(struct sd_dev)); + memset(p_sdhandle->card, 0, sizeof(struct sd_card_info)); + + if (chal_sd_start((CHAL_HANDLE *) p_sdhandle->device, + SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK) + return NULL; + + set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, SD_DMA_OFF, + SD_DMA_BOUNDARY_4K, EMMC_BLOCK_SIZE, EMMC_WFE_RETRY); + + return &emmc_global_vars_ptr->sdHandle; +} + +uint32_t sdio_idle(struct sd_handle *p_sdhandle) +{ + reset_card(p_sdhandle); + + SD_US_DELAY(1000); + + if (init_card(p_sdhandle, SD_CARD_DETECT_MMC) != SD_OK) { + reset_card(p_sdhandle); + reset_host_ctrl(p_sdhandle); + return EMMC_BOOT_NO_CARD; + } + + return EMMC_BOOT_OK; +} + +/* + * This function read eMMC + */ +uint32_t sdio_read(struct sd_handle *p_sdhandle, + uintptr_t mem_addr, + uintptr_t storage_addr, + size_t storage_size, size_t bytes_to_read) +{ + uint32_t offset = 0, blockAddr, readLen = 0, rdCount; + uint32_t remSize, manual_copy_size; + uint8_t *outputBuf = (uint8_t *) storage_addr; + const size_t blockSize = p_sdhandle->device->cfg.blockSize; + + VERBOSE("EMMC READ: dst=0x%lx, src=0x%lx, size=0x%lx\n", + storage_addr, mem_addr, bytes_to_read); + + if (storage_size < bytes_to_read) + /* Don't have sufficient storage to complete the operation */ + return 0; + + /* Range check non high capacity memory */ + if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) { + if (mem_addr > 0x80000000) + return 0; + } + + /* High capacity card use block address mode */ + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { + blockAddr = (uint32_t) (mem_addr / blockSize); + offset = (uint32_t) (mem_addr - (blockAddr * blockSize)); + } else { + blockAddr = (uint32_t) (mem_addr / blockSize) * blockSize; + offset = (uint32_t) (mem_addr - blockAddr); + } + + remSize = bytes_to_read; + + rdCount = 0; + + /* Process first unaligned block of MAX_READ_LENGTH */ + if (offset > 0) { + if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, + blockAddr, SD_MAX_READ_LENGTH)) { + + if (remSize < (blockSize - offset)) { + rdCount += remSize; + manual_copy_size = remSize; + remSize = 0; /* read is done */ + } else { + remSize -= (blockSize - offset); + rdCount += (blockSize - offset); + manual_copy_size = blockSize - offset; + } + + /* Check for overflow */ + if (manual_copy_size > storage_size || + (((uintptr_t)outputBuf + manual_copy_size) > + (storage_addr + storage_size))) { + ERROR("EMMC READ: Overflow 1\n"); + return 0; + } + + memcpy(outputBuf, + (void *)((uintptr_t) + (emmc_global_buf_ptr->u.tempbuf + offset)), + manual_copy_size); + + /* Update Physical address */ + outputBuf += manual_copy_size; + + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + blockAddr++; + else + blockAddr += blockSize; + } else { + return 0; + } + } + + while (remSize >= blockSize) { + + if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH) + readLen = SD_MAX_BLK_TRANSFER_LENGTH; + else + readLen = (remSize / blockSize) * blockSize; + + /* Check for overflow */ + if ((rdCount + readLen) > storage_size || + (((uintptr_t) outputBuf + readLen) > + (storage_addr + storage_size))) { + ERROR("EMMC READ: Overflow\n"); + return 0; + } + + if (!read_block(p_sdhandle, outputBuf, blockAddr, readLen)) { + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + blockAddr += (readLen / blockSize); + else + blockAddr += readLen; + + remSize -= readLen; + rdCount += readLen; + + /* Update Physical address */ + outputBuf += readLen; + } else { + return 0; + } + } + + /* process the last unaligned block reading */ + if (remSize > 0) { + if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, + blockAddr, SD_MAX_READ_LENGTH)) { + + rdCount += remSize; + /* Check for overflow */ + if (rdCount > storage_size || + (((uintptr_t) outputBuf + remSize) > + (storage_addr + storage_size))) { + ERROR("EMMC READ: Overflow\n"); + return 0; + } + + memcpy(outputBuf, + emmc_global_buf_ptr->u.tempbuf, remSize); + + /* Update Physical address */ + outputBuf += remSize; + } else { + rdCount = 0; + } + } + + return rdCount; +} + +#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE +static uint32_t sdio_write(struct sd_handle *p_sdhandle, uintptr_t mem_addr, + uintptr_t data_addr, size_t bytes_to_write) +{ + + uint32_t offset, blockAddr, writeLen, wtCount = 0; + uint32_t remSize, manual_copy_size = 0; + + uint8_t *inputBuf = (uint8_t *)data_addr; + + /* range check non high capacity memory */ + if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) { + if (mem_addr > 0x80000000) + return 0; + } + + /* the high capacity card use block address mode */ + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) { + blockAddr = + (uint32_t)(mem_addr / p_sdhandle->device->cfg.blockSize); + offset = + (uint32_t)(mem_addr - + blockAddr * p_sdhandle->device->cfg.blockSize); + } else { + blockAddr = + ((uint32_t)mem_addr / p_sdhandle->device->cfg.blockSize) * + p_sdhandle->device->cfg.blockSize; + offset = (uint32_t) mem_addr - blockAddr; + } + + remSize = bytes_to_write; + + wtCount = 0; + + /* process first unaligned block */ + if (offset > 0) { + if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf, + blockAddr, p_sdhandle->device->cfg.blockSize)) { + + if (remSize < + (p_sdhandle->device->cfg.blockSize - offset)) + manual_copy_size = remSize; + else + manual_copy_size = + p_sdhandle->device->cfg.blockSize - offset; + + memcpy((void *)((uintptr_t) + (emmc_global_buf_ptr->u.tempbuf + offset)), + inputBuf, + manual_copy_size); + + /* Update Physical address */ + + if (!write_block(p_sdhandle, + emmc_global_buf_ptr->u.tempbuf, + blockAddr, + p_sdhandle->device->cfg.blockSize)) { + + if (remSize < + (p_sdhandle->device->cfg.blockSize - + offset)) { + wtCount += remSize; + manual_copy_size = remSize; + remSize = 0; /* read is done */ + } else { + remSize -= + (p_sdhandle->device->cfg.blockSize - + offset); + wtCount += + (p_sdhandle->device->cfg.blockSize - + offset); + manual_copy_size = + p_sdhandle->device->cfg.blockSize - + offset; + } + + inputBuf += manual_copy_size; + + if (p_sdhandle->device->ctrl.ocr & + SD_CARD_HIGH_CAPACITY) + blockAddr++; + else + blockAddr += + p_sdhandle->device->cfg.blockSize; + } else + return 0; + } else { + return 0; + } + } + + /* process block writing */ + while (remSize >= p_sdhandle->device->cfg.blockSize) { + if (remSize >= SD_MAX_READ_LENGTH) { + writeLen = SD_MAX_READ_LENGTH; + } else { + writeLen = + (remSize / p_sdhandle->device->cfg.blockSize) * + p_sdhandle->device->cfg.blockSize; + } + + if (!write_block(p_sdhandle, inputBuf, blockAddr, writeLen)) { + if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) + blockAddr += + (writeLen / + p_sdhandle->device->cfg.blockSize); + else + blockAddr += writeLen; + + remSize -= writeLen; + wtCount += writeLen; + inputBuf += writeLen; + } else { + return 0; + } + } + + /* process the last unaligned block reading */ + if (remSize > 0) { + if (!read_block(p_sdhandle, + emmc_global_buf_ptr->u.tempbuf, + blockAddr, p_sdhandle->device->cfg.blockSize)) { + + memcpy(emmc_global_buf_ptr->u.tempbuf, + inputBuf, remSize); + + /* Update Physical address */ + + if (!write_block(p_sdhandle, + emmc_global_buf_ptr->u.tempbuf, + blockAddr, + p_sdhandle->device->cfg.blockSize)) { + wtCount += remSize; + inputBuf += remSize; + } else { + return 0; + } + } else { + wtCount = 0; + } + } + + return wtCount; +} +#endif + +/* + * Function to put the card in Ready state by sending CMD0 and CMD1 + */ +static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle) +{ + int32_t result = 0; + uint32_t argument = MMC_CMD_IDLE_RESET_ARG; /* Exit from Boot mode */ + + if (p_sdhandle) { + send_sdio_cmd(SD_CMD_GO_IDLE_STATE, argument, 0, NULL); + + result = reset_card(p_sdhandle); + if (result != SD_OK) { + EMMC_TRACE("eMMC Reset error\n"); + return SD_RESET_ERROR; + } + SD_US_DELAY(2000); + result = mmc_cmd1(p_sdhandle); + } + + return result; +} diff --git a/drivers/brcm/iproc_gpio.c b/drivers/brcm/iproc_gpio.c new file mode 100644 index 000000000..f61a3bca7 --- /dev/null +++ b/drivers/brcm/iproc_gpio.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <drivers/gpio.h> +#include <lib/mmio.h> +#include <plat/common/platform.h> + +#include <iproc_gpio.h> +#include <platform_def.h> + +#define IPROC_GPIO_DATA_IN_OFFSET 0x00 +#define IPROC_GPIO_DATA_OUT_OFFSET 0x04 +#define IPROC_GPIO_OUT_EN_OFFSET 0x08 +#define IPROC_GPIO_PAD_RES_OFFSET 0x34 +#define IPROC_GPIO_RES_EN_OFFSET 0x38 + +#define PINMUX_OFFSET(gpio) ((gpio) * 4) +#define PINCONF_OFFSET(gpio) ((gpio) * 4) +#define PINCONF_PULL_UP BIT(4) +#define PINCONF_PULL_DOWN BIT(5) + +/* + * iProc GPIO bank is always 0x200 per bank, + * with each bank supporting 32 GPIOs. + */ +#define GPIO_BANK_SIZE 0x200 +#define NGPIOS_PER_BANK 32 +#define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK) + +#define IPROC_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg)) +#define IPROC_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK) + +#define MUX_GPIO_MODE 0x3 + +/* + * @base: base address of the gpio controller + * @pinconf_base: base address of the pinconf + * @pinmux_base: base address of the mux controller + * @nr_gpios: maxinum number of GPIOs + */ +struct iproc_gpio { + uintptr_t base; + uintptr_t pinconf_base; + uintptr_t pinmux_base; + int nr_gpios; +}; + +static struct iproc_gpio iproc_gpio; + +static void gpio_set_bit(uintptr_t base, unsigned int reg, int gpio, bool set) +{ + unsigned int offset = IPROC_GPIO_REG(gpio, reg); + unsigned int shift = IPROC_GPIO_SHIFT(gpio); + uint32_t val; + + val = mmio_read_32(base + offset); + if (set) + val |= BIT(shift); + else + val &= ~BIT(shift); + + mmio_write_32(base + offset, val); +} + +static bool gpio_get_bit(uintptr_t base, unsigned int reg, int gpio) +{ + unsigned int offset = IPROC_GPIO_REG(gpio, reg); + unsigned int shift = IPROC_GPIO_SHIFT(gpio); + + return !!(mmio_read_32(base + offset) & BIT(shift)); +} + +static void mux_to_gpio(struct iproc_gpio *g, int gpio) +{ + /* mux pad to GPIO if IOPAD configuration is mandatory */ + if (g->pinmux_base) + mmio_write_32(g->pinmux_base + PINMUX_OFFSET(gpio), + MUX_GPIO_MODE); +} + +static void set_direction(int gpio, int direction) +{ + struct iproc_gpio *g = &iproc_gpio; + bool dir = (direction == GPIO_DIR_OUT) ? true : false; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + gpio_set_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio, dir); +} + +static int get_direction(int gpio) +{ + struct iproc_gpio *g = &iproc_gpio; + int dir; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + dir = gpio_get_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio) ? + GPIO_DIR_OUT : GPIO_DIR_IN; + + return dir; +} + +static int get_value(int gpio) +{ + struct iproc_gpio *g = &iproc_gpio; + unsigned int offset; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + + /* + * If GPIO is configured as output, read from the GPIO_OUT register; + * otherwise, read from the GPIO_IN register + */ + offset = gpio_get_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio) ? + IPROC_GPIO_DATA_OUT_OFFSET : IPROC_GPIO_DATA_IN_OFFSET; + + return gpio_get_bit(g->base, offset, gpio); +} + +static void set_value(int gpio, int val) +{ + struct iproc_gpio *g = &iproc_gpio; + + assert(gpio < g->nr_gpios); + + mux_to_gpio(g, gpio); + + /* make sure GPIO is configured to output, and then set the value */ + gpio_set_bit(g->base, IPROC_GPIO_OUT_EN_OFFSET, gpio, true); + gpio_set_bit(g->base, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val)); +} + +static int get_pull(int gpio) +{ + struct iproc_gpio *g = &iproc_gpio; + uint32_t val; + + assert(gpio < g->nr_gpios); + mux_to_gpio(g, gpio); + + /* when there's a valid pinconf_base, use it */ + if (g->pinconf_base) { + val = mmio_read_32(g->pinconf_base + PINCONF_OFFSET(gpio)); + + if (val & PINCONF_PULL_UP) + return GPIO_PULL_UP; + else if (val & PINCONF_PULL_DOWN) + return GPIO_PULL_DOWN; + else + return GPIO_PULL_NONE; + } + + /* no pinconf_base. fall back to GPIO internal pull control */ + if (!gpio_get_bit(g->base, IPROC_GPIO_RES_EN_OFFSET, gpio)) + return GPIO_PULL_NONE; + + return gpio_get_bit(g->base, IPROC_GPIO_PAD_RES_OFFSET, gpio) ? + GPIO_PULL_UP : GPIO_PULL_DOWN; +} + +static void set_pull(int gpio, int pull) +{ + struct iproc_gpio *g = &iproc_gpio; + uint32_t val; + + assert(gpio < g->nr_gpios); + mux_to_gpio(g, gpio); + + /* when there's a valid pinconf_base, use it */ + if (g->pinconf_base) { + val = mmio_read_32(g->pinconf_base + PINCONF_OFFSET(gpio)); + + if (pull == GPIO_PULL_NONE) { + val &= ~(PINCONF_PULL_UP | PINCONF_PULL_DOWN); + } else if (pull == GPIO_PULL_UP) { + val |= PINCONF_PULL_UP; + val &= ~PINCONF_PULL_DOWN; + } else if (pull == GPIO_PULL_DOWN) { + val |= PINCONF_PULL_DOWN; + val &= ~PINCONF_PULL_UP; + } else { + return; + } + mmio_write_32(g->pinconf_base + PINCONF_OFFSET(gpio), val); + } + + /* no pinconf_base. fall back to GPIO internal pull control */ + if (pull == GPIO_PULL_NONE) { + gpio_set_bit(g->base, IPROC_GPIO_RES_EN_OFFSET, gpio, false); + return; + } + + /* enable pad register and pull up or down */ + gpio_set_bit(g->base, IPROC_GPIO_RES_EN_OFFSET, gpio, true); + gpio_set_bit(g->base, IPROC_GPIO_PAD_RES_OFFSET, gpio, + !!(pull == GPIO_PULL_UP)); +} + +const gpio_ops_t iproc_gpio_ops = { + .get_direction = get_direction, + .set_direction = set_direction, + .get_value = get_value, + .set_value = set_value, + .get_pull = get_pull, + .set_pull = set_pull, +}; + +void iproc_gpio_init(uintptr_t base, int nr_gpios, uintptr_t pinmux_base, + uintptr_t pinconf_base) +{ + iproc_gpio.base = base; + iproc_gpio.nr_gpios = nr_gpios; + + /* pinmux/pinconf base is optional for some SoCs */ + if (pinmux_base) + iproc_gpio.pinmux_base = pinmux_base; + + if (pinconf_base) + iproc_gpio.pinconf_base = pinconf_base; + + gpio_init(&iproc_gpio_ops); +} diff --git a/drivers/brcm/ocotp.c b/drivers/brcm/ocotp.c new file mode 100644 index 000000000..6ff855453 --- /dev/null +++ b/drivers/brcm/ocotp.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> + +#include <ocotp.h> +#include <platform_def.h> + +#define OTP_MAP 2 +#define OTP_NUM_WORDS 2048 +/* + * # of tries for OTP Status. The time to execute a command varies. The slowest + * commands are writes which also vary based on the # of bits turned on. Writing + * 0xffffffff takes ~3800 us. + */ +#define OTPC_RETRIES_US 5000 + +/* Sequence to enable OTP program */ +#define OTPC_PROG_EN_SEQ { 0xf, 0x4, 0x8, 0xd } + +/* OTPC Commands */ +#define OTPC_CMD_READ 0x0 +#define OTPC_CMD_OTP_PROG_ENABLE 0x2 +#define OTPC_CMD_OTP_PROG_DISABLE 0x3 +#define OTPC_CMD_PROGRAM 0x8 +#define OTPC_CMD_ECC 0x10 +#define OTPC_ECC_ADDR 0x1A +#define OTPC_ECC_VAL 0x00EC0000 + +/* OTPC Status Bits */ +#define OTPC_STAT_CMD_DONE BIT(1) +#define OTPC_STAT_PROG_OK BIT(2) + +/* OTPC register definition */ +#define OTPC_MODE_REG_OFFSET 0x0 +#define OTPC_MODE_REG_OTPC_MODE 0 +#define OTPC_COMMAND_OFFSET 0x4 +#define OTPC_COMMAND_COMMAND_WIDTH 6 +#define OTPC_CMD_START_OFFSET 0x8 +#define OTPC_CMD_START_START 0 +#define OTPC_CPU_STATUS_OFFSET 0xc +#define OTPC_CPUADDR_REG_OFFSET 0x28 +#define OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH 16 +#define OTPC_CPU_WRITE_REG_OFFSET 0x2c + +#define OTPC_CMD_MASK (BIT(OTPC_COMMAND_COMMAND_WIDTH) - 1) +#define OTPC_ADDR_MASK (BIT(OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH) - 1) + +#define OTPC_MODE_REG OCOTP_REGS_BASE + +struct chip_otp_cfg { + uint32_t base; + uint32_t num_words; +}; + +struct chip_otp_cfg ocotp_cfg = { + .base = OTPC_MODE_REG, + .num_words = 2048, +}; + +struct otpc_priv { + uint32_t base; + struct otpc_map *map; + int size; + int state; +}; + +struct otpc_priv otpc_info; + +static inline void set_command(uint32_t base, uint32_t command) +{ + mmio_write_32(base + OTPC_COMMAND_OFFSET, command & OTPC_CMD_MASK); +} + +static inline void set_cpu_address(uint32_t base, uint32_t addr) +{ + mmio_write_32(base + OTPC_CPUADDR_REG_OFFSET, addr & OTPC_ADDR_MASK); +} + +static inline void set_start_bit(uint32_t base) +{ + mmio_write_32(base + OTPC_CMD_START_OFFSET, 1 << OTPC_CMD_START_START); +} + +static inline void reset_start_bit(uint32_t base) +{ + mmio_write_32(base + OTPC_CMD_START_OFFSET, 0); +} + +static inline void write_cpu_data(uint32_t base, uint32_t value) +{ + mmio_write_32(base + OTPC_CPU_WRITE_REG_OFFSET, value); +} + +static int poll_cpu_status(uint32_t base, uint32_t value) +{ + uint32_t status; + uint32_t retries; + + for (retries = 0; retries < OTPC_RETRIES_US; retries++) { + status = mmio_read_32(base + OTPC_CPU_STATUS_OFFSET); + if (status & value) + break; + udelay(1); + } + if (retries == OTPC_RETRIES_US) + return -1; + + return 0; +} + +static int bcm_otpc_ecc(uint32_t enable) +{ + struct otpc_priv *priv = &otpc_info; + int ret; + + set_command(priv->base, OTPC_CMD_ECC); + set_cpu_address(priv->base, OTPC_ECC_ADDR); + + if (!enable) + write_cpu_data(priv->base, OTPC_ECC_VAL); + else + write_cpu_data(priv->base, ~OTPC_ECC_VAL); + + set_start_bit(priv->base); + ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE); + if (ret) { + ERROR("otp ecc op error: 0x%x", ret); + return -1; + } + reset_start_bit(priv->base); + + return 0; +} + +/* + * bcm_otpc_read read otp data in the size of 8 byte rows. + * bytes has to be the multiple of 8. + * return -1 in error case, return read bytes in success. + */ +int bcm_otpc_read(unsigned int offset, void *val, uint32_t bytes, + uint32_t ecc_flag) +{ + struct otpc_priv *priv = &otpc_info; + uint32_t *buf = val; + uint32_t bytes_read; + uint32_t address = offset / priv->map->word_size; + int i, ret; + + if (!priv->state) { + ERROR("OCOTP read failed\n"); + return -1; + } + + bcm_otpc_ecc(ecc_flag); + + for (bytes_read = 0; (bytes_read + priv->map->word_size) <= bytes;) { + set_command(priv->base, OTPC_CMD_READ); + set_cpu_address(priv->base, address++); + set_start_bit(priv->base); + ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE); + if (ret) { + ERROR("otp read error: 0x%x", ret); + return -1; + } + + for (i = 0; i < priv->map->otpc_row_size; i++) { + *buf++ = mmio_read_32(priv->base + + priv->map->data_r_offset[i]); + bytes_read += sizeof(*buf); + } + + reset_start_bit(priv->base); + } + + return bytes_read; +} + +int bcm_otpc_init(struct otpc_map *map) +{ + struct otpc_priv *priv; + + priv = &otpc_info; + priv->base = ocotp_cfg.base; + priv->map = map; + + priv->size = 4 * ocotp_cfg.num_words; + + /* Enable CPU access to OTPC. */ + mmio_setbits_32(priv->base + OTPC_MODE_REG_OFFSET, + BIT(OTPC_MODE_REG_OTPC_MODE)); + reset_start_bit(priv->base); + priv->state = 1; + VERBOSE("OTPC Initialization done\n"); + + return 0; +} diff --git a/drivers/brcm/rng.c b/drivers/brcm/rng.c new file mode 100644 index 000000000..ee2e6561e --- /dev/null +++ b/drivers/brcm/rng.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <platform_def.h> + +#define RNG_CTRL_REG (RNG_BASE_ADDR + 0x00) +#define RNG_CTRL_MASK 0x00001FFF +#define RNG_CTRL_ENABLE 0x00000001 +#define RNG_CTRL_DISABLE 0x00000000 + +#define RNG_SOFT_RESET_REG (RNG_BASE_ADDR + 0x04) +#define RNG_SOFT_RESET_MASK 0x00000001 + +#define RNG_FIFO_DATA_REG (RNG_BASE_ADDR + 0x20) + +#define RNG_FIFO_COUNT_REG (RNG_BASE_ADDR + 0x24) +#define RNG_FIFO_COUNT_MASK 0x000000FF + +#define RNG_FIFO_WORDS_MAX 16 +#define MAX_WAIT_COUNT_50US 20000 + + +static void rng_reset(void) +{ + /* Disable RBG */ + mmio_clrbits_32(RNG_CTRL_REG, RNG_CTRL_MASK); + + /* Reset RNG and RBG */ + mmio_setbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK); + + /* Take all out of reset */ + mmio_clrbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK); +} + +static void rng_enable(void) +{ + /* Setup RNG. */ + mmio_clrsetbits_32(RNG_CTRL_REG, RNG_CTRL_MASK, RNG_CTRL_ENABLE); +} + +int rng_init(void) +{ + rng_reset(); + + rng_enable(); + + return 0; +} + +int rng_read(uint32_t *p_out, uint32_t *words_read) +{ + uint32_t available_words; + uint32_t i; + uint32_t word_processed = 0; + uint32_t wait_count = MAX_WAIT_COUNT_50US; + + if (*words_read == 0) { + ERROR("RNG Parameter: No word requested\n"); + return -1; + } + + do { + available_words = mmio_read_32(RNG_FIFO_COUNT_REG); + available_words &= RNG_FIFO_COUNT_MASK; + + if (available_words != 0) { + available_words = MIN(available_words, + *words_read - word_processed); + + for (i = 0; i < available_words; i++) + p_out[word_processed + i] = + mmio_read_32(RNG_FIFO_DATA_REG); + word_processed += available_words; + } else { + udelay(50); + } + + if (word_processed == *words_read) + break; + + } while (--wait_count); + + if (word_processed != *words_read) { + ERROR("RNG Timeout: requested %d word(s) got %d\n", + *words_read, word_processed); + *words_read = word_processed; + return -1; + } + + return 0; +} diff --git a/drivers/brcm/scp.c b/drivers/brcm/scp.c new file mode 100644 index 000000000..61960735a --- /dev/null +++ b/drivers/brcm/scp.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> + +#include <arch_helpers.h> +#include <common/debug.h> + +/* MCU binary image structure: <header> <data> + * + * Header structure: + * <magic-start> + * <num-sections> + * {<src-offset> <src-size> <dst-addr>}* + * <magic-end> + * + * MCU data (<data>) consists of several sections of code/data, to be + * installed (copied) into MCU memories. + * Header (<header>) gives information about sections contained in <data>. + * + * The installer code iterates over sections in MCU binary. + * For each section, it copies the section into MCU memory. + * + * The header contains: + * - <magic-start> - 32-bit magic number to mark header start + * - <num-sections> - number of sections in <data> + * - <num-sections> tuples. Each tuple describes a section. + * A tuple contains three 32-bit words. + * - <magic-end> - 32-bit magic number to mark header end + * + * Each section is describes by a tuple, consisting of three 32-bit words: + * - offset of section within MCU binary (relative to beginning of <data>) + * - section size (in bytes) in MCU binary + * - target address (in MCU memory). Section is copied to this location. + * + * All fields are 32-bit unsigned integers in little endian format. + * All sizes are assumed to be 32-bit aligned. + */ + +#define SCP_BIN_HEADER_MAGIC_START 0xfa587D01 +#define SCP_BIN_HEADER_MAGIC_END 0xf3e06a85 + +int download_scp_patch(void *image, unsigned int image_size) +{ + unsigned int *pheader = (unsigned int *)(image); + unsigned int header_size; + unsigned char *pdata; + void *dest; + unsigned int num_sections; + unsigned int section_src_offset; + unsigned int section_size; + + if (pheader && (pheader[0] != SCP_BIN_HEADER_MAGIC_START)) { + ERROR("SCP: Could not find SCP header.\n"); + return -1; + } + + num_sections = pheader[1]; + INFO("...Number of sections: %d\n", num_sections); + header_size = 4 * (1 + 1 + 3 * num_sections + 1); + + if (image_size < header_size) { + ERROR("SCP: Wrong size.\n"); + return -1; + } + + if (*(pheader + header_size/4 - 1) != SCP_BIN_HEADER_MAGIC_END) { + ERROR("SCP: Could not find SCP footer.\n"); + return -1; + } + + VERBOSE("SCP image header validated successfully\n"); + pdata = (unsigned char *)pheader + header_size; + + for (pheader += 2; num_sections > 0; num_sections--) { + + section_src_offset = pheader[0]; + section_size = pheader[1]; + dest = (void *)(unsigned long)pheader[2]; + + INFO("section: src:0x%x, size:%d, dst:0x%x\n", + section_src_offset, section_size, pheader[2]); + + if ((section_src_offset + section_size) > image_size) { + ERROR("SCP: Section points to outside of patch.\n"); + return -1; + } + + /* copy from source to target section */ + memcpy(dest, pdata + section_src_offset, section_size); + flush_dcache_range((uintptr_t)dest, section_size); + + /* next section */ + pheader += 3; + } + return 0; +} diff --git a/drivers/brcm/sotp.c b/drivers/brcm/sotp.c new file mode 100644 index 000000000..63c482066 --- /dev/null +++ b/drivers/brcm/sotp.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2016-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> + +#include <common/debug.h> +#include <lib/mmio.h> +#include <sotp.h> + +#include <platform_def.h> +#include <platform_sotp.h> + +#ifdef USE_SOFT_SOTP +extern uint64_t soft_sotp[]; +#endif + +#define SOTP_PROG_CONTROL (SOTP_REGS_OTP_BASE + 0x0000) +#define SOTP_PROG_CONTROL__OTP_CPU_MODE_EN 15 +#define SOTP_PROG_CONTROL__OTP_DISABLE_ECC 9 +#define SOTP_PROG_CONTROL__OTP_ECC_WREN 8 + +#define SOTP_WRDATA_0 (SOTP_REGS_OTP_BASE + 0x0004) +#define SOTP_WRDATA_1 (SOTP_REGS_OTP_BASE + 0x0008) + +#define SOTP_ADDR (SOTP_REGS_OTP_BASE + 0x000c) +#define SOTP_ADDR__OTP_ROW_ADDR_R 6 +#define SOTP_ADDR_MASK 0x3FF + +#define SOTP_CTRL_0 (SOTP_REGS_OTP_BASE + 0x0010) +#define SOTP_CTRL_0__START 0 +#define SOTP_CTRL_0__OTP_CMD 1 + +#define SOTP_STATUS_0 (SOTP_REGS_OTP_BASE + 0x0018) +#define SOTP_STATUS__FDONE 3 + +#define SOTP_STATUS_1 (SOTP_REGS_OTP_BASE + 0x001c) +#define SOTP_STATUS_1__CMD_DONE 1 +#define SOTP_STATUS_1__ECC_DET 17 + +#define SOTP_RDDATA_0 (SOTP_REGS_OTP_BASE + 0x0020) +#define SOTP_RDDATA_1 (SOTP_REGS_OTP_BASE + 0x0024) + +#define SOTP_READ 0 + +#define SOTP_PROG_WORD 10 +#define SOTP_STATUS__PROGOK 2 +#define SOTP_PROG_ENABLE 2 + +#define SOTP_ROW_DATA_MASK 0xffffffff +#define SOTP_ECC_ERR_BITS_MASK 0x1ff00000000 + +#define SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES 4 +#define SOTP_CHIP_CTRL_SW_MANU_PROG 5 +#define SOTP_CHIP_CTRL_SW_CID_PROG 6 +#define SOTP_CHIP_CTRL_SW_AB_DEVICE 8 +#define SOTP_CHIP_CTRL_SW_AB_DEV_MODE 9 +#define CHIP_STATE_UNPROGRAMMED 0x1 +#define CHIP_STATE_UNASSIGNED 0x2 + +uint64_t sotp_mem_read(uint32_t offset, uint32_t sotp_add_ecc) +{ +#ifdef USE_SOFT_SOTP + (void)sotp_add_ecc; + + return soft_sotp[offset]; +#else + uint64_t read_data = 0; + uint64_t read_data1 = 0; + uint64_t read_data2 = 0; + + /* Check for FDONE status */ + while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) != + BIT(SOTP_STATUS__FDONE)) + ; + + /* Enable OTP access by CPU */ + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + if (sotp_add_ecc == 1) { + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC)); + } + + if (sotp_add_ecc == 0) { + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC)); + } + + mmio_write_32(SOTP_ADDR, + ((offset & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R)); + mmio_write_32(SOTP_CTRL_0, (SOTP_READ << SOTP_CTRL_0__OTP_CMD)); + + /* Start bit to tell SOTP to send command to the OTP controller */ + mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + /* Wait for SOTP command done to be set */ + while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) != + BIT(SOTP_STATUS_1__CMD_DONE)) + ; + + /* Clr Start bit after command done */ + mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + if ((offset > SOTP_DEVICE_SECURE_CFG3_ROW) && + (mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__ECC_DET))) { + ERROR("SOTP ECC ERROR Detected row offset %d\n", offset); + read_data = SOTP_ECC_ERR_DETECT; + } else { + read_data1 = (uint64_t)mmio_read_32(SOTP_RDDATA_0); + read_data1 = read_data1 & 0xFFFFFFFF; + read_data2 = (uint64_t)mmio_read_32(SOTP_RDDATA_1); + read_data2 = (read_data2 & 0x1ff) << 32; + read_data = read_data1 | read_data2; + } + + /* Command done is cleared */ + mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); + + /* disable OTP access by CPU */ + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + return read_data; +#endif +} + +void sotp_mem_write(uint32_t addr, uint32_t sotp_add_ecc, uint64_t wdata) +{ +#ifdef USE_SOFT_SOTP + (void)sotp_add_ecc; + + soft_sotp[addr] = wdata; +#else + uint32_t loop; + uint8_t prog_array[4] = { 0x0F, 0x04, 0x08, 0x0D }; + + uint32_t chip_state_default = + (CHIP_STATE_UNASSIGNED|CHIP_STATE_UNPROGRAMMED); + uint32_t chip_state = mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES); + uint32_t chip_ctrl_default = 0; + + /* + * The override settings is required to allow the customer to program + * the application specific keys into SOTP, before the conversion to + * one of the AB modes. + * At the end of write operation, the chip ctrl settings will restored + * to the state prior to write call + */ + if (chip_state & chip_state_default) { + uint32_t chip_ctrl; + + chip_ctrl_default = mmio_read_32(SOTP_CHIP_CTRL); + INFO("SOTP: enable special prog mode\n"); + + chip_ctrl = BIT(SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES) | + BIT(SOTP_CHIP_CTRL_SW_MANU_PROG) | + BIT(SOTP_CHIP_CTRL_SW_CID_PROG) | + BIT(SOTP_CHIP_CTRL_SW_AB_DEVICE); + mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl); + } + + /* Check for FDONE status */ + while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) != + BIT(SOTP_STATUS__FDONE)) + ; + + /* Enable OTP acces by CPU */ + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + if (addr > SOTP_DEVICE_SECURE_CFG3_ROW) { + if (sotp_add_ecc == 0) { + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); + } + if (sotp_add_ecc == 1) { + mmio_setbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); + } + } else { + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); + } + + mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_ENABLE << 1)); + + /* + * In order to avoid unintentional writes / programming of the OTP + * array, the OTP Controller must be put into programming mode before + * it will accept program commands. This is done by writing 0xF, 0x4, + * 0x8, 0xD with program commands prior to starting the actual + * programming sequence + */ + for (loop = 0; loop < 4; loop++) { + mmio_write_32(SOTP_WRDATA_0, prog_array[loop]); + + /* + * Start bit to tell SOTP to send command to the OTP controller + */ + mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + /* Wait for SOTP command done to <-- be set */ + while ((mmio_read_32(SOTP_STATUS_1) & + BIT(SOTP_STATUS_1__CMD_DONE)) != + BIT(SOTP_STATUS_1__CMD_DONE)) + ; + + /* Command done is cleared w1c */ + mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); + + /* Clr Start bit after command done */ + mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + } + + /* Check for PROGOK */ + while ((mmio_read_32(SOTP_STATUS_0) & 0x4) != BIT(SOTP_STATUS__PROGOK)) + ; + + /* Set 10 bit row address */ + mmio_write_32(SOTP_ADDR, + ((addr & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R)); + + /* Set SOTP Row data */ + mmio_write_32(SOTP_WRDATA_0, (wdata & SOTP_ROW_DATA_MASK)); + + /* Set SOTP ECC and error bits */ + mmio_write_32(SOTP_WRDATA_1, ((wdata & SOTP_ECC_ERR_BITS_MASK) >> 32)); + + /* Set prog_word command */ + mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_WORD << 1)); + + /* Start bit to tell SOTP to send command to the OTP controller */ + mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + /* Wait for SOTP command done to be set */ + while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) != + BIT(SOTP_STATUS_1__CMD_DONE)) + ; + + /* Command done is cleared w1c */ + mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); + + /* disable OTP acces by CPU */ + mmio_clrbits_32(SOTP_PROG_CONTROL, + BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); + + /* Clr Start bit after command done */ + mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); + + if (chip_state & chip_state_default) + mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl_default); + +#endif +} + +int sotp_read_key(uint8_t *key, size_t keysize, int start_row, int end_row) +{ + int row; + uint32_t status = 0; + uint32_t status2 = 0xFFFFFFFF; + uint64_t row_data; + uint32_t data; + uint32_t *temp_key = (uint32_t *)key; + + row = start_row; + while ((keysize > 0) && (row <= end_row)) { + row_data = sotp_mem_read(row, SOTP_ROW_ECC); + if (!(row_data & (SOTP_ECC_ERR_DETECT | SOTP_FAIL_BITS))) { + memcpy(temp_key++, &row_data, sizeof(uint32_t)); + keysize -= sizeof(uint32_t); + data = (uint32_t)(row_data & SOTP_ROW_DATA_MASK); + status |= data; + status2 &= data; + } + row++; + } + + if ((status2 == 0xFFFFFFFF) || (status == 0) || (row > end_row)) + return -1; + + return 0; +} + +int sotp_key_erased(void) +{ + uint64_t row_data; + int status = 0; + + row_data = sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0); + if (row_data & SOTP_DEVICE_SECURE_CFG0_OTP_ERASED_MASK) + status = 1; + + else if (mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES) & + SOTP_REGS_SOTP_CHIP_STATES_OTP_ERASED_MASK) + status = 1; + + return status; +} + +/* + * This function optimise the SOTP redundancy + * by considering the 00- zero and 01,10,11 - one + */ +uint32_t sotp_redundancy_reduction(uint32_t sotp_row_data) +{ + uint32_t opt_data; + uint32_t opt_loop; + uint32_t temp_data; + + opt_data = 0; + + for (opt_loop = 0; opt_loop < 16; opt_loop = opt_loop + 1) { + temp_data = ((sotp_row_data >> (opt_loop * 2)) & 0x3); + + if (temp_data != 0x0) + opt_data = (opt_data | (1 << opt_loop)); + } + return opt_data; +} diff --git a/drivers/brcm/spi/iproc_qspi.c b/drivers/brcm/spi/iproc_qspi.c new file mode 100644 index 000000000..4c533d534 --- /dev/null +++ b/drivers/brcm/spi/iproc_qspi.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <endian.h> +#include <lib/mmio.h> + +#include <platform_def.h> +#include <spi.h> + +#include "iproc_qspi.h" + +struct bcmspi_priv spi_cfg; + +/* Redefined by platform to force appropriate information */ +#pragma weak plat_spi_init +int plat_spi_init(uint32_t *max_hz) +{ + return 0; +} + +/* Initialize & setup iproc qspi controller */ +int iproc_qspi_setup(uint32_t bus, uint32_t cs, uint32_t max_hz, uint32_t mode) +{ + struct bcmspi_priv *priv = NULL; + uint32_t spbr; + + priv = &spi_cfg; + priv->spi_mode = mode; + priv->state = QSPI_STATE_DISABLED; + priv->bspi_hw = QSPI_BSPI_MODE_REG_BASE; + priv->mspi_hw = QSPI_MSPI_MODE_REG_BASE; + + /* Initialize clock and platform specific */ + if (plat_spi_init(&max_hz) != 0) + return -1; + + priv->max_hz = max_hz; + + /* MSPI: Basic hardware initialization */ + mmio_write_32(priv->mspi_hw + MSPI_SPCR1_LSB_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_SPCR1_MSB_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_NEWQP_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_ENDQP_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_SPCR2_REG, 0); + + /* MSPI: SCK configuration */ + spbr = (QSPI_AXI_CLK - 1) / (2 * priv->max_hz) + 1; + spbr = MIN(spbr, SPBR_DIV_MAX); + spbr = MAX(spbr, SPBR_DIV_MIN); + mmio_write_32(priv->mspi_hw + MSPI_SPCR0_LSB_REG, spbr); + + /* MSPI: Mode configuration (8 bits by default) */ + priv->mspi_16bit = 0; + mmio_write_32(priv->mspi_hw + MSPI_SPCR0_MSB_REG, + BIT(MSPI_SPCR0_MSB_REG_MSTR_SHIFT) | /* Master */ + MSPI_SPCR0_MSB_REG_16_BITS_PER_WD_SHIFT | /* 16 bits per word */ + (priv->spi_mode & MSPI_SPCR0_MSB_REG_MODE_MASK)); /* mode: CPOL / CPHA */ + + /* Display bus info */ + VERBOSE("SPI: SPCR0_LSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR0_LSB_REG)); + VERBOSE("SPI: SPCR0_MSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR0_MSB_REG)); + VERBOSE("SPI: SPCR1_LSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR1_LSB_REG)); + VERBOSE("SPI: SPCR1_MSB: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR1_MSB_REG)); + VERBOSE("SPI: SPCR2: 0x%x\n", + mmio_read_32(priv->mspi_hw + MSPI_SPCR2_REG)); + VERBOSE("SPI: CLK: %d\n", priv->max_hz); + + return 0; +} + +void bcmspi_enable_bspi(struct bcmspi_priv *priv) +{ + if (priv->state != QSPI_STATE_BSPI) { + /* Switch to BSPI */ + mmio_write_32(priv->bspi_hw + BSPI_MAST_N_BOOT_CTRL_REG, 0); + + priv->state = QSPI_STATE_BSPI; + } +} + +static int bcmspi_disable_bspi(struct bcmspi_priv *priv) +{ + uint32_t retry; + + if (priv->state == QSPI_STATE_MSPI) + return 0; + + /* Switch to MSPI if not yet */ + if ((mmio_read_32(priv->bspi_hw + BSPI_MAST_N_BOOT_CTRL_REG) & + MSPI_CTRL_MASK) == 0) { + retry = QSPI_RETRY_COUNT_US_MAX; + do { + if ((mmio_read_32( + priv->bspi_hw + BSPI_BUSY_STATUS_REG) & + BSPI_BUSY_MASK) == 0) { + mmio_write_32(priv->bspi_hw + + BSPI_MAST_N_BOOT_CTRL_REG, + MSPI_CTRL_MASK); + udelay(1); + break; + } + udelay(1); + } while (retry--); + + if ((mmio_read_32(priv->bspi_hw + BSPI_MAST_N_BOOT_CTRL_REG) & + MSPI_CTRL_MASK) != MSPI_CTRL_MASK) { + ERROR("QSPI: Switching to QSPI error.\n"); + return -1; + } + } + + /* Update state */ + priv->state = QSPI_STATE_MSPI; + + return 0; +} + +int iproc_qspi_claim_bus(void) +{ + struct bcmspi_priv *priv = &spi_cfg; + + /* Switch to MSPI by default */ + if (bcmspi_disable_bspi(priv) != 0) + return -1; + + return 0; +} + +void iproc_qspi_release_bus(void) +{ + struct bcmspi_priv *priv = &spi_cfg; + + /* Switch to BSPI by default */ + bcmspi_enable_bspi(priv); +} + +static int mspi_xfer(struct bcmspi_priv *priv, uint32_t bytes, + const uint8_t *tx, uint8_t *rx, uint32_t flag) +{ + uint32_t retry; + uint32_t mode = CDRAM_PCS0; + + if (flag & SPI_XFER_QUAD) { + mode |= CDRAM_QUAD_MODE; + VERBOSE("SPI: QUAD mode\n"); + + if (!tx) { + VERBOSE("SPI: 4 lane input\n"); + mode |= CDRAM_RBIT_INPUT; + } + } + + /* Use 8-bit queue for odd-bytes transfer */ + if (bytes & 1) + priv->mspi_16bit = 0; + else { + priv->mspi_16bit = 1; + mode |= CDRAM_BITS_EN; + } + + while (bytes) { + uint32_t chunk; + uint32_t queues; + uint32_t i; + + /* Separate code for 16bit and 8bit transfers for performance */ + if (priv->mspi_16bit) { + VERBOSE("SPI: 16 bits xfer\n"); + /* Determine how many bytes to process this time */ + chunk = MIN(bytes, NUM_CDRAM_BYTES * 2); + queues = (chunk - 1) / 2 + 1; + bytes -= chunk; + + /* Fill CDRAMs */ + for (i = 0; i < queues; i++) + mmio_write_32(priv->mspi_hw + MSPI_CDRAM_REG + + (i << 2), mode | CDRAM_CONT); + + /* Fill TXRAMs */ + for (i = 0; i < chunk; i++) + if (tx) + mmio_write_32(priv->mspi_hw + + MSPI_TXRAM_REG + + (i << 2), tx[i]); + } else { + VERBOSE("SPI: 8 bits xfer\n"); + /* Determine how many bytes to process this time */ + chunk = MIN(bytes, NUM_CDRAM_BYTES); + queues = chunk; + bytes -= chunk; + + /* Fill CDRAMs and TXRAMS */ + for (i = 0; i < chunk; i++) { + mmio_write_32(priv->mspi_hw + MSPI_CDRAM_REG + + (i << 2), mode | CDRAM_CONT); + if (tx) + mmio_write_32(priv->mspi_hw + + MSPI_TXRAM_REG + + (i << 3), tx[i]); + } + } + + /* Advance pointers */ + if (tx) + tx += chunk; + + /* Setup queue pointers */ + mmio_write_32(priv->mspi_hw + MSPI_NEWQP_REG, 0); + mmio_write_32(priv->mspi_hw + MSPI_ENDQP_REG, queues - 1); + + /* Remove CONT on the last byte command */ + if (bytes == 0 && (flag & SPI_XFER_END)) + mmio_write_32(priv->mspi_hw + MSPI_CDRAM_REG + + ((queues - 1) << 2), mode); + + /* Kick off */ + mmio_write_32(priv->mspi_hw + MSPI_STATUS_REG, 0); + if (bytes == 0 && (flag & SPI_XFER_END)) + mmio_write_32(priv->mspi_hw + MSPI_SPCR2_REG, MSPI_SPE); + else + mmio_write_32(priv->mspi_hw + MSPI_SPCR2_REG, + MSPI_SPE | MSPI_CONT_AFTER_CMD); + + /* Wait for completion */ + retry = QSPI_RETRY_COUNT_US_MAX; + do { + if (mmio_read_32(priv->mspi_hw + MSPI_STATUS_REG) & + MSPI_CMD_COMPLETE_MASK) + break; + udelay(1); + } while (retry--); + + if ((mmio_read_32(priv->mspi_hw + MSPI_STATUS_REG) & + MSPI_CMD_COMPLETE_MASK) == 0) { + ERROR("SPI: Completion timeout.\n"); + return -1; + } + + /* Read data out */ + if (rx) { + if (priv->mspi_16bit) { + for (i = 0; i < chunk; i++) { + rx[i] = mmio_read_32(priv->mspi_hw + + MSPI_RXRAM_REG + + (i << 2)) + & 0xff; + } + } else { + for (i = 0; i < chunk; i++) { + rx[i] = mmio_read_32(priv->mspi_hw + + MSPI_RXRAM_REG + + (((i << 1) + 1) << 2)) + & 0xff; + } + } + rx += chunk; + } + } + + return 0; +} + +int iproc_qspi_xfer(uint32_t bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct bcmspi_priv *priv; + const uint8_t *tx = dout; + uint8_t *rx = din; + uint32_t bytes = bitlen / 8; + int ret = 0; + + priv = &spi_cfg; + + if (priv->state == QSPI_STATE_DISABLED) { + ERROR("QSPI: state disabled\n"); + return -1; + } + + /* we can only do 8 bit transfers */ + if (bitlen % 8) { + ERROR("QSPI: Only support 8 bit transfers (requested %d)\n", + bitlen); + return -1; + } + + /* MSPI: Enable write lock at the beginning */ + if (flags & SPI_XFER_BEGIN) { + /* Switch to MSPI if not yet */ + if (bcmspi_disable_bspi(priv) != 0) { + ERROR("QSPI: Switch to MSPI failed\n"); + return -1; + } + + mmio_write_32(priv->mspi_hw + MSPI_WRITE_LOCK_REG, 1); + } + + /* MSPI: Transfer it */ + if (bytes) + ret = mspi_xfer(priv, bytes, tx, rx, flags); + + /* MSPI: Disable write lock if it's done */ + if (flags & SPI_XFER_END) + mmio_write_32(priv->mspi_hw + MSPI_WRITE_LOCK_REG, 0); + + return ret; +} diff --git a/drivers/brcm/spi/iproc_qspi.h b/drivers/brcm/spi/iproc_qspi.h new file mode 100644 index 000000000..7a8bd91f7 --- /dev/null +++ b/drivers/brcm/spi/iproc_qspi.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IPROC_QSPI_H +#define IPROC_QSPI_H + +#include <platform_def.h> + +/*SPI configuration enable*/ +#define IPROC_QSPI_CLK_SPEED 62500000 +#define SPI_CPHA (1 << 0) +#define SPI_CPOL (1 << 1) +#define IPROC_QSPI_MODE0 0 +#define IPROC_QSPI_MODE3 (SPI_CPOL|SPI_CPHA) + +#define IPROC_QSPI_BUS 0 +#define IPROC_QSPI_CS 0 +#define IPROC_QSPI_BASE_REG QSPI_CTRL_BASE_ADDR +#define IPROC_QSPI_CRU_CONTROL_REG QSPI_CLK_CTRL + +#define QSPI_AXI_CLK 200000000 + +#define QSPI_RETRY_COUNT_US_MAX 200000 + +/* Chip attributes */ +#define QSPI_REG_BASE IPROC_QSPI_BASE_REG +#define CRU_CONTROL_REG IPROC_QSPI_CRU_CONTROL_REG +#define SPBR_DIV_MIN 8U +#define SPBR_DIV_MAX 255U +#define NUM_CDRAM_BYTES 16U + +/* Register fields */ +#define MSPI_SPCR0_MSB_BITS_8 0x00000020 + +/* Flash opcode and parameters */ +#define CDRAM_PCS0 2 +#define CDRAM_CONT (1 << 7) +#define CDRAM_BITS_EN (1 << 6) +#define CDRAM_QUAD_MODE (1 << 8) +#define CDRAM_RBIT_INPUT (1 << 10) + +/* MSPI registers */ +#define QSPI_MSPI_MODE_REG_BASE (QSPI_REG_BASE + 0x200) +#define MSPI_SPCR0_LSB_REG 0x000 +#define MSPI_SPCR0_MSB_REG 0x004 +#define MSPI_SPCR1_LSB_REG 0x008 +#define MSPI_SPCR1_MSB_REG 0x00c +#define MSPI_NEWQP_REG 0x010 +#define MSPI_ENDQP_REG 0x014 +#define MSPI_SPCR2_REG 0x018 +#define MSPI_STATUS_REG 0x020 +#define MSPI_CPTQP_REG 0x024 +#define MSPI_TXRAM_REG 0x040 +#define MSPI_RXRAM_REG 0x0c0 +#define MSPI_CDRAM_REG 0x140 +#define MSPI_WRITE_LOCK_REG 0x180 +#define MSPI_DISABLE_FLUSH_GEN_REG 0x184 + +#define MSPI_SPCR0_MSB_REG_MSTR_SHIFT 7 +#define MSPI_SPCR0_MSB_REG_16_BITS_PER_WD_SHIFT (0 << 2) +#define MSPI_SPCR0_MSB_REG_MODE_MASK 0x3 + +/* BSPI registers */ +#define QSPI_BSPI_MODE_REG_BASE QSPI_REG_BASE +#define BSPI_MAST_N_BOOT_CTRL_REG 0x008 +#define BSPI_BUSY_STATUS_REG 0x00c + +#define MSPI_CMD_COMPLETE_MASK 1 +#define BSPI_BUSY_MASK 1 +#define MSPI_CTRL_MASK 1 + +#define MSPI_SPE (1 << 6) +#define MSPI_CONT_AFTER_CMD (1 << 7) + +/* State */ +enum bcm_qspi_state { + QSPI_STATE_DISABLED, + QSPI_STATE_MSPI, + QSPI_STATE_BSPI +}; + +/* QSPI private data */ +struct bcmspi_priv { + /* Specified SPI parameters */ + uint32_t max_hz; + uint32_t spi_mode; + + /* State */ + enum bcm_qspi_state state; + int mspi_16bit; + + /* Registers */ + uintptr_t mspi_hw; + uintptr_t bspi_hw; +}; + +int iproc_qspi_setup(uint32_t bus, uint32_t cs, + uint32_t max_hz, uint32_t mode); +int iproc_qspi_claim_bus(void); +void iproc_qspi_release_bus(void); +int iproc_qspi_xfer(uint32_t bitlen, const void *dout, + void *din, unsigned long flags); + +#endif /* _IPROC_QSPI_H_ */ diff --git a/drivers/brcm/spi/iproc_spi.c b/drivers/brcm/spi/iproc_spi.c new file mode 100644 index 000000000..551e58732 --- /dev/null +++ b/drivers/brcm/spi/iproc_spi.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 - 2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <spi.h> + +#include "iproc_qspi.h" + +int spi_init(void) +{ + return iproc_qspi_setup(IPROC_QSPI_BUS, IPROC_QSPI_CS, + IPROC_QSPI_CLK_SPEED, IPROC_QSPI_MODE0); +} + +int spi_claim_bus(void) +{ + return iproc_qspi_claim_bus(); +} + +void spi_release_bus(void) +{ + iproc_qspi_release_bus(); +} + +int spi_xfer(uint32_t bitlen, const void *dout, + void *din, uint32_t flags) +{ + return iproc_qspi_xfer(bitlen, dout, din, flags); +} diff --git a/drivers/brcm/spi_flash.c b/drivers/brcm/spi_flash.c new file mode 100644 index 000000000..336d2304b --- /dev/null +++ b/drivers/brcm/spi_flash.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <errno.h> + +#include <sf.h> +#include <spi.h> + +#define SPI_FLASH_CMD_LEN 4 +#define QSPI_WAIT_TIMEOUT_US 200000U /* usec */ + +#define FINFO(jedec_id, ext_id, _sector_size, _n_sectors, _page_size, _flags) \ + .id = { \ + ((jedec_id) >> 16) & 0xff, \ + ((jedec_id) >> 8) & 0xff, \ + (jedec_id) & 0xff, \ + ((ext_id) >> 8) & 0xff, \ + (ext_id) & 0xff, \ + }, \ + .id_len = (!(jedec_id) ? 0 : (3 + ((ext_id) ? 2 : 0))), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = _page_size, \ + .flags = (_flags), + +/* SPI/QSPI flash device params structure */ +const struct spi_flash_info spi_flash_ids[] = { + {"W25Q64CV", FINFO(0xef4017, 0x0, 64 * 1024, 128, 256, WR_QPP | SECT_4K)}, + {"W25Q64DW", FINFO(0xef6017, 0x0, 64 * 1024, 128, 256, WR_QPP | SECT_4K)}, + {"W25Q32", FINFO(0xef4016, 0x0, 64 * 1024, 64, 256, SECT_4K)}, + {"MX25l3205D", FINFO(0xc22016, 0x0, 64 * 1024, 64, 256, SECT_4K)}, +}; + +static void spi_flash_addr(uint32_t addr, uint8_t *cmd) +{ + /* + * cmd[0] holds a SPI Flash command, stored earlier + * cmd[1/2/3] holds 24bit flash address + */ + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr >> 0; +} + +static const struct spi_flash_info *spi_flash_read_id(void) +{ + const struct spi_flash_info *info; + uint8_t id[SPI_FLASH_MAX_ID_LEN]; + int ret; + + ret = spi_flash_cmd(CMD_READ_ID, id, SPI_FLASH_MAX_ID_LEN); + if (ret < 0) { + ERROR("SF: Error %d reading JEDEC ID\n", ret); + return NULL; + } + + for (info = spi_flash_ids; info->name != NULL; info++) { + if (info->id_len) { + if (!memcmp(info->id, id, info->id_len)) + return info; + } + } + + printf("SF: unrecognized JEDEC id bytes: %02x, %02x, %02x\n", + id[0], id[1], id[2]); + return NULL; +} + +/* Enable writing on the SPI flash */ +static inline int spi_flash_cmd_write_enable(struct spi_flash *flash) +{ + return spi_flash_cmd(CMD_WRITE_ENABLE, NULL, 0); +} + +static int spi_flash_cmd_wait(struct spi_flash *flash) +{ + uint8_t cmd; + uint32_t i; + uint8_t status; + int ret; + + i = 0; + while (1) { + cmd = CMD_RDSR; + ret = spi_flash_cmd_read(&cmd, 1, &status, 1); + if (ret < 0) { + ERROR("SF: cmd wait failed\n"); + break; + } + if (!(status & STATUS_WIP)) + break; + + i++; + if (i >= QSPI_WAIT_TIMEOUT_US) { + ERROR("SF: cmd wait timeout\n"); + ret = -1; + break; + } + udelay(1); + } + + return ret; +} + +static int spi_flash_write_common(struct spi_flash *flash, const uint8_t *cmd, + size_t cmd_len, const void *buf, + size_t buf_len) +{ + int ret; + + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { + ERROR("SF: enabling write failed\n"); + return ret; + } + + ret = spi_flash_cmd_write(cmd, cmd_len, buf, buf_len); + if (ret < 0) { + ERROR("SF: write cmd failed\n"); + return ret; + } + + ret = spi_flash_cmd_wait(flash); + if (ret < 0) { + ERROR("SF: write timed out\n"); + return ret; + } + + return ret; +} + +static int spi_flash_read_common(const uint8_t *cmd, size_t cmd_len, + void *data, size_t data_len) +{ + int ret; + + ret = spi_flash_cmd_read(cmd, cmd_len, data, data_len); + if (ret < 0) { + ERROR("SF: read cmd failed\n"); + return ret; + } + + return ret; +} + +int spi_flash_read(struct spi_flash *flash, uint32_t offset, + uint32_t len, void *data) +{ + uint32_t read_len = 0, read_addr; + uint8_t cmd[SPI_FLASH_CMD_LEN]; + int ret; + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: unable to claim SPI bus\n"); + return ret; + } + + cmd[0] = CMD_READ_NORMAL; + while (len) { + read_addr = offset; + read_len = MIN(flash->page_size, (len - read_len)); + spi_flash_addr(read_addr, cmd); + + ret = spi_flash_read_common(cmd, sizeof(cmd), data, read_len); + if (ret < 0) { + ERROR("SF: read failed\n"); + break; + } + + offset += read_len; + len -= read_len; + data += read_len; + } + SPI_DEBUG("SF read done\n"); + + spi_release_bus(); + return ret; +} + +int spi_flash_write(struct spi_flash *flash, uint32_t offset, + uint32_t len, void *buf) +{ + unsigned long byte_addr, page_size; + uint8_t cmd[SPI_FLASH_CMD_LEN]; + uint32_t chunk_len, actual; + uint32_t write_addr; + int ret; + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: unable to claim SPI bus\n"); + return ret; + } + + page_size = flash->page_size; + + cmd[0] = flash->write_cmd; + for (actual = 0; actual < len; actual += chunk_len) { + write_addr = offset; + byte_addr = offset % page_size; + chunk_len = MIN(len - actual, + (uint32_t)(page_size - byte_addr)); + spi_flash_addr(write_addr, cmd); + + SPI_DEBUG("SF:0x%p=>cmd:{0x%02x 0x%02x%02x%02x} chunk_len:%d\n", + buf + actual, cmd[0], cmd[1], + cmd[2], cmd[3], chunk_len); + + ret = spi_flash_write_common(flash, cmd, sizeof(cmd), + buf + actual, chunk_len); + if (ret < 0) { + ERROR("SF: write cmd failed\n"); + break; + } + + offset += chunk_len; + } + SPI_DEBUG("SF write done\n"); + + spi_release_bus(); + return ret; +} + +int spi_flash_erase(struct spi_flash *flash, uint32_t offset, uint32_t len) +{ + uint8_t cmd[SPI_FLASH_CMD_LEN]; + uint32_t erase_size, erase_addr; + int ret; + + erase_size = flash->erase_size; + + if (offset % erase_size || len % erase_size) { + ERROR("SF: Erase offset/length not multiple of erase size\n"); + return -1; + } + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: unable to claim SPI bus\n"); + return ret; + } + + cmd[0] = flash->erase_cmd; + while (len) { + erase_addr = offset; + spi_flash_addr(erase_addr, cmd); + + SPI_DEBUG("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], + cmd[2], cmd[3], erase_addr); + + ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); + if (ret < 0) { + ERROR("SF: erase failed\n"); + break; + } + + offset += erase_size; + len -= erase_size; + } + SPI_DEBUG("sf erase done\n"); + + spi_release_bus(); + return ret; +} + +int spi_flash_probe(struct spi_flash *flash) +{ + const struct spi_flash_info *info = NULL; + int ret; + + ret = spi_claim_bus(); + if (ret) { + ERROR("SF: Unable to claim SPI bus\n"); + ERROR("SF: probe failed\n"); + return ret; + } + + info = spi_flash_read_id(); + if (!info) + goto probe_fail; + + INFO("Flash Name: %s sectors %x, sec size %x\n", + info->name, info->n_sectors, + info->sector_size); + flash->size = info->n_sectors * info->sector_size; + flash->sector_size = info->sector_size; + flash->page_size = info->page_size; + flash->flags = info->flags; + + flash->read_cmd = CMD_READ_NORMAL; + flash->write_cmd = CMD_PAGE_PROGRAM; + flash->erase_cmd = CMD_ERASE_64K; + flash->erase_size = ERASE_SIZE_64K; + +probe_fail: + spi_release_bus(); + return ret; +} diff --git a/drivers/brcm/spi_sf.c b/drivers/brcm/spi_sf.c new file mode 100644 index 000000000..8bbb09fac --- /dev/null +++ b/drivers/brcm/spi_sf.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019-2020, Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> + +#include <spi.h> + +#define BITS_PER_BYTE 8 +#define CMD_LEN1 1 + +static int spi_flash_read_write(const uint8_t *cmd, + size_t cmd_len, + const uint8_t *data_out, + uint8_t *data_in, + size_t data_len) +{ + unsigned long flags = SPI_XFER_BEGIN; + int ret; + + if (data_len == 0) + flags |= SPI_XFER_END; + + ret = spi_xfer(cmd_len * BITS_PER_BYTE, cmd, NULL, flags); + if (ret) { + ERROR("SF: Failed to send command (%zu bytes): %d\n", + cmd_len, ret); + } else if (data_len != 0) { + ret = spi_xfer(data_len * BITS_PER_BYTE, data_out, + data_in, SPI_XFER_END); + if (ret) + ERROR("SF: Failed to transfer %zu bytes of data: %d\n", + data_len, ret); + } + + return ret; +} + +int spi_flash_cmd_read(const uint8_t *cmd, + size_t cmd_len, + void *data, + size_t data_len) +{ + return spi_flash_read_write(cmd, cmd_len, NULL, data, data_len); +} + +int spi_flash_cmd(uint8_t cmd, void *response, size_t len) +{ + return spi_flash_cmd_read(&cmd, CMD_LEN1, response, len); +} + +int spi_flash_cmd_write(const uint8_t *cmd, + size_t cmd_len, + const void *data, + size_t data_len) +{ + return spi_flash_read_write(cmd, cmd_len, data, NULL, data_len); +} diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S index ecd0c478d..4c1a80efc 100644 --- a/drivers/cadence/uart/aarch64/cdns_console.S +++ b/drivers/cadence/uart/aarch64/cdns_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -56,14 +56,14 @@ endfunc console_cdns_core_init /* ----------------------------------------------- * int console_cdns_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_cdns_t *console); + * console_t *console); * Function to initialize and register a new CDNS * 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_16550_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -72,7 +72,7 @@ func console_cdns_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_CDNS_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_cdns_core_init cbz x0, register_fail @@ -105,21 +105,21 @@ func console_cdns_core_putc cmp w0, #0xA b.ne 2f 1: - /* Check if the transmit FIFO is full */ + /* Check if the transmit FIFO is empty */ ldr w2, [x1, #R_UART_SR] - tbnz w2, #UART_SR_INTR_TFUL_BIT, 1b + tbz w2, #UART_SR_INTR_TEMPTY_BIT, 1b mov w2, #0xD str w2, [x1, #R_UART_TX] 2: - /* Check if the transmit FIFO is full */ + /* Check if the transmit FIFO is empty */ ldr w2, [x1, #R_UART_SR] - tbnz w2, #UART_SR_INTR_TFUL_BIT, 2b + tbz w2, #UART_SR_INTR_TEMPTY_BIT, 2b str w0, [x1, #R_UART_TX] ret endfunc console_cdns_core_putc /* -------------------------------------------------------- - * int console_cdns_putc(int c, console_cdns_t *cdns) + * int console_cdns_putc(int c, console_t *cdns) * 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 @@ -133,7 +133,7 @@ func console_cdns_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_CDNS_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_cdns_core_putc endfunc console_cdns_putc @@ -165,7 +165,7 @@ no_char: endfunc console_cdns_core_getc /* --------------------------------------------- - * int console_cdns_getc(console_cdns_t *console) + * int console_cdns_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 if no character is available. @@ -179,16 +179,16 @@ func console_cdns_getc cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_CDNS_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_cdns_core_getc endfunc console_cdns_getc /* --------------------------------------------- - * int console_cdns_core_flush(uintptr_t base_addr) + * void console_cdns_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void * Clobber list : x0, x1 * --------------------------------------------- */ @@ -198,16 +198,15 @@ func console_cdns_core_flush ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ /* Placeholder */ - mov w0, #0 ret endfunc console_cdns_core_flush /* --------------------------------------------- - * int console_cdns_flush(console_pl011_t *console) + * void console_cdns_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -216,6 +215,6 @@ func console_cdns_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_CDNS_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_cdns_core_flush endfunc console_cdns_flush diff --git a/drivers/cfi/v2m/v2m_flash.c b/drivers/cfi/v2m/v2m_flash.c index aadafbce2..669018919 100644 --- a/drivers/cfi/v2m/v2m_flash.c +++ b/drivers/cfi/v2m/v2m_flash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,7 +27,7 @@ #define DWS_WORD_LOCK_RETRIES 1000 /* Helper macro to detect end of command */ -#define NOR_CMD_END (NOR_DWS | NOR_DWS << 16l) +#define NOR_CMD_END (NOR_DWS | (NOR_DWS << 16l)) /* Helper macros to access two flash banks in parallel */ #define NOR_2X16(d) ((d << 16) | (d & 0xffff)) diff --git a/drivers/console/aarch32/skeleton_console.S b/drivers/console/aarch32/skeleton_console.S index 45ad13927..a9e13ec44 100644 --- a/drivers/console/aarch32/skeleton_console.S +++ b/drivers/console/aarch32/skeleton_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -50,7 +50,7 @@ func console_xxx_register * by later console callback (e.g. putc). * Example: */ - str r1, [r0, #CONSOLE_T_XXX_BASE] + str r1, [r0, #CONSOLE_T_BASE] str r2, [r0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] /* @@ -87,7 +87,7 @@ func console_xxx_putc * console_xxx_t structure pointed to by r1. * Example: */ - ldr r1, [r1, #CONSOLE_T_XXX_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] /* * Write r0 to hardware. @@ -125,7 +125,7 @@ func console_xxx_getc * console_xxx_t structure pointed to by r0. * Example: */ - ldr r1, [r0, #CONSOLE_T_XXX_BASE] + ldr r1, [r0, #CONSOLE_T_BASE] /* * Try to read character into r0 from hardware. @@ -149,7 +149,7 @@ endfunc console_xxx_getc * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_xxx_t struct - * Out: r0 - 0 on success, < 0 on error + * Out: void * Clobber list : r0, r1, r2, r3, r4, r5 * --------------------------------------------- */ @@ -159,18 +159,12 @@ func console_xxx_flush * console_xxx_t structure pointed to by r0. * Example: */ - ldr r1, [r0, #CONSOLE_T_XXX_BASE] + ldr r1, [r0, #CONSOLE_T_BASE] /* * Flush all remaining output from hardware FIFOs. Do not return until * all data has been flushed or there was an unrecoverable error. */ - mov r0, #0 - bx lr - - /* Jump here if an unrecoverable error has been encountered. */ -flush_error: - mov r0, #-1 bx lr endfunc console_xxx_flush diff --git a/drivers/console/aarch64/skeleton_console.S b/drivers/console/aarch64/skeleton_console.S index 957ed83a9..7ea2eec9f 100644 --- a/drivers/console/aarch64/skeleton_console.S +++ b/drivers/console/aarch64/skeleton_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -50,7 +50,7 @@ func console_xxx_register * by later console callback (e.g. putc). * Example: */ - str x1, [x0, #CONSOLE_T_XXX_BASE] + str x1, [x0, #CONSOLE_T_BASE] str x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] /* @@ -87,7 +87,7 @@ func console_xxx_putc * console_xxx_t structure pointed to by x1. * Example: */ - ldr x1, [x1, #CONSOLE_T_XXX_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] /* * Write w0 to hardware. @@ -125,7 +125,7 @@ func console_xxx_getc * console_xxx_t structure pointed to by x0. * Example: */ - ldr x1, [x0, #CONSOLE_T_XXX_BASE] + ldr x1, [x0, #CONSOLE_T_BASE] /* * Try to read character into w0 from hardware. @@ -145,11 +145,11 @@ getc_error: endfunc console_xxx_getc /* --------------------------------------------- - * int console_xxx_flush(console_xxx_t *console) + * void console_xxx_flush(console_xxx_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_xxx_t struct - * Out: w0 - 0 on success, < 0 on error + * Out: void * Clobber list : x0, x1, x2, x3, x4, x5 * --------------------------------------------- */ @@ -159,18 +159,12 @@ func console_xxx_flush * console_xxx_t structure pointed to by x0. * Example: */ - ldr x1, [x0, #CONSOLE_T_XXX_BASE] + ldr x1, [x0, #CONSOLE_T_BASE] /* * Flush all remaining output from hardware FIFOs. Do not return until * all data has been flushed or there was an unrecoverable error. */ - mov w0, #0 - ret - - /* Jump here if an unrecoverable error has been encountered. */ -flush_error: - mov w0, #-1 ret endfunc console_xxx_flush diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c index 215f49517..08b8e9fb1 100644 --- a/drivers/console/multi_console.c +++ b/drivers/console/multi_console.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -90,7 +90,7 @@ int console_putc(int c) console_t *console; for (console = console_list; console != NULL; console = console->next) - if ((console->flags & console_state) && console->putc) { + if ((console->flags & console_state) && (console->putc != NULL)) { int ret = do_putc(c, console); if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err)) err = ret; @@ -107,7 +107,7 @@ int console_getc(void) do { /* Keep polling while at least one console works correctly. */ for (console = console_list; console != NULL; console = console->next) - if ((console->flags & console_state) && console->getc) { + if ((console->flags & console_state) && (console->getc != NULL)) { int ret = console->getc(console); if (ret >= 0) return ret; @@ -119,17 +119,12 @@ int console_getc(void) return err; } -int console_flush(void) +void console_flush(void) { - int err = ERROR_NO_VALID_CONSOLE; console_t *console; for (console = console_list; console != NULL; console = console->next) - if ((console->flags & console_state) && console->flush) { - int ret = console->flush(console); - if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err)) - err = ret; + if ((console->flags & console_state) && (console->flush != NULL)) { + console->flush(console); } - - return err; } diff --git a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S index fd04c2e7e..db07e6c0b 100644 --- a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S +++ b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -35,7 +35,7 @@ * ----------------------------------------------- */ func console_cbmc_register - str x0, [x1, #CONSOLE_T_CBMC_BASE] + str x0, [x1, #CONSOLE_T_BASE] ldr w2, [x0] str w2, [x1, #CONSOLE_T_CBMC_SIZE] mov x0, x1 @@ -54,7 +54,7 @@ endfunc console_cbmc_register */ func console_cbmc_putc ldr w2, [x1, #CONSOLE_T_CBMC_SIZE] - ldr x1, [x1, #CONSOLE_T_CBMC_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] add x1, x1, #8 /* keep address of body in x1 */ ldr w16, [x1, #-4] /* load cursor (one u32 before body) */ @@ -82,20 +82,17 @@ putc_write_back: endfunc console_cbmc_putc /* ----------------------------------------------- - * int console_cbmc_flush(console_cbmc_t *console) + * void console_cbmc_flush(console_cbmc_t *console) * Flushes the CBMEM console by flushing the * console buffer from the CPU's data cache. * In: x0 - pointer to console_cbmc_t struct - * Out: x0 - 0 for success - * Clobber list: x0, x1, x2, x3, x5 + * Out: void + * Clobber list: x0, x1, x2, x3 * ----------------------------------------------- */ func console_cbmc_flush - mov x5, x30 ldr x1, [x0, #CONSOLE_T_CBMC_SIZE] - ldr x0, [x0, #CONSOLE_T_CBMC_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] add x1, x1, #8 /* add size of console header */ - bl clean_dcache_range /* (clobbers x2 and x3) */ - mov x0, #0 - ret x5 + b clean_dcache_range /* (clobbers x2 and x3) */ endfunc console_cbmc_flush diff --git a/drivers/delay_timer/generic_delay_timer.c b/drivers/delay_timer/generic_delay_timer.c index 3d0a11f59..ca522e05a 100644 --- a/drivers/delay_timer/generic_delay_timer.c +++ b/drivers/delay_timer/generic_delay_timer.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,11 +13,9 @@ #include <common/debug.h> #include <drivers/delay_timer.h> #include <drivers/generic_delay_timer.h> +#include <lib/utils_def.h> #include <plat/common/platform.h> -/* Ticks elapsed in one second by a signal of 1 MHz */ -#define MHZ_TICKS_PER_SEC 1000000 - static timer_ops_t ops; static uint32_t get_timer_value(void) diff --git a/drivers/imx/uart/imx_uart.c b/drivers/imx/uart/imx_uart.c index 2c9652d19..dfe2e92b9 100644 --- a/drivers/imx/uart/imx_uart.c +++ b/drivers/imx/uart/imx_uart.c @@ -171,12 +171,11 @@ int console_imx_uart_core_getc(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void * Clobber list : r0, r1 * --------------------------------------------- */ -int console_imx_uart_core_flush(uintptr_t base_addr) +void console_imx_uart_core_flush(uintptr_t base_addr) { - return 0; } diff --git a/drivers/imx/uart/imx_uart.h b/drivers/imx/uart/imx_uart.h index 4f6d3de2e..a13302484 100644 --- a/drivers/imx/uart/imx_uart.h +++ b/drivers/imx/uart/imx_uart.h @@ -154,15 +154,10 @@ #ifndef __ASSEMBLER__ -typedef struct { - console_t console; - uintptr_t base; -} console_imx_uart_t; - int console_imx_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, - console_imx_uart_t *console); + console_t *console); #endif /*__ASSEMBLER__*/ #endif /* IMX_UART_H */ diff --git a/drivers/io/io_encrypted.c b/drivers/io/io_encrypted.c new file mode 100644 index 000000000..744ca8356 --- /dev/null +++ b/drivers/io/io_encrypted.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2020, Linaro Limited. All rights reserved. + * Author: Sumit Garg <sumit.garg@linaro.org> + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> +#include <stdint.h> +#include <string.h> + +#include <platform_def.h> + +#include <common/bl_common.h> +#include <common/debug.h> +#include <drivers/auth/crypto_mod.h> +#include <drivers/io/io_driver.h> +#include <drivers/io/io_encrypted.h> +#include <drivers/io/io_storage.h> +#include <lib/utils.h> +#include <plat/common/platform.h> +#include <tools_share/firmware_encrypted.h> +#include <tools_share/uuid.h> + +static uintptr_t backend_dev_handle; +static uintptr_t backend_dev_spec; +static uintptr_t backend_handle; +static uintptr_t backend_image_spec; + +static io_dev_info_t enc_dev_info; + +/* Encrypted firmware driver functions */ +static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); +static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity); +static int enc_file_len(io_entity_t *entity, size_t *length); +static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read); +static int enc_file_close(io_entity_t *entity); +static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params); +static int enc_dev_close(io_dev_info_t *dev_info); + +static inline int is_valid_header(struct fw_enc_hdr *header) +{ + if (header->magic == ENC_HEADER_MAGIC) + return 1; + else + return 0; +} + +static io_type_t device_type_enc(void) +{ + return IO_TYPE_ENCRYPTED; +} + +static const io_dev_connector_t enc_dev_connector = { + .dev_open = enc_dev_open +}; + +static const io_dev_funcs_t enc_dev_funcs = { + .type = device_type_enc, + .open = enc_file_open, + .seek = NULL, + .size = enc_file_len, + .read = enc_file_read, + .write = NULL, + .close = enc_file_close, + .dev_init = enc_dev_init, + .dev_close = enc_dev_close, +}; + +static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) +{ + assert(dev_info != NULL); + + enc_dev_info.funcs = &enc_dev_funcs; + *dev_info = &enc_dev_info; + + return 0; +} + +static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) +{ + int result; + unsigned int image_id = (unsigned int)init_params; + + /* Obtain a reference to the image by querying the platform layer */ + result = plat_get_image_source(image_id, &backend_dev_handle, + &backend_dev_spec); + if (result != 0) { + WARN("Failed to obtain reference to image id=%u (%i)\n", + image_id, result); + return -ENOENT; + } + + return result; +} + +static int enc_dev_close(io_dev_info_t *dev_info) +{ + backend_dev_handle = (uintptr_t)NULL; + backend_dev_spec = (uintptr_t)NULL; + + return 0; +} + +static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec, + io_entity_t *entity) +{ + int result; + + assert(spec != 0); + assert(entity != NULL); + + backend_image_spec = spec; + + result = io_open(backend_dev_handle, backend_image_spec, + &backend_handle); + if (result != 0) { + WARN("Failed to open backend device (%i)\n", result); + result = -ENOENT; + } + + return result; +} + +static int enc_file_len(io_entity_t *entity, size_t *length) +{ + int result; + + assert(entity != NULL); + assert(length != NULL); + + result = io_size(backend_handle, length); + if (result != 0) { + WARN("Failed to read blob length (%i)\n", result); + return -ENOENT; + } + + /* + * Encryption header is attached at the beginning of the encrypted file + * and is not considered a part of the payload. + */ + if (*length < sizeof(struct fw_enc_hdr)) + return -EIO; + + *length -= sizeof(struct fw_enc_hdr); + + return result; +} + +static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, + size_t *length_read) +{ + int result; + struct fw_enc_hdr header; + enum fw_enc_status_t fw_enc_status; + size_t bytes_read; + uint8_t key[ENC_MAX_KEY_SIZE]; + size_t key_len = sizeof(key); + unsigned int key_flags = 0; + const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)backend_image_spec; + + assert(entity != NULL); + assert(length_read != NULL); + + result = io_read(backend_handle, (uintptr_t)&header, sizeof(header), + &bytes_read); + if (result != 0) { + WARN("Failed to read encryption header (%i)\n", result); + return -ENOENT; + } + + if (!is_valid_header(&header)) { + WARN("Encryption header check failed.\n"); + return -ENOENT; + } + + VERBOSE("Encryption header looks OK.\n"); + fw_enc_status = header.flags & FW_ENC_STATUS_FLAG_MASK; + + if ((header.iv_len > ENC_MAX_IV_SIZE) || + (header.tag_len > ENC_MAX_TAG_SIZE)) { + WARN("Incorrect IV or tag length\n"); + return -ENOENT; + } + + result = io_read(backend_handle, buffer, length, &bytes_read); + if (result != 0) { + WARN("Failed to read encrypted payload (%i)\n", result); + return -ENOENT; + } + + *length_read = bytes_read; + + result = plat_get_enc_key_info(fw_enc_status, key, &key_len, &key_flags, + (uint8_t *)&uuid_spec->uuid, + sizeof(uuid_t)); + if (result != 0) { + WARN("Failed to obtain encryption key (%i)\n", result); + return -ENOENT; + } + + result = crypto_mod_auth_decrypt(header.dec_algo, + (void *)buffer, *length_read, key, + key_len, key_flags, header.iv, + header.iv_len, header.tag, + header.tag_len); + memset(key, 0, key_len); + + if (result != 0) { + ERROR("File decryption failed (%i)\n", result); + return -ENOENT; + } + + return result; +} + +static int enc_file_close(io_entity_t *entity) +{ + io_close(backend_handle); + + backend_image_spec = (uintptr_t)NULL; + entity->info = 0; + + return 0; +} + +/* Exported functions */ + +/* Register the Encrypted Firmware driver with the IO abstraction */ +int register_io_dev_enc(const io_dev_connector_t **dev_con) +{ + int result; + + assert(dev_con != NULL); + + result = io_register_device(&enc_dev_info); + if (result == 0) + *dev_con = &enc_dev_connector; + + return result; +} diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c index 5d49fffaa..6e152959f 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -36,7 +36,7 @@ typedef struct { unsigned int file_pos; fip_toc_entry_t entry; -} file_state_t; +} fip_file_state_t; /* * Maintain dev_spec per FIP Device @@ -46,9 +46,9 @@ typedef struct { */ typedef struct { uintptr_t dev_spec; + uint16_t plat_toc_flag; } fip_dev_state_t; -static const uuid_t uuid_null; /* * Only one file can be open across all FIP device * as backends like io_memmap don't support @@ -56,7 +56,7 @@ static const uuid_t uuid_null; * backend handle should be maintained per FIP device * if the same support is available in the backend */ -static file_state_t current_file = {0}; +static fip_file_state_t current_fip_file = {0}; static uintptr_t backend_dev_handle; static uintptr_t backend_image_spec; @@ -220,6 +220,11 @@ static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) uintptr_t backend_handle; fip_toc_header_t header; size_t bytes_read; + fip_dev_state_t *state; + + assert(dev_info != NULL); + + state = (fip_dev_state_t *)dev_info->info; /* Obtain a reference to the image by querying the platform layer */ result = plat_get_image_source(image_id, &backend_dev_handle, @@ -248,6 +253,11 @@ static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) result = -ENOENT; } else { VERBOSE("FIP header looks OK.\n"); + /* + * Store 16-bit Platform ToC flags field which occupies + * bits [32-47] in fip header. + */ + state->plat_toc_flag = (header.flags >> 32) & 0xffff; } } @@ -277,6 +287,7 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, int result; uintptr_t backend_handle; const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)spec; + static const uuid_t uuid_null = { {0} }; /* Double braces for clang */ size_t bytes_read; int found_file = 0; @@ -289,9 +300,9 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, * When the system supports dynamic memory allocation we can allow more * than one open file at a time if needed. */ - if (current_file.entry.offset_address != 0) { + if (current_fip_file.entry.offset_address != 0U) { WARN("fip_file_open : Only one open file at a time.\n"); - return -ENOMEM; + return -ENFILE; } /* Attempt to access the FIP image */ @@ -315,31 +326,32 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec, found_file = 0; do { result = io_read(backend_handle, - (uintptr_t)¤t_file.entry, - sizeof(current_file.entry), + (uintptr_t)¤t_fip_file.entry, + sizeof(current_fip_file.entry), &bytes_read); if (result == 0) { - if (compare_uuids(¤t_file.entry.uuid, + if (compare_uuids(¤t_fip_file.entry.uuid, &uuid_spec->uuid) == 0) { found_file = 1; - break; } } else { WARN("Failed to read FIP (%i)\n", result); goto fip_file_open_close; } - } while (compare_uuids(¤t_file.entry.uuid, &uuid_null) != 0); + } while ((found_file == 0) && + (compare_uuids(¤t_fip_file.entry.uuid, + &uuid_null) != 0)); if (found_file == 1) { /* All fine. Update entity info with file state and return. Set - * the file position to 0. The 'current_file.entry' holds the - * base and size of the file. + * the file position to 0. The 'current_fip_file.entry' holds + * the base and size of the file. */ - current_file.file_pos = 0; - entity->info = (uintptr_t)¤t_file; + current_fip_file.file_pos = 0; + entity->info = (uintptr_t)¤t_fip_file; } else { /* Did not find the file in the FIP. */ - current_file.entry.offset_address = 0; + current_fip_file.entry.offset_address = 0; result = -ENOENT; } @@ -357,7 +369,7 @@ static int fip_file_len(io_entity_t *entity, size_t *length) assert(entity != NULL); assert(length != NULL); - *length = ((file_state_t *)entity->info)->entry.size; + *length = ((fip_file_state_t *)entity->info)->entry.size; return 0; } @@ -368,7 +380,7 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { int result; - file_state_t *fp; + fip_file_state_t *fp; size_t file_offset; size_t bytes_read; uintptr_t backend_handle; @@ -386,7 +398,7 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, goto fip_file_read_exit; } - fp = (file_state_t *)entity->info; + fp = (fip_file_state_t *)entity->info; /* Seek to the position in the FIP where the payload lives */ file_offset = fp->entry.offset_address + fp->file_pos; @@ -425,8 +437,8 @@ static int fip_file_close(io_entity_t *entity) /* Clear our current file pointer. * If we had malloc() we would free() here. */ - if (current_file.entry.offset_address != 0) { - zeromem(¤t_file, sizeof(current_file)); + if (current_fip_file.entry.offset_address != 0U) { + zeromem(¤t_fip_file, sizeof(current_fip_file)); } /* Clear the Entity info. */ @@ -453,3 +465,17 @@ int register_io_dev_fip(const io_dev_connector_t **dev_con) return result; } + +/* Function to retrieve plat_toc_flags, previously saved in FIP dev */ +int fip_dev_get_plat_toc_flag(io_dev_info_t *dev_info, uint16_t *plat_toc_flag) +{ + fip_dev_state_t *state; + + assert(dev_info != NULL); + + state = (fip_dev_state_t *)dev_info->info; + + *plat_toc_flag = state->plat_toc_flag; + + return 0; +} diff --git a/drivers/io/io_memmap.c b/drivers/io/io_memmap.c index eed50cc08..eb69163b7 100644 --- a/drivers/io/io_memmap.c +++ b/drivers/io/io_memmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,9 +27,9 @@ typedef struct { uintptr_t base; unsigned long long file_pos; unsigned long long size; -} file_state_t; +} memmap_file_state_t; -static file_state_t current_file = {0}; +static memmap_file_state_t current_memmap_file = {0}; /* Identify the device type as memmap */ static io_type_t device_type_memmap(void) @@ -71,7 +71,7 @@ static const io_dev_funcs_t memmap_dev_funcs = { /* No state associated with this device so structure can be const */ -static const io_dev_info_t memmap_dev_info = { +static io_dev_info_t memmap_dev_info = { .funcs = &memmap_dev_funcs, .info = (uintptr_t)NULL }; @@ -82,8 +82,7 @@ static int memmap_dev_open(const uintptr_t dev_spec __unused, io_dev_info_t **dev_info) { assert(dev_info != NULL); - *dev_info = (io_dev_info_t *)&memmap_dev_info; /* cast away const */ - + *dev_info = &memmap_dev_info; return 0; } @@ -109,16 +108,16 @@ static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec, * spec at a time. When we have dynamic memory we can malloc and set * entity->info. */ - if (current_file.in_use == 0) { + if (current_memmap_file.in_use == 0) { assert(block_spec != NULL); assert(entity != NULL); - current_file.in_use = 1; - current_file.base = block_spec->offset; + current_memmap_file.in_use = 1; + current_memmap_file.base = block_spec->offset; /* File cursor offset for seek and incremental reads etc. */ - current_file.file_pos = 0; - current_file.size = block_spec->length; - entity->info = (uintptr_t)¤t_file; + current_memmap_file.file_pos = 0; + current_memmap_file.size = block_spec->length; + entity->info = (uintptr_t)¤t_memmap_file; result = 0; } else { WARN("A Memmap device is already active. Close first.\n"); @@ -133,13 +132,13 @@ static int memmap_block_seek(io_entity_t *entity, int mode, signed long long offset) { int result = -ENOENT; - file_state_t *fp; + memmap_file_state_t *fp; /* We only support IO_SEEK_SET for the moment. */ if (mode == IO_SEEK_SET) { assert(entity != NULL); - fp = (file_state_t *) entity->info; + fp = (memmap_file_state_t *) entity->info; /* Assert that new file position is valid */ assert((offset >= 0) && @@ -160,7 +159,7 @@ static int memmap_block_len(io_entity_t *entity, size_t *length) assert(entity != NULL); assert(length != NULL); - *length = (size_t)((file_state_t *)entity->info)->size; + *length = (size_t)((memmap_file_state_t *)entity->info)->size; return 0; } @@ -170,13 +169,13 @@ static int memmap_block_len(io_entity_t *entity, size_t *length) static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { - file_state_t *fp; + memmap_file_state_t *fp; unsigned long long pos_after; assert(entity != NULL); assert(length_read != NULL); - fp = (file_state_t *) entity->info; + fp = (memmap_file_state_t *) entity->info; /* Assert that file position is valid for this read operation */ pos_after = fp->file_pos + length; @@ -198,13 +197,13 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer, static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer, size_t length, size_t *length_written) { - file_state_t *fp; + memmap_file_state_t *fp; unsigned long long pos_after; assert(entity != NULL); assert(length_written != NULL); - fp = (file_state_t *) entity->info; + fp = (memmap_file_state_t *) entity->info; /* Assert that file position is valid for this write operation */ pos_after = fp->file_pos + length; @@ -230,7 +229,7 @@ static int memmap_block_close(io_entity_t *entity) entity->info = 0; /* This would be a mem free() if we had malloc.*/ - zeromem((void *)¤t_file, sizeof(current_file)); + zeromem((void *)¤t_memmap_file, sizeof(current_memmap_file)); return 0; } diff --git a/drivers/io/io_semihosting.c b/drivers/io/io_semihosting.c index 4ceddc6cc..1c2f84d54 100644 --- a/drivers/io/io_semihosting.c +++ b/drivers/io/io_semihosting.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,8 +51,7 @@ static const io_dev_funcs_t sh_dev_funcs = { }; -/* No state associated with this device so structure can be const */ -static const io_dev_info_t sh_dev_info = { +static io_dev_info_t sh_dev_info = { .funcs = &sh_dev_funcs, .info = (uintptr_t)NULL }; @@ -63,7 +62,7 @@ static int sh_dev_open(const uintptr_t dev_spec __unused, io_dev_info_t **dev_info) { assert(dev_info != NULL); - *dev_info = (io_dev_info_t *)&sh_dev_info; /* cast away const */ + *dev_info = &sh_dev_info; return 0; } diff --git a/drivers/io/io_storage.c b/drivers/io/io_storage.c index b8c1d6479..053426891 100644 --- a/drivers/io/io_storage.c +++ b/drivers/io/io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,36 +32,34 @@ static unsigned int dev_count; #if ENABLE_ASSERTIONS /* Return a boolean value indicating whether a device connector is valid */ -static int is_valid_dev_connector(const io_dev_connector_t *dev_con) +static bool is_valid_dev_connector(const io_dev_connector_t *dev_con) { - int result = (dev_con != NULL) && (dev_con->dev_open != NULL); - return result; + return (dev_con != NULL) && (dev_con->dev_open != NULL); } - /* Return a boolean value indicating whether a device handle is valid */ -static int is_valid_dev(const uintptr_t dev_handle) +static bool is_valid_dev(const uintptr_t dev_handle) { const io_dev_info_t *dev = (io_dev_info_t *)dev_handle; - int result = (dev != NULL) && (dev->funcs != NULL) && + + return (dev != NULL) && (dev->funcs != NULL) && (dev->funcs->type != NULL) && (dev->funcs->type() < IO_TYPE_MAX); - return result; } /* Return a boolean value indicating whether an IO entity is valid */ -static int is_valid_entity(const uintptr_t handle) +static bool is_valid_entity(const uintptr_t handle) { const io_entity_t *entity = (io_entity_t *)handle; - int result = (entity != NULL) && + + return (entity != NULL) && (is_valid_dev((uintptr_t)entity->dev_handle)); - return result; } /* Return a boolean value indicating whether a seek mode is valid */ -static int is_valid_seek_mode(io_seek_mode_t mode) +static bool is_valid_seek_mode(io_seek_mode_t mode) { return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX)); } @@ -71,15 +69,14 @@ static int is_valid_seek_mode(io_seek_mode_t mode) /* Open a connection to a specific device */ -static int dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, +static int io_storage_dev_open(const io_dev_connector_t *dev_con, + const uintptr_t dev_spec, io_dev_info_t **dev_info) { - int result; assert(dev_info != NULL); assert(is_valid_dev_connector(dev_con)); - result = dev_con->dev_open(dev_spec, dev_info); - return result; + return dev_con->dev_open(dev_spec, dev_info); } @@ -116,7 +113,8 @@ static int allocate_entity(io_entity_t **entity) unsigned int index = 0; result = find_first_entity(NULL, &index); assert(result == 0); - *entity = entity_map[index] = &entity_pool[index]; + *entity = &entity_pool[index]; + entity_map[index] = &entity_pool[index]; ++entity_count; } @@ -163,11 +161,8 @@ int io_register_device(const io_dev_info_t *dev_info) int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, uintptr_t *handle) { - int result; assert(handle != NULL); - - result = dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); - return result; + return io_storage_dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); } diff --git a/drivers/marvell/ap807_clocks_init.c b/drivers/marvell/ap807_clocks_init.c index 04c256b61..c1f861909 100644 --- a/drivers/marvell/ap807_clocks_init.c +++ b/drivers/marvell/ap807_clocks_init.c @@ -39,19 +39,29 @@ #define AP807_CPU_PLL_PARAM(cluster) AP807_CPU_PLL_CTRL(cluster) #define AP807_CPU_PLL_CFG(cluster) (AP807_CPU_PLL_CTRL(cluster) + 0x4) #define AP807_CPU_PLL_CFG_BYPASS_MODE (0x1) +#define AP807_CPU_PLL_FRC_DSCHG (0x2) #define AP807_CPU_PLL_CFG_USE_REG_FILE (0x1 << 9) static void pll_set_freq(unsigned int freq_val) { int i; + if (freq_val != PLL_FREQ_2200) + return; + for (i = 0 ; i < AP807_CLUSTER_NUM ; i++) { + /* Set parameter of cluster i PLL to 2.2GHz */ + mmio_write_32(AP807_CPU_PLL_PARAM(i), freq_val); + /* Set apll_lpf_frc_dschg - Control + * voltage of internal VCO is discharged + */ mmio_write_32(AP807_CPU_PLL_CFG(i), - AP807_CPU_PLL_CFG_USE_REG_FILE); + AP807_CPU_PLL_FRC_DSCHG); + /* Set use_rf_conf load PLL parameter from register */ mmio_write_32(AP807_CPU_PLL_CFG(i), - AP807_CPU_PLL_CFG_USE_REG_FILE | - AP807_CPU_PLL_CFG_BYPASS_MODE); - mmio_write_32(AP807_CPU_PLL_PARAM(i), freq_val); + AP807_CPU_PLL_FRC_DSCHG | + AP807_CPU_PLL_CFG_USE_REG_FILE); + /* Un-set apll_lpf_frc_dschg */ mmio_write_32(AP807_CPU_PLL_CFG(i), AP807_CPU_PLL_CFG_USE_REG_FILE); } @@ -84,19 +94,16 @@ static void aro_to_pll(void) */ void ap807_clocks_init(unsigned int freq_option) { - /* Switch from ARO to PLL */ - aro_to_pll(); - /* Modifications in frequency table: * 0x0: 764x: change to 2000 MHz. * 0x2: 744x change to 1800 MHz, 764x change to 2200/2400. * 0x3: 3900/744x/764x change to 1200 MHz. */ - switch (freq_option) { - case CPU_2000_DDR_1200_RCLK_1200: - pll_set_freq(PLL_FREQ_2000); - break; - default: - break; - } + + if (freq_option == CPU_2200_DDR_1200_RCLK_1200) + pll_set_freq(PLL_FREQ_2200); + + /* Switch from ARO to PLL */ + aro_to_pll(); + } diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c index 3df93a43b..4b06b4752 100644 --- a/drivers/marvell/cache_llc.c +++ b/drivers/marvell/cache_llc.c @@ -31,19 +31,19 @@ void llc_cache_sync(int ap_index) void llc_flush_all(int ap_index) { - mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_CLEAN_INV_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } void llc_clean_all(int ap_index) { - mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_CLEAN_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } void llc_inv_all(int ap_index) { - mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK); + mmio_write_32(LLC_INV_WAY(ap_index), LLC_ALL_WAYS_MASK); llc_cache_sync(ap_index); } @@ -109,3 +109,81 @@ void llc_runtime_enable(int ap_index) reg |= (0x1 << CCU_SET_POC_OFFSET); mmio_write_32(CCU_HTC_CR(ap_index), reg); } + +#if LLC_SRAM +int llc_sram_enable(int ap_index, int size) +{ + uint32_t tc, way, ways_to_allocate; + uint32_t way_addr; + + if ((size <= 0) || (size > LLC_SIZE) || (size % LLC_WAY_SIZE)) + return -1; + + llc_enable(ap_index, 1); + llc_inv_all(ap_index); + + ways_to_allocate = size / LLC_WAY_SIZE; + + /* Lockdown all available ways for all traffic classes */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), LLC_ALL_WAYS_MASK); + + /* Clear the high bits of SRAM address */ + mmio_write_32(LLC_BANKED_MNT_AHR(ap_index), 0); + + way_addr = PLAT_MARVELL_TRUSTED_RAM_BASE; + for (way = 0; way < ways_to_allocate; way++) { + /* Trigger allocation block command */ + mmio_write_32(LLC_BLK_ALOC(ap_index), + LLC_BLK_ALOC_BASE_ADDR(way_addr) | + LLC_BLK_ALOC_WAY_DATA_SET | + LLC_BLK_ALOC_WAY_ID(way)); + way_addr += LLC_WAY_SIZE; + } + return 0; +} + +void llc_sram_disable(int ap_index) +{ + uint32_t tc; + + /* Disable the line lockings */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), 0); + + /* Invalidate all ways */ + llc_inv_all(ap_index); +} + +int llc_sram_test(int ap_index, int size, char *msg) +{ + uintptr_t addr, end_addr; + uint32_t data = 0; + + if ((size <= 0) || (size > LLC_SIZE)) + return -1; + + INFO("=== LLC SRAM WRITE test %s\n", msg); + for (addr = PLAT_MARVELL_TRUSTED_RAM_BASE, + end_addr = PLAT_MARVELL_TRUSTED_RAM_BASE + size; + addr < end_addr; addr += 4) { + mmio_write_32(addr, addr); + } + INFO("=== LLC SRAM WRITE test %s PASSED\n", msg); + INFO("=== LLC SRAM READ test %s\n", msg); + for (addr = PLAT_MARVELL_TRUSTED_RAM_BASE, + end_addr = PLAT_MARVELL_TRUSTED_RAM_BASE + size; + addr < end_addr; addr += 4) { + data = mmio_read_32(addr); + if (data != addr) { + INFO("=== LLC SRAM READ test %s FAILED @ 0x%08lx)\n", + msg, addr); + return -1; + } + } + INFO("=== LLC SRAM READ test %s PASSED (last read = 0x%08x)\n", + msg, data); + return 0; +} + +#endif /* LLC_SRAM */ diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c index 1e4ab44da..b4251f49b 100644 --- a/drivers/marvell/ccu.c +++ b/drivers/marvell/ccu.c @@ -26,10 +26,40 @@ #define ADDRESS_MASK (0xFFFFFFF0) #define CCU_WIN_ALIGNMENT (0x100000) +/* + * Physical address of the highest address of window bits[31:19] = 0x6FF + * Physical address of the lowest address of window bits[18:6] = 0x6E0 + * Unit Id bits [5:2] = 2 + * RGF Window Enable bit[0] = 1 + * 0x37f9b809 - 11011111111 0011011100000 0010 0 1 + */ +#define ERRATA_WA_CCU_WIN4 0x37f9b809U + +/* + * Physical address of the highest address of window bits[31:19] = 0xFFF + * Physical address of the lowest address of window bits[18:6] = 0x800 + * Unit Id bits [5:2] = 2 + * RGF Window Enable bit[0] = 1 + * 0x7ffa0009 - 111111111111 0100000000000 0010 0 1 + */ +#define ERRATA_WA_CCU_WIN5 0x7ffa0009U + +/* + * Physical address of the highest address of window bits[31:19] = 0x1FFF + * Physical address of the lowest address of window bits[18:6] = 0x1000 + * Unit Id bits [5:2] = 2 + * RGF Window Enable bit[0] = 1 + * 0xfffc000d - 1111111111111 1000000000000 0011 0 1 + */ +#define ERRATA_WA_CCU_WIN6 0xfffc000dU + #define IS_DRAM_TARGET(tgt) ((((tgt) == DRAM_0_TID) || \ ((tgt) == DRAM_1_TID) || \ ((tgt) == RAR_TID)) ? 1 : 0) +#define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \ + 0x90 + 4 * (win)) + /* For storage of CR, SCR, ALR, AHR abd GCR */ static uint32_t ccu_regs_save[MVEBU_CCU_MAX_WINS * 4 + 1]; @@ -54,8 +84,8 @@ static void dump_ccu(int ap_index) win_id)); start = ((uint64_t)alr << ADDRESS_SHIFT); end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT); - printf("\tccu %02x 0x%016llx 0x%016llx\n", - target_id, start, end); + printf("\tccu%d %02x 0x%016llx 0x%016llx\n", + win_id, target_id, start, end); } } win_cr = mmio_read_32(CCU_WIN_GCR_OFFSET(ap_index)); @@ -81,6 +111,12 @@ void ccu_win_check(struct addr_map_win *win) } } +int ccu_is_win_enabled(int ap_index, uint32_t win_id) +{ + return mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id)) & + WIN_ENABLE_BIT; +} + void ccu_enable_win(int ap_index, struct addr_map_win *win, uint32_t win_id) { uint32_t ccu_win_reg; @@ -360,3 +396,19 @@ int init_ccu(int ap_index) return 0; } + +void errata_wa_init(void) +{ + /* + * EERATA ID: RES-3033912 - Internal Address Space Init state causes + * a hang upon accesses to [0xf070_0000, 0xf07f_ffff] + * Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to + * split [0x6e_0000, 0x1ff_ffff] to values [0x6e_0000, 0x6f_ffff] and + * [0x80_0000, 0xff_ffff] and [0x100_0000, 0x1ff_ffff],that cause + * accesses to the segment of [0xf070_0000, 0xf1ff_ffff] + * to act as RAZWI. + */ + mmio_write_32(CCU_RGF(4), ERRATA_WA_CCU_WIN4); + mmio_write_32(CCU_RGF(5), ERRATA_WA_CCU_WIN5); + mmio_write_32(CCU_RGF(6), ERRATA_WA_CCU_WIN6); +} diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h index 6eb7fd0d2..9b10619ed 100644 --- a/drivers/marvell/comphy/comphy-cp110.h +++ b/drivers/marvell/comphy/comphy-cp110.h @@ -116,6 +116,9 @@ (0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET) #define SD_EXTERNAL_CONFIG1_REG 0x4 +#define SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET 2 +#define SD_EXTERNAL_CONFIG1_TX_IDLE_MASK \ + (0x1 << SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET) #define SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET 3 #define SD_EXTERNAL_CONFIG1_RESET_IN_MASK \ (0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET) @@ -352,6 +355,14 @@ #define HPIPE_CDR_LOCK_DET_EN_MASK \ (0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET) +#define HPIPE_SYNC_PATTERN_REG 0x090 +#define HPIPE_SYNC_PATTERN_TXD_INV_OFFSET 10 +#define HPIPE_SYNC_PATTERN_TXD_INV_MASK \ + (0x1 << HPIPE_SYNC_PATTERN_TXD_INV_OFFSET) +#define HPIPE_SYNC_PATTERN_RXD_INV_OFFSET 11 +#define HPIPE_SYNC_PATTERN_RXD_INV_MASK \ + (0x1 << HPIPE_SYNC_PATTERN_RXD_INV_OFFSET) + #define HPIPE_INTERFACE_REG 0x94 #define HPIPE_INTERFACE_GEN_MAX_OFFSET 10 #define HPIPE_INTERFACE_GEN_MAX_MASK \ @@ -659,18 +670,32 @@ (0x3f << HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET) #define HPIPE_CDR_CONTROL_REG 0x418 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \ - (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET) -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12 -#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \ - (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET) -#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9 -#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \ - (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET) +#define HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET 0 +#define HPIPE_CRD_MIDPOINT_PHASE_OS_MASK \ + (0x3f << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET) #define HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET 6 #define HPIPE_CDR_MAX_DFE_ADAPT_1_MASK \ (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET) +#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9 +#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \ + (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET) +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12 +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \ + (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET) +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14 +#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \ + (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET) + + +#define HPIPE_CDR_CONTROL1_REG 0x41c +#define HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF 12 +#define HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK \ + (0xf << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF) + +#define HPIPE_CDR_CONTROL2_REG 0x420 +#define HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF 12 +#define HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK \ + (0xf << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF) #define HPIPE_TX_TRAIN_CTRL_11_REG 0x438 #define HPIPE_TX_STATUS_CHECK_MODE_OFFSET 6 @@ -749,6 +774,30 @@ #define HPIPE_DFE_CTRL_28_PIPE4_MASK \ (0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET) +#define HPIPE_TRX0_REG 0x4cc /*in doc 0x133*4*/ +#define HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF 2 +#define HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK \ + (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF) +#define HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF 0 +#define HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK \ + (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF) + +#define HPIPE_TRX_REG1 0x4d0 /*in doc 0x134*4*/ +#define HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF 3 +#define HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK \ + (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF) +#define HPIPE_TRX_REG1_SUMFTAP_EN_OFF 10 +#define HPIPE_TRX_REG1_SUMFTAP_EN_MASK \ + (0x3f << HPIPE_TRX_REG1_SUMFTAP_EN_OFF) + +#define HPIPE_TRX_REG2 0x4d8 /*in doc 0x136*4*/ +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF 11 +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK \ + (0x1f << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF) +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF 7 +#define HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK \ + (0xf << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF) + #define HPIPE_G1_SETTING_5_REG 0x538 #define HPIPE_G1_SETTING_5_G1_ICP_OFFSET 0 #define HPIPE_G1_SETTING_5_G1_ICP_MASK \ diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 384dd39f2..d1c26f8d3 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -11,6 +11,7 @@ #include <common/debug.h> #include <drivers/delay_timer.h> +#include <mg_conf_cm3/mg_conf_cm3.h> #include <lib/mmio.h> #include <lib/spinlock.h> @@ -209,8 +210,10 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base, * as SFI1/XFI1 available only for CP115. */ if ((mode == COMPHY_SGMII_MODE || - mode == COMPHY_HS_SGMII_MODE || - mode == COMPHY_SFI_MODE || mode == COMPHY_XFI_MODE) + mode == COMPHY_HS_SGMII_MODE || + mode == COMPHY_SFI_MODE || + mode == COMPHY_XFI_MODE || + mode == COMPHY_AP_MODE) && COMPHY_GET_ID(comphy_mode) == 1) reg |= COMMON_SELECTOR_COMPHY4_PORT1 << comphy_offset; @@ -320,12 +323,33 @@ int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index) return ret; } +static void mvebu_cp110_polarity_invert(uintptr_t addr, uint8_t phy_polarity_invert) +{ + uint32_t mask, data; + + /* Set RX / TX polarity */ + data = mask = 0x0U; + if ((phy_polarity_invert & COMPHY_POLARITY_TXD_INVERT) != 0) { + data |= (1 << HPIPE_SYNC_PATTERN_TXD_INV_OFFSET); + mask |= HPIPE_SYNC_PATTERN_TXD_INV_MASK; + debug("%s: inverting TX polarity\n", __func__); + } + + if ((phy_polarity_invert & COMPHY_POLARITY_RXD_INVERT) != 0) { + data |= (1 << HPIPE_SYNC_PATTERN_RXD_INV_OFFSET); + mask |= HPIPE_SYNC_PATTERN_RXD_INV_MASK; + debug("%s: inverting RX polarity\n", __func__); + } + + reg_set(addr, data, mask); +} + static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base, uint8_t comphy_index, uint32_t comphy_mode) { uintptr_t hpipe_addr, sd_ip_addr, comphy_addr; uint32_t mask, data; - uint8_t ap_nr, cp_nr; + uint8_t ap_nr, cp_nr, phy_polarity_invert; int ret = 0; debug_enter(); @@ -335,6 +359,7 @@ static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base, const struct sata_params *sata_static_values = &sata_static_values_tab[ap_nr][cp_nr][comphy_index]; + phy_polarity_invert = sata_static_values->polarity_invert; /* configure phy selector for SATA */ mvebu_cp110_comphy_set_phy_selector(comphy_base, @@ -626,6 +651,11 @@ static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base, reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK); + + if (phy_polarity_invert != 0) + mvebu_cp110_polarity_invert(hpipe_addr + HPIPE_SYNC_PATTERN_REG, + phy_polarity_invert); + /* SW reset for interrupt logic */ reg_set(hpipe_addr + HPIPE_PWR_CTR_REG, 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, @@ -895,11 +925,21 @@ static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base, data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; + mask |= SD_EXTERNAL_CONFIG1_TX_IDLE_MASK; + data |= 0x1 << SD_EXTERNAL_CONFIG1_TX_IDLE_OFFSET; reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); /* Wait 1ms - until band gap and ref clock ready */ mdelay(1); + /* + * Erratum IPCE_COMPHY-1353: toggle TX_IDLE bit in + * addition to the PHY reset + */ + mask = SD_EXTERNAL_CONFIG1_TX_IDLE_MASK; + data = 0x0U; + reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); + /* Start comphy Configuration */ debug("stage: Comphy configuration\n"); /* set reference clock */ @@ -1882,6 +1922,7 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, { uintptr_t hpipe_addr, comphy_addr, addr; uint32_t mask, data; + uint8_t ap_nr, cp_nr, phy_polarity_invert; int ret = 0; debug_enter(); @@ -1890,6 +1931,13 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index, comphy_mode); + mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); + + const struct usb_params *usb_static_values = + &usb_static_values_tab[ap_nr][cp_nr][comphy_index]; + + phy_polarity_invert = usb_static_values->polarity_invert; + hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), comphy_index); comphy_addr = COMPHY_ADDR(comphy_base, comphy_index); @@ -1969,6 +2017,13 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET, HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK); + /* The polarity inversion for USB was not tested due to lack of hw + * design which requires it. Support is added for customer needs. + */ + if (phy_polarity_invert) + mvebu_cp110_polarity_invert(hpipe_addr + HPIPE_SYNC_PATTERN_REG, + phy_polarity_invert); + /* Start analog parameters from ETP(HW) */ debug("stage: Analog parameters from ETP(HW)\n"); /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */ @@ -2012,12 +2067,58 @@ static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base, return ret; } +static void rx_pre_train(uint64_t comphy_base, uint8_t comphy_index) +{ + uintptr_t hpipe_addr; + uint32_t mask, data; + + hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), + comphy_index); + + debug("rx_training preparation\n\n"); + + mask = HPIPE_TRX0_GAIN_TRAIN_WITH_C_MASK; + data = (0x1 << HPIPE_TRX0_GAIN_TRAIN_WITH_C_OFF); + mask |= HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_MASK; + data |= (0x0 << HPIPE_TRX0_GAIN_TRAIN_WITH_SAMPLER_OFF); + reg_set(hpipe_addr + HPIPE_TRX0_REG, data, mask); + + + mask = HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK; + data = (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF); + mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_MASK; + data |= (0x0 << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_K_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG2, data, mask); + + mask = HPIPE_TRX_REG1_MIN_BOOST_MODE_MASK; + data = (0x1 << HPIPE_TRX_REG1_MIN_BOOST_MODE_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask); + + mask = HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_MASK; + data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_SMALL_THRES_K_OFF); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL1_REG, data, mask); + + mask = HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_MASK; + data = (0x8 << HPIPE_CRD2_CRD_MIDPOINT_LARGE_THRES_K_OFF); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL2_REG, data, mask); + + mask = HPIPE_CRD_MIDPOINT_PHASE_OS_MASK; + data = (0x0 << HPIPE_CRD_MIDPOINT_PHASE_OS_OFFSET); + reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask); + + mask = HPIPE_TRX_REG1_SUMFTAP_EN_MASK; + data = (0x38 << HPIPE_TRX_REG1_SUMFTAP_EN_OFF); + mask |= HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_MASK; + data |= (0x1e << HPIPE_TRX_REG2_SUMF_BOOST_TARGET_C_OFF); + reg_set(hpipe_addr + HPIPE_TRX_REG1, data, mask); +} + int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, uint8_t comphy_index) { uint32_t mask, data, timeout; uint32_t g1_ffe_cap_sel, g1_ffe_res_sel, align90, g1_dfe_res; - uintptr_t hpipe_addr, sd_ip_addr; + uintptr_t hpipe_addr; uint8_t ap_nr, cp_nr; @@ -2025,30 +2126,10 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), comphy_index); - sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), - comphy_index); debug_enter(); - debug("stage: RF Reset\n"); - - /* Release from hard reset */ - mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; - data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; - data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; - data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); - - mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; - data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; - mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; - data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask); - - /* Wait 50ms - until band gap and ref clock ready */ - mdelay(50); + rx_pre_train(comphy_base, comphy_index); debug("Preparation for rx_training\n\n"); @@ -2068,34 +2149,10 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, data = 0 << HPIPE_DFE_RES_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); - debug("PRBS31 loppback\n\n"); - - /* Configure PRBS counters */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_DATA_MASK; - data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask); - - mask = HPIPE_PHY_TEST_EN_MASK; - data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mdelay(10); - debug("Enable TX/RX training\n\n"); + debug("Enable RX training\n\n"); mask = HPIPE_TRX_RX_TRAIN_EN_MASK; data = 0x1 << HPIPE_TRX_RX_TRAIN_EN_OFFSET; - mask |= HPIPE_TRX_RX_ANA_IF_CLK_ENE_MASK; - data |= 0x1 << HPIPE_TRX_RX_ANA_IF_CLK_ENE_OFFSET; - mask |= HPIPE_TRX_TX_CTRL_CLK_EN_MASK; - data |= 0x1 << HPIPE_TRX_TX_CTRL_CLK_EN_OFFSET; - mask |= HPIPE_TRX_UPDATE_THEN_HOLD_MASK; - data |= 0x1 << HPIPE_TRX_UPDATE_THEN_HOLD_OFFSET; - mask |= HPIPE_TRX_TX_F0T_EO_BASED_MASK; - data |= 0x1 << HPIPE_TRX_TX_F0T_EO_BASED_OFFSET; reg_set(hpipe_addr + HPIPE_TRX_TRAIN_CTRL_0_REG, data, mask); /* Check the result of RX training */ @@ -2180,21 +2237,9 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, data = 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); - /* Use the value from CAL_OS_PH_EXT */ - mask = HPIPE_CAL_RXCLKALIGN_90_EXT_EN_MASK; - data = 1 << HPIPE_CAL_RXCLKALIGN_90_EXT_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG, - data, mask); - - /* Update align90 */ - mask = HPIPE_CAL_OS_PH_EXT_MASK; - data = align90 << HPIPE_CAL_OS_PH_EXT_OFFSET; - reg_set(hpipe_addr + HPIPE_RX_CLK_ALIGN90_AND_TX_IDLE_CALIB_CTRL_REG, - data, mask); - /* Force DFE resolution (use gen table value) */ mask = HPIPE_DFE_RES_FORCE_MASK; - data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET; + data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET; reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); /* 0x111-G1 DFE_Setting_4 */ @@ -2202,41 +2247,9 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, data = g1_dfe_res << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET; reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask); - debug("PRBS31 loppback\n\n"); - - mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK; - data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask); - - /* Configure PRBS counters */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_DATA_MASK; - data = 0xc4 << HPIPE_PHY_TEST_DATA_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask); - - mask = HPIPE_PHY_TEST_EN_MASK; - data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - /* Reset PRBS error counter */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_PT_TESTMODE_MASK; - data = 0x1 << HPIPE_PHY_TEST_PT_TESTMODE_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_OOB_0_REGISTER, data, mask); - printf("########################################################\n"); printf("# To use trained values update the ATF sources:\n"); - printf("# plat/marvell/a8k/<board_type>/board/phy-porting-layer.h "); + printf("# plat/marvell/armada/a8k/<board_type>/board/phy-porting-layer.h "); printf("file\n# with new values as below (for appropriate AP nr %d", ap_nr); printf("and CP nr: %d comphy_index %d\n\n", @@ -2252,12 +2265,6 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, printf("};\n\n"); printf("########################################################\n"); - /* check */ - debug("PRBS error counter[0x%lx] 0x%x\n\n", - hpipe_addr + HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG, - mmio_read_32(hpipe_addr + - HPIPE_PHY_TEST_PRBS_ERROR_COUNTER_1_REG)); - rx_trainng_done[ap_nr][cp_nr][comphy_index] = 1; return 0; @@ -2273,12 +2280,17 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, * the network registers like: MG, AP, MAC, PCS, Serdes etc.) */ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, - uint8_t comphy_index) + uint8_t comphy_index, + uint32_t comphy_mode) { uint32_t mask, data; + uint8_t ap_nr, cp_nr; uintptr_t comphy_addr = comphy_addr = COMPHY_ADDR(comphy_base, comphy_index); + /* configure phy selector for XFI/SFI */ + mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index, + comphy_mode); debug_enter(); debug("stage: RFU configurations - hard reset comphy\n"); /* RFU configurations - hard reset comphy */ @@ -2289,6 +2301,10 @@ static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base, reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask); debug_exit(); + /* Start AP Firmware */ + mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base); + mg_start_ap_fw(cp_nr, comphy_index); + return 0; } @@ -2371,7 +2387,8 @@ int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint8_t comphy_index, comphy_mode); break; case (COMPHY_AP_MODE): - err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index); + err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index, + comphy_mode); break; default: ERROR("comphy%d: unsupported comphy mode\n", comphy_index); diff --git a/drivers/marvell/comphy/phy-comphy-cp110.h b/drivers/marvell/comphy/phy-comphy-cp110.h index 407909bf7..b4a210242 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.h +++ b/drivers/marvell/comphy/phy-comphy-cp110.h @@ -7,7 +7,7 @@ /* Those are parameters for xfi mode, which need to be tune for each board type. * For known DB boards the parameters was already calibrated and placed under - * the plat/marvell/a8k/<board_type>/board/phy-porting-layer.h + * the plat/marvell/armada/a8k/<board_type>/board/phy-porting-layer.h */ struct xfi_params { uint8_t g1_ffe_res_sel; @@ -76,9 +76,15 @@ struct sata_params { uint8_t g2_rx_selmupi; uint8_t g3_rx_selmupi; + uint8_t polarity_invert; + _Bool valid; }; +struct usb_params { + uint8_t polarity_invert; +}; + int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index); int mvebu_cp110_comphy_power_off(uint64_t comphy_base, @@ -89,3 +95,7 @@ int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base, uint8_t comphy_index); int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base, uint8_t comphy_index, uint32_t comphy_mode, uint32_t command); + +#define COMPHY_POLARITY_NO_INVERT 0 +#define COMPHY_POLARITY_TXD_INVERT 1 +#define COMPHY_POLARITY_RXD_INVERT 2 diff --git a/drivers/marvell/comphy/phy-default-porting-layer.h b/drivers/marvell/comphy/phy-default-porting-layer.h index b3ad7eb14..3c63c64b8 100644 --- a/drivers/marvell/comphy/phy-default-porting-layer.h +++ b/drivers/marvell/comphy/phy-default-porting-layer.h @@ -45,7 +45,15 @@ static const struct sata_params .g3_rx_selmupf = 0x2, .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2, + .polarity_invert = COMPHY_POLARITY_NO_INVERT, .valid = 0x1 }, }; + +static const struct usb_params + usb_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + [0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = { + .polarity_invert = COMPHY_POLARITY_NO_INVERT + }, +}; #endif /* PHY_DEFAULT_PORTING_LAYER_H */ diff --git a/drivers/marvell/mci.c b/drivers/marvell/mci.c index 06fe88e13..2b5470042 100644 --- a/drivers/marvell/mci.c +++ b/drivers/marvell/mci.c @@ -571,21 +571,21 @@ static int mci_enable_simultaneous_transactions(int mci_index) debug_enter(); /* ID assignment (assigning global ID offset to CP) */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(2) | MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(2) | MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(2)); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG) | MCI_INDIRECT_CTRL_ASSIGN_CMD); ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); /* Assigning dest. ID=3 to all transactions entering from AXI at AP */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) | MCI_HB_CTRL_WIN0_DEST_ID(3)); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | @@ -593,10 +593,10 @@ static int mci_enable_simultaneous_transactions(int mci_index) ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); /* Assigning dest. ID=1 to all transactions entering from AXI at CP */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) | MCI_HB_CTRL_WIN0_DEST_ID(1)); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) | @@ -607,8 +607,8 @@ static int mci_enable_simultaneous_transactions(int mci_index) * This will lead to get match for any AXI address * and receive destination ID=3 */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 0xffffffff); + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | @@ -619,8 +619,8 @@ static int mci_enable_simultaneous_transactions(int mci_index) * This will lead to get match for any AXI address * and receive destination ID=1 */ - mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 0xffffffff); + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) | @@ -653,7 +653,7 @@ static _Bool mci_simulatenous_trans_missing(int mci_index) * performed by BootROM. */ debug_enter(); - mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), + mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), MCI_INDIRECT_REG_CTRL_ADDR( MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | @@ -697,7 +697,8 @@ int mci_configure(int mci_index) * wasn't already enabled in bootrom. */ if (mci_simulatenous_trans_missing(mci_index)) { - VERBOSE("Enabling MCI simultaneous transaction\n"); + VERBOSE("Enabling MCI simultaneous transaction for mci%d\n", + mci_index); /* set MCI to support read/write transactions * to arrive at the same time */ @@ -819,7 +820,7 @@ void mci_turn_link_on(void) } /* Initialize MCI for performance improvements */ -int mci_initialize(int mci_index) +int mci_link_tune(int mci_index) { int ret; diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c new file mode 100644 index 000000000..98e189687 --- /dev/null +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include <a8k_plat_def.h> +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <mss_scp_bl2_format.h> + +/* CONFI REGISTERS */ +#define MG_CM3_CONFI_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) +#define MG_CM3_SRAM_BASE(CP) MG_CM3_CONFI_BASE(CP) +#define MG_CM3_CONFI_GLOB_CFG_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B500) +#define CM3_CPU_EN_BIT BIT(28) +#define MG_CM3_MG_INT_MFX_REG(CP) (MG_CM3_CONFI_BASE(CP) + 0x2B054) +#define CM3_SYS_RESET_BIT BIT(0) + +#define MG_CM3_SHARED_MEM_BASE(CP) (MG_CM3_SRAM_BASE(CP) + 0x1FC00ULL) + +#define MG_SRAM_SIZE 0x20000 /* 128KB */ + +#define MG_ACK_TIMEOUT 10 + +/** + * struct ap_sharedmem_ctrl - used to pass information between the HOST and CM3 + * @init_done: Set by CM3 when ap_proces initialzied. Host check if CM3 set + * this flag to confirm that the process is running + * @lane_nr: Set by Host to mark which comphy lane should be configure. E.g.: + * - A8K development board uses comphy lane 2 for eth0 + * - CN913x development board uses comphy lane 4 for eth0 + */ +struct ap_sharedmem_ctrl { + uint32_t init_done; + uint32_t lane_nr; +}; + +int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index) +{ + uintptr_t mg_regs = MG_CM3_SRAM_BASE(cp_index); + + if (size > MG_SRAM_SIZE) { + ERROR("image is too big to fit into MG CM3 memory\n"); + return 1; + } + + NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", + src_addr, size, mg_regs); + + /* Copy image to MG CM3 SRAM */ + memcpy((void *)mg_regs, (void *)src_addr, size); + + /* Don't release MG CM3 from reset - it will be done by next step + * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which + * has enabeld 802.3. auto-neg) will be choosen. + */ + + return 0; +} + +void mg_start_ap_fw(int cp_nr, uint8_t comphy_index) +{ + volatile struct ap_sharedmem_ctrl *ap_shared_ctrl = + (void *)MG_CM3_SHARED_MEM_BASE(cp_nr); + int timeout = MG_ACK_TIMEOUT; + + if (mmio_read_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr)) & CM3_CPU_EN_BIT) { + VERBOSE("cm3 already running\n"); + return; /* cm3 already running */ + } + + /* + * Mark which comphy lane should be used - it will be read via shared + * mem by ap process + */ + ap_shared_ctrl->lane_nr = comphy_index; + /* Make sure it took place before enabling cm3 */ + dmbst(); + + mmio_setbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), CM3_CPU_EN_BIT); + mmio_setbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), CM3_SYS_RESET_BIT); + + /* Check for ap process initialization by fw */ + while (ap_shared_ctrl->init_done != 1 && timeout--) + VERBOSE("Waiting for ap process ack, timeout %d\n", timeout); + + if (timeout == 0) { + ERROR("AP process failed, disabling cm3\n"); + mmio_clrbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), + CM3_SYS_RESET_BIT); + mmio_clrbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), + CM3_CPU_EN_BIT); + } +} diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h new file mode 100644 index 000000000..e2756de9c --- /dev/null +++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +void mg_start_ap_fw(int cp_nr, uint8_t comphy_index); +int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index); diff --git a/drivers/marvell/mochi/ap807_setup.c b/drivers/marvell/mochi/ap807_setup.c index 864c9230a..1069f8cef 100644 --- a/drivers/marvell/mochi/ap807_setup.c +++ b/drivers/marvell/mochi/ap807_setup.c @@ -11,6 +11,7 @@ #include <drivers/marvell/cache_llc.h> #include <drivers/marvell/ccu.h> #include <drivers/marvell/io_win.h> +#include <drivers/marvell/iob.h> #include <drivers/marvell/mci.h> #include <drivers/marvell/mochi/ap_setup.h> #include <lib/mmio.h> @@ -31,6 +32,11 @@ #define DSS_CR0 (MVEBU_RFU_BASE + 0x100) #define DVM_48BIT_VA_ENABLE (1 << 21) + +/* SoC RFU / IHBx4 Control */ +#define MCIX4_807_REG_START_ADDR_REG(unit_id) (MVEBU_RFU_BASE + \ + 0x4258 + (unit_id * 0x4)) + /* Secure MoChi incoming access */ #define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738) #define SEC_MOCHI_IN_ACC_IHB0_EN (1) @@ -41,6 +47,14 @@ SEC_MOCHI_IN_ACC_IHB1_EN | \ SEC_MOCHI_IN_ACC_IHB2_EN | \ SEC_MOCHI_IN_ACC_PIDI_EN) +#define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0) +#define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1) +#define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2) +#define MOCHI_IN_ACC_LEVEL_MASK_ALL (3) +#define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1) +#define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4) +#define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10) + /* SYSRST_OUTn Config definitions */ #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) @@ -65,19 +79,36 @@ enum axi_attr { static void ap_sec_masters_access_en(uint32_t enable) { - uint32_t reg; - /* Open/Close incoming access for all masters. * The access is disabled in trusted boot mode * Could only be done in EL3 */ - reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG); - if (enable) - mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg | - SEC_IN_ACCESS_ENA_ALL_MASTERS); - else - mmio_write_32(SEC_MOCHI_IN_ACC_REG, - reg & ~SEC_IN_ACCESS_ENA_ALL_MASTERS); + if (enable != 0) { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */ + SEC_IN_ACCESS_ENA_ALL_MASTERS); +#if LLC_SRAM + /* Do not change access security level + * for PIDI masters + */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_LEAVE_ORIG)); +#endif + } else { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_IN_ACCESS_ENA_ALL_MASTERS, + 0x0U /* no set */); +#if LLC_SRAM + /* Return PIDI access level to the default */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_FORCE_NONSEC)); +#endif + } } static void setup_smmu(void) @@ -111,6 +142,8 @@ static void init_aurora2(void) reg |= (0x1 << CCU_SET_POC_OFFSET); mmio_write_32(CCU_HTC_CR, reg); #endif /* LLC_ENABLE */ + + errata_wa_init(); } @@ -124,7 +157,7 @@ static void mci_remap_indirect_access_base(void) uint32_t mci; for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++) - mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci), + mmio_write_32(MCIX4_807_REG_START_ADDR_REG(mci), MVEBU_MCI_REG_BASE_REMAP(mci) >> MCI_REMAP_OFF_SHIFT); } @@ -186,6 +219,38 @@ static void misc_soc_configurations(void) mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg); } +/* + * By default all external CPs start with configuration address space set to + * 0xf200_0000. To overcome this issue, go in the loop and initialize the + * CP one by one, using temporary window configuration which allows to access + * each CP and update its configuration space according to decoding + * windows scheme defined for each platform. + */ +void update_cp110_default_win(int cp_id) +{ + int mci_id = cp_id - 1; + uintptr_t cp110_base, cp110_temp_base; + + /* CP110 default configuration address space */ + cp110_temp_base = MVEBU_AP_IO_BASE(MVEBU_AP0); + + struct addr_map_win iowin_temp_win = { + .base_addr = cp110_temp_base, + .win_size = MVEBU_CP_OFFSET, + }; + + iowin_temp_win.target_id = mci_id; + iow_temp_win_insert(0, &iowin_temp_win, 1); + + /* Calculate the new CP110 - base address */ + cp110_base = MVEBU_CP_REGS_BASE(cp_id); + /* Go and update the CP110 configuration address space */ + iob_cfg_space_update(0, cp_id, cp110_temp_base, cp110_base); + + /* Remove the temporary IO-WIN window */ + iow_temp_win_remove(0, &iowin_temp_win, 1); +} + void ap_init(void) { /* Setup Aurora2. */ diff --git a/drivers/marvell/mochi/apn806_setup.c b/drivers/marvell/mochi/apn806_setup.c index 1e91c4317..8c3ba9296 100644 --- a/drivers/marvell/mochi/apn806_setup.c +++ b/drivers/marvell/mochi/apn806_setup.c @@ -28,9 +28,6 @@ 0x200) #define CCU_SET_POC_OFFSET 5 -#define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \ - 0x90 + 4 * (win)) - #define DSS_CR0 (MVEBU_RFU_BASE + 0x100) #define DVM_48BIT_VA_ENABLE (1 << 21) @@ -44,6 +41,14 @@ SEC_MOCHI_IN_ACC_IHB1_EN | \ SEC_MOCHI_IN_ACC_IHB2_EN | \ SEC_MOCHI_IN_ACC_PIDI_EN) +#define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0) +#define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1) +#define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2) +#define MOCHI_IN_ACC_LEVEL_MASK_ALL (3) +#define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1) +#define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4) +#define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10) + /* SYSRST_OUTn Config definitions */ #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4) @@ -70,19 +75,36 @@ enum axi_attr { static void apn_sec_masters_access_en(uint32_t enable) { - uint32_t reg; - /* Open/Close incoming access for all masters. * The access is disabled in trusted boot mode * Could only be done in EL3 */ - reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG); - if (enable) - mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg | + if (enable != 0) { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */ SEC_IN_ACCESS_ENA_ALL_MASTERS); - else - mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg & - ~SEC_IN_ACCESS_ENA_ALL_MASTERS); +#if LLC_SRAM + /* Do not change access security level + * for PIDI masters + */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_LEAVE_ORIG)); +#endif + } else { + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_IN_ACCESS_ENA_ALL_MASTERS, + 0x0U /* no set */); +#if LLC_SRAM + /* Return PIDI access level to the default */ + mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_MASK_ALL), + SEC_MOCHI_IN_ACC_PIDI_LEVEL( + MOCHI_IN_ACC_LEVEL_FORCE_NONSEC)); +#endif + } } static void setup_smmu(void) @@ -95,20 +117,6 @@ static void setup_smmu(void) mmio_write_32(SMMU_sACR, reg); } -static void apn806_errata_wa_init(void) -{ - /* - * ERRATA ID: RES-3033912 - Internal Address Space Init state causes - * a hang upon accesses to [0xf070_0000, 0xf07f_ffff] - * Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to - * split [0x6e_0000, 0xff_ffff] to values [0x6e_0000, 0x6f_ffff] and - * [0x80_0000, 0xff_ffff] that cause accesses to the - * segment of [0xf070_0000, 0xf07f_ffff] to act as RAZWI. - */ - mmio_write_32(CCU_RGF(4), 0x37f9b809); - mmio_write_32(CCU_RGF(5), 0x7ffa0009); -} - static void init_aurora2(void) { uint32_t reg; @@ -131,7 +139,7 @@ static void init_aurora2(void) mmio_write_32(CCU_HTC_CR, reg); #endif /* LLC_ENABLE */ - apn806_errata_wa_init(); + errata_wa_init(); } @@ -250,3 +258,6 @@ int ap_get_count(void) return 1; } +void update_cp110_default_win(int cp_id) +{ +} diff --git a/drivers/marvell/mochi/cp110_setup.c b/drivers/marvell/mochi/cp110_setup.c index b4b4e0c82..0fa049764 100644 --- a/drivers/marvell/mochi/cp110_setup.c +++ b/drivers/marvell/mochi/cp110_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -130,6 +130,7 @@ enum axi_attr { #define USB3H_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x10) #define SATA_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x14) #define SATA_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x18) +#define SDIO_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x28) #define CP_DMA_0_STREAM_ID_REG (0x6B0010) #define CP_DMA_1_STREAM_ID_REG (0x6D0010) @@ -144,6 +145,7 @@ uintptr_t stream_id_reg[] = { CP_DMA_1_STREAM_ID_REG, SATA_0_STREAM_ID_REG, SATA_1_STREAM_ID_REG, + SDIO_0_STREAM_ID_REG, 0 }; @@ -303,7 +305,7 @@ static void cp110_axi_attr_init(uintptr_t base) DOMAIN_SYSTEM_SHAREABLE); } -static void amb_bridge_init(uintptr_t base) +void cp110_amb_init(uintptr_t base) { uint32_t reg; @@ -399,7 +401,7 @@ void cp110_init(uintptr_t cp110_base, uint32_t stream_id) cp110_stream_id_init(cp110_base, stream_id); /* Open AMB bridge for comphy for CP0 & CP1*/ - amb_bridge_init(cp110_base); + cp110_amb_init(cp110_base); /* Reset RTC if needed */ cp110_rtc_init(cp110_base); @@ -411,7 +413,7 @@ void cp110_ble_init(uintptr_t cp110_base) #if PCI_EP_SUPPORT INFO("%s: Initialize CPx - base = %lx\n", __func__, cp110_base); - amb_bridge_init(cp110_base); + cp110_amb_init(cp110_base); /* Configure PCIe clock */ cp110_pcie_clk_cfg(cp110_base); diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S index da1ce351c..58dad7aa5 100644 --- a/drivers/marvell/uart/a3700_console.S +++ b/drivers/marvell/uart/a3700_console.S @@ -60,14 +60,14 @@ func console_a3700_core_init str w3, [x0, #UART_POSSR_REG] /* - * Wait for the TX FIFO to be empty. If wait for 20ms, the TX FIFO is + * Wait for the TX (THR and TSR) to be empty. If wait for 20ms, the TX FIFO is * still not empty, TX FIFO will reset by all means. */ mov w1, #20 /* max time out 20ms */ 2: - /* Check whether TX FIFO is empty */ + /* Check whether TX (THR and TSR) is empty */ ldr w3, [x0, #UART_STATUS_REG] - and w3, w3, #UARTLSR_TXFIFOEMPTY + and w3, w3, #UARTLSR_TXEMPTY cmp w3, #0 b.ne 4f @@ -110,7 +110,7 @@ endfunc console_a3700_core_init .globl console_a3700_register /* ----------------------------------------------- - * int console_a3700_register(console_16550_t *console, + * int console_a3700_register(console_t *console, uintptr_t base, uint32_t clk, uint32_t baud) * Function to initialize and register a new a3700 * console. Storage passed in for the console struct @@ -118,7 +118,7 @@ endfunc console_a3700_core_init * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate - * x3 - pointer to empty console_a3700_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -127,7 +127,7 @@ func console_a3700_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_A3700_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_a3700_core_init cbz x0, register_fail @@ -178,7 +178,7 @@ putc_error: endfunc console_a3700_core_putc /* -------------------------------------------------------- - * int console_a3700_putc(int c, console_a3700_t *console) + * int console_a3700_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 @@ -188,7 +188,7 @@ endfunc console_a3700_core_putc * -------------------------------------------------------- */ func console_a3700_putc - ldr x1, [x1, #CONSOLE_T_A3700_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_a3700_core_putc endfunc console_a3700_putc @@ -196,19 +196,28 @@ endfunc console_a3700_putc * int console_a3700_core_getc(void) * Function to get a character from the console. * It returns the character grabbed on success - * or -1 on error. + * or -1 if no character is available. * In : w0 - console base address - * Out : return -1 on error else return character. + * Out : w0 - character if available, else -1 * Clobber list : x0, x1 * --------------------------------------------- */ func console_a3700_core_getc - mov w0, #-1 + /* Check if there is a pending character */ + ldr w1, [x0, #UART_STATUS_REG] + and w1, w1, #UARTLSR_RXRDY + cmp w1, #UARTLSR_RXRDY + b.ne getc_no_char + ldr w0, [x0, #UART_RX_REG] + and w0, w0, #0xff + ret +getc_no_char: + mov w0, #ERROR_NO_PENDING_CHAR ret endfunc console_a3700_core_getc /* --------------------------------------------- - * int console_a3700_getc(console_a3700_t *console) + * int console_a3700_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on if no character is available. @@ -218,35 +227,39 @@ endfunc console_a3700_core_getc * --------------------------------------------- */ func console_a3700_getc - ldr x0, [x0, #CONSOLE_T_A3700_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_a3700_core_getc endfunc console_a3700_getc /* --------------------------------------------- - * int console_a3700_core_flush(uintptr_t base_addr) + * void console_a3700_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ func console_a3700_core_flush - mov w0, #0 + /* Wait for the TX (THR and TSR) to be empty */ +1: ldr w1, [x0, #UART_STATUS_REG] + and w1, w1, #UARTLSR_TXEMPTY + cmp w1, #UARTLSR_TXEMPTY + b.ne 1b ret endfunc console_a3700_core_flush /* --------------------------------------------- - * int console_a3700_flush(console_a3700_t *console) + * void console_a3700_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ func console_a3700_flush - ldr x0, [x0, #CONSOLE_T_A3700_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_a3700_core_flush endfunc console_a3700_flush diff --git a/drivers/measured_boot/event_log.c b/drivers/measured_boot/event_log.c new file mode 100644 index 000000000..727bdf5f3 --- /dev/null +++ b/drivers/measured_boot/event_log.c @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <arch_helpers.h> + +#include <common/bl_common.h> +#include <common/debug.h> +#include <drivers/auth/crypto_mod.h> +#include <drivers/measured_boot/event_log.h> +#include <mbedtls/md.h> + +#include <plat/common/platform.h> + +/* Event Log data */ +static uint8_t event_log[EVENT_LOG_SIZE]; + +/* End of Event Log */ +#define EVENT_LOG_END ((uintptr_t)event_log + sizeof(event_log) - 1U) + +CASSERT(sizeof(event_log) >= LOG_MIN_SIZE, assert_event_log_size); + +/* Pointer in event_log[] */ +static uint8_t *log_ptr = event_log; + +/* Pointer to measured_boot_data_t */ +const static measured_boot_data_t *plat_data_ptr; + +static uintptr_t tos_fw_config_base; +static uintptr_t nt_fw_config_base; + +/* TCG_EfiSpecIdEvent */ +static const id_event_headers_t id_event_header = { + .header = { + .pcr_index = PCR_0, + .event_type = EV_NO_ACTION, + .digest = {0}, + .event_size = (uint32_t)(sizeof(id_event_struct_t) + + (sizeof(id_event_algorithm_size_t) * + HASH_ALG_COUNT)) + }, + + .struct_header = { + .signature = TCG_ID_EVENT_SIGNATURE_03, + .platform_class = PLATFORM_CLASS_CLIENT, + .spec_version_minor = TCG_SPEC_VERSION_MINOR_TPM2, + .spec_version_major = TCG_SPEC_VERSION_MAJOR_TPM2, + .spec_errata = TCG_SPEC_ERRATA_TPM2, + .uintn_size = (uint8_t)(sizeof(unsigned int) / + sizeof(uint32_t)), + .number_of_algorithms = HASH_ALG_COUNT + } +}; + +static const event2_header_t locality_event_header = { + /* + * All EV_NO_ACTION events SHALL set + * TCG_PCR_EVENT2.pcrIndex = 0, unless otherwise specified + */ + .pcr_index = PCR_0, + + /* + * All EV_NO_ACTION events SHALL set + * TCG_PCR_EVENT2.eventType = 03h + */ + .event_type = EV_NO_ACTION, + + /* + * All EV_NO_ACTION events SHALL set + * TCG_PCR_EVENT2.digests to all + * 0x00's for each allocated Hash algorithm + */ + .digests = { + .count = HASH_ALG_COUNT + } +}; + +/* Platform's table with platform specific image IDs, names and PCRs */ +static const image_data_t plat_images_data[] = { + { BL2_IMAGE_ID, BL2_STRING, PCR_0 }, /* Reserved for BL2 */ + { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ +}; + +static const measured_boot_data_t plat_measured_boot_data = { + plat_images_data, + NULL, /* platform_set_nt_fw_info */ + NULL /* platform_set_tos_fw_info */ +}; + +/* + * Function retuns pointer to platform's measured_boot_data_t structure + * + * Must be overridden in the platform code + */ +#pragma weak plat_get_measured_boot_data + +const measured_boot_data_t *plat_get_measured_boot_data(void) +{ + return &plat_measured_boot_data; +} + +/* + * Add TCG_PCR_EVENT2 event + * + * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes + * @param[in] image_ptr Pointer to image_data_t structure + * @return: + * 0 = success + * < 0 = error code + */ +static int add_event2(const uint8_t *hash, const image_data_t *image_ptr) +{ + void *ptr = log_ptr; + uint32_t name_len; + uint32_t size_of_event; + + assert(image_ptr != NULL); + assert(image_ptr->name != NULL); + + name_len = (uint32_t)strlen(image_ptr->name) + 1U; + size_of_event = name_len + (uint32_t)EVENT2_HDR_SIZE; + + /* Check for space in Event Log buffer */ + if (((uintptr_t)ptr + size_of_event) > EVENT_LOG_END) { + ERROR("%s(): Event Log is short of memory", __func__); + return -ENOMEM; + } + + /* + * As per TCG specifications, firmware components that are measured + * into PCR[0] must be logged in the event log using the event type + * EV_POST_CODE. + */ + /* TCG_PCR_EVENT2.PCRIndex */ + ((event2_header_t *)ptr)->pcr_index = image_ptr->pcr; + + /* TCG_PCR_EVENT2.EventType */ + ((event2_header_t *)ptr)->event_type = EV_POST_CODE; + + /* TCG_PCR_EVENT2.Digests.Count */ + ptr = (uint8_t *)ptr + offsetof(event2_header_t, digests); + ((tpml_digest_values *)ptr)->count = HASH_ALG_COUNT; + + /* TCG_PCR_EVENT2.Digests[] */ + ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(tpml_digest_values, digests)); + + /* TCG_PCR_EVENT2.Digests[].AlgorithmId */ + ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; + + /* TCG_PCR_EVENT2.Digests[].Digest[] */ + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); + + /* Check for space in Event Log buffer */ + if (((uintptr_t)ptr + TCG_DIGEST_SIZE) > EVENT_LOG_END) { + ERROR("%s(): Event Log is short of memory", __func__); + return -ENOMEM; + } + + if (hash == NULL) { + /* Get BL2 hash from DTB */ + bl2_plat_get_hash(ptr); + } else { + /* Copy digest */ + (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE); + } + + /* TCG_PCR_EVENT2.EventSize */ + ptr = (uint8_t *)((uintptr_t)ptr + TCG_DIGEST_SIZE); + ((event2_data_t *)ptr)->event_size = name_len; + + /* Copy event data to TCG_PCR_EVENT2.Event */ + (void)memcpy((void *)(((event2_data_t *)ptr)->event), + (const void *)image_ptr->name, name_len); + + /* End of event data */ + log_ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(event2_data_t, event) + name_len); + + return 0; +} + +/* + * Init Event Log + * + * Initialises Event Log by writing Specification ID and + * Startup Locality events. + */ +void event_log_init(void) +{ + const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE; + const uint8_t *start_ptr; + void *ptr = event_log; + + /* Get pointer to platform's measured_boot_data_t structure */ + plat_data_ptr = plat_get_measured_boot_data(); + + /* + * Add Specification ID Event first + * + * Copy TCG_EfiSpecIDEventStruct structure header + */ + (void)memcpy(ptr, (const void *)&id_event_header, + sizeof(id_event_header)); + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_header)); + + /* TCG_EfiSpecIdEventAlgorithmSize structure */ + ((id_event_algorithm_size_t *)ptr)->algorithm_id = TPM_ALG_ID; + ((id_event_algorithm_size_t *)ptr)->digest_size = TCG_DIGEST_SIZE; + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_algorithm_size_t)); + + /* + * TCG_EfiSpecIDEventStruct.vendorInfoSize + * No vendor data + */ + ((id_event_struct_data_t *)ptr)->vendor_info_size = 0; + ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(id_event_struct_data_t, vendor_info)); + if ((uintptr_t)ptr != ((uintptr_t)event_log + ID_EVENT_SIZE)) { + panic(); + } + + start_ptr = (uint8_t *)ptr; + + /* + * The Startup Locality event should be placed in the log before + * any event which extends PCR[0]. + * + * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3 + */ + + /* Copy Startup Locality Event Header */ + (void)memcpy(ptr, (const void *)&locality_event_header, + sizeof(locality_event_header)); + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(locality_event_header)); + + /* TCG_PCR_EVENT2.Digests[].AlgorithmId */ + ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; + + /* TCG_PCR_EVENT2.Digests[].Digest[] */ + (void)memset(&((tpmt_ha *)ptr)->digest, 0, TPM_ALG_ID); + ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE); + + /* TCG_PCR_EVENT2.EventSize */ + ((event2_data_t *)ptr)->event_size = + (uint32_t)sizeof(startup_locality_event_t); + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); + + /* TCG_EfiStartupLocalityEvent.Signature */ + (void)memcpy(ptr, (const void *)locality_signature, + sizeof(TCG_STARTUP_LOCALITY_SIGNATURE)); + + /* + * TCG_EfiStartupLocalityEvent.StartupLocality = 0: + * the platform's boot firmware + */ + ((startup_locality_event_t *)ptr)->startup_locality = 0U; + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t)); + if ((uintptr_t)ptr != ((uintptr_t)start_ptr + LOC_EVENT_SIZE)) { + panic(); + } + + log_ptr = (uint8_t *)ptr; + + /* Add BL2 event */ + if (add_event2(NULL, plat_data_ptr->images_data) != 0) { + panic(); + } +} + +/* + * Calculate and write hash of image, configuration data, etc. + * to Event Log. + * + * @param[in] data_base Address of data + * @param[in] data_size Size of data + * @param[in] data_id Data ID + * @return: + * 0 = success + * < 0 = error + */ +int tpm_record_measurement(uintptr_t data_base, uint32_t data_size, + uint32_t data_id) +{ + const image_data_t *data_ptr = plat_data_ptr->images_data; + unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; + int rc; + + /* Check if image_id is supported */ + while (data_ptr->id != data_id) { + if ((data_ptr++)->id == INVALID_ID) { + ERROR("%s(): image_id %u not supported\n", + __func__, data_id); + return -EINVAL; + } + } + + if (data_id == TOS_FW_CONFIG_ID) { + tos_fw_config_base = data_base; + } else if (data_id == NT_FW_CONFIG_ID) { + nt_fw_config_base = data_base; + } else { + /* No action */ + } + + /* Calculate hash */ + rc = crypto_mod_calc_hash((unsigned int)MBEDTLS_MD_ID, + (void *)data_base, data_size, hash_data); + if (rc != 0) { + return rc; + } + + return add_event2(hash_data, data_ptr); +} + +/* + * Finalise Event Log + * + * @param[out] log_addr Pointer to return Event Log address + * @param[out] log_size Pointer to return Event Log size + * @return: + * 0 = success + * < 0 = error code + */ +int event_log_finalise(uint8_t **log_addr, size_t *log_size) +{ + /* Event Log size */ + size_t num_bytes = (uintptr_t)log_ptr - (uintptr_t)event_log; + int rc; + + assert(log_addr != NULL); + assert(log_size != NULL); + + if (nt_fw_config_base == 0UL) { + ERROR("%s(): %s_FW_CONFIG not loaded\n", __func__, "NT"); + return -ENOENT; + } + + /* + * Set Event Log data in NT_FW_CONFIG and + * get Event Log address in Non-Secure memory + */ + if (plat_data_ptr->set_nt_fw_info != NULL) { + + /* Event Log address in Non-Secure memory */ + uintptr_t ns_log_addr; + + rc = plat_data_ptr->set_nt_fw_info( + nt_fw_config_base, +#ifdef SPD_opteed + (uintptr_t)event_log, +#endif + num_bytes, &ns_log_addr); + if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "NT"); + return rc; + } + + /* Copy Event Log to Non-secure memory */ + (void)memcpy((void *)ns_log_addr, (const void *)event_log, + num_bytes); + + /* Ensure that the Event Log is visible in Non-secure memory */ + flush_dcache_range(ns_log_addr, num_bytes); + + /* Return Event Log address in Non-Secure memory */ + *log_addr = (uint8_t *)ns_log_addr; + + } else { + INFO("%s(): set_%s_fw_info not set\n", __func__, "nt"); + + /* Return Event Log address in Secure memory */ + *log_addr = event_log; + } + + if (tos_fw_config_base != 0UL) { + if (plat_data_ptr->set_tos_fw_info != NULL) { + + /* Set Event Log data in TOS_FW_CONFIG */ + rc = plat_data_ptr->set_tos_fw_info( + tos_fw_config_base, + (uintptr_t)event_log, + num_bytes); + if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "TOS"); + return rc; + } + } else { + INFO("%s(): set_%s_fw_info not set\n", __func__, "tos"); + } + } else { + INFO("%s(): %s_FW_CONFIG not loaded\n", __func__, "TOS"); + } + + /* Ensure that the Event Log is visible in Secure memory */ + flush_dcache_range((uintptr_t)event_log, num_bytes); + + /* Return Event Log size */ + *log_size = num_bytes; + + return 0; +} diff --git a/drivers/measured_boot/event_print.c b/drivers/measured_boot/event_print.c new file mode 100644 index 000000000..84ed4b1cb --- /dev/null +++ b/drivers/measured_boot/event_print.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <string.h> + +#include <common/debug.h> +#include <drivers/measured_boot/event_log.h> + +#if LOG_LEVEL >= EVENT_LOG_LEVEL + +/* + * Print TCG_EfiSpecIDEventStruct + * + * @param[in/out] log_addr Pointer to Event Log + * @param[in/out] log_size Pointer to Event Log size + */ +static void id_event_print(uint8_t **log_addr, size_t *log_size) +{ + unsigned int i; + uint8_t info_size, *info_size_ptr; + void *ptr = *log_addr; + id_event_headers_t *event = (id_event_headers_t *)ptr; + id_event_algorithm_size_t *alg_ptr; + uint32_t event_size, number_of_algorithms; + size_t digest_len; +#if ENABLE_ASSERTIONS + const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); + bool valid = true; +#endif + + assert(*log_size >= sizeof(id_event_headers_t)); + + /* The fields of the event log header are defined to be PCRIndex of 0, + * EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and + * Event content defined as TCG_EfiSpecIDEventStruct. + */ + LOG_EVENT("TCG_EfiSpecIDEvent:\n"); + LOG_EVENT(" PCRIndex : %u\n", event->header.pcr_index); + assert(event->header.pcr_index == (uint32_t)PCR_0); + + LOG_EVENT(" EventType : %u\n", event->header.event_type); + assert(event->header.event_type == EV_NO_ACTION); + + LOG_EVENT(" Digest :"); + for (i = 0U; i < sizeof(event->header.digest); ++i) { + uint8_t val = event->header.digest[i]; + + (void)printf(" %02x", val); + if ((i & U(0xF)) == 0U) { + (void)printf("\n"); + LOG_EVENT("\t\t :"); + } +#if ENABLE_ASSERTIONS + if (val != 0U) { + valid = false; + } +#endif + } + if ((i & U(0xF)) != 0U) { + (void)printf("\n"); + } + + assert(valid); + + /* EventSize */ + event_size = event->header.event_size; + LOG_EVENT(" EventSize : %u\n", event_size); + + LOG_EVENT(" Signature : %s\n", + event->struct_header.signature); + LOG_EVENT(" PlatformClass : %u\n", + event->struct_header.platform_class); + LOG_EVENT(" SpecVersion : %u.%u.%u\n", + event->struct_header.spec_version_major, + event->struct_header.spec_version_minor, + event->struct_header.spec_errata); + LOG_EVENT(" UintnSize : %u\n", + event->struct_header.uintn_size); + + /* NumberOfAlgorithms */ + number_of_algorithms = event->struct_header.number_of_algorithms; + LOG_EVENT(" NumberOfAlgorithms : %u\n", number_of_algorithms); + + /* Address of DigestSizes[] */ + alg_ptr = event->struct_header.digest_size; + + /* Size of DigestSizes[] */ + digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t); + assert(((uintptr_t)alg_ptr + digest_len) <= (uintptr_t)end_ptr); + + LOG_EVENT(" DigestSizes :\n"); + for (i = 0U; i < number_of_algorithms; ++i) { + LOG_EVENT(" #%u AlgorithmId : SHA", i); + uint16_t algorithm_id = alg_ptr[i].algorithm_id; + + switch (algorithm_id) { + case TPM_ALG_SHA256: + (void)printf("256\n"); + break; + case TPM_ALG_SHA384: + (void)printf("384\n"); + break; + case TPM_ALG_SHA512: + (void)printf("512\n"); + break; + default: + (void)printf("?\n"); + ERROR("Algorithm 0x%x not found\n", algorithm_id); + assert(false); + } + + LOG_EVENT(" DigestSize : %u\n", + alg_ptr[i].digest_size); + } + + /* Address of VendorInfoSize */ + info_size_ptr = (uint8_t *)((uintptr_t)alg_ptr + digest_len); + assert((uintptr_t)info_size_ptr <= (uintptr_t)end_ptr); + + info_size = *info_size_ptr++; + LOG_EVENT(" VendorInfoSize : %u\n", info_size); + + /* Check VendorInfo end address */ + assert(((uintptr_t)info_size_ptr + info_size) <= (uintptr_t)end_ptr); + + /* Check EventSize */ + assert(event_size == (sizeof(id_event_struct_t) + + digest_len + info_size)); + if (info_size != 0U) { + LOG_EVENT(" VendorInfo :"); + for (i = 0U; i < info_size; ++i) { + (void)printf(" %02x", *info_size_ptr++); + } + (void)printf("\n"); + } + + *log_size -= (uintptr_t)info_size_ptr - (uintptr_t)*log_addr; + *log_addr = info_size_ptr; +} + +/* + * Print TCG_PCR_EVENT2 + * + * @param[in/out] log_addr Pointer to Event Log + * @param[in/out] log_size Pointer to Event Log size + */ +static void event2_print(uint8_t **log_addr, size_t *log_size) +{ + uint32_t event_size, count; + size_t sha_size, digests_size = 0U; + void *ptr = *log_addr; +#if ENABLE_ASSERTIONS + const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); +#endif + + assert(*log_size >= sizeof(event2_header_t)); + + LOG_EVENT("PCR_Event2:\n"); + LOG_EVENT(" PCRIndex : %u\n", + ((event2_header_t *)ptr)->pcr_index); + LOG_EVENT(" EventType : %u\n", + ((event2_header_t *)ptr)->event_type); + + count = ((event2_header_t *)ptr)->digests.count; + LOG_EVENT(" Digests Count : %u\n", count); + + /* Address of TCG_PCR_EVENT2.Digests[] */ + ptr = (uint8_t *)ptr + sizeof(event2_header_t); + assert(((uintptr_t)ptr <= (uintptr_t)end_ptr) && (count != 0U)); + + for (unsigned int i = 0U; i < count; ++i) { + /* Check AlgorithmId address */ + assert(((uintptr_t)ptr + + offsetof(tpmt_ha, digest)) <= (uintptr_t)end_ptr); + + LOG_EVENT(" #%u AlgorithmId : SHA", i); + switch (((tpmt_ha *)ptr)->algorithm_id) { + case TPM_ALG_SHA256: + sha_size = SHA256_DIGEST_SIZE; + (void)printf("256\n"); + break; + case TPM_ALG_SHA384: + sha_size = SHA384_DIGEST_SIZE; + (void)printf("384\n"); + break; + case TPM_ALG_SHA512: + sha_size = SHA512_DIGEST_SIZE; + (void)printf("512\n"); + break; + default: + (void)printf("?\n"); + ERROR("Algorithm 0x%x not found\n", + ((tpmt_ha *)ptr)->algorithm_id); + panic(); + } + + /* End of Digest[] */ + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); + assert(((uintptr_t)ptr + sha_size) <= (uintptr_t)end_ptr); + + /* Total size of all digests */ + digests_size += sha_size; + + LOG_EVENT(" Digest :"); + for (unsigned int j = 0U; j < sha_size; ++j) { + (void)printf(" %02x", *(uint8_t *)ptr++); + if ((j & U(0xF)) == U(0xF)) { + (void)printf("\n"); + if (j < (sha_size - 1U)) { + LOG_EVENT("\t\t :"); + } + } + } + } + + /* TCG_PCR_EVENT2.EventSize */ + assert(((uintptr_t)ptr + offsetof(event2_data_t, event)) <= (uintptr_t)end_ptr); + + event_size = ((event2_data_t *)ptr)->event_size; + LOG_EVENT(" EventSize : %u\n", event_size); + + /* Address of TCG_PCR_EVENT2.Event[EventSize] */ + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); + + /* End of TCG_PCR_EVENT2.Event[EventSize] */ + assert(((uintptr_t)ptr + event_size) <= (uintptr_t)end_ptr); + + if ((event_size == sizeof(startup_locality_event_t)) && + (strcmp((const char *)ptr, TCG_STARTUP_LOCALITY_SIGNATURE) == 0)) { + LOG_EVENT(" Signature : %s\n", + ((startup_locality_event_t *)ptr)->signature); + LOG_EVENT(" StartupLocality : %u\n", + ((startup_locality_event_t *)ptr)->startup_locality); + } else { + LOG_EVENT(" Event : %s\n", (uint8_t *)ptr); + } + + *log_size -= (uintptr_t)ptr + event_size - (uintptr_t)*log_addr; + *log_addr = (uint8_t *)ptr + event_size; +} +#endif /* LOG_LEVEL >= EVENT_LOG_LEVEL */ + +/* + * Print Event Log + * + * @param[in] log_addr Pointer to Event Log + * @param[in] log_size Event Log size + */ +void dump_event_log(uint8_t *log_addr, size_t log_size) +{ +#if LOG_LEVEL >= EVENT_LOG_LEVEL + assert(log_addr != NULL); + + /* Print TCG_EfiSpecIDEvent */ + id_event_print(&log_addr, &log_size); + + while (log_size != 0U) { + event2_print(&log_addr, &log_size); + } +#endif +} diff --git a/drivers/measured_boot/measured_boot.c b/drivers/measured_boot/measured_boot.c new file mode 100644 index 000000000..37fddfbdc --- /dev/null +++ b/drivers/measured_boot/measured_boot.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <drivers/measured_boot/measured_boot.h> + +/* + * Init Measured Boot driver + * + * Initialises Event Log. + */ +void measured_boot_init(void) +{ + event_log_init(); +} + +/* + * Finish Measured Boot driver + * + * Finalises Event Log and dumps the records to the debug console. + */ +void measured_boot_finish(void) +{ + uint8_t *log_addr; + size_t log_size; + int rc; + + rc = event_log_finalise(&log_addr, &log_size); + if (rc != 0) { + panic(); + } + + dump_event_log(log_addr, log_size); +} diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/measured_boot.mk new file mode 100644 index 000000000..497fdbaae --- /dev/null +++ b/drivers/measured_boot/measured_boot.mk @@ -0,0 +1,52 @@ +# +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Default log level to dump the event log (LOG_LEVEL_INFO) +EVENT_LOG_LEVEL ?= 40 + +# TPM hash algorithm +TPM_HASH_ALG := sha256 + +ifeq (${TPM_HASH_ALG}, sha512) + MBEDTLS_MD_ID := MBEDTLS_MD_SHA512 + TPM_ALG_ID := TPM_ALG_SHA512 + TCG_DIGEST_SIZE := 64U +else ifeq (${TPM_HASH_ALG}, sha384) + MBEDTLS_MD_ID := MBEDTLS_MD_SHA384 + TPM_ALG_ID := TPM_ALG_SHA384 + TCG_DIGEST_SIZE := 48U +else + MBEDTLS_MD_ID := MBEDTLS_MD_SHA256 + TPM_ALG_ID := TPM_ALG_SHA256 + TCG_DIGEST_SIZE := 32U +endif + +# Event Log length in bytes +EVENT_LOG_SIZE := 1024 + +# Set definitions for mbed TLS library and Measured Boot driver +$(eval $(call add_defines,\ + $(sort \ + MBEDTLS_MD_ID \ + TPM_ALG_ID \ + TCG_DIGEST_SIZE \ + EVENT_LOG_SIZE \ + EVENT_LOG_LEVEL \ +))) + +ifeq (${HASH_ALG}, sha256) +ifneq (${TPM_HASH_ALG}, sha256) +$(eval $(call add_define,MBEDTLS_SHA512_C)) +endif +endif + +MEASURED_BOOT_SRC_DIR := drivers/measured_boot/ + +MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}measured_boot.c \ + ${MEASURED_BOOT_SRC_DIR}event_log.c \ + ${MEASURED_BOOT_SRC_DIR}event_print.c + +BL2_SOURCES += ${MEASURED_BOOT_SOURCES} diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c index 48131fcb2..1fb5facaf 100644 --- a/drivers/mtd/nand/raw_nand.c +++ b/drivers/mtd/nand/raw_nand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -190,7 +190,7 @@ static int nand_status(uint8_t *status) return ret; } -int nand_wait_ready(unsigned long delay) +int nand_wait_ready(unsigned int delay_ms) { uint8_t status; int ret; @@ -204,7 +204,7 @@ int nand_wait_ready(unsigned long delay) return ret; } - timeout = timeout_init_us(delay); + timeout = timeout_init_us(delay_ms * 1000U); while (!timeout_elapsed(timeout)) { ret = nand_read_data(&status, 1U, true); if (ret != 0) { diff --git a/drivers/mtd/nor/spi_nor.c b/drivers/mtd/nor/spi_nor.c index 22d3ae3d9..108f893d3 100644 --- a/drivers/mtd/nor/spi_nor.c +++ b/drivers/mtd/nor/spi_nor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -368,7 +368,7 @@ int spi_nor_init(unsigned long long *size, unsigned int *erase_size) if (nor_dev.read_op.data.buswidth == 4U) { switch (id) { case MACRONIX_ID: - WARN("Enable Macronix quad support\n"); + INFO("Enable Macronix quad support\n"); ret = spi_nor_macronix_quad_enable(); break; case MICRON_ID: diff --git a/drivers/renesas/rcar/auth/auth_mod.c b/drivers/renesas/common/auth/auth_mod.c index ece3462f4..4aa86e2a4 100644 --- a/drivers/renesas/rcar/auth/auth_mod.c +++ b/drivers/renesas/common/auth/auth_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights * reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -7,29 +7,28 @@ #include <stddef.h> -#include <platform_def.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_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) +#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; @@ -125,9 +124,9 @@ verify_image: #if RCAR_BL2_DCACHE == 1 /* enable */ write_sctlr_el3(read_sctlr_el3() | SCTLR_C_BIT); -#endif +#endif /* RCAR_BL2_DCACHE */ -#endif +#endif /* IMAGE_BL2 */ return ret; } diff --git a/drivers/renesas/rcar/avs/avs_driver.c b/drivers/renesas/common/avs/avs_driver.c index 647869ede..2c939cd59 100644 --- a/drivers/renesas/rcar/avs/avs_driver.c +++ b/drivers/renesas/common/avs/avs_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,8 @@ #include <lib/mmio.h> #include <lib/utils_def.h> -#include "cpg_registers.h" #include "avs_driver.h" +#include "cpg_registers.h" #include "rcar_def.h" #include "rcar_private.h" @@ -22,12 +22,12 @@ #endif /* PMIC_ROHM_BD9571 */ /* Base address of Adaptive Voltage Scaling module registers*/ -#define AVS_BASE (0xE60A0000U) +#define AVS_BASE (0xE60A0000U) /* Adaptive Dynamic Voltage ADJust Parameter2 registers */ -#define ADVADJP2 (AVS_BASE + 0x013CU) +#define ADVADJP2 (AVS_BASE + 0x013CU) /* Mask VOLCOND bit in ADVADJP2 registers */ -#define ADVADJP2_VOLCOND_MASK (0x000001FFU) /* VOLCOND[8:0] */ +#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*/ @@ -38,19 +38,19 @@ #if PMIC_ROHM_BD9571 /* Base address of IICDVFS registers*/ -#define IIC_DVFS_BASE (0xE60B0000U) +#define IIC_DVFS_BASE (0xE60B0000U) /* IIC bus data register */ -#define IIC_ICDR (IIC_DVFS_BASE + 0x0000U) +#define IIC_ICDR (IIC_DVFS_BASE + 0x0000U) /* IIC bus control register */ -#define IIC_ICCR (IIC_DVFS_BASE + 0x0004U) +#define IIC_ICCR (IIC_DVFS_BASE + 0x0004U) /* IIC bus status register */ -#define IIC_ICSR (IIC_DVFS_BASE + 0x0008U) +#define IIC_ICSR (IIC_DVFS_BASE + 0x0008U) /* IIC interrupt control register */ -#define IIC_ICIC (IIC_DVFS_BASE + 0x000CU) +#define IIC_ICIC (IIC_DVFS_BASE + 0x000CU) /* IIC clock control register low */ -#define IIC_ICCL (IIC_DVFS_BASE + 0x0010U) +#define IIC_ICCL (IIC_DVFS_BASE + 0x0010U) /* IIC clock control register high */ -#define IIC_ICCH (IIC_DVFS_BASE + 0x0014U) +#define IIC_ICCH (IIC_DVFS_BASE + 0x0014U) /* Bit in ICSR register */ #define ICSR_BUSY (0x10U) @@ -76,20 +76,23 @@ #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 */ +#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 */ +#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 */ -#define PMIC_W_SLAVE_ADDRESS (0x60U) /* ROHM BD9571 slave address + (W) */ -#define PMIC_R_SLAVE_ADDRESS (0x61U) /* ROHM BD9571 slave address + (R) */ -#define PMIC_DVFS_SETVID (0x54U) /* ROHM BD9571 DVFS SetVID register */ +/* 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 */ @@ -102,7 +105,7 @@ typedef struct { } initial_voltage_t; static const initial_voltage_t init_vol_tbl[] = { - /* AVS code, RHOM BD9571 DVFS SetVID register */ + /* AVS code, ROHM BD9571 DVFS SetVID register */ {0x00U, 0x53U}, /* AVS0, 0.83V */ {0x01U, 0x52U}, /* AVS1, 0.82V */ {0x02U, 0x51U}, /* AVS2, 0.81V */ @@ -188,7 +191,7 @@ void rcar_avs_init(void) /* 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. */ + /* Disable I2C module and all internal registers initialized. */ mmio_write_8(IIC_ICCR, 0x00U); } @@ -283,8 +286,8 @@ void rcar_avs_setting(void) /* Dose efuse_avs exceed the number of */ /* the tables? */ if (efuse_avs >= EFUSE_AVS_NUM) { - ERROR("AVS number of eFuse is out " - "of a range. number=%u\n", + ERROR("%s%s=%u\n", "AVS number of ", + "eFuse is out of range. number", efuse_avs); /* Infinite loop */ panic(); @@ -417,7 +420,8 @@ void rcar_avs_end(void) { 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", + + NOTICE("Read PMIC register. address=0x%x value=0x%x\n", addr, value); } #endif @@ -446,8 +450,8 @@ static avs_error_t avs_check_error(void) avs_error_t ret; if ((mmio_read_8(IIC_ICSR) & ICSR_AL) == ICSR_AL) { - NOTICE("Loss of arbitration is detected. " - "AVS status=%d Retry=%u\n", avs_status, avs_retry); + 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", @@ -458,8 +462,8 @@ static avs_error_t avs_check_error(void) /* Set the error detected to error status. */ ret = avs_error_al; } else if ((mmio_read_8(IIC_ICSR) & ICSR_TACK) == ICSR_TACK) { - NOTICE("Non-acknowledge is detected. " - "AVS status=%d Retry=%u\n", avs_status, avs_retry); + 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", @@ -526,8 +530,10 @@ static uint8_t avs_read_pmic_reg(uint8_t addr) /* Set frequency of 400kHz */ avs_set_iic_clock(); - /* Set ICIC.WAITE=1, ICIC.DTEE=1 to enable data transmission */ - /* interrupt and wait interrupt. */ + /* + * 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 */ diff --git a/drivers/renesas/rcar/avs/avs_driver.h b/drivers/renesas/common/avs/avs_driver.h index aa773b604..aa773b604 100644 --- a/drivers/renesas/rcar/avs/avs_driver.h +++ b/drivers/renesas/common/avs/avs_driver.h diff --git a/drivers/renesas/common/common.c b/drivers/renesas/common/common.c new file mode 100644 index 000000000..9b7c1eb16 --- /dev/null +++ b/drivers/renesas/common/common.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/mmio.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((uintptr_t) RCAR_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) { + } +} diff --git a/drivers/renesas/rcar/console/rcar_console.S b/drivers/renesas/common/console/rcar_console.S index 859efeceb..29baa67a4 100644 --- a/drivers/renesas/rcar/console/rcar_console.S +++ b/drivers/renesas/common/console/rcar_console.S @@ -20,14 +20,14 @@ /* ----------------------------------------------- * int console_rcar_register( * uintptr_t base, uint32_t clk, uint32_t baud, - * console_rcar_t *console) + * 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_rcar_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -36,7 +36,7 @@ func console_rcar_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_RCAR_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl rcar_log_init cbz x0, register_fail @@ -68,11 +68,11 @@ func console_rcar_init endfunc console_rcar_init /* -------------------------------------------------------- - * int console_rcar_putc(int c, console_rcar_t *console) + * 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_rcar_t structure + * x1 - pointer to console_t structure * Out : return -1 on error else return character. * Clobber list : x2 * -------------------------------------------------------- @@ -82,15 +82,12 @@ func console_rcar_putc endfunc console_rcar_putc /* --------------------------------------------- - * int console_rcar_flush(void) + * void console_rcar_flush(void) * Function to force a write of all buffered - * data that hasn't been output. It returns 0 - * upon successful completion, otherwise it - * returns -1. + * data that hasn't been output. It returns void * Clobber list : x0, x1 * --------------------------------------------- */ func console_rcar_flush - mov w0, #0 ret endfunc console_rcar_flush diff --git a/drivers/renesas/rcar/console/rcar_printf.c b/drivers/renesas/common/console/rcar_printf.c index e75b9f454..ad074fe05 100644 --- a/drivers/renesas/rcar/console/rcar_printf.c +++ b/drivers/renesas/common/console/rcar_printf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,11 +19,22 @@ #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 { - uint8_t head[4]; + uint32_t head; uint32_t index; uint32_t size; - uint8_t res[4]; + uint32_t res; } loghead_t; typedef struct log_map { @@ -66,15 +77,12 @@ int32_t rcar_set_log_data(int32_t c) int32_t rcar_log_init(void) { - - static const uint8_t const_header[] = "TLOG"; - logmap_t *t_log; + 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; - t_log = (logmap_t *) RCAR_BL31_LOG_BASE; - if (memcmp - ((const void *)t_log->header.head, (const void *)const_header, - sizeof(t_log->header.head)) != 0) { + if (t_log->header.head != RCAR_LOG_HEAD) { /* * Log header is not "TLOG", then log area initialize */ @@ -87,11 +95,10 @@ int32_t rcar_log_init(void) init_flag = 1; } if (init_flag == 1) { - (void)memset((void *)t_log->log_data, 0, - (size_t) RCAR_BL31_LOG_MAX); - (void)memcpy((void *)t_log->header.head, - (const void *)const_header, - sizeof(t_log->header.head)); + 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; } diff --git a/drivers/renesas/rcar/console/rcar_printf.h b/drivers/renesas/common/console/rcar_printf.h index 5da70e636..5da70e636 100644 --- a/drivers/renesas/rcar/console/rcar_printf.h +++ b/drivers/renesas/common/console/rcar_printf.h diff --git a/drivers/renesas/rcar/ddr/ddr_regs.h b/drivers/renesas/common/ddr_regs.h index ba26c69c8..ba26c69c8 100644 --- a/drivers/renesas/rcar/ddr/ddr_regs.h +++ b/drivers/renesas/common/ddr_regs.h diff --git a/drivers/renesas/rcar/delay/micro_delay.c b/drivers/renesas/common/delay/micro_delay.c index aced5891a..a5e2a6928 100644 --- a/drivers/renesas/rcar/delay/micro_delay.c +++ b/drivers/renesas/common/delay/micro_delay.c @@ -1,18 +1,19 @@ /* - * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved. + * 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"))) + __attribute__ ((section(".system_ram"))) #endif rcar_micro_delay(uint64_t micro_sec) { diff --git a/drivers/renesas/rcar/delay/micro_delay.h b/drivers/renesas/common/delay/micro_delay.h index 37b71f80a..37b71f80a 100644 --- a/drivers/renesas/rcar/delay/micro_delay.h +++ b/drivers/renesas/common/delay/micro_delay.h diff --git a/drivers/renesas/rcar/dma/dma_driver.c b/drivers/renesas/common/dma/dma_driver.c index e0be46e6f..44ee98592 100644 --- a/drivers/renesas/rcar/dma/dma_driver.c +++ b/drivers/renesas/common/dma/dma_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,15 +11,15 @@ #include <common/debug.h> #include <lib/mmio.h> -#include "rcar_def.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 +#define DMA_CH 16 #else -#define DMA_CH 0 +#define DMA_CH 0 #endif #if (DMA_CH == 0) @@ -39,7 +39,7 @@ /* DMA operation */ #define DMA_DMAOR (DMA_BASE + 0x0060U) /* DMA secure control */ -#define DMA_DMASEC (DMA_BASE + 0x0030U) +#define DMA_DMASEC (DMA_BASE + 0x0030U) /* DMA channel clear */ #define DMA_DMACHCLR (DMA_BASE + 0x0080U) /* DMA source address */ @@ -53,21 +53,21 @@ /* 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_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 */ @@ -129,16 +129,16 @@ void rcar_dma_exec(uintptr_t dst, uint32_t src, uint32_t len) } if (src & DMA_FRACTION_MASK) { - ERROR("BL2: DMA - source address invalid (0x%x), " - "length (0x%x)\n", src, dma_len); + 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_len > DMA_DST_LIMIT) || (dst & DMA_FRACTION_MASK)) { - ERROR("BL2: DMA - destination address invalid (0x%lx), " - "length (0x%x)\n", dst, dma_len); + ERROR("BL2: DMA - dest address invalid (0x%lx), len=(0x%x)\n", + dst, dma_len); panic(); } diff --git a/drivers/renesas/rcar/emmc/emmc_cmd.c b/drivers/renesas/common/emmc/emmc_cmd.c index a2e25e339..d255bffc9 100644 --- a/drivers/renesas/rcar/emmc/emmc_cmd.c +++ b/drivers/renesas/common/emmc/emmc_cmd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,10 +7,10 @@ #include <common/debug.h> #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" #include "micro_delay.h" static void emmc_little_to_big(uint8_t *p, uint32_t value) @@ -22,6 +22,7 @@ static void emmc_little_to_big(uint8_t *p, uint32_t value) p[1] = (uint8_t) (value >> 16); p[2] = (uint8_t) (value >> 8); p[3] = (uint8_t) value; + } static void emmc_softreset(void) @@ -64,7 +65,6 @@ reset: 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) @@ -96,8 +96,7 @@ static EMMC_ERROR_CODE emmc_response_check(uint32_t *response, { HAL_MEMCARD_RESPONSE_TYPE response_type = - (HAL_MEMCARD_RESPONSE_TYPE) (mmc_drv_obj.cmd_info. - cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); + ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); if (response == NULL) return EMMC_ERR_PARAM; @@ -117,7 +116,7 @@ static EMMC_ERROR_CODE emmc_response_check(uint32_t *response, } return EMMC_ERR_CARD_STATUS_BIT; } - return EMMC_SUCCESS;; + return EMMC_SUCCESS; } if (response_type == HAL_MEMCARD_RESPONSE_R4) { @@ -223,11 +222,11 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) state = ESTATE_BEGIN; response_type = - (HAL_MEMCARD_RESPONSE_TYPE) (mmc_drv_obj.cmd_info. - cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK); + ((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); + ((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)) { @@ -427,8 +426,9 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) case ESTATE_ACCESS_END: /* clear flag */ - if (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) { - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + 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; } @@ -448,8 +448,9 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) case ESTATE_TRANSFER_ERROR: /* The error occurred in the Data transfer. */ - if (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) { - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ + 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; } @@ -468,8 +469,8 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) default: state = ESTATE_END; break; - } /* switch (state) */ - } /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */ + } /* switch (state) */ + } /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */ /* force terminate */ if (mmc_drv_obj.force_terminate == TRUE) { @@ -481,7 +482,7 @@ EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response) ERROR("BL2: emmc exec_cmd:EMMC_ERR_FORCE_TERMINATE\n"); emmc_softreset(); - return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */ + return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */ } /* success */ diff --git a/drivers/renesas/common/emmc/emmc_config.h b/drivers/renesas/common/emmc/emmc_config.h new file mode 100644 index 000000000..16b6b8aa9 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_config.h @@ -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 */ diff --git a/drivers/renesas/rcar/emmc/emmc_def.h b/drivers/renesas/common/emmc/emmc_def.h index 178c795b9..178c795b9 100644 --- a/drivers/renesas/rcar/emmc/emmc_def.h +++ b/drivers/renesas/common/emmc/emmc_def.h diff --git a/drivers/renesas/common/emmc/emmc_hal.h b/drivers/renesas/common/emmc/emmc_hal.h new file mode 100644 index 000000000..0a8551719 --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_hal.h @@ -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 */ diff --git a/drivers/renesas/rcar/emmc/emmc_init.c b/drivers/renesas/common/emmc/emmc_init.c index b27e16586..354aa3c82 100644 --- a/drivers/renesas/rcar/emmc/emmc_init.c +++ b/drivers/renesas/common/emmc/emmc_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,12 +32,12 @@ EMMC_ERROR_CODE rcar_emmc_memcard_power(uint8_t mode) return EMMC_SUCCESS; } -static __inline void emmc_set_retry_count(uint32_t retry) +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) +static inline void emmc_set_data_timeout(uint32_t data_timeout) { mmc_drv_obj.data_timeout = data_timeout; } @@ -73,7 +73,8 @@ static EMMC_ERROR_CODE emmc_dev_finalize(void) EMMC_ERROR_CODE result; uint32_t dataL; - /* MMC power off + /* + * MMC power off * the power supply of eMMC device is always turning on. * RST_n : Hi --> Low level. */ @@ -115,27 +116,25 @@ static EMMC_ERROR_CODE emmc_dev_init(void) 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); /* Automatic Control=Disable, Clock Output=Disable */ + 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 retult; + EMMC_ERROR_CODE result; /* initialize mmc driver */ emmc_drv_init(); /* initialize H/W */ - retult = emmc_dev_init(); - if (EMMC_SUCCESS != retult) { - return retult; + result = emmc_dev_init(); + if (result == EMMC_SUCCESS) { + mmc_drv_obj.initialize = TRUE; } - mmc_drv_obj.initialize = TRUE; - - return retult; + return result; } @@ -152,14 +151,12 @@ EMMC_ERROR_CODE emmc_terminate(void) EMMC_ERROR_CODE rcar_emmc_init(void) { - EMMC_ERROR_CODE retult; + EMMC_ERROR_CODE result; - retult = emmc_reset_controller(); - if (EMMC_SUCCESS != retult) { - return retult; + result = emmc_reset_controller(); + if (result == EMMC_SUCCESS) { + emmc_driver_config(); } - emmc_driver_config(); - - return EMMC_SUCCESS; + return result; } diff --git a/drivers/renesas/rcar/emmc/emmc_interrupt.c b/drivers/renesas/common/emmc/emmc_interrupt.c index 2557280cf..092fdfb72 100644 --- a/drivers/renesas/rcar/emmc/emmc_interrupt.c +++ b/drivers/renesas/common/emmc/emmc_interrupt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights * reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -118,7 +118,7 @@ uint32_t emmc_interrupt(void) 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 occured */ + /* DM_CM_INFO2: DMA-ch0 error occurred */ if ((BIT16 & mmc_drv_obj.dm_event2) != 0) { mmc_drv_obj.dma_error_flag = TRUE; } else { @@ -128,13 +128,13 @@ uint32_t emmc_interrupt(void) /* wait next interrupt */ mmc_drv_obj.state_machine_blocking = FALSE; } - /* DM_CM_INFO1: DMA-ch1 transfer complete or error occured */ + /* 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 occured */ + /* DM_CM_INFO2: DMA-ch1 error occurred */ if ((BIT17 & mmc_drv_obj.dm_event2) != 0) { mmc_drv_obj.dma_error_flag = TRUE; } else { diff --git a/drivers/renesas/rcar/emmc/emmc_mount.c b/drivers/renesas/common/emmc/emmc_mount.c index df8203ea8..e04afd4cf 100644 --- a/drivers/renesas/rcar/emmc/emmc_mount.c +++ b/drivers/renesas/common/emmc/emmc_mount.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,10 +8,10 @@ #include <lib/mmio.h> #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" #include "micro_delay.h" #include "rcar_def.h" @@ -53,7 +53,7 @@ static EMMC_ERROR_CODE emmc_card_init(void) int32_t retry; uint32_t freq = MMC_400KHZ; /* 390KHz */ EMMC_ERROR_CODE result; - uint32_t resultCalc; + uint32_t result_calc; /* state check */ if ((mmc_drv_obj.initialize != TRUE) @@ -161,9 +161,12 @@ static EMMC_ERROR_CODE emmc_card_init(void) mmc_drv_obj.selected = TRUE; - /* card speed check */ - resultCalc = emmc_calc_tran_speed(&freq); /* Card spec is calculated from TRAN_SPEED(CSD). */ - if (resultCalc == 0) { + /* + * 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; @@ -201,7 +204,8 @@ static EMMC_ERROR_CODE emmc_card_init(void) HAL_MEMCARD_NOT_DMA); result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response); if (result != EMMC_SUCCESS) { - /* CMD12 is not send. + /* + * CMD12 is not send. * If BUS initialization is failed, user must be execute Bus initialization again. * Bus initialization is start CMD0(soft reset command). */ @@ -217,7 +221,7 @@ static EMMC_ERROR_CODE emmc_card_init(void) static EMMC_ERROR_CODE emmc_high_speed(void) { - uint32_t freq; /**< High speed mode clock frequency */ + uint32_t freq; /* High speed mode clock frequency */ EMMC_ERROR_CODE result; uint8_t cardType; @@ -236,8 +240,8 @@ static EMMC_ERROR_CODE emmc_high_speed(void) else freq = MMC_20MHZ; - /* Hi-Speed-mode selction */ - if ((MMC_52MHZ == freq) || (MMC_26MHZ == freq)) { + /* Hi-Speed-mode selection */ + if ((freq == MMC_52MHZ) || (freq == MMC_26MHZ)) { /* CMD6 */ emmc_make_nontrans_cmd(CMD6_SWITCH, EMMC_SWITCH_HS_TIMING); result = @@ -322,7 +326,8 @@ static EMMC_ERROR_CODE emmc_bus_width(uint32_t width) return EMMC_ERR_STATE; } - mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); /* 2 = 8bit, 1 = 4bit, 0 =1bit */ + /* 2 = 8bit, 1 = 4bit, 0 =1bit */ + mmc_drv_obj.bus_width = (HAL_MEMCARD_DATA_WIDTH) (width >> 2); /* CMD6 */ emmc_make_nontrans_cmd(CMD6_SWITCH, @@ -371,7 +376,6 @@ static EMMC_ERROR_CODE emmc_bus_width(uint32_t width) return EMMC_SUCCESS; EXIT: - emmc_write_error_info(EMMC_FUNCNO_BUS_WIDTH, result); ERROR("BL2: emmc bus_width error end\n"); return result; @@ -489,82 +493,83 @@ static void emmc_get_partition_access(void) static uint32_t emmc_calc_tran_speed(uint32_t *freq) { - const uint32_t unit[8] = { 10000, 100000, 1000000, 10000000, - 0, 0, 0, 0 }; /**< frequency unit (1/10) */ - const uint32_t mult[16] = { 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, - 52, 55, 60, 70, 80 }; - - uint32_t maxFreq; - uint32_t result; + 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 + /* + * tran_speed = 0x32 * unit[tran_speed&0x7] = uint[0x2] = 1000000 * mult[(tran_speed&0x78)>>3] = mult[0x30>>3] = mult[6] = 26 * 1000000 * 26 = 26000000 (26MHz) */ result = 1; - maxFreq = + max_freq = unit[tran_speed & EMMC_TRANSPEED_FREQ_UNIT_MASK] * mult[(tran_speed & EMMC_TRANSPEED_MULT_MASK) >> EMMC_TRANSPEED_MULT_SHIFT]; - if (maxFreq == 0) { + if (max_freq == 0) { result = 0; - } else if (MMC_FREQ_52MHZ <= maxFreq) + } else if (max_freq >= MMC_FREQ_52MHZ) { *freq = MMC_52MHZ; - else if (MMC_FREQ_26MHZ <= maxFreq) + } else if (max_freq >= MMC_FREQ_26MHZ) { *freq = MMC_26MHZ; - else if (MMC_FREQ_20MHZ <= maxFreq) + } else if (max_freq >= MMC_FREQ_20MHZ) { *freq = MMC_20MHZ; - else + } else { *freq = MMC_400KHZ; + } return result; } static uint32_t emmc_set_timeout_register_value(uint32_t freq) { - uint32_t timeoutCnt; /* SD_OPTION - Timeout Counter */ + uint32_t timeout_cnt; /* SD_OPTION - Timeout Counter */ switch (freq) { case 1U: - timeoutCnt = 0xE0U; + timeout_cnt = 0xE0U; break; /* SDCLK * 2^27 */ case 2U: - timeoutCnt = 0xE0U; + timeout_cnt = 0xE0U; break; /* SDCLK * 2^27 */ case 4U: - timeoutCnt = 0xD0U; + timeout_cnt = 0xD0U; break; /* SDCLK * 2^26 */ case 8U: - timeoutCnt = 0xC0U; + timeout_cnt = 0xC0U; break; /* SDCLK * 2^25 */ case 16U: - timeoutCnt = 0xB0U; + timeout_cnt = 0xB0U; break; /* SDCLK * 2^24 */ case 32U: - timeoutCnt = 0xA0U; + timeout_cnt = 0xA0U; break; /* SDCLK * 2^23 */ case 64U: - timeoutCnt = 0x90U; + timeout_cnt = 0x90U; break; /* SDCLK * 2^22 */ case 128U: - timeoutCnt = 0x80U; + timeout_cnt = 0x80U; break; /* SDCLK * 2^21 */ case 256U: - timeoutCnt = 0x70U; + timeout_cnt = 0x70U; break; /* SDCLK * 2^20 */ case 512U: - timeoutCnt = 0x70U; + timeout_cnt = 0x70U; break; /* SDCLK * 2^20 */ default: - timeoutCnt = 0xE0U; + timeout_cnt = 0xE0U; break; /* SDCLK * 2^27 */ } - return timeoutCnt; + return timeout_cnt; } EMMC_ERROR_CODE emmc_set_ext_csd(uint32_t arg) diff --git a/drivers/renesas/rcar/emmc/emmc_read.c b/drivers/renesas/common/emmc/emmc_read.c index 390d0caac..96e73ca56 100644 --- a/drivers/renesas/rcar/emmc/emmc_read.c +++ b/drivers/renesas/common/emmc/emmc_read.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,15 +7,15 @@ #include <arch_helpers.h> #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" -#define MIN_EMMC(a, b) (((a) < (b)) ? (a) : (b)) -#define EMMC_RW_SECTOR_COUNT_MAX 0x0000ffffU +#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, +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) { @@ -39,7 +39,8 @@ static EMMC_ERROR_CODE emmc_multiple_block_read (uint32_t *buff_address_virtual, } SETR_32(SD_SECCNT, count); SETR_32(SD_STOP, 0x00000100); - SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE)); /* SD_BUF Read/Write DMA Transfer enable */ + /* 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, diff --git a/drivers/renesas/common/emmc/emmc_registers.h b/drivers/renesas/common/emmc/emmc_registers.h new file mode 100644 index 000000000..392abb8fb --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_registers.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2015-2020, 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) +#define USE_MMC_CH (MMC_CH1) /* R-Car E3 or RZ/G2M */ +#else /* RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2M */ +#define USE_MMC_CH (MMC_CH0) /* R-Car H3/M3/M3N */ +#endif /* RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2M */ + +#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) + +/* Clock Pulse Generator (CPG) registers */ +#define CPG_BASE (0xE6150000U) +/* Module stop status register 3 */ +#define CPG_MSTPSR3 (CPG_BASE + 0x0048U) +/* System module stop control register 3 */ +#define CPG_SMSTPCR3 (CPG_BASE + 0x013CU) +/* SDHI2 clock frequency control register */ +#define CPG_SD2CKCR (CPG_BASE + 0x0268U) +/* SDHI3 clock frequency control register */ +#define CPG_SD3CKCR (CPG_BASE + 0x026CU) +/* CPG Write Protect Register */ +#define CPG_CPGWPR (CPG_BASE + 0x0900U) + +#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 */ diff --git a/drivers/renesas/common/emmc/emmc_std.h b/drivers/renesas/common/emmc/emmc_std.h new file mode 100644 index 000000000..087c6e91d --- /dev/null +++ b/drivers/renesas/common/emmc/emmc_std.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 */ diff --git a/drivers/renesas/rcar/emmc/emmc_utility.c b/drivers/renesas/common/emmc/emmc_utility.c index 39d9ede5a..2e88abc75 100644 --- a/drivers/renesas/rcar/emmc/emmc_utility.c +++ b/drivers/renesas/common/emmc/emmc_utility.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,10 +7,10 @@ #include <common/debug.h> #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" -#include "emmc_std.h" #include "emmc_registers.h" -#include "emmc_def.h" +#include "emmc_std.h" static const uint32_t cmd_reg_hw[EMMC_CMD_MAX + 1] = { 0x00000000, /* CMD0 */ @@ -97,8 +97,8 @@ uint32_t emmc_bit_field(uint8_t *data, uint32_t top, uint32_t bottom) value = (uint32_t) ((data[index_top] << 24) | (data[index_top + 1] << 16) | - (data[index_top + 2] << 8) | data[index_top + - 3]); + (data[index_top + 2] << 8) | + data[index_top + 3]); } value = ((value >> (bottom & 0x07)) & ((1 << (top - bottom + 1)) - 1)); @@ -150,7 +150,7 @@ void emmc_make_nontrans_cmd(HAL_MEMCARD_COMMAND cmd, uint32_t arg) 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.cmd_info.hw |= BIT10; /* bit10 = R1 busy bit */ mmc_drv_obj.response = &mmc_drv_obj.r1_card_status; break; case HAL_MEMCARD_RESPONSE_R2: diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c b/drivers/renesas/common/iic_dvfs/iic_dvfs.c index 28b56c10e..e1c9a5bd4 100644 --- a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c +++ b/drivers/renesas/common/iic_dvfs/iic_dvfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,59 +7,59 @@ #include <common/debug.h> #include <lib/mmio.h> -#include "rcar_def.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 (0x07) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0B) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0E) -#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15) - -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05) -#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07) - -#define CPG_BIT_SMSTPCR9_DVFS (0x04000000) - -#define IIC_DVFS_REG_BASE (0xE60B0000) -#define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000) -#define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004) -#define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008) -#define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000C) -#define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010) -#define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014) - -#define IIC_DVFS_BIT_ICSR_BUSY (0x10) -#define IIC_DVFS_BIT_ICSR_AL (0x08) -#define IIC_DVFS_BIT_ICSR_TACK (0x04) -#define IIC_DVFS_BIT_ICSR_WAIT (0x02) -#define IIC_DVFS_BIT_ICSR_DTE (0x01) - -#define IIC_DVFS_BIT_ICCR_ENABLE (0x80) -#define IIC_DVFS_SET_ICCR_START (0x94) -#define IIC_DVFS_SET_ICCR_STOP (0x90) -#define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94) -#define IIC_DVFS_SET_ICCR_CHANGE (0x81) -#define IIC_DVFS_SET_ICCR_STOP_READ (0xC0) - -#define IIC_DVFS_BIT_ICIC_TACKE (0x04) -#define IIC_DVFS_BIT_ICIC_WAITE (0x02) -#define IIC_DVFS_BIT_ICIC_DTEE (0x01) - -#define DVFS_READ_MODE (0x01) -#define DVFS_WRITE_MODE (0x00) - -#define IIC_DVFS_SET_DUMMY (0x52) +#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) -typedef enum { +enum dvfs_state_t { DVFS_START = 0, DVFS_STOP, DVFS_RETRANSMIT, @@ -69,9 +69,9 @@ typedef enum { DVFS_SET_SLAVE, DVFS_WRITE_ADDR, DVFS_WRITE_DATA, - DVFS_CHANGE_SEND_TO_RECIEVE, + DVFS_CHANGE_SEND_TO_RECEIVE, DVFS_DONE, -} DVFS_STATE_T; +}; #define DVFS_PROCESS (1) #define DVFS_COMPLETE (0) @@ -79,26 +79,26 @@ typedef enum { #if IMAGE_BL31 #define IIC_DVFS_FUNC(__name, ...) \ -static int32_t __attribute__ ((section (".system_ram"))) \ +static int32_t __attribute__ ((section(".system_ram"))) \ dvfs_ ##__name(__VA_ARGS__) #define RCAR_DVFS_API(__name, ...) \ -int32_t __attribute__ ((section (".system_ram"))) \ +int32_t __attribute__ ((section(".system_ram"))) \ rcar_iic_dvfs_ ##__name(__VA_ARGS__) #else -#define IIC_DVFS_FUNC(__name, ...) \ +#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, DVFS_STATE_T *state, uint32_t *err, uint8_t mode) +IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode) { - uint8_t icsr_al = 0, icsr_tack = 0; + uint8_t icsr_al = 0U, icsr_tack = 0U; uint8_t reg, stop; - uint32_t i = 0; + uint32_t i = 0U; stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ : IIC_DVFS_SET_ICCR_STOP; @@ -107,43 +107,48 @@ IIC_DVFS_FUNC(check_error, DVFS_STATE_T *state, uint32_t *err, uint8_t mode) 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 == 0 && icsr_tack == 0) + 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) + 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 == 0); + } 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 = 0; + i = 0U; do { reg = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY; - if (reg == 0) + if (reg == 0U) { break; + } - if (i++ > IIC_DVFS_SET_BUSY_LOOP) + if (i++ > IIC_DVFS_SET_BUSY_LOOP) { panic(); + } - } while (1); + } while (true); mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U); (*err)++; - if (*err > DVFS_RETRY_MAX) + if (*err > DVFS_RETRY_MAX) { return DVFS_ERROR; + } *state = DVFS_START; @@ -161,24 +166,26 @@ IIC_DVFS_FUNC(check_error, DVFS_STATE_T *state, uint32_t *err, uint8_t mode) reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK; mmio_write_8(IIC_DVFS_REG_ICSR, reg); - i = 0; - while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0) { - if (i++ > IIC_DVFS_SET_BUSY_LOOP) + 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, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); (*err)++; - if (*err > DVFS_RETRY_MAX) + if (*err > DVFS_RETRY_MAX) { return DVFS_ERROR; + } *state = DVFS_START; return DVFS_PROCESS; } -IIC_DVFS_FUNC(start, DVFS_STATE_T * state) +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; @@ -190,8 +197,9 @@ IIC_DVFS_FUNC(start, DVFS_STATE_T * state) mmio_write_8(IIC_DVFS_REG_ICCR, mode); lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; - if (lsi_product == PRR_PRODUCT_E3) + if (lsi_product == PRR_PRODUCT_E3) { goto start; + } reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14; switch (reg) { @@ -228,19 +236,21 @@ start: return result; } -IIC_DVFS_FUNC(set_slave, DVFS_STATE_T * state, uint32_t *err, uint8_t slave) +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) + 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) + 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); @@ -253,18 +263,20 @@ IIC_DVFS_FUNC(set_slave, DVFS_STATE_T * state, uint32_t *err, uint8_t slave) return result; } -IIC_DVFS_FUNC(write_addr, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_addr) +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) + 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) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); @@ -276,18 +288,21 @@ IIC_DVFS_FUNC(write_addr, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_addr) return result; } -IIC_DVFS_FUNC(write_data, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_data) +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) + 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) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICDR, reg_data); @@ -299,18 +314,20 @@ IIC_DVFS_FUNC(write_data, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_data) return result; } -IIC_DVFS_FUNC(stop, DVFS_STATE_T *state, uint32_t *err) +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) + 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) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP); @@ -326,32 +343,35 @@ IIC_DVFS_FUNC(done, void) { uint32_t i; - for (i = 0; i < IIC_DVFS_SET_BUSY_LOOP; i++) { - if (mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) + 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, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); return DVFS_COMPLETE; } -IIC_DVFS_FUNC(write_reg_addr_read, DVFS_STATE_T *state, uint32_t *err, - uint8_t reg_addr) +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) + 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) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr); @@ -363,18 +383,20 @@ IIC_DVFS_FUNC(write_reg_addr_read, DVFS_STATE_T *state, uint32_t *err, return result; } -IIC_DVFS_FUNC(retransmit, DVFS_STATE_T *state, uint32_t *err) +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) + 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) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION); @@ -389,20 +411,22 @@ IIC_DVFS_FUNC(retransmit, DVFS_STATE_T *state, uint32_t *err) return result; } -IIC_DVFS_FUNC(set_slave_read, DVFS_STATE_T *state, uint32_t *err, - uint8_t slave) +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) + 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) + 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); @@ -410,23 +434,25 @@ IIC_DVFS_FUNC(set_slave_read, DVFS_STATE_T *state, uint32_t *err, address = ((uint8_t) (slave << 1) + DVFS_READ_MODE); mmio_write_8(IIC_DVFS_REG_ICDR, address); - *state = DVFS_CHANGE_SEND_TO_RECIEVE; + *state = DVFS_CHANGE_SEND_TO_RECEIVE; return result; } -IIC_DVFS_FUNC(change_send_to_recieve, DVFS_STATE_T *state, uint32_t *err) +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) + 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) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE); @@ -438,18 +464,20 @@ IIC_DVFS_FUNC(change_send_to_recieve, DVFS_STATE_T *state, uint32_t *err) return result; } -IIC_DVFS_FUNC(stop_read, DVFS_STATE_T *state, uint32_t *err) +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) + 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) + if (mode != IIC_DVFS_BIT_ICSR_WAIT) { return result; + } mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ); @@ -464,13 +492,14 @@ IIC_DVFS_FUNC(stop_read, DVFS_STATE_T *state, uint32_t *err) return result; } -IIC_DVFS_FUNC(read, DVFS_STATE_T *state, uint8_t *reg_data) +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) + 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); @@ -483,12 +512,12 @@ IIC_DVFS_FUNC(read, DVFS_STATE_T *state, uint8_t *reg_data) RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data) { - DVFS_STATE_T state = DVFS_START; + enum dvfs_state_t state = DVFS_START; int32_t result = DVFS_PROCESS; - uint32_t err = 0; + uint32_t err = 0U; mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); - mmio_write_8(IIC_DVFS_REG_ICCR, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); again: switch (state) { case DVFS_START: @@ -514,20 +543,21 @@ again: break; } - if (result == DVFS_PROCESS) + if (result == DVFS_PROCESS) { goto again; + } return result; } RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data) { - DVFS_STATE_T state = DVFS_START; + enum dvfs_state_t state = DVFS_START; int32_t result = DVFS_PROCESS; - uint32_t err = 0; + uint32_t err = 0U; mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS); - mmio_write_8(IIC_DVFS_REG_ICCR, 0); + mmio_write_8(IIC_DVFS_REG_ICCR, 0U); again: switch (state) { case DVFS_START: @@ -545,8 +575,8 @@ again: case DVFS_SET_SLAVE_READ: result = dvfs_set_slave_read(&state, &err, slave); break; - case DVFS_CHANGE_SEND_TO_RECIEVE: - result = dvfs_change_send_to_recieve(&state, &err); + 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); @@ -562,8 +592,9 @@ again: break; } - if (result == DVFS_PROCESS) + if (result == DVFS_PROCESS) { goto again; + } return result; } diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h b/drivers/renesas/common/iic_dvfs/iic_dvfs.h index 2dec58f64..244c06cfd 100644 --- a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h +++ b/drivers/renesas/common/iic_dvfs/iic_dvfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,14 +8,14 @@ #define IIC_DVFS_H /* PMIC slave */ -#define PMIC (0x30) -#define BKUP_MODE_CNT (0x20) -#define DVFS_SET_VID (0x54) -#define REG_KEEP10 (0x79) +#define PMIC (0x30U) +#define BKUP_MODE_CNT (0x20U) +#define DVFS_SET_VID (0x54U) +#define REG_KEEP10 (0x79U) /* EEPROM slave */ -#define EEPROM (0x50) -#define BOARD_ID (0x70) +#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); diff --git a/drivers/renesas/rcar/io/io_common.h b/drivers/renesas/common/io/io_common.h index 6eb77777a..6eb77777a 100644 --- a/drivers/renesas/rcar/io/io_common.h +++ b/drivers/renesas/common/io/io_common.h diff --git a/drivers/renesas/rcar/io/io_emmcdrv.c b/drivers/renesas/common/io/io_emmcdrv.c index 84240d260..c2b5f7c08 100644 --- a/drivers/renesas/rcar/io/io_emmcdrv.c +++ b/drivers/renesas/common/io/io_emmcdrv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,13 +10,13 @@ #include <drivers/io/io_driver.h> #include <drivers/io/io_storage.h> -#include "io_common.h" -#include "io_emmcdrv.h" -#include "io_private.h" #include "emmc_config.h" +#include "emmc_def.h" #include "emmc_hal.h" #include "emmc_std.h" -#include "emmc_def.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); @@ -41,8 +41,9 @@ static io_type_t device_type_emmcdrv(void) static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode, signed long long offset) { - if (mode != IO_SEEK_SET) + if (mode != IO_SEEK_SET) { return IO_FAIL; + } ((file_state_t *) entity->info)->file_pos = offset; @@ -64,12 +65,14 @@ static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer, current_file.partition, current_file.file_pos, sector_add, length, sector_num); - if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX) + 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) + emmc_dma) != EMMC_SUCCESS) { result = IO_FAIL; + } *length_read = length; fp->file_pos += (signed long long)length; @@ -92,8 +95,8 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, if (emmcdrv_bootpartition == PARTITION_ID_USER) { emmcdrv_bootpartition = mmc_drv_obj.boot_partition_en; - if ((PARTITION_ID_BOOT_1 == emmcdrv_bootpartition) || - (PARTITION_ID_BOOT_2 == emmcdrv_bootpartition)) { + 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", @@ -103,16 +106,18 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info, return IO_FAIL; } - if ((PARTITION_ID_USER == block_spec->partition) || - (PARTITION_ID_BOOT_1 == block_spec->partition) || - (PARTITION_ID_BOOT_2 == block_spec->partition)) + 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 + } else { current_file.partition = emmcdrv_bootpartition; + } done: - if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) + if (emmc_select_partition(current_file.partition) != EMMC_SUCCESS) { return IO_FAIL; + } entity->info = (uintptr_t) ¤t_file; @@ -166,8 +171,9 @@ 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) + if (rc == IO_SUCCESS) { *dev_con = &emmcdrv_dev_connector; + } return rc; } diff --git a/drivers/renesas/rcar/io/io_emmcdrv.h b/drivers/renesas/common/io/io_emmcdrv.h index 95070f24b..95070f24b 100644 --- a/drivers/renesas/rcar/io/io_emmcdrv.h +++ b/drivers/renesas/common/io/io_emmcdrv.h diff --git a/drivers/renesas/rcar/io/io_memdrv.c b/drivers/renesas/common/io/io_memdrv.c index 7e8c1d3a6..1f31c0fb9 100644 --- a/drivers/renesas/rcar/io/io_memdrv.c +++ b/drivers/renesas/common/io/io_memdrv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,8 +11,8 @@ #include <drivers/io/io_storage.h> #include "io_common.h" -#include "io_private.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); @@ -21,7 +21,8 @@ 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 +/* + * 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. */ @@ -43,12 +44,14 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, { 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 + /* + * 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) + 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; @@ -63,8 +66,9 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec, static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode, signed long long offset) { - if (mode != IO_SEEK_SET) + if (mode != IO_SEEK_SET) { return IO_FAIL; + } ((file_state_t *) entity->info)->file_pos = offset; @@ -142,8 +146,9 @@ 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) + if (result == IO_SUCCESS) { *dev_con = &memdrv_dev_connector; + } return result; } diff --git a/drivers/renesas/rcar/io/io_memdrv.h b/drivers/renesas/common/io/io_memdrv.h index 90e68123e..90e68123e 100644 --- a/drivers/renesas/rcar/io/io_memdrv.h +++ b/drivers/renesas/common/io/io_memdrv.h diff --git a/drivers/renesas/rcar/io/io_private.h b/drivers/renesas/common/io/io_private.h index 207523a73..207523a73 100644 --- a/drivers/renesas/rcar/io/io_private.h +++ b/drivers/renesas/common/io/io_private.h diff --git a/drivers/renesas/rcar/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c index b82c51078..c3e8319de 100644 --- a/drivers/renesas/rcar/io/io_rcar.c +++ b/drivers/renesas/common/io/io_rcar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,6 @@ #include <stdint.h> #include <string.h> -#include <platform_def.h> - #include <arch_helpers.h> #include <common/bl_common.h> #include <common/debug.h> @@ -24,6 +22,7 @@ #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); @@ -39,7 +38,8 @@ typedef struct { } plat_rcar_name_offset_t; typedef struct { - /* Put position above the struct to allow {0} on static init. + /* + * 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 */ @@ -59,7 +59,7 @@ typedef struct { #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_ISNOLOAD(b) |\ RCAR_ATTR_SET_CERTOFF(c))) #define RCAR_ATTR_GET_CALCADDR(a) ((a) & 0xFU) @@ -136,9 +136,11 @@ 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) + if (name != cert_offset[i].name) { continue; + } *cert = RCAR_CERT_SIZE; *cert *= RCAR_ATTR_GET_CERTOFF(cert_offset[i].attr); @@ -157,12 +159,14 @@ static int32_t file_to_offset(const int32_t name, uintptr_t *offset, int32_t i; for (i = 0; i < ARRAY_SIZE(name_offset); i++) { - if (name != name_offset[i].name) + if (name != name_offset[i].name) { continue; + } addr = RCAR_ATTR_GET_CALCADDR(name_offset[i].attr); - if (rcar_image_number + 2 < addr) + if (rcar_image_number + 2U < addr) { continue; + } *offset = rcar_image_header[addr]; *cert = RCAR_CERT_SIZE; @@ -175,8 +179,9 @@ static int32_t file_to_offset(const int32_t name, uintptr_t *offset, #if TRUSTED_BOARD_BOOT for (i = 0; i < ARRAY_SIZE(cert_offset); i++) { - if (name != cert_offset[i].name) + if (name != cert_offset[i].name) { continue; + } *no_load = RCAR_ATTR_GET_ISNOLOAD(cert_offset[i].attr); *partition = 0U; @@ -282,8 +287,9 @@ static int32_t check_load_area(uintptr_t dst, uintptr_t len) result = IO_FAIL; } done: - if (result == IO_FAIL) + if (result == IO_FAIL) { ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len); + } return result; } @@ -307,14 +313,15 @@ static int32_t load_bl33x(void) BL338_IMAGE_ID }; - if (loaded != IO_NOT_SUPPORTED) + 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("load_bl33x: failed to get offset\n"); + WARN("%s: failed to get offset\n", __func__); loaded = IO_FAIL; return loaded; } @@ -324,34 +331,34 @@ static int32_t load_bl33x(void) rc = io_open(rcar_handle, rcar_spec, &handle); if (rc != IO_SUCCESS) { - WARN("Failed to open FIP (%i)\n", rc); + 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("load_bl33x: failed to seek\n"); + WARN("%s: failed to seek\n", __func__); loaded = IO_FAIL; return loaded; } rc = check_load_area(dst, len); if (rc != IO_SUCCESS) { - WARN("load_bl33x: check load area\n"); + WARN("%s: check load area\n", __func__); loaded = IO_FAIL; return loaded; } rc = io_read(handle, dst, len, &cnt); if (rc != IO_SUCCESS) { - WARN("load_bl33x: failed to read\n"); + 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) { + if (rc != 0) { memset((void *)dst, 0x00, len); loaded = IO_FAIL; return loaded; @@ -367,8 +374,7 @@ static int32_t load_bl33x(void) static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) { - uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = { - 0}; + uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = {0UL}; uintptr_t handle; ssize_t offset; uint32_t i; @@ -382,8 +388,9 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) return IO_FAIL; } - if (RCAR_CERT_LOAD == rcar_cert_load) + if (rcar_cert_load == RCAR_CERT_LOAD) { return IO_SUCCESS; + } rc = io_open(rcar_handle, rcar_spec, &handle); if (rc != IO_SUCCESS) { @@ -391,16 +398,18 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) 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 */ + /* + * 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); @@ -447,8 +456,9 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) rcar_cert_load = RCAR_CERT_LOAD; error: - if (rc != IO_SUCCESS) + if (rc != IO_SUCCESS) { rc = IO_FAIL; + } io_close(handle); @@ -464,13 +474,15 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, 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 + /* + * 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. */ + * than one open file at a time. + */ if (current_file.offset != 0U) { - WARN("rcar_file_open : Only one open file at a time.\n"); + WARN("%s: Only one open file at a time.\n", __func__); return IO_RESOURCES_EXHAUSTED; } @@ -480,7 +492,7 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, return IO_FAIL; } - if (noload) { + if (noload != 0U) { current_file.offset = 1; current_file.dst = 0; current_file.size = 1; @@ -494,12 +506,10 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec, rcar_read_certificate((uint64_t) cert, &len, &dst); - /*----------------* - * Baylibre: HACK * - *----------------*/ - if (BL31_IMAGE_ID == spec->offset && len < RCAR_TRUSTED_SRAM_SIZE) { - WARN("r-car ignoring the BL31 size from certificate," - "using RCAR_TRUSTED_SRAM_SIZE instead\n"); + /* 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; } @@ -536,7 +546,7 @@ static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, #else static uint32_t load_bl33x_counter; #endif - if (current_file.no_load) { + if (current_file.no_load != 0U) { *cnt = length; return IO_SUCCESS; } @@ -551,14 +561,14 @@ static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, rc = io_seek(handle, IO_SEEK_SET, offset); if (rc != IO_SUCCESS) { - WARN("rcar_file_read: failed to seek\n"); + 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("rcar_file_read: load area err\n"); + WARN("%s: load area err\n", __func__); goto error; } } @@ -573,8 +583,9 @@ static int32_t rcar_file_read(io_entity_t *entity, uintptr_t buffer, io_close(handle); load_bl33x_counter += 1; - if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33X) + if (load_bl33x_counter == RCAR_COUNT_LOAD_BL33X) { return load_bl33x(); + } return IO_SUCCESS; error: @@ -584,8 +595,9 @@ error: static int32_t rcar_file_close(io_entity_t *entity) { - if (current_file.offset) + if (current_file.offset != 0U) { memset(¤t_file, 0, sizeof(current_file)); + } entity->info = 0U; @@ -634,8 +646,9 @@ 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) + if (result == IO_SUCCESS) { *dev_con = &rcar_dev_connector; + } return result; } diff --git a/drivers/renesas/rcar/io/io_rcar.h b/drivers/renesas/common/io/io_rcar.h index c26a61767..c26a61767 100644 --- a/drivers/renesas/rcar/io/io_rcar.h +++ b/drivers/renesas/common/io/io_rcar.h diff --git a/drivers/renesas/rcar/pfc/pfc_regs.h b/drivers/renesas/common/pfc_regs.h index 418773366..418773366 100644 --- a/drivers/renesas/rcar/pfc/pfc_regs.h +++ b/drivers/renesas/common/pfc_regs.h diff --git a/drivers/renesas/rcar/pwrc/call_sram.S b/drivers/renesas/common/pwrc/call_sram.S index aa8644cb9..aa8644cb9 100644 --- a/drivers/renesas/rcar/pwrc/call_sram.S +++ b/drivers/renesas/common/pwrc/call_sram.S diff --git a/drivers/renesas/rcar/pwrc/pwrc.c b/drivers/renesas/common/pwrc/pwrc.c index 2ce6b6139..c0f015f04 100644 --- a/drivers/renesas/rcar/pwrc/pwrc.c +++ b/drivers/renesas/common/pwrc/pwrc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,10 +16,10 @@ #include <plat/common/platform.h> #include "iic_dvfs.h" -#include "rcar_def.h" -#include "rcar_private.h" #include "micro_delay.h" #include "pwrc.h" +#include "rcar_def.h" +#include "rcar_private.h" /* * Someday there will be a generic power controller api. At the moment each @@ -27,105 +27,105 @@ */ 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 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) /* 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 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) @@ -136,17 +136,17 @@ RCAR_INSTANTIATE_LOCK #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 -#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) +#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); @@ -320,11 +320,13 @@ void rcar_pwrc_clusteroff(uint64_t mpidr) c = rcar_pwrc_get_mpidr_cluster(mpidr); dst = IS_CA53(c) ? RCAR_CA53CPUCMCR : RCAR_CA57CPUCMCR; - if (PRR_PRODUCT_M3 == product && cut < PRR_PRODUCT_30) + if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { goto done; + } - if (PRR_PRODUCT_H3 == product && cut <= PRR_PRODUCT_20) + 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); @@ -343,7 +345,7 @@ static void rcar_pwrc_save_timer_state(void) rcar_pwrc_saved_cntfid = mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF)); } -#endif +#endif /* RCAR_SYSTEM_SUSPEND */ void rcar_pwrc_restore_timer_state(void) { @@ -372,10 +374,10 @@ void rcar_pwrc_system_reset(void) } #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) +#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) { @@ -427,11 +429,13 @@ static void __attribute__ ((section(".system_ram"))) product = reg & PRR_PRODUCT_MASK; cut = reg & PRR_CUT_MASK; - if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) + if (product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) { goto self_refresh; + } - if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) + if (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20) { goto self_refresh; + } mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE); @@ -509,7 +513,7 @@ self_refresh: } static void __attribute__ ((section(".system_ram"))) - rcar_pwrc_set_self_refresh_e3(void) +rcar_pwrc_set_self_refresh_e3(void) { uint32_t ddr_md; uint32_t reg; @@ -533,8 +537,10 @@ static void __attribute__ ((section(".system_ram"))) while (mmio_read_32(DBSC4_REG_DBWAIT)) ; - /* Set the auto-refresh enable register */ - /* Set the ARFEN bit to 0 in the DBRFEN */ + /* + * 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); @@ -638,7 +644,7 @@ static void __attribute__ ((section(".system_ram"))) } void __attribute__ ((section(".system_ram"))) __attribute__ ((noinline)) - rcar_pwrc_go_suspend_to_ram(void) +rcar_pwrc_go_suspend_to_ram(void) { #if PMIC_ROHM_BD9571 int32_t rc = -1, qllm = -1; @@ -713,7 +719,7 @@ void rcar_pwrc_suspend_to_ram(void) error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, 0); if (error) { - ERROR("Failed send KEEP10 init ret=%d \n", error); + ERROR("Failed send KEEP10 init ret=%d\n", error); return; } #endif @@ -835,7 +841,6 @@ int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr) 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 @@ -861,6 +866,6 @@ int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr) } } } - return (rtn); + return rtn; } diff --git a/drivers/renesas/rcar/pwrc/pwrc.h b/drivers/renesas/common/pwrc/pwrc.h index 2b8178397..f73099b0b 100644 --- a/drivers/renesas/rcar/pwrc/pwrc.h +++ b/drivers/renesas/common/pwrc/pwrc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -31,12 +31,12 @@ #define WKUP_PPONR 0x2 #define WKUP_GICREQ 0x3 -#define RCAR_INVALID (0xffffffffU) +#define RCAR_INVALID (0xffffffffU) #define PSYSR_INVALID 0xffffffff -#define RCAR_CLUSTER_A53A57 (0U) -#define RCAR_CLUSTER_CA53 (1U) -#define RCAR_CLUSTER_CA57 (2U) +#define RCAR_CLUSTER_A53A57 (0U) +#define RCAR_CLUSTER_CA53 (1U) +#define RCAR_CLUSTER_CA57 (2U) #ifndef __ASSEMBLER__ void rcar_pwrc_disable_interrupt_wakeup(uint64_t mpidr); diff --git a/drivers/renesas/rcar/qos/qos_reg.h b/drivers/renesas/common/qos_reg.h index f2012fa45..f2012fa45 100644 --- a/drivers/renesas/rcar/qos/qos_reg.h +++ b/drivers/renesas/common/qos_reg.h diff --git a/drivers/renesas/rcar/rom/rom_api.c b/drivers/renesas/common/rom/rom_api.c index fda28150e..fda28150e 100644 --- a/drivers/renesas/rcar/rom/rom_api.c +++ b/drivers/renesas/common/rom/rom_api.c diff --git a/drivers/renesas/rcar/rom/rom_api.h b/drivers/renesas/common/rom/rom_api.h index 1d5b03d7f..1d5b03d7f 100644 --- a/drivers/renesas/rcar/rom/rom_api.h +++ b/drivers/renesas/common/rom/rom_api.h diff --git a/drivers/renesas/rcar/rpc/rpc_driver.c b/drivers/renesas/common/rpc/rpc_driver.c index 63de5b851..63de5b851 100644 --- a/drivers/renesas/rcar/rpc/rpc_driver.c +++ b/drivers/renesas/common/rpc/rpc_driver.c diff --git a/drivers/renesas/rcar/rpc/rpc_registers.h b/drivers/renesas/common/rpc/rpc_registers.h index 79aea8599..79aea8599 100644 --- a/drivers/renesas/rcar/rpc/rpc_registers.h +++ b/drivers/renesas/common/rpc/rpc_registers.h diff --git a/drivers/renesas/rcar/scif/scif.S b/drivers/renesas/common/scif/scif.S index 8309bb26e..beb8dd838 100644 --- a/drivers/renesas/rcar/scif/scif.S +++ b/drivers/renesas/common/scif/scif.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,43 +9,43 @@ #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 +#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) +#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_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) +#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) +#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 @@ -60,80 +60,81 @@ #endif /* mode pin */ -#define RST_MODEMR (0xE6160060) -#define MODEMR_MD12 (0x00001000) +#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 + \ +#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_115200BPSON (16) -#define SCBRR_115200BPS_E3_SSCG (15) -#define SCBRR_230400BPS (8) +#define SCBRR_115200BPS (17) +#define SCBRR_115200BPSON (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) +#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) +#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) +#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) +#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_rcar_t *console) + * 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_rcar_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -142,7 +143,7 @@ func console_rcar_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_RCAR_BASE] + str x0, [x6, #CONSOLE_T_BASE] bl console_rcar_init @@ -154,7 +155,7 @@ 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 @@ -166,7 +167,6 @@ endfunc console_rcar_register * w2 - Baud rate * Out: return 1 on success * Clobber list : x1, x2 - * ----------------------------------------------- */ func console_rcar_init ldr x0, =CPG_BASE @@ -188,8 +188,10 @@ func console_rcar_init 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 */ + /* + * 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 @@ -265,7 +267,7 @@ func console_rcar_init 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. @@ -273,7 +275,6 @@ endfunc console_rcar_init * 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 @@ -304,14 +305,11 @@ func console_rcar_putc ret endfunc console_rcar_putc - /* --------------------------------------------- - * int console_rcar_flush(void) + /* + * void console_rcar_flush(void) * Function to force a write of all buffered - * data that hasn't been output. It returns 0 - * upon successful completion, otherwise it - * returns -1. + * data that hasn't been output. It returns void * Clobber list : x0, x1 - * --------------------------------------------- */ func console_rcar_flush ldr x0, =SCIF_BASE @@ -327,6 +325,5 @@ func console_rcar_flush and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN) strh w1, [x0, #SCIF_SCSCR] - mov w0, #0 ret endfunc console_rcar_flush diff --git a/drivers/renesas/rcar/watchdog/swdt.c b/drivers/renesas/common/watchdog/swdt.c index 111e65174..05987ab70 100644 --- a/drivers/renesas/rcar/watchdog/swdt.c +++ b/drivers/renesas/common/watchdog/swdt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -162,6 +162,6 @@ void rcar_swdt_exec(uint64_t p) gicv2_end_of_interrupt(ARM_IRQ_SEC_WDT); rcar_swdt_release(); ERROR("\n"); - ERROR("System WDT overflow, occured address is %p\n", (void *)p); + ERROR("System WDT overflow, occurred address is %p\n", (void *)p); panic(); } diff --git a/drivers/renesas/rcar/board/board.c b/drivers/renesas/rcar/board/board.c index df17802aa..cd194ff9f 100644 --- a/drivers/renesas/rcar/board/board.c +++ b/drivers/renesas/rcar/board/board.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights * reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -33,7 +33,7 @@ #define SXS_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define SX_ID { 0x10U, 0x11U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define SKP_ID { 0x10U, 0x10U, 0x20U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } -#define SK_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } +#define SK_ID { 0x10U, 0x30U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define EB4_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define EB_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } #define DR_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } diff --git a/drivers/renesas/rcar/common.c b/drivers/renesas/rcar/common.c deleted file mode 100644 index 42bdce579..000000000 --- a/drivers/renesas/rcar/common.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <lib/mmio.h> - -#include "rcar_private.h" - -void -#if IMAGE_BL31 - __attribute__ ((section(".system_ram"))) -#endif - cpg_write(uintptr_t regadr, uint32_t regval) -{ - uint32_t value = (regval); - mmio_write_32((uintptr_t) RCAR_CPGWPR, ~value); - mmio_write_32(regadr, value); -} - -void -#if IMAGE_BL31 - __attribute__ ((section(".system_ram"))) -#endif - mstpcr_write(uint32_t mstpcr, uint32_t mstpsr, uint32_t target_bit) -{ - uint32_t reg; - reg = mmio_read_32(mstpcr); - reg &= ~target_bit; - cpg_write(mstpcr, reg); - while ((mmio_read_32(mstpsr) & target_bit) != 0U) { - } -} diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c index 1d6e83a2c..ac83c9a10 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -510,6 +510,14 @@ static void send_dbcmd(uint32_t cmd) dsb_sev(); } +static void dbwait_loop(uint32_t wait_loop) +{ + uint32_t i; + + for (i = 0; i < wait_loop; i++) + wait_dbcmd(); +} + /* DDRPHY register access (raw) */ static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd) { @@ -866,6 +874,7 @@ struct _jedec_spec1 { uint8_t WL; uint8_t nwr; uint8_t nrtp; + uint8_t odtlon; uint8_t MR1; uint8_t MR2; }; @@ -877,21 +886,21 @@ struct _jedec_spec1 { #define JS1_MR2(f) (0x00 | ((f) << 3) | (f)) const struct _jedec_spec1 js1[JS1_FREQ_TBL_NUM] = { /* 533.333Mbps */ - { 800, 6, 6, 4, 6, 8, JS1_MR1(0), JS1_MR2(0) | 0x40 }, + { 800, 6, 6, 4, 6, 8, 0, JS1_MR1(0), JS1_MR2(0) | 0x40 }, /* 1066.666Mbps */ - { 1600, 10, 12, 8, 10, 8, JS1_MR1(1), JS1_MR2(1) | 0x40 }, + { 1600, 10, 12, 8, 10, 8, 0, JS1_MR1(1), JS1_MR2(1) | 0x40 }, /* 1600.000Mbps */ - { 2400, 14, 16, 12, 16, 8, JS1_MR1(2), JS1_MR2(2) | 0x40 }, + { 2400, 14, 16, 12, 16, 8, 6, JS1_MR1(2), JS1_MR2(2) | 0x40 }, /* 2133.333Mbps */ - { 3200, 20, 22, 10, 20, 8, JS1_MR1(3), JS1_MR2(3) }, + { 3200, 20, 22, 10, 20, 8, 4, JS1_MR1(3), JS1_MR2(3) }, /* 2666.666Mbps */ - { 4000, 24, 28, 12, 24, 10, JS1_MR1(4), JS1_MR2(4) }, + { 4000, 24, 28, 12, 24, 10, 4, JS1_MR1(4), JS1_MR2(4) }, /* 3200.000Mbps */ - { 4800, 28, 32, 14, 30, 12, JS1_MR1(5), JS1_MR2(5) }, + { 4800, 28, 32, 14, 30, 12, 6, JS1_MR1(5), JS1_MR2(5) }, /* 3733.333Mbps */ - { 5600, 32, 36, 16, 34, 14, JS1_MR1(6), JS1_MR2(6) }, + { 5600, 32, 36, 16, 34, 14, 6, JS1_MR1(6), JS1_MR2(6) }, /* 4266.666Mbps */ - { 6400, 36, 40, 18, 40, 16, JS1_MR1(7), JS1_MR2(7) } + { 6400, 36, 40, 18, 40, 16, 8, JS1_MR1(7), JS1_MR2(7) } }; struct _jedec_spec2 { @@ -921,7 +930,8 @@ struct _jedec_spec2 { #define js2_tzqcalns 19 #define js2_tzqlat 20 #define js2_tiedly 21 -#define JS2_TBLCNT 22 +#define js2_tODTon_min 22 +#define JS2_TBLCNT 23 #define js2_trcpb (JS2_TBLCNT) #define js2_trcab (JS2_TBLCNT + 1) @@ -954,7 +964,8 @@ const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = { /*tMRD*/ {14000, 10}, /*tZQCALns*/ {1000 * 10, 0}, /*tZQLAT*/ {30000, 10}, -/*tIEdly*/ {12500, 0} +/*tIEdly*/ {12500, 0}, +/*tODTon_min*/ {1500, 0} }, { /*tSR */ {15000, 3}, /*tXP */ {7500, 3}, @@ -977,7 +988,8 @@ const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = { /*tMRD*/ {14000, 10}, /*tZQCALns*/ {1000 * 10, 0}, /*tZQLAT*/ {30000, 10}, -/*tIEdly*/ {12500, 0} +/*tIEdly*/ {12500, 0}, +/*tODTon_min*/ {1500, 0} } }; @@ -1452,7 +1464,7 @@ static void ddrtbl_load(void) if ((prr_product == PRR_PRODUCT_M3N) || (prr_product == PRR_PRODUCT_V3H)) { ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, - _reg_PHY_RDDATA_EN_OE_DLY, dataS); + _reg_PHY_RDDATA_EN_OE_DLY, dataS - 2); } ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1, RL - dataS); @@ -1498,9 +1510,10 @@ static void ddrtbl_load(void) /* DDRPHY INT START */ if ((prr_product == PRR_PRODUCT_H3) && (prr_cut <= PRR_PRODUCT_11)) { - /* non */ + /* non */ } else { regif_pll_wa(); + dbwait_loop(5); } /* FREQ_SEL_MULTICAST & PER_CS_TRAINING_MULTICAST SET (for safety) */ @@ -2067,12 +2080,18 @@ static void dbsc_regset(void) /* DBTR9.TRDPR : tRTP */ mmio_write_32(DBSC_DBTR(9), js2[js2_trtp]); - /* DBTR10.TWR : nwr */ + /* DBTR10.TWR : nWR */ mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr); - /* DBTR11.TRDWR : RL + tDQSCK + BL/2 + Rounddown(tRPST) - WL + tWPRE */ + /* + * DBTR11.TRDWR : RL + BL / 2 + Rounddown(tRPST) + PHY_ODTLoff - + * odtlon + tDQSCK - tODTon,min + + * PCB delay (out+in) + tPHY_ODToff + */ mmio_write_32(DBSC_DBTR(11), - RL + js2[js2_tdqsck] + (16 / 2) + 1 - WL + 2 + 2); + RL + (16 / 2) + 1 + 2 - js1[js1_ind].odtlon + + js2[js2_tdqsck] - js2[js2_tODTon_min] + + _f_scale(ddr_mbps, ddr_mbpsdiv, 1300, 0)); /* DBTR12.TWRRD : WL + 1 + BL/2 + tWTR */ data_l = WL + 1 + (16 / 2) + js2[js2_twtr]; @@ -2338,10 +2357,23 @@ static void dbsc_regset_post(void) } } if ((prr_product == PRR_PRODUCT_H3) && (prr_cut > PRR_PRODUCT_11)) { +#if RCAR_DRAM_SPLIT == 2 + if (board_cnf->phyvalid == 0x05) { + mmio_write_32(DBSC_DBTR(24), + (rdlat_max << 24) + (rdlat_min << 16) + + mmio_read_32(DBSC_DBTR(24))); + } else { + mmio_write_32(DBSC_DBTR(24), + ((rdlat_max * 2 - rdlat_min + 4) << 24) + + ((rdlat_min + 2) << 16) + + mmio_read_32(DBSC_DBTR(24))); + } +#else /*RCAR_DRAM_SPLIT == 2 */ mmio_write_32(DBSC_DBTR(24), ((rdlat_max * 2 - rdlat_min + 4) << 24) + ((rdlat_min + 2) << 16) + mmio_read_32(DBSC_DBTR(24))); +#endif /*RCAR_DRAM_SPLIT == 2 */ } else { mmio_write_32(DBSC_DBTR(24), ((rdlat_max + 2) << 24) + @@ -2383,37 +2415,6 @@ static void dbsc_regset_post(void) mmio_write_32(DBSC_DBRFCNF1, 0x00080000 | (data_l & 0x0000ffff)); mmio_write_32(DBSC_DBRFCNF2, 0x00010000 | DBSC_REFINTS); -#ifdef DDR_BACKUPMODE - if (ddr_backup == DRAM_BOOT_STATUS_WARM) { -#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0,1 only) */ - DEBUG(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1); - send_dbcmd(0x08040001); - wait_dbcmd(); - send_dbcmd(0x0A040001); - wait_dbcmd(); - send_dbcmd(0x04040010); - wait_dbcmd(); - - if (prr_product == PRR_PRODUCT_H3) { - send_dbcmd(0x08140001); - wait_dbcmd(); - send_dbcmd(0x0A140001); - wait_dbcmd(); - send_dbcmd(0x04140010); - wait_dbcmd(); - } -#else /* DDR_BACKUPMODE_HALF //for All channels */ - send_dbcmd(0x08840001); - wait_dbcmd(); - send_dbcmd(0x0A840001); - wait_dbcmd(); - - send_dbcmd(0x04840010); - wait_dbcmd(); -#endif /* DDR_BACKUPMODE_HALF */ - } -#endif /* DDR_BACKUPMODE */ - #if RCAR_REWT_TRAINING != 0 /* Periodic-WriteDQ Training seeting */ if (((prr_product == PRR_PRODUCT_H3) && @@ -2422,12 +2423,7 @@ static void dbsc_regset_post(void) (prr_cut == PRR_PRODUCT_10))) { /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */ } else { - /* - * H3 Ver.2.0 or later/M3-W Ver.1.1 or - * later/M3-N/V3H -> Periodic-WriteDQ Training seeting - */ - - /* Periodic WriteDQ Training seeting */ + /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H */ mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000); ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04); @@ -2440,7 +2436,6 @@ static void dbsc_regset_post(void) _reg_PI_WDQLVL_CS_MAP)); ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1f); ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00); - ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100); ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01); ddr_setval_ach(_reg_PI_TREF_F0, 0x0000); ddr_setval_ach(_reg_PI_TREF_F1, 0x0000); @@ -2458,8 +2453,10 @@ static void dbsc_regset_post(void) mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011); } #endif /* RCAR_REWT_TRAINING */ - /* periodic dram zqcal and phy ctrl update enable */ + /* periodic dram zqcal enable */ mmio_write_32(DBSC_DBCALCNF, 0x01000010); + + /* periodic phy ctrl update enable */ if (((prr_product == PRR_PRODUCT_H3) && (prr_cut <= PRR_PRODUCT_11)) || ((prr_product == PRR_PRODUCT_M3) && @@ -2477,7 +2474,36 @@ static void dbsc_regset_post(void) #endif /* RCAR_DRAM_SPLIT == 2 */ } +#ifdef DDR_BACKUPMODE + /* SRX */ + if (ddr_backup == DRAM_BOOT_STATUS_WARM) { +#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0, 1 only) */ + NOTICE("BL2: [DEBUG_MESS] DDR_BACKUPMODE_HALF\n"); + send_dbcmd(0x0A040001); + if (Prr_Product == PRR_PRODUCT_H3) + send_dbcmd(0x0A140001); +#else /* DDR_BACKUPMODE_HALF */ /* for All channels */ + send_dbcmd(0x0A840001); +#endif /* DDR_BACKUPMODE_HALF */ + } +#endif /* DDR_BACKUPMODE */ + + /* set Auto Refresh */ mmio_write_32(DBSC_DBRFEN, 0x00000001); + +#if RCAR_REWT_TRAINING != 0 + /* Periodic WriteDQ Traning */ + if (((prr_product == PRR_PRODUCT_H3) && + (prr_cut <= PRR_PRODUCT_11)) || + ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10))) { + /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */ + } else { + /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H */ + ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100); + } +#endif /* RCAR_REWT_TRAINING */ + /* dram access enable */ mmio_write_32(DBSC_DBACEN, 0x00000001); @@ -3026,6 +3052,9 @@ static uint32_t init_ddr(void) return INITDRAM_ERR_O; MSG_LF(__func__ ":5\n"); + /* Dummy PDE */ + send_dbcmd(0x08840000); + /* PDX */ send_dbcmd(0x08840001); @@ -3477,10 +3506,13 @@ static uint32_t wdqdm_man(void) { uint32_t err, retry_cnt; const uint32_t retry_max = 0x10; - uint32_t ch, ddr_csn, mr14_bkup[4][4]; + uint32_t datal, ch, ddr_csn, mr14_bkup[4][4]; + + datal = RL + js2[js2_tdqsck] + (16 / 2) + 1 - WL + 2 + 2 + 19; + if ((mmio_read_32(DBSC_DBTR(11)) & 0xFF) > datal) + datal = mmio_read_32(DBSC_DBTR(11)) & 0xFF; + ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, datal); - ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, - (mmio_read_32(DBSC_DBTR(11)) & 0xFF) + 19); if (((prr_product == PRR_PRODUCT_H3) && (prr_cut > PRR_PRODUCT_11)) || (prr_product == PRR_PRODUCT_M3N) || (prr_product == PRR_PRODUCT_V3H)) { diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c index f8caade27..de126de86 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -1571,8 +1571,13 @@ void boardcnf_get_ddr_mbps(uint32_t brd, uint32_t *mbps, uint32_t *div) { uint32_t md; - md = (mmio_read_32(RST_MODEMR) >> 17) & 0x5; - md = (md | (md >> 1)) & 0x3; + if (prr_product == PRR_PRODUCT_V3H) { + md = (mmio_read_32(RST_MODEMR) >> 19) & 0x1; + md = (md | (md << 1)) & 0x3; /* 0 or 3 */ + } else { + md = (mmio_read_32(RST_MODEMR) >> 17) & 0x5; + md = (md | (md >> 1)) & 0x3; + } switch (md) { case 0x0: *mbps = 3200; @@ -1722,8 +1727,13 @@ static uint32_t _board_judge(void) #endif } } else if (prr_product == PRR_PRODUCT_M3) { - /* RENESAS Starter Kit(M3-W/SIP 8Gbit 1rank) board */ - brd = 3; + if (prr_cut >= PRR_PRODUCT_30) { + /* RENESAS Starter Kit (M3-W Ver.3.0/SIP) */ + brd = 18; + } else { + /* RENESAS Starter Kit(M3-W/SIP 8Gbit 1rank) board */ + brd = 3; + } } else { /* RENESAS Starter Kit(M3-N/SIP) board */ brd = 11; diff --git a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h index 5047e5cc2..56363eb99 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h +++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#define RCAR_DDR_VERSION "rev.0.37" +#define RCAR_DDR_VERSION "rev.0.40" #define DRAM_CH_CNT 0x04 #define SLICE_CNT 0x04 #define CS_CNT 0x02 @@ -22,7 +22,7 @@ /* for ddr deisity setting */ #define DBMEMCONF_REG(d3, row, bank, col, dw) \ - ((d3) << 30 | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw)) + (((d3) << 30) | ((row) << 24) | ((bank) << 16) | ((col) << 8) | (dw)) #define DBMEMCONF_REGD(density) \ (DBMEMCONF_REG((density) % 2, ((density) + 1) / \ diff --git a/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h index 8d80842fd..fb3032dee 100644 --- a/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h +++ b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -116,7 +116,7 @@ static const uint32_t DDR_PHY_SLICE_REGSET_M3N[DDR_PHY_SLICE_REGSET_NUM_M3N] = { /*0859*/ 0x00000200, /*085a*/ 0x00000004, /*085b*/ 0x4041a151, - /*085c*/ 0x0141c0a0, + /*085c*/ 0x0141a0a0, /*085d*/ 0x0000c0c0, /*085e*/ 0x0e0c000e, /*085f*/ 0x10001000, diff --git a/drivers/renesas/rcar/emmc/emmc_config.h b/drivers/renesas/rcar/emmc/emmc_config.h deleted file mode 100644 index 686ccb99c..000000000 --- a/drivers/renesas/rcar/emmc/emmc_config.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file emmc_config.h - * @brief Configuration file - * - */ - -#ifndef EMMC_CONFIG_H -#define EMMC_CONFIG_H - -/* ************************ HEADER (INCLUDE) SECTION *********************** */ - -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ - -/** @brief MMC driver config - */ -#define EMMC_RCA 1UL /* RCA */ -#define EMMC_RW_DATA_TIMEOUT 0x40UL /* 314ms (freq = 400KHz, timeout Counter = 0x04(SDCLK * 2^17) */ -#define EMMC_RETRY_COUNT 0 /* how many times to try after fail. Don't change. */ -#define EMMC_CMD_MAX 60UL /* Don't change. */ - -/** @brief etc - */ -#define LOADIMAGE_FLAGS_DMA_ENABLE 0x00000001UL - -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ - -/* ********************************* CODE ********************************** */ - -#endif /* EMMC_CONFIG_H */ -/* ******************************** END ************************************ */ diff --git a/drivers/renesas/rcar/emmc/emmc_hal.h b/drivers/renesas/rcar/emmc/emmc_hal.h deleted file mode 100644 index f0b7e9d77..000000000 --- a/drivers/renesas/rcar/emmc/emmc_hal.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file emmc_hal.h - * @brief emmc boot driver is expecting this header file - * - */ - -#ifndef EMMC_HAL_H -#define EMMC_HAL_H -/* ************************ HEADER (INCLUDE) SECTION *********************** */ -#include <stdint.h> -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ - -/** @brief 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 - -/** @brief Memory card response types - */ -#define HAL_MEMCARD_COMMAND_INDEX_MASK 0x0003f - -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/** @brief 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, /**< A non-masked error bit was set in the card status */ - 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; - -/** @brief memory access operation - */ -typedef enum { - HAL_MEMCARD_READ = 0U, /**< read */ - HAL_MEMCARD_WRITE = 1U /**< write */ -} HAL_MEMCARD_OPERATION; - -/** @brief 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 */ - -/** @brief 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 */ - -/** @brief mode of data transfer - */ -typedef enum { - HAL_MEMCARD_DMA = 0U, - HAL_MEMCARD_NOT_DMA = 1U -} HAL_MEMCARD_DATA_TRANSFER_MODE; - -/** @brief 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; - -/** @brief 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; - -/** @brief 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; - -/** @brief 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; - -/** @brief Memory card command codes. - */ -typedef enum { -/* class 0 and class 1 */ - CMD0_GO_IDLE_STATE = 0 | HAL_MEMCARD_RESPONSE_NONE | HAL_MEMCARD_COMMAND_TYPE_BC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD0 */ - CMD1_SEND_OP_COND = 1 | HAL_MEMCARD_RESPONSE_R3 | HAL_MEMCARD_COMMAND_TYPE_BCR | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD1 */ - CMD2_ALL_SEND_CID_MMC = 2 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_BCR | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD2 */ - CMD2_ALL_SEND_CID_SD = - 2 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_BCR | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, - CMD3_SET_RELATIVE_ADDR = 3 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD3 */ - CMD3_SEND_RELATIVE_ADDR = - 3 | HAL_MEMCARD_RESPONSE_R6 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, - CMD4_SET_DSR = 4 | HAL_MEMCARD_RESPONSE_NONE | HAL_MEMCARD_COMMAND_TYPE_BC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD4 */ - CMD5_SLEEP_AWAKE = 5 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD5 */ - CMD6_SWITCH = 6 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD6 */ - CMD6_SWITCH_FUNC = - 6 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, - ACMD6_SET_BUS_WIDTH = - 6 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD7_SELECT_CARD = 7 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD7 */ - CMD7_SELECT_CARD_PROG = 7 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD7(from Disconnected State to Programming State) */ - CMD7_DESELECT_CARD = - 7 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, - CMD8_SEND_EXT_CSD = 8 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD8 */ - CMD8_SEND_IF_COND = - 8 | HAL_MEMCARD_RESPONSE_R7 | HAL_MEMCARD_COMMAND_TYPE_BCR | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, - CMD9_SEND_CSD = 9 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD9 */ - CMD10_SEND_CID = 10 | HAL_MEMCARD_RESPONSE_R2 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD10 */ - CMD11_READ_DAT_UNTIL_STOP = 11 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, /* CMD11 */ - CMD12_STOP_TRANSMISSION = 12 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD12 */ - CMD12_STOP_TRANSMISSION_WRITE = 12 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD12(R1b : write case) */ - CMD13_SEND_STATUS = 13 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD13 */ - ACMD13_SD_STATUS = - 13 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD14_BUSTEST_R = 14 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD14 */ - CMD15_GO_INACTIVE_STATE = 15 | HAL_MEMCARD_RESPONSE_NONE | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD15 */ - -/* class 2 */ - CMD16_SET_BLOCKLEN = 16 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD16 */ - CMD17_READ_SINGLE_BLOCK = 17 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD17 */ - CMD18_READ_MULTIPLE_BLOCK = 18 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD18 */ - CMD19_BUS_TEST_W = 19 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD19 */ - -/* class 3 */ - CMD20_WRITE_DAT_UNTIL_STOP = 20 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD20 */ - CMD21 = 21, /* CMD21 */ - CMD22 = 22, /* CMD22 */ - ACMD22_SEND_NUM_WR_BLOCKS = - 22 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - -/* class 4 */ - CMD23_SET_BLOCK_COUNT = 23 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD23 */ - ACMD23_SET_WR_BLK_ERASE_COUNT = - 23 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD24_WRITE_BLOCK = 24 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD24 */ - CMD25_WRITE_MULTIPLE_BLOCK = 25 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD25 */ - CMD26_PROGRAM_CID = 26 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD26 */ - CMD27_PROGRAM_CSD = 27 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD27 */ - -/* class 6 */ - CMD28_SET_WRITE_PROT = 28 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD28 */ - CMD29_CLR_WRITE_PROT = 29 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD29 */ - CMD30_SEND_WRITE_PROT = 30 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD30 */ - CMD30_SEND_WRITE_PROT_TYPE = 31 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD31 */ - -/* class 5 */ - CMD32_ERASE_WR_BLK_START = 32 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, /* CMD32 */ - CMD33_ERASE_WR_BLK_END = 33 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_NORMAL, /* CMD33 */ - CMD34 = 34, /* CMD34 */ - CMD35_ERASE_GROUP_START = 35 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD35 */ - CMD36_ERASE_GROUP_END = 36 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD36 */ - CMD37 = 37, /* CMD37 */ - CMD38_ERASE = 38 | HAL_MEMCARD_RESPONSE_R1b | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD38 */ - -/* class 9 */ - CMD39_FASTIO = 39 | HAL_MEMCARD_RESPONSE_R4 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD39 */ - CMD40_GO_IRQSTATE = 40 | HAL_MEMCARD_RESPONSE_R5 | HAL_MEMCARD_COMMAND_TYPE_BCR | HAL_MEMCARD_COMMAND_CARD_TYPE_MMC | HAL_MEMCARD_COMMAND_NORMAL, /* CMD40 */ - CMD41 = 41, /* CMD41 */ - ACMD41_SD_SEND_OP_COND = - 41 | HAL_MEMCARD_RESPONSE_R3 | HAL_MEMCARD_COMMAND_TYPE_BCR | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - -/* class 7 */ - CMD42_LOCK_UNLOCK = 42 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD42 */ - ACMD42_SET_CLR_CARD_DETECT = - 42 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD43 = 43, /* CMD43 */ - CMD44 = 44, /* CMD44 */ - CMD45 = 45, /* CMD45 */ - CMD46 = 46, /* CMD46 */ - CMD47 = 47, /* CMD47 */ - CMD48 = 48, /* CMD48 */ - CMD49 = 49, /* CMD49 */ - CMD50 = 50, /* CMD50 */ - CMD51 = 51, /* CMD51 */ - ACMD51_SEND_SCR = - 51 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_READ | - HAL_MEMCARD_COMMAND_CARD_TYPE_SD | HAL_MEMCARD_COMMAND_APP, - CMD52 = 52, /* CMD52 */ - CMD53 = 53, /* CMD53 */ - CMD54 = 54, /* CMD54 */ - -/* class 8 */ - CMD55_APP_CMD = 55 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_AC | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD55 */ - CMD56_GEN_CMD = 56 | HAL_MEMCARD_RESPONSE_R1 | HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE | HAL_MEMCARD_COMMAND_CARD_TYPE_COMMON | HAL_MEMCARD_COMMAND_NORMAL, /* CMD56 */ - CMD57 = 57, /* CMD57 */ - CMD58 = 58, /* CMD58 */ - CMD59 = 59, /* CMD59 */ - CMD60 = 60, /* CMD60 */ - CMD61 = 61, /* CMD61 */ - CMD62 = 62, /* CMD62 */ - CMD63 = 63 /* CMD63 */ -} HAL_MEMCARD_COMMAND; - -/** @brief 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 - * - * @note 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 implemention year. (2000 = 0, 2001 = 1, ...)<br> - * bits [7:0] API implemention week.<br> - * Example: API specification 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; - -/** @brief 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; - -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ - -/* ********************************* CODE ********************************** */ - -#endif /* EMMC_HAL_H */ - -/* ******************************** END ************************************ */ diff --git a/drivers/renesas/rcar/emmc/emmc_registers.h b/drivers/renesas/rcar/emmc/emmc_registers.h deleted file mode 100644 index 55ff33d8c..000000000 --- a/drivers/renesas/rcar/emmc/emmc_registers.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file emmc_registers.h - * @brief emmc boot driver is expecting this header file. HS-MMC module header file. - * - */ - -#ifndef EMMC_REGISTERS_H -#define EMMC_REGISTERS_H - -/* ************************ HEADER (INCLUDE) SECTION *********************** */ - -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ - -/* MMC channel select */ -#define MMC_CH0 (0U) /* SDHI2/MMC0 */ -#define MMC_CH1 (1U) /* SDHI3/MMC1 */ - -#if RCAR_LSI == RCAR_E3 -#define USE_MMC_CH (MMC_CH1) /* R-Car E3 */ -#else /* RCAR_LSI == RCAR_E3 */ -#define USE_MMC_CH (MMC_CH0) /* R-Car H3/M3/M3N */ -#endif /* RCAR_LSI == RCAR_E3 */ - -#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) - -/** @brief Clock Pulse Generator (CPG) registers - */ -#define CPG_BASE (0xE6150000U) - -#define CPG_MSTPSR3 (CPG_BASE+0x0048U) /* Module stop status register 3 */ - -#define CPG_SMSTPCR3 (CPG_BASE+0x013CU) /* System module stop control register 3 */ - -#define CPG_SD2CKCR (CPG_BASE+0x0268U) /* SDHI2 clock frequency control register */ -#define CPG_SD3CKCR (CPG_BASE+0x026CU) /* SDHI3 clock frequency control register */ - -#define CPG_CPGWPR (CPG_BASE+0x0900U) /* CPG Write Protect Register */ - -#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) - -/** brief 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) - -/** @brief 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 */ - -/** @brief 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 The write value should always be 1. HWM_0003 */ - -/** @brief SOFT_RST - */ -#define SOFT_RST_SDRST 0x00000001UL - -/** @brief 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 - -/** @brief SD_OPTION - */ -#define SD_OPTION_TIMEOUT_CNT_MASK 0x000000F0UL - -/** @brief 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 High speed mode 26Mhz */ -#define MMC_52MHZ 4UL /* 200MHz * 1/4 = 50 MHz High speed 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 - -/** @brief 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 */ - -/** @brief 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 - -/** @brief 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. */ - -/** @brief 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 - -/** @brief DM_DTRAN_ADDR - */ -#define DM_DTRAN_ADDR_WRITE_MASK 0xFFFFFFF8UL - -/** @brief DM_CM_DTRAN_CTRL - */ -#define DM_CM_DTRAN_CTRL_START 0x00000001UL - -/** @brief 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 */ - -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ - -/* ********************************* CODE ********************************** */ - -#endif /* EMMC_REGISTERS_H */ -/* ******************************** END ************************************ */ diff --git a/drivers/renesas/rcar/emmc/emmc_std.h b/drivers/renesas/rcar/emmc/emmc_std.h deleted file mode 100644 index 99cb6b992..000000000 --- a/drivers/renesas/rcar/emmc/emmc_std.h +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file emmc_std.h - * @brief eMMC boot is expecting this header file - * - */ - -#ifndef EMMC_STD_H -#define EMMC_STD_H - -#include "emmc_hal.h" - -/* ************************ HEADER (INCLUDE) SECTION *********************** */ - -/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */ -#ifndef FALSE -#define FALSE 0U -#endif -#ifndef TRUE -#define TRUE 1U -#endif - -/** @brief 64bit registers - **/ -#define SETR_64(r, v) (*(volatile uint64_t *)(r) = (v)) -#define GETR_64(r) (*(volatile uint64_t *)(r)) - -/** @brief 32bit registers - **/ -#define SETR_32(r, v) (*(volatile uint32_t *)(r) = (v)) -#define GETR_32(r) (*(volatile uint32_t *)(r)) - -/** @brief 16bit registers - */ -#define SETR_16(r, v) (*(volatile uint16_t *)(r) = (v)) -#define GETR_16(r) (*(volatile uint16_t *)(r)) - -/** @brief 8bit registers - */ -#define SETR_8(r, v) (*(volatile uint8_t *)(r) = (v)) -#define GETR_8(r) (*(volatile uint8_t *)(r)) - -/** @brief 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)) - -/** @brief 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)) - -/** @brief for 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 */ - -/** @brief 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 */ - -/** @brief 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. Non-masked error bit was set in the card status */ - 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; - -/** @brief 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 -/** @brief Response - */ -/** R1 */ -#define EMMC_R1_ERROR_MASK 0xFDBFE080U /* Type 'E' bit and bit14(must be 0). ignore bit22 */ -#define EMMC_R1_ERROR_MASK_WITHOUT_CRC (0xFD3FE080U) /* Ignore bit23 (Not check CRC error) */ -#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 */ -#define EMMC_SWITCH_PARTITION_CONFIG 0x03B30000UL /**< Partition config = 0x00 */ - -#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 - -/** @brief for TAAC mask - */ -#define TAAC_TIME_UNIT_MASK (0x07) -#define TAAC_MULTIPLIER_FACTOR_MASK (0x0F) - -/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */ - -/** @brief 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; - -/** @brief 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; - -/** @brief eMMC boot driver error information - */ -typedef struct { - uint16_t num; /**< error no */ - uint16_t code; /**< error code */ - volatile uint32_t info1; /**< SD_INFO1 register value. (hardware dependence) */ - volatile uint32_t info2; /**< SD_INFO2 register value. (hardware dependence) */ - volatile uint32_t status1;/**< SD_ERR_STS1 register value. (hardware dependence) */ - volatile uint32_t status2;/**< SD_ERR_STS2 register value. (hardware dependence) */ - volatile uint32_t dm_info1;/**< DM_CM_INFO1 register value. (hardware dependence) */ - volatile uint32_t dm_info2;/**< DM_CM_INFO2 register value. (hardware dependence) */ -} st_error_info; - -/** @brief Command information - */ -typedef struct { - HAL_MEMCARD_COMMAND cmd; /**< Command information */ - uint32_t arg; /**< argument */ - HAL_MEMCARD_OPERATION dir; /**< direction */ - uint32_t hw; /**< H/W dependence. SD_CMD register value. */ -} st_command_info; - -/** @brief 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 */ - uint32_t max_freq; /**< Max frequency (Card Spec)[Hz]. It changes dynamically by CSD and EXT_CSD. */ - uint32_t request_freq; /**< request freq [Hz] (400K, 26MHz, 52MHz, etc) */ - uint32_t current_freq; /**< current MMC clock[Hz] (the closest frequency supported by HW) */ - - /* state flag */ - HAL_MEMCARD_PRESENCE_STATUS card_present; - /**< presence status of the memory card */ - uint32_t card_power_enable; /**< True : Power ON */ - uint32_t clock_enable; /**< True : Clock ON */ - uint32_t initialize; /**< True : initialize complete. */ - uint32_t access_mode; /**< True : sector access, FALSE : byte access */ - uint32_t mount; /**< True : mount complete. */ - uint32_t selected; /**< True : selected card. */ - HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode; - /**< 0: DMA, 1:PIO */ - uint32_t image_num; /**< loaded ISSW image No. ISSW have copy image. */ - EMMC_R1_STATE current_state; /**< card state */ - volatile uint32_t during_cmd_processing; /**< True : during command processing */ - volatile uint32_t during_transfer; /**< True : during transfer */ - volatile uint32_t during_dma_transfer; /**< True : during transfer (DMA)*/ - volatile uint32_t dma_error_flag; /**< True : occurred DMAC error */ - volatile uint32_t force_terminate; /**< force terminate flag */ - volatile uint32_t state_machine_blocking; /**< state machine blocking flag : True or False */ - volatile uint32_t get_partition_access_flag; - /**< True : get partition access processing */ - - EMMC_PARTITION_ID boot_partition_en; /**< Boot partition */ - EMMC_PARTITION_ID partition_access; /**< Current access partition */ - - /* timeout */ - uint32_t hs_timing; /**< high speed */ - - /* timeout */ - uint32_t data_timeout; /**< read and write data timeout.*/ - - /* retry */ - uint32_t retries_after_fail; /**< how many times to try after fail, for instance sending command */ - - /* 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; /**< pointer to buffer 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 */ - - uint32_t low_clock_mode_enable; - /**< True : clock mode is low. (MMC clock = Max26MHz) */ - 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); - -/* ********************** DECLARATION OF EXTERNAL DATA ********************* */ - -/* ************************** FUNCTION PROTOTYPES ************************** */ -uint32_t emmc_get_csd_time(void); - -#define MMC_DEBUG -/* ********************************* CODE ********************************** */ - -/* ******************************** END ************************************ */ -#endif /* EMMC_STD_H */ diff --git a/drivers/renesas/rzg/board/board.c b/drivers/renesas/rzg/board/board.c new file mode 100644 index 000000000..cfbb04719 --- /dev/null +++ b/drivers/renesas/rzg/board/board.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <lib/mmio.h> +#include <lib/utils_def.h> + +#include "board.h" +#include "rcar_def.h" + +#ifndef BOARD_DEFAULT +#define BOARD_DEFAULT (BOARD_HIHOPE_RZ_G2M << BOARD_CODE_SHIFT) +#endif /* BOARD_DEFAULT */ + +#define BOARD_CODE_MASK (0xF8U) +#define BOARD_REV_MASK (0x07U) +#define BOARD_CODE_SHIFT (0x03) +#define BOARD_ID_UNKNOWN (0xFFU) + +#define GPIO_INDT5 0xE605500C +#define GP5_19_BIT (0x01U << 19) +#define GP5_21_BIT (0x01U << 21) +#define GP5_25_BIT (0x01U << 25) + +#define HM_ID { 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU } + +const char *g_board_tbl[] = { + [BOARD_HIHOPE_RZ_G2M] = "HiHope RZ/G2M", + [BOARD_UNKNOWN] = "unknown" +}; + +void rzg_get_board_type(uint32_t *type, uint32_t *rev) +{ + static uint8_t board_id = BOARD_ID_UNKNOWN; + const uint8_t board_tbl[][8] = { + [BOARD_HIHOPE_RZ_G2M] = HM_ID, + }; + uint32_t reg, boardInfo; + + if (board_id == BOARD_ID_UNKNOWN) { + board_id = BOARD_DEFAULT; + } + + *type = ((uint32_t) board_id & BOARD_CODE_MASK) >> BOARD_CODE_SHIFT; + + if (*type >= ARRAY_SIZE(board_tbl)) { + /* no revision information, set Rev0.0. */ + *rev = 0; + } else { + reg = mmio_read_32(RCAR_PRR); + if ((reg & PRR_CUT_MASK) == RCAR_M3_CUT_VER11) { + *rev = board_tbl[*type][(uint8_t)(board_id & BOARD_REV_MASK)]; + } else { + boardInfo = mmio_read_32(GPIO_INDT5) & + (GP5_19_BIT | GP5_21_BIT); + *rev = (((boardInfo & GP5_19_BIT) >> 14) | + ((boardInfo & GP5_21_BIT) >> 17)) + 0x30U; + } + } +} diff --git a/drivers/renesas/rzg/board/board.h b/drivers/renesas/rzg/board/board.h new file mode 100644 index 000000000..c0c3d0cda --- /dev/null +++ b/drivers/renesas/rzg/board/board.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZ_G2_BOARD_H +#define RZ_G2_BOARD_H + +enum rzg2_board_id { + BOARD_HIHOPE_RZ_G2M = 0, + BOARD_UNKNOWN +}; + +#define BOARD_REV_UNKNOWN (0xFFU) + +extern const char *g_board_tbl[]; + +/************************************************************************ + * Revisions are expressed in 8 bits. + * The upper 4 bits are major version. + * The lower 4 bits are minor version. + ************************************************************************/ +#define GET_BOARD_MAJOR(a) ((uint32_t)(a) >> 0x4) +#define GET_BOARD_MINOR(a) ((uint32_t)(a) & 0xF) +#define GET_BOARD_NAME(a) (g_board_tbl[(a)]) + +void rzg_get_board_type(uint32_t *type, uint32_t *rev); + +#endif /* RZ_G2_BOARD_H */ diff --git a/drivers/renesas/rzg/ddr/boot_init_dram.h b/drivers/renesas/rzg/ddr/boot_init_dram.h new file mode 100644 index 000000000..294582fa7 --- /dev/null +++ b/drivers/renesas/rzg/ddr/boot_init_dram.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, 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 rzg_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 */ diff --git a/drivers/renesas/rzg/ddr/ddr.mk b/drivers/renesas/rzg/ddr/ddr.mk new file mode 100644 index 000000000..7558216e3 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr.mk @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk diff --git a/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c new file mode 100644 index 000000000..45259e3c5 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c @@ -0,0 +1,3700 @@ +/* + * Copyright (c) 2021, 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 "boot_init_dram.h" +#include "boot_init_dram_regdef.h" +#include "ddr_regdef.h" +#include "dram_sub_func.h" +#include "init_dram_tbl_g2m.h" +#include "micro_delay.h" +#include "rcar_def.h" + +/* load board configuration */ +#include "boot_init_dram_config.c" + +#define DDR_BACKUPMODE +#define FATAL_MSG(x) NOTICE(x) + +/* variables */ +#ifdef RCAR_DDR_FIXED_LSI_TYPE +#ifndef RCAR_AUTO +#define RCAR_AUTO 99U +#define RZ_G2M 100U + +#define RCAR_CUT_10 0U +#define RCAR_CUT_11 1U +#define RCAR_CUT_20 10U +#define RCAR_CUT_30 20U +#endif /* RCAR_AUTO */ +#ifndef RCAR_LSI +#define RCAR_LSI RCAR_AUTO +#endif + +#if (RCAR_LSI == RCAR_AUTO) +static uint32_t prr_product; +static uint32_t prr_cut; +#else /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) +static const uint32_t prr_product = PRR_PRODUCT_M3; +#endif /* RCAR_LSI == RZ_G2M */ + +#ifndef RCAR_LSI_CUT +static uint32_t prr_cut; +#else /* RCAR_LSI_CUT */ +#if (RCAR_LSI_CUT == RCAR_CUT_10) +static const uint32_t prr_cut = PRR_PRODUCT_10; +#elif(RCAR_LSI_CUT == RCAR_CUT_11) +static const uint32_t prr_cut = PRR_PRODUCT_11; +#elif(RCAR_LSI_CUT == RCAR_CUT_20) +static const uint32_t prr_cut = PRR_PRODUCT_20; +#elif(RCAR_LSI_CUT == RCAR_CUT_30) +static const uint32_t prr_cut = PRR_PRODUCT_30; +#endif /* RCAR_LSI_CUT == RCAR_CUT_10 */ +#endif /* RCAR_LSI_CUT */ +#endif /* RCAR_LSI == RCAR_AUTO */ +#else /* RCAR_DDR_FIXED_LSI_TYPE */ +static uint32_t prr_product; +static uint32_t prr_cut; +#endif /* RCAR_DDR_FIXED_LSI_TYPE */ + +static const uint32_t *p_ddr_regdef_tbl; +static uint32_t brd_clk; +static uint32_t brd_clkdiv; +static uint32_t brd_clkdiva; +static uint32_t ddr_mbps; +static uint32_t ddr_mbpsdiv; +static uint32_t ddr_tccd; +static uint32_t ddr_phycaslice; +static const struct _boardcnf *board_cnf; +static uint32_t ddr_phyvalid; +static uint32_t ddr_density[DRAM_CH_CNT][CS_CNT]; +static uint32_t ch_have_this_cs[CS_CNT] __aligned(64); +static uint32_t rdqdm_dly[DRAM_CH_CNT][CSAB_CNT][SLICE_CNT * 2U][9U]; +static uint32_t max_density; +static uint32_t ddr0800_mul; +static uint32_t ddr_mul; +static uint32_t DDR_PHY_SLICE_REGSET_OFS; +static uint32_t DDR_PHY_ADR_V_REGSET_OFS; +static uint32_t DDR_PHY_ADR_I_REGSET_OFS; +static uint32_t DDR_PHY_ADR_G_REGSET_OFS; +static uint32_t DDR_PI_REGSET_OFS; +static uint32_t DDR_PHY_SLICE_REGSET_SIZE; +static uint32_t DDR_PHY_ADR_V_REGSET_SIZE; +static uint32_t DDR_PHY_ADR_I_REGSET_SIZE; +static uint32_t DDR_PHY_ADR_G_REGSET_SIZE; +static uint32_t DDR_PI_REGSET_SIZE; +static uint32_t DDR_PHY_SLICE_REGSET_NUM; +static uint32_t DDR_PHY_ADR_V_REGSET_NUM; +static uint32_t DDR_PHY_ADR_I_REGSET_NUM; +static uint32_t DDR_PHY_ADR_G_REGSET_NUM; +static uint32_t DDR_PI_REGSET_NUM; +static uint32_t DDR_PHY_ADR_I_NUM; +#define DDR_PHY_REGSET_MAX 128 +#define DDR_PI_REGSET_MAX 320 +static uint32_t _cnf_DDR_PHY_SLICE_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PHY_ADR_V_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PHY_ADR_I_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PHY_ADR_G_REGSET[DDR_PHY_REGSET_MAX]; +static uint32_t _cnf_DDR_PI_REGSET[DDR_PI_REGSET_MAX]; +static uint32_t pll3_mode; +static uint32_t loop_max; +#ifdef DDR_BACKUPMODE +uint32_t ddr_backup = DRAM_BOOT_STATUS_COLD; +/* #define DDR_BACKUPMODE_HALF */ /* for Half channel(ch0,1 only) */ +#endif + +#ifdef DDR_QOS_INIT_SETTING /* only for non qos_init */ +#define OPERATING_FREQ (400U) /* Mhz */ +#define BASE_SUB_SLOT_NUM (0x6U) +#define SUB_SLOT_CYCLE (0x7EU) /* 126 */ +#define QOSWT_WTSET0_CYCLE \ + ((SUB_SLOT_CYCLE * BASE_SUB_SLOT_NUM * 1000U) / \ + OPERATING_FREQ) /* unit:ns */ + +uint32_t get_refperiod(void) +{ + return QOSWT_WTSET0_CYCLE; +} +#else /* DDR_QOS_INIT_SETTING */ +extern uint32_t get_refperiod(void); +#endif /* DDR_QOS_INIT_SETTING */ + +#define _reg_PHY_RX_CAL_X_NUM 11U +static const uint32_t _reg_PHY_RX_CAL_X[_reg_PHY_RX_CAL_X_NUM] = { + _reg_PHY_RX_CAL_DQ0, + _reg_PHY_RX_CAL_DQ1, + _reg_PHY_RX_CAL_DQ2, + _reg_PHY_RX_CAL_DQ3, + _reg_PHY_RX_CAL_DQ4, + _reg_PHY_RX_CAL_DQ5, + _reg_PHY_RX_CAL_DQ6, + _reg_PHY_RX_CAL_DQ7, + _reg_PHY_RX_CAL_DM, + _reg_PHY_RX_CAL_DQS, + _reg_PHY_RX_CAL_FDBK +}; + +#define _reg_PHY_CLK_WRX_SLAVE_DELAY_NUM 10U +static const uint32_t _reg_PHY_CLK_WRX_SLAVE_DELAY + [_reg_PHY_CLK_WRX_SLAVE_DELAY_NUM] = { + _reg_PHY_CLK_WRDQ0_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ1_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ2_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ3_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ4_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ5_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ6_SLAVE_DELAY, + _reg_PHY_CLK_WRDQ7_SLAVE_DELAY, + _reg_PHY_CLK_WRDM_SLAVE_DELAY, + _reg_PHY_CLK_WRDQS_SLAVE_DELAY +}; + +#define _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY_NUM 9U +static const uint32_t _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY + [_reg_PHY_RDDQS_X_FALL_SLAVE_DELAY_NUM] = { + _reg_PHY_RDDQS_DQ0_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ1_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ2_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ3_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ4_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ5_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ6_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ7_FALL_SLAVE_DELAY, + _reg_PHY_RDDQS_DM_FALL_SLAVE_DELAY +}; + +#define _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY_NUM 9U +static const uint32_t _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY + [_reg_PHY_RDDQS_X_RISE_SLAVE_DELAY_NUM] = { + _reg_PHY_RDDQS_DQ0_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ1_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ2_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ3_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ4_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ5_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ6_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DQ7_RISE_SLAVE_DELAY, + _reg_PHY_RDDQS_DM_RISE_SLAVE_DELAY +}; + +#define _reg_PHY_PAD_TERM_X_NUM 8U +static const uint32_t _reg_PHY_PAD_TERM_X[_reg_PHY_PAD_TERM_X_NUM] = { + _reg_PHY_PAD_FDBK_TERM, + _reg_PHY_PAD_DATA_TERM, + _reg_PHY_PAD_DQS_TERM, + _reg_PHY_PAD_ADDR_TERM, + _reg_PHY_PAD_CLK_TERM, + _reg_PHY_PAD_CKE_TERM, + _reg_PHY_PAD_RST_TERM, + _reg_PHY_PAD_CS_TERM +}; + +#define _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM 10U +static const uint32_t _reg_PHY_CLK_CACS_SLAVE_DELAY_X + [_reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM] = { + _reg_PHY_ADR0_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR1_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR2_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR3_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR4_CLK_WR_SLAVE_DELAY, + _reg_PHY_ADR5_CLK_WR_SLAVE_DELAY, + + _reg_PHY_GRP_SLAVE_DELAY_0, + _reg_PHY_GRP_SLAVE_DELAY_1, + _reg_PHY_GRP_SLAVE_DELAY_2, + _reg_PHY_GRP_SLAVE_DELAY_3 +}; + +/* Prototypes */ +static inline uint32_t vch_nxt(uint32_t pos); +static void cpg_write_32(uint32_t a, uint32_t v); +static void pll3_control(uint32_t high); +static inline void dsb_sev(void); +static void wait_dbcmd(void); +static void send_dbcmd(uint32_t cmd); +static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd); +static void reg_ddrphy_write(uint32_t phyno, uint32_t regadd, uint32_t regdata); +static void reg_ddrphy_write_a(uint32_t regadd, uint32_t regdata); +static inline uint32_t ddr_regdef(uint32_t _regdef); +static inline uint32_t ddr_regdef_adr(uint32_t _regdef); +static inline uint32_t ddr_regdef_lsb(uint32_t _regdef); +static void ddr_setval_s(uint32_t ch, uint32_t slice, uint32_t _regdef, + uint32_t val); +static uint32_t ddr_getval_s(uint32_t ch, uint32_t slice, uint32_t _regdef); +static void ddr_setval(uint32_t ch, uint32_t regdef, uint32_t val); +static void ddr_setval_ach_s(uint32_t slice, uint32_t regdef, uint32_t val); +static void ddr_setval_ach(uint32_t regdef, uint32_t val); +static void ddr_setval_ach_as(uint32_t regdef, uint32_t val); +static uint32_t ddr_getval(uint32_t ch, uint32_t regdef); +static uint32_t ddr_getval_ach(uint32_t regdef, uint32_t *p); +static uint32_t ddr_getval_ach_as(uint32_t regdef, uint32_t *p); +static void _tblcopy(uint32_t *to, const uint32_t *from, uint32_t size); +static void ddrtbl_setval(uint32_t *tbl, uint32_t _regdef, uint32_t val); +static uint32_t ddrtbl_getval(uint32_t *tbl, uint32_t _regdef); +static uint32_t ddrphy_regif_chk(void); +static inline void ddrphy_regif_idle(void); +static uint16_t _f_scale(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, uint32_t ps, + uint16_t cyc); +static void _f_scale_js2(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, + uint16_t *_js2); +static int16_t _f_scale_adj(int16_t ps); +static void ddrtbl_load(void); +static void ddr_config_sub(void); +static void ddr_config(void); +static void dbsc_regset(void); +static void dbsc_regset_post(void); +static uint32_t dfi_init_start(void); +static void change_lpddr4_en(uint32_t mode); +static uint32_t set_term_code(void); +static void ddr_register_set(void); +static inline uint32_t wait_freqchgreq(uint32_t assert); +static inline void set_freqchgack(uint32_t assert); +static inline void set_dfifrequency(uint32_t freq); +static uint32_t pll3_freq(uint32_t on); +static void update_dly(void); +static uint32_t pi_training_go(void); +static uint32_t init_ddr(void); +static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick); +static uint32_t wdqdm_man1(void); +static uint32_t wdqdm_man(void); +static uint32_t rdqdm_man1(void); +static uint32_t rdqdm_man(void); + +static int32_t _find_change(uint64_t val, uint32_t dir); +static uint32_t _rx_offset_cal_updn(uint32_t code); +static uint32_t rx_offset_cal(void); +static uint32_t rx_offset_cal_hw(void); +static void adjust_wpath_latency(void); + +struct ddrt_data { + int32_t init_temp; /* Initial Temperature (do) */ + uint32_t init_cal[4U]; /* Initial io-code (4 is for G2H) */ + uint32_t tcomp_cal[4U]; /* Temp. compensated io-code (4 is for G2H) */ +}; + +static struct ddrt_data tcal; + +static void pvtcode_update(void); +static void pvtcode_update2(void); +static void ddr_padcal_tcompensate_getinit(uint32_t override); + +#ifndef DDR_FAST_INIT +static uint32_t rdqdm_le[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U][9U]; +static uint32_t rdqdm_te[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U][9U]; +static uint32_t rdqdm_nw[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U][9U]; +static uint32_t rdqdm_win[DRAM_CH_CNT][CS_CNT][SLICE_CNT]; +static uint32_t rdqdm_st[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2U]; +static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn); +static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn); + +static uint32_t wdqdm_le[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9U]; +static uint32_t wdqdm_te[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9U]; +static uint32_t wdqdm_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9U]; +static uint32_t wdqdm_st[DRAM_CH_CNT][CS_CNT][SLICE_CNT]; +static uint32_t wdqdm_win[DRAM_CH_CNT][CS_CNT][SLICE_CNT]; +static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn); +static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn); +#endif/* DDR_FAST_INIT */ + +/* macro for channel selection loop */ +static inline uint32_t vch_nxt(uint32_t pos) +{ + uint32_t posn; + + for (posn = pos; posn < DRAM_CH_CNT; posn++) { + if ((ddr_phyvalid & (1U << posn)) != 0U) { + break; + } + } + return posn; +} + +#define foreach_vch(ch) \ +for (ch = vch_nxt(0U); ch < DRAM_CH_CNT; ch = vch_nxt(ch + 1U)) + +#define foreach_ech(ch) \ +for (ch = 0U; ch < DRAM_CH_CNT; ch++) + +/* Printing functions */ +#define MSG_LF(...) + +/* clock settings, reset control */ +static void cpg_write_32(uint32_t a, uint32_t v) +{ + mmio_write_32(CPG_CPGWPR, ~v); + mmio_write_32(a, v); +} + +static void wait_for_pll3_status_bit_turned_on(void) +{ + uint32_t data_l; + + do { + data_l = mmio_read_32(CPG_PLLECR); + } while ((data_l & CPG_PLLECR_PLL3ST_BIT) == 0); + dsb_sev(); +} + +static void pll3_control(uint32_t high) +{ + uint32_t data_l, data_div, data_mul, tmp_div; + + if (high != 0U) { + tmp_div = 3999U * brd_clkdiv * (brd_clkdiva + 1U) / + (brd_clk * ddr_mul) / 2U; + data_mul = ((ddr_mul * tmp_div) - 1U) << 24U; + pll3_mode = 1U; + loop_max = 2U; + } else { + tmp_div = 3999U * brd_clkdiv * (brd_clkdiva + 1U) / + (brd_clk * ddr0800_mul) / 2U; + data_mul = ((ddr0800_mul * tmp_div) - 1U) << 24U; + pll3_mode = 0U; + loop_max = 8U; + } + + switch (tmp_div) { + case 1: + data_div = 0U; + break; + case 2: + case 3: + case 4: + data_div = tmp_div; + break; + default: + data_div = 6U; + data_mul = (data_mul * tmp_div) / 3U; + break; + } + data_mul = data_mul | (brd_clkdiva << 7); + + /* PLL3 disable */ + data_l = mmio_read_32(CPG_PLLECR) & ~CPG_PLLECR_PLL3E_BIT; + cpg_write_32(CPG_PLLECR, data_l); + dsb_sev(); + + if (prr_product == PRR_PRODUCT_M3) { + /* PLL3 DIV resetting(Lowest value:3) */ + data_l = 0x00030003U | (0xFF80FF80U & mmio_read_32(CPG_FRQCRD)); + cpg_write_32(CPG_FRQCRD, data_l); + dsb_sev(); + + /* zb3 clk stop */ + data_l = CPG_ZB3CKCR_ZB3ST_BIT | mmio_read_32(CPG_ZB3CKCR); + cpg_write_32(CPG_ZB3CKCR, data_l); + dsb_sev(); + + /* PLL3 enable */ + data_l = CPG_PLLECR_PLL3E_BIT | mmio_read_32(CPG_PLLECR); + cpg_write_32(CPG_PLLECR, data_l); + dsb_sev(); + + wait_for_pll3_status_bit_turned_on(); + + /* PLL3 DIV resetting (Highest value:0) */ + data_l = (0xFF80FF80U & mmio_read_32(CPG_FRQCRD)); + cpg_write_32(CPG_FRQCRD, data_l); + dsb_sev(); + + /* DIV SET KICK */ + data_l = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB); + cpg_write_32(CPG_FRQCRB, data_l); + dsb_sev(); + + /* PLL3 multiplier set */ + cpg_write_32(CPG_PLL3CR, data_mul); + dsb_sev(); + + wait_for_pll3_status_bit_turned_on(); + + /* PLL3 DIV resetting(Target value) */ + data_l = (data_div << 16U) | data_div | + (mmio_read_32(CPG_FRQCRD) & 0xFF80FF80U); + cpg_write_32(CPG_FRQCRD, data_l); + dsb_sev(); + + /* DIV SET KICK */ + data_l = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB); + cpg_write_32(CPG_FRQCRB, data_l); + dsb_sev(); + + wait_for_pll3_status_bit_turned_on(); + + /* zb3 clk start */ + data_l = (~CPG_ZB3CKCR_ZB3ST_BIT) & mmio_read_32(CPG_ZB3CKCR); + cpg_write_32(CPG_ZB3CKCR, data_l); + dsb_sev(); + } +} + +/* barrier */ +static inline void dsb_sev(void) +{ + __asm__ __volatile__("dsb sy"); +} + +/* DDR memory register access */ +static void wait_dbcmd(void) +{ + uint32_t data_l; + /* dummy read */ + data_l = mmio_read_32(DBSC_DBCMD); + dsb_sev(); + while (true) { + /* wait DBCMD 1=busy, 0=ready */ + data_l = mmio_read_32(DBSC_DBWAIT); + dsb_sev(); + if ((data_l & 0x00000001U) == 0x00U) { + break; + } + } +} + +static void send_dbcmd(uint32_t cmd) +{ + /* dummy read */ + wait_dbcmd(); + mmio_write_32(DBSC_DBCMD, cmd); + dsb_sev(); +} + +static void dbwait_loop(uint32_t wait_loop) +{ + uint32_t i; + + for (i = 0U; i < wait_loop; i++) { + wait_dbcmd(); + } +} + +/* DDRPHY register access (raw) */ +static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd) +{ + uint32_t val; + uint32_t loop; + + val = 0U; + mmio_write_32(DBSC_DBPDRGA(phyno), regadd); + dsb_sev(); + + while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) { + dsb_sev(); + } + dsb_sev(); + + for (loop = 0U; loop < loop_max; loop++) { + val = mmio_read_32(DBSC_DBPDRGD(phyno)); + dsb_sev(); + } + + return val; +} + +static void reg_ddrphy_write(uint32_t phyno, uint32_t regadd, uint32_t regdata) +{ + uint32_t loop; + + mmio_write_32(DBSC_DBPDRGA(phyno), regadd); + dsb_sev(); + for (loop = 0U; loop < loop_max; loop++) { + mmio_read_32(DBSC_DBPDRGA(phyno)); + dsb_sev(); + } + mmio_write_32(DBSC_DBPDRGD(phyno), regdata); + dsb_sev(); + + for (loop = 0U; loop < loop_max; loop++) { + mmio_read_32(DBSC_DBPDRGD(phyno)); + dsb_sev(); + } +} + +static void reg_ddrphy_write_a(uint32_t regadd, uint32_t regdata) +{ + uint32_t ch; + uint32_t loop; + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDRGA(ch), regadd); + dsb_sev(); + } + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDRGD(ch), regdata); + dsb_sev(); + } + + for (loop = 0U; loop < loop_max; loop++) { + mmio_read_32(DBSC_DBPDRGD(0)); + dsb_sev(); + } +} + +static inline void ddrphy_regif_idle(void) +{ + reg_ddrphy_read(0U, ddr_regdef_adr(_reg_PI_INT_STATUS)); + dsb_sev(); +} + +/* DDRPHY register access (field modify) */ +static inline uint32_t ddr_regdef(uint32_t _regdef) +{ + return p_ddr_regdef_tbl[_regdef]; +} + +static inline uint32_t ddr_regdef_adr(uint32_t _regdef) +{ + return DDR_REGDEF_ADR(p_ddr_regdef_tbl[_regdef]); +} + +static inline uint32_t ddr_regdef_lsb(uint32_t _regdef) +{ + return DDR_REGDEF_LSB(p_ddr_regdef_tbl[_regdef]); +} + +static void ddr_setval_s(uint32_t ch, uint32_t slice, uint32_t _regdef, + uint32_t val) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef) + 0x80U * slice; + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U) << lsb; + } + + tmp = reg_ddrphy_read(ch, adr); + tmp = (tmp & (~msk)) | ((val << lsb) & msk); + reg_ddrphy_write(ch, adr, tmp); +} + +static uint32_t ddr_getval_s(uint32_t ch, uint32_t slice, uint32_t _regdef) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef) + 0x80U * slice; + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U); + } + + tmp = reg_ddrphy_read(ch, adr); + tmp = (tmp >> lsb) & msk; + + return tmp; +} + +static void ddr_setval(uint32_t ch, uint32_t regdef, uint32_t val) +{ + ddr_setval_s(ch, 0U, regdef, val); +} + +static void ddr_setval_ach_s(uint32_t slice, uint32_t regdef, uint32_t val) +{ + uint32_t ch; + + foreach_vch(ch) { + ddr_setval_s(ch, slice, regdef, val); + } +} + +static void ddr_setval_ach(uint32_t regdef, uint32_t val) +{ + ddr_setval_ach_s(0U, regdef, val); +} + +static void ddr_setval_ach_as(uint32_t regdef, uint32_t val) +{ + uint32_t slice; + + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_ach_s(slice, regdef, val); + } +} + +static uint32_t ddr_getval(uint32_t ch, uint32_t regdef) +{ + return ddr_getval_s(ch, 0U, regdef); +} + +static uint32_t ddr_getval_ach(uint32_t regdef, uint32_t *p) +{ + uint32_t ch; + + foreach_vch(ch) { + p[ch] = ddr_getval_s(ch, 0U, regdef); + } + return p[0U]; +} + +static uint32_t ddr_getval_ach_as(uint32_t regdef, uint32_t *p) +{ + uint32_t ch, slice; + uint32_t *pp; + + pp = p; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + *pp++ = ddr_getval_s(ch, slice, regdef); + } + } + return p[0U]; +} + +/* handling functions for setting ddrphy value table */ +static void _tblcopy(uint32_t *to, const uint32_t *from, uint32_t size) +{ + uint32_t i; + + for (i = 0U; i < size; i++) { + to[i] = from[i]; + } +} + +static void ddrtbl_setval(uint32_t *tbl, uint32_t _regdef, uint32_t val) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t adrmsk; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef); + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U) << lsb; + } + + if (adr < 0x400U) { + adrmsk = 0xffU; + } else { + adrmsk = 0x7fU; + } + + tmp = tbl[adr & adrmsk]; + tmp = (tmp & (~msk)) | ((val << lsb) & msk); + tbl[adr & adrmsk] = tmp; +} + +static uint32_t ddrtbl_getval(uint32_t *tbl, uint32_t _regdef) +{ + uint32_t adr; + uint32_t lsb; + uint32_t len; + uint32_t msk; + uint32_t tmp; + uint32_t adrmsk; + uint32_t regdef; + + regdef = ddr_regdef(_regdef); + adr = DDR_REGDEF_ADR(regdef); + len = DDR_REGDEF_LEN(regdef); + lsb = DDR_REGDEF_LSB(regdef); + if (len == 0x20U) { + msk = 0xffffffffU; + } else { + msk = ((1U << len) - 1U); + } + + if (adr < 0x400U) { + adrmsk = 0xffU; + } else { + adrmsk = 0x7fU; + } + + tmp = tbl[adr & adrmsk]; + tmp = (tmp >> lsb) & msk; + + return tmp; +} + +/* DDRPHY register access handling */ +static uint32_t ddrphy_regif_chk(void) +{ + uint32_t tmp_ach[DRAM_CH_CNT]; + uint32_t ch; + uint32_t err; + uint32_t PI_VERSION_CODE; + + if (prr_product == PRR_PRODUCT_M3) { + PI_VERSION_CODE = 0x2041U; /* G2M */ + } + + ddr_getval_ach(_reg_PI_VERSION, (uint32_t *)tmp_ach); + err = 0U; + foreach_vch(ch) { + if (tmp_ach[ch] != PI_VERSION_CODE) { + err = 1U; + } + } + return err; +} + +/* functions and parameters for timing setting */ +struct _jedec_spec1 { + uint16_t fx3; + uint8_t rlwodbi; + uint8_t rlwdbi; + uint8_t WL; + uint8_t nwr; + uint8_t nrtp; + uint8_t odtlon; + uint8_t MR1; + uint8_t MR2; +}; + +#define JS1_USABLEC_SPEC_LO 2U +#define JS1_USABLEC_SPEC_HI 5U +#define JS1_FREQ_TBL_NUM 8 +#define JS1_MR1(f) (0x04U | ((f) << 4U)) +#define JS1_MR2(f) (0x00U | ((f) << 3U) | (f)) +static const struct _jedec_spec1 js1[JS1_FREQ_TBL_NUM] = { + /* 533.333Mbps */ + { 800U, 6U, 6U, 4U, 6U, 8U, 0U, JS1_MR1(0U), JS1_MR2(0U) | 0x40U }, + /* 1066.666Mbps */ + { 1600U, 10U, 12U, 8U, 10U, 8U, 0U, JS1_MR1(1U), JS1_MR2(1U) | 0x40U }, + /* 1600.000Mbps */ + { 2400U, 14U, 16U, 12U, 16U, 8U, 6U, JS1_MR1(2U), JS1_MR2(2U) | 0x40U }, + /* 2133.333Mbps */ + { 3200U, 20U, 22U, 10U, 20U, 8U, 4U, JS1_MR1(3U), JS1_MR2(3U) }, + /* 2666.666Mbps */ + { 4000U, 24U, 28U, 12U, 24U, 10U, 4U, JS1_MR1(4U), JS1_MR2(4U) }, + /* 3200.000Mbps */ + { 4800U, 28U, 32U, 14U, 30U, 12U, 6U, JS1_MR1(5U), JS1_MR2(5U) }, + /* 3733.333Mbps */ + { 5600U, 32U, 36U, 16U, 34U, 14U, 6U, JS1_MR1(6U), JS1_MR2(6U) }, + /* 4266.666Mbps */ + { 6400U, 36U, 40U, 18U, 40U, 16U, 8U, JS1_MR1(7U), JS1_MR2(7U) } +}; + +struct _jedec_spec2 { + uint16_t ps; + uint16_t cyc; +}; + +#define js2_tsr 0 +#define js2_txp 1 +#define js2_trtp 2 +#define js2_trcd 3 +#define js2_trppb 4 +#define js2_trpab 5 +#define js2_tras 6 +#define js2_twr 7 +#define js2_twtr 8 +#define js2_trrd 9 +#define js2_tppd 10 +#define js2_tfaw 11 +#define js2_tdqsck 12 +#define js2_tckehcmd 13 +#define js2_tckelcmd 14 +#define js2_tckelpd 15 +#define js2_tmrr 16 +#define js2_tmrw 17 +#define js2_tmrd 18 +#define js2_tzqcalns 19 +#define js2_tzqlat 20 +#define js2_tiedly 21 +#define js2_tODTon_min 22 +#define JS2_TBLCNT 23 + +#define js2_trcpb (JS2_TBLCNT) +#define js2_trcab (JS2_TBLCNT + 1) +#define js2_trfcab (JS2_TBLCNT + 2) +#define JS2_CNT (JS2_TBLCNT + 3) + +#ifndef JS2_DERATE +#define JS2_DERATE 0 +#endif +static const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = { + { +/* tSR */ { 15000, 3 }, +/* tXP */ { 7500, 3 }, +/* tRTP */ { 7500, 8 }, +/* tRCD */ { 18000, 4 }, +/* tRPpb */ { 18000, 3 }, +/* tRPab */ { 21000, 3 }, +/* tRAS */ { 42000, 3 }, +/* tWR */ { 18000, 4 }, +/* tWTR */ { 10000, 8 }, +/* tRRD */ { 10000, 4 }, +/* tPPD */ { 0, 0 }, +/* tFAW */ { 40000, 0 }, +/* tDQSCK */ { 3500, 0 }, +/* tCKEHCMD */ { 7500, 3 }, +/* tCKELCMD */ { 7500, 3 }, +/* tCKELPD */ { 7500, 3 }, +/* tMRR */ { 0, 8 }, +/* tMRW */ { 10000, 10 }, +/* tMRD */ { 14000, 10 }, +/* tZQCALns */ { 1000 * 10, 0 }, +/* tZQLAT */ { 30000, 10 }, +/* tIEdly */ { 12500, 0 }, +/* tODTon_min */{ 1500, 0 } + }, { +/* tSR */ { 15000, 3 }, +/* tXP */ { 7500, 3 }, +/* tRTP */ { 7500, 8 }, +/* tRCD */ { 19875, 4 }, +/* tRPpb */ { 19875, 3 }, +/* tRPab */ { 22875, 3 }, +/* tRAS */ { 43875, 3 }, +/* tWR */ { 18000, 4 }, +/* tWTR */ { 10000, 8 }, +/* tRRD */ { 11875, 4 }, +/* tPPD */ { 0, 0 }, +/* tFAW */ { 40000, 0 }, +/* tDQSCK */ { 3600, 0 }, +/* tCKEHCMD */ { 7500, 3 }, +/* tCKELCMD */ { 7500, 3 }, +/* tCKELPD */ { 7500, 3 }, +/* tMRR */ { 0, 8 }, +/* tMRW */ { 10000, 10 }, +/* tMRD */ { 14000, 10 }, +/* tZQCALns */ { 1000 * 10, 0 }, +/* tZQLAT */ { 30000, 10 }, +/* tIEdly */ { 12500, 0 }, +/* tODTon_min */{ 1500, 0 } + } +}; + +static const uint16_t jedec_spec2_trfc_ab[7] = { + /* 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb(non), 32Gb(non) */ + 130U, 180U, 180U, 280U, 280U, 560U, 560U +}; + +static uint32_t js1_ind; +static uint16_t js2[JS2_CNT]; +static uint8_t RL; +static uint8_t WL; + +static uint16_t _f_scale(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, uint32_t ps, + uint16_t cyc) +{ + uint16_t ret = cyc; + uint32_t tmp; + uint32_t div; + + tmp = (((uint32_t)(ps) + 9U) / 10U) * _ddr_mbps; + div = tmp / (200000U * _ddr_mbpsdiv); + if (tmp != (div * 200000U * _ddr_mbpsdiv)) { + div = div + 1U; + } + + if (div > cyc) { + ret = (uint16_t)div; + } + + return ret; +} + +static void _f_scale_js2(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, + uint16_t *_js2) +{ + int i; + + for (i = 0; i < JS2_TBLCNT; i++) { + _js2[i] = _f_scale(_ddr_mbps, _ddr_mbpsdiv, + jedec_spec2[JS2_DERATE][i].ps, + jedec_spec2[JS2_DERATE][i].cyc); + } + + _js2[js2_trcpb] = _js2[js2_tras] + _js2[js2_trppb]; + _js2[js2_trcab] = _js2[js2_tras] + _js2[js2_trpab]; +} + +/* scaler for DELAY value */ +static int16_t _f_scale_adj(int16_t ps) +{ + int32_t tmp; + /* + * tmp = (int32_t)512 * ps * ddr_mbps /2 / ddr_mbpsdiv / 1000 / 1000; + * = ps * ddr_mbps /2 / ddr_mbpsdiv *512 / 8 / 8 / 125 / 125 + * = ps * ddr_mbps / ddr_mbpsdiv *4 / 125 / 125 + */ + tmp = (int32_t)4 * (int32_t)ps * (int32_t)ddr_mbps / + (int32_t)ddr_mbpsdiv; + tmp = (int32_t)tmp / (int32_t)15625; + + return (int16_t)tmp; +} + +static const uint32_t reg_pi_mr1_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR1_DATA_F0_0, + _reg_PI_MR1_DATA_F0_1, + _reg_PI_MR1_DATA_F0_2, + _reg_PI_MR1_DATA_F0_3}, + { + _reg_PI_MR1_DATA_F1_0, + _reg_PI_MR1_DATA_F1_1, + _reg_PI_MR1_DATA_F1_2, + _reg_PI_MR1_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr2_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR2_DATA_F0_0, + _reg_PI_MR2_DATA_F0_1, + _reg_PI_MR2_DATA_F0_2, + _reg_PI_MR2_DATA_F0_3}, + { + _reg_PI_MR2_DATA_F1_0, + _reg_PI_MR2_DATA_F1_1, + _reg_PI_MR2_DATA_F1_2, + _reg_PI_MR2_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr3_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR3_DATA_F0_0, + _reg_PI_MR3_DATA_F0_1, + _reg_PI_MR3_DATA_F0_2, + _reg_PI_MR3_DATA_F0_3}, + { + _reg_PI_MR3_DATA_F1_0, + _reg_PI_MR3_DATA_F1_1, + _reg_PI_MR3_DATA_F1_2, + _reg_PI_MR3_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr11_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR11_DATA_F0_0, + _reg_PI_MR11_DATA_F0_1, + _reg_PI_MR11_DATA_F0_2, + _reg_PI_MR11_DATA_F0_3}, + { + _reg_PI_MR11_DATA_F1_0, + _reg_PI_MR11_DATA_F1_1, + _reg_PI_MR11_DATA_F1_2, + _reg_PI_MR11_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr12_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR12_DATA_F0_0, + _reg_PI_MR12_DATA_F0_1, + _reg_PI_MR12_DATA_F0_2, + _reg_PI_MR12_DATA_F0_3}, + { + _reg_PI_MR12_DATA_F1_0, + _reg_PI_MR12_DATA_F1_1, + _reg_PI_MR12_DATA_F1_2, + _reg_PI_MR12_DATA_F1_3} +}; + +static const uint32_t reg_pi_mr14_data_fx_csx[2U][CSAB_CNT] = { + { + _reg_PI_MR14_DATA_F0_0, + _reg_PI_MR14_DATA_F0_1, + _reg_PI_MR14_DATA_F0_2, + _reg_PI_MR14_DATA_F0_3}, + { + _reg_PI_MR14_DATA_F1_0, + _reg_PI_MR14_DATA_F1_1, + _reg_PI_MR14_DATA_F1_2, + _reg_PI_MR14_DATA_F1_3} +}; + +/* + * regif pll w/a ( REGIF G2M WA ) + */ +static void regif_pll_wa(void) +{ + uint32_t ch; + uint32_t reg_ofs; + + /* PLL setting for PHY : G2M */ + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_WAIT), + (0x5064U << + ddr_regdef_lsb(_reg_PHY_PLL_WAIT))); + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL), + (ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PLL_CTRL_TOP) << 16) | + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PLL_CTRL)); + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL_CA), + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PLL_CTRL_CA)); + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_PLL_CTRL), + (ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_LP4_BOOT_PLL_CTRL_CA) << 16) | + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_LP4_BOOT_PLL_CTRL)); + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_TOP_PLL_CTRL), + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_LP4_BOOT_TOP_PLL_CTRL)); + + reg_ofs = ddr_regdef_adr(_reg_PHY_LPDDR3_CS) - DDR_PHY_ADR_G_REGSET_OFS; + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LPDDR3_CS), + _cnf_DDR_PHY_ADR_G_REGSET[reg_ofs]); + + /* protect register interface */ + ddrphy_regif_idle(); + pll3_control(0U); + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_DLL_RST_EN), + (0x01U << ddr_regdef_lsb(_reg_PHY_DLL_RST_EN))); + ddrphy_regif_idle(); + + /* + * init start + * dbdficnt0: + * dfi_dram_clk_disable=1 + * dfi_frequency = 0 + * freq_ratio = 01 (2:1) + * init_start =0 + */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F10U); + } + dsb_sev(); + + /* + * dbdficnt0: + * dfi_dram_clk_disable=1 + * dfi_frequency = 0 + * freq_ratio = 01 (2:1) + * init_start =1 + */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F11U); + } + dsb_sev(); + + foreach_ech(ch) { + if ((board_cnf->phyvalid & BIT(ch)) != 0U) { + while ((mmio_read_32(DBSC_PLL_LOCK(ch)) & 0x1fU) != 0x1fU) { + } + } + } + dsb_sev(); +} + +/* load table data into DDR registers */ +static void ddrtbl_load(void) +{ + uint32_t i; + uint32_t slice; + uint32_t csab; + uint32_t adr; + uint32_t data_l; + uint32_t tmp[3]; + uint16_t dataS; + + /* + * TIMING REGISTERS + * search jedec_spec1 index + */ + for (i = JS1_USABLEC_SPEC_LO; i < (uint32_t)JS1_FREQ_TBL_NUM - 1U; i++) { + if ((js1[i].fx3 * 2U * ddr_mbpsdiv >= ddr_mbps * 3U) != 0U) { + break; + } + } + if (i > JS1_USABLEC_SPEC_HI) { + js1_ind = JS1_USABLEC_SPEC_HI; + } else { + js1_ind = i; + } + + if (board_cnf->dbi_en != 0U) { + RL = js1[js1_ind].rlwdbi; + } else { + RL = js1[js1_ind].rlwodbi; + } + + WL = js1[js1_ind].WL; + + /* calculate jedec_spec2 */ + _f_scale_js2(ddr_mbps, ddr_mbpsdiv, js2); + + /* PREPARE TBL */ + if (prr_product == PRR_PRODUCT_M3) { + /* G2M */ + _tblcopy(_cnf_DDR_PHY_SLICE_REGSET, + DDR_PHY_SLICE_REGSET_G2M, DDR_PHY_SLICE_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET, + DDR_PHY_ADR_V_REGSET_G2M, DDR_PHY_ADR_V_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET, + DDR_PHY_ADR_I_REGSET_G2M, DDR_PHY_ADR_I_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET, + DDR_PHY_ADR_G_REGSET_G2M, DDR_PHY_ADR_G_REGSET_NUM_G2M); + _tblcopy(_cnf_DDR_PI_REGSET, + DDR_PI_REGSET_G2M, DDR_PI_REGSET_NUM_G2M); + + DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_G2M; + DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_G2M; + DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_G2M; + DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_G2M; + DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_G2M; + DDR_PHY_SLICE_REGSET_SIZE = DDR_PHY_SLICE_REGSET_SIZE_G2M; + DDR_PHY_ADR_V_REGSET_SIZE = DDR_PHY_ADR_V_REGSET_SIZE_G2M; + DDR_PHY_ADR_I_REGSET_SIZE = DDR_PHY_ADR_I_REGSET_SIZE_G2M; + DDR_PHY_ADR_G_REGSET_SIZE = DDR_PHY_ADR_G_REGSET_SIZE_G2M; + DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_G2M; + DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_G2M; + DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_G2M; + DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_G2M; + DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_G2M; + DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_G2M; + + DDR_PHY_ADR_I_NUM = 2U; + } + + /* on fly gate adjust */ + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut == PRR_PRODUCT_10)) { + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_ON_FLY_GATE_ADJUST_EN, 0x00); + } + + /* Adjust PI parameters */ +#ifdef _def_LPDDR4_ODT + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr11_data_fx_csx[i][csab], + _def_LPDDR4_ODT); + } + } +#endif /* _def_LPDDR4_ODT */ + +#ifdef _def_LPDDR4_VREFCA + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr12_data_fx_csx[i][csab], + _def_LPDDR4_VREFCA); + } + } +#endif /* _def_LPDDR4_VREFCA */ + + if ((js2[js2_tiedly]) >= 0x0eU) { + dataS = 0x0eU; + } else { + dataS = js2[js2_tiedly]; + } + + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_DLY, dataS); + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_TSEL_DLY, + (dataS - 2U)); + ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1, RL - dataS); + + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD) != 0U) { + data_l = WL - 1U; + } else { + data_l = WL; + } + ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1, data_l - 2U); + ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1, data_l); + + if (board_cnf->dbi_en != 0U) { + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE, + 0x01U); + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_WDQLVL_DATADM_MASK, 0x000U); + } else { + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE, + 0x00U); + ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_WDQLVL_DATADM_MASK, 0x100U); + } + + tmp[0] = js1[js1_ind].MR1; + tmp[1] = js1[js1_ind].MR2; + data_l = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_MR3_DATA_F1_0); + if (board_cnf->dbi_en != 0U) { + tmp[2] = data_l | 0xc0U; + } else { + tmp[2] = data_l & (~0xc0U); + } + + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr1_data_fx_csx[i][csab], tmp[0]); + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr2_data_fx_csx[i][csab], tmp[1]); + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr3_data_fx_csx[i][csab], tmp[2]); + } + } + + /* DDRPHY INT START */ + regif_pll_wa(); + dbwait_loop(5U); + + /* FREQ_SEL_MULTICAST & PER_CS_TRAINING_MULTICAST SET (for safety) */ + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), + BIT(ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN))); + ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x01U); + + /* SET DATA SLICE TABLE */ + for (slice = 0U; slice < SLICE_CNT; slice++) { + adr = + DDR_PHY_SLICE_REGSET_OFS + + DDR_PHY_SLICE_REGSET_SIZE * slice; + for (i = 0U; i < DDR_PHY_SLICE_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, + _cnf_DDR_PHY_SLICE_REGSET[i]); + } + } + + /* SET ADR SLICE TABLE */ + adr = DDR_PHY_ADR_V_REGSET_OFS; + for (i = 0U; i < DDR_PHY_ADR_V_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_V_REGSET[i]); + } + + if ((prr_product == PRR_PRODUCT_M3) && + ((0x00ffffffU & (uint32_t)((board_cnf->ch[0].ca_swap) >> 40U)) + != 0x00U)) { + adr = DDR_PHY_ADR_I_REGSET_OFS + DDR_PHY_ADR_I_REGSET_SIZE; + for (i = 0U; i < DDR_PHY_ADR_V_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, + _cnf_DDR_PHY_ADR_V_REGSET[i]); + } + ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_ADR_DISABLE, 0x02); + DDR_PHY_ADR_I_NUM -= 1U; + ddr_phycaslice = 1U; + +#ifndef _def_LPDDR4_ODT + for (i = 0U; i < 2U; i++) { + for (csab = 0U; csab < CSAB_CNT; csab++) { + ddrtbl_setval(_cnf_DDR_PI_REGSET, + reg_pi_mr11_data_fx_csx[i][csab], + 0x66); + } + } +#endif/* _def_LPDDR4_ODT */ + } else { + ddr_phycaslice = 0U; + } + + if (DDR_PHY_ADR_I_NUM > 0U) { + for (slice = 0U; slice < DDR_PHY_ADR_I_NUM; slice++) { + adr = + DDR_PHY_ADR_I_REGSET_OFS + + DDR_PHY_ADR_I_REGSET_SIZE * slice; + for (i = 0U; i < DDR_PHY_ADR_I_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, + _cnf_DDR_PHY_ADR_I_REGSET + [i]); + } + } + } + + /* SET ADRCTRL SLICE TABLE */ + adr = DDR_PHY_ADR_G_REGSET_OFS; + for (i = 0U; i < DDR_PHY_ADR_G_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_G_REGSET[i]); + } + + /* SET PI REGISTERS */ + adr = DDR_PI_REGSET_OFS; + for (i = 0U; i < DDR_PI_REGSET_NUM; i++) { + reg_ddrphy_write_a(adr + i, _cnf_DDR_PI_REGSET[i]); + } +} + +/* CONFIGURE DDR REGISTERS */ +static void ddr_config_sub(void) +{ + const uint32_t _par_CALVL_DEVICE_MAP = 1U; + uint8_t high_byte[SLICE_CNT]; + uint32_t ch, slice; + uint32_t data_l; + uint32_t tmp; + uint32_t i; + + foreach_vch(ch) { + /* BOARD SETTINGS (DQ,DM,VREF_DRIVING) */ + for (slice = 0U; slice < SLICE_CNT; slice++) { + high_byte[slice] = + (board_cnf->ch[ch].dqs_swap >> (4U * slice)) % 2U; + ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE0, + board_cnf->ch[ch].dq_swap[slice]); + ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE1, + board_cnf->ch[ch].dm_swap[slice]); + if (high_byte[slice] != 0U) { + /* HIGHER 16 BYTE */ + ddr_setval_s(ch, slice, + _reg_PHY_CALVL_VREF_DRIVING_SLICE, + 0x00); + } else { + /* LOWER 16 BYTE */ + ddr_setval_s(ch, slice, + _reg_PHY_CALVL_VREF_DRIVING_SLICE, + 0x01); + } + } + + /* BOARD SETTINGS (CA,ADDR_SEL) */ + data_l = (0x00ffffffU & (uint32_t)(board_cnf->ch[ch].ca_swap)) | + 0x00888888U; + + /* --- ADR_CALVL_SWIZZLE --- */ + if (prr_product == PRR_PRODUCT_M3) { + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_0, data_l); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_0, + 0x00000000); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_1, data_l); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_1, + 0x00000000); + ddr_setval(ch, _reg_PHY_ADR_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } else { + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0, data_l); + ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1, 0x00000000); + ddr_setval(ch, _reg_PHY_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } + + /* --- ADR_ADDR_SEL --- */ + data_l = 0U; + tmp = board_cnf->ch[ch].ca_swap; + for (i = 0U; i < 6U; i++) { + data_l |= ((tmp & 0x0fU) << (i * 5U)); + tmp = tmp >> 4; + } + ddr_setval(ch, _reg_PHY_ADR_ADDR_SEL, data_l); + if (ddr_phycaslice == 1U) { + /* ----------- adr slice2 swap ----------- */ + tmp = (uint32_t)((board_cnf->ch[ch].ca_swap) >> 40); + data_l = (tmp & 0x00ffffffU) | 0x00888888U; + + /* --- ADR_CALVL_SWIZZLE --- */ + if (prr_product == PRR_PRODUCT_M3) { + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE0_0, + data_l); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE1_0, + 0x00000000); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE0_1, + data_l); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE1_1, + 0x00000000); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } else { + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE0, + data_l); + ddr_setval_s(ch, 2, + _reg_PHY_ADR_CALVL_SWIZZLE1, + 0x00000000); + ddr_setval_s(ch, 2, + _reg_PHY_CALVL_DEVICE_MAP, + _par_CALVL_DEVICE_MAP); + } + + /* --- ADR_ADDR_SEL --- */ + data_l = 0U; + for (i = 0U; i < 6U; i++) { + data_l |= ((tmp & 0x0fU) << (i * 5U)); + tmp = tmp >> 4U; + } + + ddr_setval_s(ch, 2, _reg_PHY_ADR_ADDR_SEL, data_l); + } + + /* BOARD SETTINGS (BYTE_ORDER_SEL) */ + if (prr_product == PRR_PRODUCT_M3) { + /* --- DATA_BYTE_SWAP --- */ + data_l = 0U; + tmp = board_cnf->ch[ch].dqs_swap; + for (i = 0U; i < 4U; i++) { + data_l |= ((tmp & 0x03U) << (i * 2U)); + tmp = tmp >> 4U; + } + } else { + /* --- DATA_BYTE_SWAP --- */ + data_l = board_cnf->ch[ch].dqs_swap; + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_EN, 0x01); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE0, + (data_l) & 0x0fU); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE1, + (data_l >> 4U * 1U) & 0x0fU); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE2, + (data_l >> 4U * 2U) & 0x0fU); + ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE3, + (data_l >> 4U * 3U) & 0x0fU); + + ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL_HIGH, 0x00U); + } + ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL, data_l); + } +} + +static void ddr_config(void) +{ + uint32_t num_cacs_dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; + uint32_t reg_ofs, dly; + uint32_t ch, slice; + uint32_t data_l; + uint32_t tmp; + uint32_t i; + int8_t _adj; + int16_t adj; + uint32_t dq; + union { + uint32_t ui32[4]; + uint8_t ui8[16]; + } patt; + uint16_t patm; + + /* configure ddrphy registers */ + ddr_config_sub(); + + /* WDQ_USER_PATT */ + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + patm = 0U; + for (i = 0U; i < 16U; i++) { + tmp = board_cnf->ch[ch].wdqlvl_patt[i]; + patt.ui8[i] = tmp & 0xffU; + if ((tmp & 0x100U) != 0U) { + patm |= (1U << (uint16_t)i); + } + } + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT0, + patt.ui32[0]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT1, + patt.ui32[1]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT2, + patt.ui32[2]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT3, + patt.ui32[3]); + ddr_setval_s(ch, slice, _reg_PHY_USER_PATT4, patm); + } + } + + /* CACS DLY */ + data_l = board_cnf->cacs_dly + (uint32_t)_f_scale_adj(board_cnf->cacs_dly_adj); + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), 0x00U); + foreach_vch(ch) { + for (i = 0U; i < num_cacs_dly - 4U; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i]); + dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]; + ddrtbl_setval(_cnf_DDR_PHY_ADR_V_REGSET, dly, + data_l + (uint32_t)adj); + reg_ofs = ddr_regdef_adr(dly) - DDR_PHY_ADR_V_REGSET_OFS; + reg_ddrphy_write(ch, ddr_regdef_adr(dly), + _cnf_DDR_PHY_ADR_V_REGSET[reg_ofs]); + } + + for (i = num_cacs_dly - 4U; i < num_cacs_dly; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i]); + dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]; + ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, dly, + data_l + (uint32_t)adj); + reg_ofs = ddr_regdef_adr(dly) - DDR_PHY_ADR_G_REGSET_OFS; + reg_ddrphy_write(ch, ddr_regdef_adr(dly), + _cnf_DDR_PHY_ADR_G_REGSET[reg_ofs]); + } + + if (ddr_phycaslice == 1U) { + for (i = 0U; i < 6U; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i + num_cacs_dly]); + dly = _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]; + ddrtbl_setval(_cnf_DDR_PHY_ADR_V_REGSET, dly, + data_l + (uint32_t)adj); + reg_ofs = ddr_regdef_adr(dly) - DDR_PHY_ADR_V_REGSET_OFS; + reg_ddrphy_write(ch, ddr_regdef_adr(dly) + 0x0100U, + _cnf_DDR_PHY_ADR_V_REGSET[reg_ofs]); + } + } + } + + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), + BIT(ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN))); + + /* WDQDM DLY */ + data_l = board_cnf->dqdm_dly_w; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (i = 0U; i <= 8U; i++) { + dq = slice * 8U + (uint32_t)i; + if (i == 8U) { + _adj = board_cnf->ch[ch].dm_adj_w[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_w[dq]; + } + adj = _f_scale_adj(_adj); + ddr_setval_s(ch, slice, + _reg_PHY_CLK_WRX_SLAVE_DELAY[i], + data_l + (uint32_t)adj); + } + } + } + + /* RDQDM DLY */ + data_l = board_cnf->dqdm_dly_r; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (i = 0U; i <= 8U; i++) { + dq = slice * 8U + (uint32_t)i; + if (i == 8U) { + _adj = board_cnf->ch[ch].dm_adj_r[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_r[dq]; + } + adj = _f_scale_adj(_adj); + dly = _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]; + ddr_setval_s(ch, slice, dly, data_l + (uint32_t)adj); + dly = _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]; + ddr_setval_s(ch, slice, dly, data_l + (uint32_t)adj); + } + } + } +} + +/* DBSC register setting functions */ +static void dbsc_regset_pre(void) +{ + uint32_t ch, csab; + uint32_t data_l; + + /* PRIMARY SETTINGS */ + /* LPDDR4, BL=16, DFI interface */ + mmio_write_32(DBSC_DBKIND, 0x0000000aU); + mmio_write_32(DBSC_DBBL, 0x00000002U); + mmio_write_32(DBSC_DBPHYCONF0, 0x00000001U); + + /* FREQRATIO=2 */ + mmio_write_32(DBSC_DBSYSCONF1, 0x00000002U); + + /* + * DRAM SIZE REGISTER: + * set all ranks as density=0(4Gb) for PHY initialization + */ + foreach_vch(ch) { + for (csab = 0U; csab < 4U; csab++) { + mmio_write_32(DBSC_DBMEMCONF(ch, csab), + DBMEMCONF_REGD(0U)); + } + } + + if (prr_product == PRR_PRODUCT_M3) { + data_l = 0xe4e4e4e4U; + foreach_ech(ch) { + if ((ddr_phyvalid & (1U << ch)) != 0U) { + data_l = (data_l & (~(0x000000FFU << (ch * 8U)))) + | (((board_cnf->ch[ch].dqs_swap & 0x0003U) + | ((board_cnf->ch[ch].dqs_swap & 0x0030U) >> 2U) + | ((board_cnf->ch[ch].dqs_swap & 0x0300U) >> 4U) + | ((board_cnf->ch[ch].dqs_swap & 0x3000U) >> 6U)) + << (ch * 8U)); + } + } + mmio_write_32(DBSC_DBBSWAP, data_l); + } +} + +static void dbsc_regset(void) +{ + int32_t i; + uint32_t ch; + uint32_t data_l; + uint32_t data_l2; + uint32_t wdql; + uint32_t dqenltncy; + uint32_t dql; + uint32_t dqienltncy; + uint32_t wrcslat; + uint32_t wrcsgap; + uint32_t rdcslat; + uint32_t rdcsgap; + uint32_t scfctst0_act_act; + uint32_t scfctst0_rda_act; + uint32_t scfctst0_wra_act; + uint32_t scfctst0_pre_act; + uint32_t scfctst1_rd_wr; + uint32_t scfctst1_wr_rd; + uint32_t scfctst1_act_rd_wr; + uint32_t scfctst1_asyncofs; + uint32_t dbschhrw1_sctrfcab; + + /* RFC */ + js2[js2_trfcab] = + _f_scale(ddr_mbps, ddr_mbpsdiv, + jedec_spec2_trfc_ab[max_density] * 1000U, 0U); + /* DBTR0.CL : RL */ + mmio_write_32(DBSC_DBTR(0), RL); + + /* DBTR1.CWL : WL */ + mmio_write_32(DBSC_DBTR(1), WL); + + /* DBTR2.AL : 0 */ + mmio_write_32(DBSC_DBTR(2), 0U); + + /* DBTR3.TRCD: tRCD */ + mmio_write_32(DBSC_DBTR(3), js2[js2_trcd]); + + /* DBTR4.TRPA,TRP: tRPab,tRPpb */ + mmio_write_32(DBSC_DBTR(4), (js2[js2_trpab] << 16) | js2[js2_trppb]); + + /* DBTR5.TRC : use tRCpb */ + mmio_write_32(DBSC_DBTR(5), js2[js2_trcpb]); + + /* DBTR6.TRAS : tRAS */ + mmio_write_32(DBSC_DBTR(6), js2[js2_tras]); + + /* DBTR7.TRRD : tRRD */ + mmio_write_32(DBSC_DBTR(7), (js2[js2_trrd] << 16) | js2[js2_trrd]); + + /* DBTR8.TFAW : tFAW */ + mmio_write_32(DBSC_DBTR(8), js2[js2_tfaw]); + + /* DBTR9.TRDPR : tRTP */ + mmio_write_32(DBSC_DBTR(9), js2[js2_trtp]); + + /* DBTR10.TWR : nWR */ + mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nwr); + + /* + * DBTR11.TRDWR : RL + BL / 2 + Rounddown(tRPST) + PHY_ODTLoff - + * odtlon + tDQSCK - tODTon,min + + * PCB delay (out+in) + tPHY_ODToff + */ + mmio_write_32(DBSC_DBTR(11), + RL + (16U / 2U) + 1U + 2U - js1[js1_ind].odtlon + + js2[js2_tdqsck] - js2[js2_tODTon_min] + + _f_scale(ddr_mbps, ddr_mbpsdiv, 1300, 0)); + + /* DBTR12.TWRRD : WL + 1 + BL/2 + tWTR */ + data_l = WL + 1U + (16U / 2U) + js2[js2_twtr]; + mmio_write_32(DBSC_DBTR(12), (data_l << 16) | data_l); + + /* DBTR13.TRFCAB : tRFCab */ + mmio_write_32(DBSC_DBTR(13), js2[js2_trfcab]); + + /* DBTR14.TCKEHDLL,tCKEH : tCKEHCMD,tCKEHCMD */ + mmio_write_32(DBSC_DBTR(14), + (js2[js2_tckehcmd] << 16) | (js2[js2_tckehcmd])); + + /* DBTR15.TCKESR,TCKEL : tSR,tCKELPD */ + mmio_write_32(DBSC_DBTR(15), (js2[js2_tsr] << 16) | (js2[js2_tckelpd])); + + /* DBTR16 */ + /* WDQL : tphy_wrlat + tphy_wrdata */ + wdql = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1); + /* DQENLTNCY : tphy_wrlat = WL-2 : PHY_WRITE_PATH_LAT_ADD == 0 + * tphy_wrlat = WL-3 : PHY_WRITE_PATH_LAT_ADD != 0 + */ + dqenltncy = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1); + /* DQL : tphy_rdlat + trdata_en */ + /* it is not important for dbsc */ + dql = RL + 16U; + /* DQIENLTNCY : trdata_en */ + dqienltncy = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1) - 1U; + mmio_write_32(DBSC_DBTR(16), + (dqienltncy << 24) | (dql << 16) | (dqenltncy << 8) | wdql); + + /* DBTR24 */ + /* WRCSLAT = WRLAT -5 */ + wrcslat = wdql - 5U; + /* WRCSGAP = 5 */ + wrcsgap = 5U; + /* RDCSLAT = RDLAT_ADJ +2 */ + rdcslat = dqienltncy; + if (prr_product != PRR_PRODUCT_M3) { + rdcslat += 2U; + } + /* RDCSGAP = 6 */ + rdcsgap = 6U; + if (prr_product == PRR_PRODUCT_M3) { + rdcsgap = 4U; + } + mmio_write_32(DBSC_DBTR(24), + (rdcsgap << 24) | (rdcslat << 16) | (wrcsgap << 8) | wrcslat); + + /* DBTR17.TMODRD,TMOD,TRDMR: tMRR,tMRD,(0) */ + mmio_write_32(DBSC_DBTR(17), + (js2[js2_tmrr] << 24) | (js2[js2_tmrd] << 16)); + + /* DBTR18.RODTL, RODTA, WODTL, WODTA : do not use in LPDDR4 */ + mmio_write_32(DBSC_DBTR(18), 0); + + /* DBTR19.TZQCL, TZQCS : do not use in LPDDR4 */ + mmio_write_32(DBSC_DBTR(19), 0); + + /* DBTR20.TXSDLL, TXS : tRFCab+tCKEHCMD */ + data_l = js2[js2_trfcab] + js2[js2_tckehcmd]; + mmio_write_32(DBSC_DBTR(20), (data_l << 16) | data_l); + + /* DBTR21.TCCD */ + /* DBTR23.TCCD */ + if (ddr_tccd == 8U) { + data_l = 8U; + mmio_write_32(DBSC_DBTR(21), (data_l << 16) | data_l); + mmio_write_32(DBSC_DBTR(23), 0x00000002); + } else if (ddr_tccd <= 11U) { + data_l = 11U; + mmio_write_32(DBSC_DBTR(21), (data_l << 16) | data_l); + mmio_write_32(DBSC_DBTR(23), 0x00000000); + } else { + data_l = ddr_tccd; + mmio_write_32(DBSC_DBTR(21), (data_l << 16) | data_l); + mmio_write_32(DBSC_DBTR(23), 0x00000000); + } + + /* DBTR22.ZQLAT : */ + data_l = js2[js2_tzqcalns] * 100U; /* 1000 * 1000 ps */ + data_l = (data_l << 16U) | (js2[js2_tzqlat] + 24U + 20U); + mmio_write_32(DBSC_DBTR(22), data_l); + + /* DBTR25 : do not use in LPDDR4 */ + mmio_write_32(DBSC_DBTR(25), 0U); + + /* + * DBRNK : + * DBSC_DBRNK2 rkrr + * DBSC_DBRNK3 rkrw + * DBSC_DBRNK4 rkwr + * DBSC_DBRNK5 rkww + */ +#define _par_DBRNK_VAL (0x7007U) + + for (i = 0; i < 4; i++) { + data_l = (_par_DBRNK_VAL >> ((uint32_t)i * 4U)) & 0x0fU; + data_l2 = 0U; + foreach_vch(ch) { + data_l2 = data_l2 | (data_l << (4U * ch)); + } + mmio_write_32(DBSC_DBRNK(2 + i), data_l2); + } + mmio_write_32(DBSC_DBADJ0, 0x00000000U); + + /* timing registers for scheduler */ + /* SCFCTST0 */ + /* SCFCTST0 ACT-ACT */ + scfctst0_act_act = js2[js2_trcpb] * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST0 RDA-ACT */ + scfctst0_rda_act = ((16U / 2U) + js2[js2_trtp] - 8U + + js2[js2_trppb]) * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST0 WRA-ACT */ + scfctst0_wra_act = (WL + 1U + (16U / 2U) + + js1[js1_ind].nwr) * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST0 PRE-ACT */ + scfctst0_pre_act = js2[js2_trppb]; + mmio_write_32(DBSC_SCFCTST0, + (scfctst0_act_act << 24) | (scfctst0_rda_act << 16) | + (scfctst0_wra_act << 8) | scfctst0_pre_act); + + /* SCFCTST1 */ + /* SCFCTST1 RD-WR */ + scfctst1_rd_wr = (mmio_read_32(DBSC_DBTR(11)) & 0xffU) * 800UL * ddr_mbpsdiv / + ddr_mbps; + /* SCFCTST1 WR-RD */ + scfctst1_wr_rd = (mmio_read_32(DBSC_DBTR(12)) & 0xff) * 800UL * ddr_mbpsdiv / + ddr_mbps; + /* SCFCTST1 ACT-RD/WR */ + scfctst1_act_rd_wr = js2[js2_trcd] * 800UL * ddr_mbpsdiv / ddr_mbps; + /* SCFCTST1 ASYNCOFS */ + scfctst1_asyncofs = 12U; + mmio_write_32(DBSC_SCFCTST1, + (scfctst1_rd_wr << 24) | (scfctst1_wr_rd << 16) | + (scfctst1_act_rd_wr << 8) | scfctst1_asyncofs); + + /* DBSCHRW1 */ + /* DBSCHRW1 SCTRFCAB */ + dbschhrw1_sctrfcab = js2[js2_trfcab] * 800UL * ddr_mbpsdiv / ddr_mbps; + data_l = (((mmio_read_32(DBSC_DBTR(16)) & 0x00FF0000U) >> 16) + + (mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFFU) + + (0x28U * 2U)) * 400U * 2U * ddr_mbpsdiv / ddr_mbps + 7U; + if (dbschhrw1_sctrfcab < data_l) { + dbschhrw1_sctrfcab = data_l; + } + + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut < PRR_PRODUCT_30)) { + mmio_write_32(DBSC_DBSCHRW1, dbschhrw1_sctrfcab + + ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFFU) * + 400U * 2U * ddr_mbpsdiv + (ddr_mbps - 1U)) / ddr_mbps - 3U); + } else { + mmio_write_32(DBSC_DBSCHRW1, dbschhrw1_sctrfcab + + ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFFU) * + 400U * 2U * ddr_mbpsdiv + (ddr_mbps - 1U)) / ddr_mbps); + } + + /* QOS and CAM */ +#ifdef DDR_QOS_INIT_SETTING /* only for non qos_init */ + /* wbkwait(0004), wbkmdhi(4,2),wbkmdlo(1,8) */ + mmio_write_32(DBSC_DBCAM0CNF1, 0x00043218U); + /* 0(fillunit),8(dirtymax),4(dirtymin) */ + mmio_write_32(DBSC_DBCAM0CNF2, 0x000000F4U); + /* stop_tolerance */ + mmio_write_32(DBSC_DBSCHRW0, 0x22421111U); + /* rd-wr/wr-rd toggle priority */ + mmio_write_32(DBSC_SCFCTST2, 0x012F1123U); + mmio_write_32(DBSC_DBSCHSZ0, 0x00000001U); + mmio_write_32(DBSC_DBSCHCNT0, 0x000F0037U); + + /* QoS Settings */ + mmio_write_32(DBSC_DBSCHQOS00, 0x00000F00U); + mmio_write_32(DBSC_DBSCHQOS01, 0x00000B00U); + mmio_write_32(DBSC_DBSCHQOS02, 0x00000000U); + mmio_write_32(DBSC_DBSCHQOS03, 0x00000000U); + mmio_write_32(DBSC_DBSCHQOS40, 0x00000300U); + mmio_write_32(DBSC_DBSCHQOS41, 0x000002F0U); + mmio_write_32(DBSC_DBSCHQOS42, 0x00000200U); + mmio_write_32(DBSC_DBSCHQOS43, 0x00000100U); + mmio_write_32(DBSC_DBSCHQOS90, 0x00000100U); + mmio_write_32(DBSC_DBSCHQOS91, 0x000000F0U); + mmio_write_32(DBSC_DBSCHQOS92, 0x000000A0U); + mmio_write_32(DBSC_DBSCHQOS93, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS120, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS121, 0x00000030U); + mmio_write_32(DBSC_DBSCHQOS122, 0x00000020U); + mmio_write_32(DBSC_DBSCHQOS123, 0x00000010U); + mmio_write_32(DBSC_DBSCHQOS130, 0x00000100U); + mmio_write_32(DBSC_DBSCHQOS131, 0x000000F0U); + mmio_write_32(DBSC_DBSCHQOS132, 0x000000A0U); + mmio_write_32(DBSC_DBSCHQOS133, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS140, 0x000000C0U); + mmio_write_32(DBSC_DBSCHQOS141, 0x000000B0U); + mmio_write_32(DBSC_DBSCHQOS142, 0x00000080U); + mmio_write_32(DBSC_DBSCHQOS143, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS150, 0x00000040U); + mmio_write_32(DBSC_DBSCHQOS151, 0x00000030U); + mmio_write_32(DBSC_DBSCHQOS152, 0x00000020U); + mmio_write_32(DBSC_DBSCHQOS153, 0x00000010U); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* DDR_QOS_INIT_SETTING */ + + /* resrdis */ + mmio_write_32(DBSC_DBBCAMDIS, 0x00000001U); +} + +static void dbsc_regset_post(void) +{ + uint32_t slice, rdlat_max, rdlat_min; + uint32_t ch, cs; + uint32_t data_l; + uint32_t srx; + + rdlat_max = 0U; + rdlat_min = 0xffffU; + foreach_vch(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + if ((ch_have_this_cs[cs] & (1U << ch)) != 0U) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX, + cs); + data_l = ddr_getval_s(ch, slice, + _reg_PHY_RDDQS_LATENCY_ADJUST); + if (data_l > rdlat_max) { + rdlat_max = data_l; + } + if (data_l < rdlat_min) { + rdlat_min = data_l; + } + } + } + } + } + + mmio_write_32(DBSC_DBTR(24), + ((rdlat_max + 2U) << 24) + + ((rdlat_max + 2U) << 16) + + mmio_read_32(DBSC_DBTR(24))); + + /* set ddr density information */ + foreach_ech(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + if (ddr_density[ch][cs] == 0xffU) { + mmio_write_32(DBSC_DBMEMCONF(ch, cs), 0x00U); + } else { + mmio_write_32(DBSC_DBMEMCONF(ch, cs), + DBMEMCONF_REGD(ddr_density[ch] + [cs])); + } + } + mmio_write_32(DBSC_DBMEMCONF(ch, 2), 0x00000000U); + mmio_write_32(DBSC_DBMEMCONF(ch, 3), 0x00000000U); + } + + mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010U); + + /* set DBI */ + if (board_cnf->dbi_en != 0U) { + mmio_write_32(DBSC_DBDBICNT, 0x00000003U); + } + + /* set REFCYCLE */ + data_l = (get_refperiod()) * ddr_mbps / 2000U / ddr_mbpsdiv; + mmio_write_32(DBSC_DBRFCNF1, 0x00080000U | (data_l & 0x0000ffffU)); + mmio_write_32(DBSC_DBRFCNF2, 0x00010000U | DBSC_REFINTS); + +#if RCAR_REWT_TRAINING != 0 + /* Periodic-WriteDQ Training seeting */ + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10)) { + /* G2M Ver.1.0 not support */ + } else { + /* G2M Ver.1.1 or later */ + mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000U); + + ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04U); + ddr_setval_ach_as(_reg_PHY_WDQLVL_QTR_DLY_STEP, 0x0FU); + ddr_setval_ach_as(_reg_PHY_WDQLVL_DLY_STEP, 0x50U); + ddr_setval_ach_as(_reg_PHY_WDQLVL_DQDM_SLV_DLY_START, 0x0300U); + + ddr_setval_ach(_reg_PI_WDQLVL_CS_MAP, + ddrtbl_getval(_cnf_DDR_PI_REGSET, + _reg_PI_WDQLVL_CS_MAP)); + ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1fU); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00U); + ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01U); + ddr_setval_ach(_reg_PI_TREF_F0, 0x0000U); + ddr_setval_ach(_reg_PI_TREF_F1, 0x0000U); + ddr_setval_ach(_reg_PI_TREF_F2, 0x0000U); + + if (prr_product == PRR_PRODUCT_M3) { + ddr_setval_ach(_reg_PI_WDQLVL_EN, 0x02U); + } else { + ddr_setval_ach(_reg_PI_WDQLVL_EN_F1, 0x02U); + } + ddr_setval_ach(_reg_PI_WDQLVL_PERIODIC, 0x01U); + + /* DFI_PHYMSTR_ACK , WTmode setting */ + /* DFI_PHYMSTR_ACK: WTmode =b'01 */ + mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011U); + } +#endif /* RCAR_REWT_TRAINING */ + /* periodic dram zqcal enable */ + mmio_write_32(DBSC_DBCALCNF, 0x01000010U); + + /* periodic phy ctrl update enable */ + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut < PRR_PRODUCT_30)) { + /* non : G2M Ver.1.x not support */ + } else { + mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001U); + } + +#ifdef DDR_BACKUPMODE + /* SRX */ + srx = 0x0A840001U; /* for All channels */ + if (ddr_backup == DRAM_BOOT_STATUS_WARM) { +#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0, 1 only) */ + NOTICE("BL2: [DEBUG_MESS] DDR_BACKUPMODE_HALF\n"); + srx = 0x0A040001U; +#endif /* DDR_BACKUPMODE_HALF */ + send_dbcmd(srx); + } +#endif /* DDR_BACKUPMODE */ + + /* set Auto Refresh */ + mmio_write_32(DBSC_DBRFEN, 0x00000001U); + +#if RCAR_REWT_TRAINING != 0 + /* Periodic WriteDQ Traning */ + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10)) { + /* non : G2M Ver.1.0 not support */ + } else { + /* G2M Ver.1.1 or later */ + ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100U); + } +#endif /* RCAR_REWT_TRAINING */ + + /* dram access enable */ + mmio_write_32(DBSC_DBACEN, 0x00000001U); + + MSG_LF(__func__ "(done)"); +} + +/* DFI_INIT_START */ +static uint32_t dfi_init_start(void) +{ + uint32_t ch; + uint32_t phytrainingok; + uint32_t retry; + uint32_t data_l; + uint32_t ret = 0U; + const uint32_t RETRY_MAX = 0x10000U; + + ddr_setval_ach_as(_reg_PHY_DLL_RST_EN, 0x02U); + dsb_sev(); + ddrphy_regif_idle(); + + /* dll_rst negate */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT3(ch), 0x0000CF01U); + } + dsb_sev(); + + /* wait init_complete */ + phytrainingok = 0U; + retry = 0U; + while (retry++ < RETRY_MAX) { + foreach_vch(ch) { + data_l = mmio_read_32(DBSC_DBDFISTAT(ch)); + if (data_l & 0x00000001U) { + phytrainingok |= (1U << ch); + } + } + dsb_sev(); + if (phytrainingok == ddr_phyvalid) { + break; + } + if (retry % 256U == 0U) { + ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01U); + } + } + + /* all ch ok? */ + if ((phytrainingok & ddr_phyvalid) != ddr_phyvalid) { + ret = 0xffU; + goto done; + } + + /* + * dbdficnt0: + * dfi_dram_clk_disable=0 + * dfi_frequency = 0 + * freq_ratio = 01 (2:1) + * init_start =0 + */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBDFICNT(ch), 0x00000010U); + } + dsb_sev(); +done: + return ret; +} + +/* drivability setting : CMOS MODE ON/OFF */ +static void change_lpddr4_en(uint32_t mode) +{ + uint32_t ch; + uint32_t i; + uint32_t data_l; + const uint32_t _reg_PHY_PAD_DRIVE_X[3] = { + _reg_PHY_PAD_ADDR_DRIVE, + _reg_PHY_PAD_CLK_DRIVE, + _reg_PHY_PAD_CS_DRIVE + }; + + foreach_vch(ch) { + for (i = 0U; i < 3U; i++) { + data_l = ddr_getval(ch, _reg_PHY_PAD_DRIVE_X[i]); + if (mode != 0U) { + data_l |= (1U << 14); + } else { + data_l &= ~(1U << 14); + } + ddr_setval(ch, _reg_PHY_PAD_DRIVE_X[i], data_l); + } + } +} + +/* drivability setting */ +static uint32_t set_term_code(void) +{ + uint32_t i; + uint32_t ch, index; + uint32_t data_l; + uint32_t chip_id[2]; + uint32_t term_code; + uint32_t override; + + term_code = ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PAD_DATA_TERM); + override = 0U; + for (i = 0U; i < 2U; i++) { + chip_id[i] = mmio_read_32(LIFEC_CHIPID(i)); + } + + index = 0U; + while (true) { + if (termcode_by_sample[index][0] == 0xffffffff) { + break; + } + if ((termcode_by_sample[index][0] == chip_id[0]) && + (termcode_by_sample[index][1] == chip_id[1])) { + term_code = termcode_by_sample[index][2]; + override = 1; + break; + } + index++; + } + + if (override != 0U) { + for (index = 0U; index < _reg_PHY_PAD_TERM_X_NUM; index++) { + data_l = + ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PAD_TERM_X[index]); + data_l = (data_l & 0xfffe0000U) | term_code; + ddr_setval_ach(_reg_PHY_PAD_TERM_X[index], data_l); + } + } else if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10)) { + /* non */ + } else { + ddr_setval_ach(_reg_PHY_PAD_TERM_X[0], + (ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET, + _reg_PHY_PAD_TERM_X[0]) & 0xFFFE0000U)); + ddr_setval_ach(_reg_PHY_CAL_CLEAR_0, 0x01U); + ddr_setval_ach(_reg_PHY_CAL_START_0, 0x01U); + foreach_vch(ch) { + do { + data_l = + ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0); + } while (!(data_l & 0x00800000U)); + } + + /* G2M Ver.1.1 or later */ + foreach_vch(ch) { + for (index = 0U; index < _reg_PHY_PAD_TERM_X_NUM; + index++) { + data_l = ddr_getval(ch, _reg_PHY_PAD_TERM_X[index]); + ddr_setval(ch, _reg_PHY_PAD_TERM_X[index], + (data_l & 0xFFFE0FFFU) | 0x00015000U); + } + } + } + + ddr_padcal_tcompensate_getinit(override); + + return 0U; +} + +/* DDR mode register setting */ +static void ddr_register_set(void) +{ + int32_t fspwp; + uint32_t tmp; + + for (fspwp = 1; fspwp >= 0; fspwp--) { + /*MR13, fspwp */ + send_dbcmd(0x0e840d08U | ((2U - fspwp) << 6)); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr1_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840100U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr2_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840200U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr3_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840300U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr11_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840b00U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr12_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840c00U | tmp); + + tmp = ddrtbl_getval(_cnf_DDR_PI_REGSET, + reg_pi_mr14_data_fx_csx[fspwp][0]); + send_dbcmd(0x0e840e00U | tmp); + /* MR22 */ + send_dbcmd(0x0e841616U); + + /* ZQCAL start */ + send_dbcmd(0x0d84004FU); + + /* ZQLAT */ + send_dbcmd(0x0d840051U); + } + + /* MR13, fspwp */ + send_dbcmd(0x0e840d08U); +} + +/* Training handshake functions */ +static inline uint32_t wait_freqchgreq(uint32_t assert) +{ + uint32_t data_l; + uint32_t count; + uint32_t ch; + + count = 100000U; + + if (assert != 0U) { + do { + data_l = 1U; + foreach_vch(ch) { + data_l &= mmio_read_32(DBSC_DBPDSTAT(ch)); + } + count = count - 1U; + } while (((data_l & 0x01U) != 0x01U) && (count != 0U)); + } else { + do { + data_l = 0U; + foreach_vch(ch) { + data_l |= mmio_read_32(DBSC_DBPDSTAT(ch)); + } + count = count - 1U; + } while (((data_l & 0x01U) != 0x00U) && (count != 0U)); + } + + return (count == 0U); +} + +static inline void set_freqchgack(uint32_t assert) +{ + uint32_t ch; + uint32_t data_l; + + if (assert != 0U) { + data_l = 0x0CF20000U; + } else { + data_l = 0x00000000U; + } + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT2(ch), data_l); + } +} + +static inline void set_dfifrequency(uint32_t freq) +{ + uint32_t ch; + + foreach_vch(ch) { + mmio_clrsetbits_32(DBSC_DBDFICNT(ch), 0x1fU << 24, freq << 24); + } + dsb_sev(); +} + +static uint32_t pll3_freq(uint32_t on) +{ + uint32_t timeout; + + timeout = wait_freqchgreq(1U); + + if (timeout != 0U) { + return 1U; + } + + pll3_control(on); + set_dfifrequency(on); + + set_freqchgack(1U); + timeout = wait_freqchgreq(0U); + set_freqchgack(0U); + + if (timeout != 0U) { + FATAL_MSG("BL2: Time out[2]\n"); + return 1U; + } + + return 0U; +} + +/* update dly */ +static void update_dly(void) +{ + ddr_setval_ach(_reg_SC_PHY_MANUAL_UPDATE, 0x01U); + ddr_setval_ach(_reg_PHY_ADRCTL_MANUAL_UPDATE, 0x01U); +} + +/* training by pi */ +static uint32_t pi_training_go(void) +{ + uint32_t flag; + uint32_t data_l; + uint32_t retry; + const uint32_t RETRY_MAX = 4096U * 16U; + uint32_t ch; + uint32_t mst_ch; + uint32_t cur_frq; + uint32_t complete; + uint32_t frqchg_req; + + /* pi_start */ + ddr_setval_ach(_reg_PI_START, 0x01U); + foreach_vch(ch) { + ddr_getval(ch, _reg_PI_INT_STATUS); + } + + /* set dfi_phymstr_ack = 1 */ + mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000001U); + dsb_sev(); + + /* wait pi_int_status[0] */ + mst_ch = 0U; + flag = 0U; + complete = 0U; + cur_frq = 0U; + for (retry = 0U; retry < RETRY_MAX; retry++) { + frqchg_req = mmio_read_32(DBSC_DBPDSTAT(mst_ch)) & 0x01; + + if (frqchg_req != 0U) { + if (cur_frq != 0U) { + /* Low frequency */ + flag = pll3_freq(0U); + cur_frq = 0U; + } else { + /* High frequency */ + flag = pll3_freq(1U); + cur_frq = 1U; + } + if (flag != 0U) { + break; + } + } else { + if (cur_frq != 0U) { + foreach_vch(ch) { + if ((complete & (1U << ch)) != 0U) { + continue; + } + data_l = ddr_getval(ch, _reg_PI_INT_STATUS); + if ((data_l & 0x01U) != 0U) { + complete |= (1U << ch); + } + } + if (complete == ddr_phyvalid) { + break; + } + } + } + } + foreach_vch(ch) { + /* dummy read */ + data_l = ddr_getval_s(ch, 0U, _reg_PHY_CAL_RESULT2_OBS_0); + data_l = ddr_getval(ch, _reg_PI_INT_STATUS); + ddr_setval(ch, _reg_PI_INT_ACK, data_l); + } + if (ddrphy_regif_chk() != 0U) { + complete = 0xfdU; + } + return complete; +} + +/* Initialize DDR */ +static uint32_t init_ddr(void) +{ + uint32_t i; + uint32_t data_l; + uint32_t phytrainingok; + uint32_t ch, slice; + uint32_t index; + uint32_t err; + int16_t adj; + + MSG_LF(__func__ ":0\n"); + + /* unlock phy */ + /* Unlock DDRPHY register(AGAIN) */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDLK(ch), 0x0000A55AU); + } + dsb_sev(); + + reg_ddrphy_write_a(0x00001010U, 0x00000001U); + /* DBSC register pre-setting */ + dbsc_regset_pre(); + + /* load ddrphy registers */ + ddrtbl_load(); + + /* configure ddrphy registers */ + ddr_config(); + + /* dfi_reset assert */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT0(ch), 0x01U); + } + dsb_sev(); + + /* dbsc register set */ + dbsc_regset(); + MSG_LF(__func__ ":1\n"); + + /* dfi_reset negate */ + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDCNT0(ch), 0x00U); + } + dsb_sev(); + + /* dfi_init_start (start ddrphy) */ + err = dfi_init_start(); + if (err != 0U) { + return INITDRAM_ERR_I; + } + MSG_LF(__func__ ":2\n"); + + /* ddr backupmode end */ +#ifdef DDR_BACKUPMODE + if (ddr_backup != 0U) { + NOTICE("BL2: [WARM_BOOT]\n"); + } else { + NOTICE("BL2: [COLD_BOOT]\n"); + } +#endif + MSG_LF(__func__ ":3\n"); + + /* override term code after dfi_init_complete */ + err = set_term_code(); + if (err != 0U) { + return INITDRAM_ERR_I; + } + MSG_LF(__func__ ":4\n"); + + /* rx offset calibration */ + if (prr_cut > PRR_PRODUCT_11) { + err = rx_offset_cal_hw(); + } else { + err = rx_offset_cal(); + } + if (err != 0U) { + return INITDRAM_ERR_O; + } + MSG_LF(__func__ ":5\n"); + + /* Dummy PDE */ + send_dbcmd(0x08840000U); + + /* PDX */ + send_dbcmd(0x08840001U); + + /* check register i/f is alive */ + err = ddrphy_regif_chk(); + if (err != 0U) { + return INITDRAM_ERR_O; + } + MSG_LF(__func__ ":6\n"); + + /* phy initialize end */ + + /* setup DDR mode registers */ + /* CMOS MODE */ + change_lpddr4_en(0); + + /* MRS */ + ddr_register_set(); + + /* Thermal sensor setting */ + /* THCTR Bit6: PONM=0 , Bit0: THSST=1 */ + data_l = (mmio_read_32(THS1_THCTR) & 0xFFFFFFBFU) | 0x00000001U; + mmio_write_32(THS1_THCTR, data_l); + + /* LPDDR4 MODE */ + change_lpddr4_en(1); + + MSG_LF(__func__ ":7\n"); + + /* mask CS_MAP if RANKx is not found */ + foreach_vch(ch) { + data_l = ddr_getval(ch, _reg_PI_CS_MAP); + if ((ch_have_this_cs[1] & (1U << ch)) == 0U) { + data_l = data_l & 0x05U; + } + ddr_setval(ch, _reg_PI_CS_MAP, data_l); + } + + /* exec pi_training */ + reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), + BIT(ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN))); + ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x00U); + + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_EN, + ((ch_have_this_cs[1]) >> ch) & 0x01U); + } + } + + phytrainingok = pi_training_go(); + + if (ddr_phyvalid != (phytrainingok & ddr_phyvalid)) { + return INITDRAM_ERR_T | phytrainingok; + } + + MSG_LF(__func__ ":8\n"); + + /* CACS DLY ADJUST */ + data_l = board_cnf->cacs_dly + (uint32_t)_f_scale_adj(board_cnf->cacs_dly_adj); + foreach_vch(ch) { + for (i = 0U; i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) { + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[i]); + ddr_setval(ch, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i], + data_l + (uint32_t)adj); + } + + if (ddr_phycaslice == 1U) { + for (i = 0U; i < 6U; i++) { + index = i + _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; + adj = _f_scale_adj(board_cnf->ch[ch].cacs_adj[index]); + ddr_setval_s(ch, 2U, + _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i], + data_l + (uint32_t)adj); + } + } + } + + update_dly(); + MSG_LF(__func__ ":9\n"); + + /* Adjust write path latency */ + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD) != 0U) { + adjust_wpath_latency(); + } + + /* RDQLVL Training */ + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0U) { + ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x01U); + } + + err = rdqdm_man(); + + if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0U) { + ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x00U); + } + + if (err != 0U) { + return INITDRAM_ERR_T; + } + update_dly(); + MSG_LF(__func__ ":10\n"); + + /* WDQLVL Training */ + err = wdqdm_man(); + if (err != 0U) { + return INITDRAM_ERR_T; + } + update_dly(); + MSG_LF(__func__ ":11\n"); + + dbsc_regset_post(); + MSG_LF(__func__ ":12\n"); + + return phytrainingok; +} + +/* SW LEVELING COMMON */ +static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick) +{ + const uint32_t RETRY_MAX = 0x1000U; + uint32_t ch, data_l; + uint32_t waiting; + uint32_t retry; + uint32_t err = 0U; + + /* set EXIT -> OP_DONE is cleared */ + ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01); + + /* kick */ + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn % 2U] & (1U << ch)) != 0U) { + ddr_setval(ch, reg_cs, ddr_csn); + ddr_setval(ch, reg_kick, 0x01U); + } + } + foreach_vch(ch) { + /*PREPARE ADDR REGISTER (for SWLVL_OP_DONE) */ + ddr_getval(ch, _reg_PI_SWLVL_OP_DONE); + } + waiting = ch_have_this_cs[ddr_csn % 2U]; + dsb_sev(); + retry = RETRY_MAX; + do { + foreach_vch(ch) { + if ((waiting & (1U << ch)) == 0U) { + continue; + } + data_l = ddr_getval(ch, _reg_PI_SWLVL_OP_DONE); + if ((data_l & 0x01U) != 0U) { + waiting &= ~(1U << ch); + } + } + retry--; + } while ((waiting != 0U) && (retry > 0U)); + if (retry == 0U) { + err = 1U; + } + + dsb_sev(); + /* set EXIT -> OP_DONE is cleared */ + ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01U); + dsb_sev(); + + return err; +} + +/* WDQ TRAINING */ +#ifndef DDR_FAST_INIT +static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn) +{ + uint32_t cs, slice; + uint32_t data_l; + int32_t i, k; + + /* clr of training results buffer */ + cs = ddr_csn % 2U; + data_l = board_cnf->dqdm_dly_w; + for (slice = 0U; slice < SLICE_CNT; slice++) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + for (i = 0; i <= 8; i++) { + if ((ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch)) != 0U) { + wdqdm_dly[ch][cs][slice][i] = + wdqdm_dly[ch][CS_CNT - 1 - cs][slice][i]; + } else { + wdqdm_dly[ch][cs][slice][i] = data_l; + } + wdqdm_le[ch][cs][slice][i] = 0U; + wdqdm_te[ch][cs][slice][i] = 0U; + } + wdqdm_st[ch][cs][slice] = 0U; + wdqdm_win[ch][cs][slice] = 0U; + } +} + +static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn) +{ + const uint32_t _par_WDQLVL_RETRY_THRES = 0x7c0U; + uint32_t cs, slice; + uint32_t data_l; + int32_t min_win; + int32_t i, k; + uint32_t err; + int32_t win; + int8_t _adj; + int16_t adj; + uint32_t dq; + + /* analysis of training results */ + err = 0U; + for (slice = 0U; slice < SLICE_CNT; slice += 1U) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + cs = ddr_csn % 2U; + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs); + for (i = 0; i < 9; i++) { + dq = slice * 8U + i; + if (i == 8) { + _adj = board_cnf->ch[ch].dm_adj_w[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_w[dq]; + } + adj = _f_scale_adj(_adj); + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_CLK_WRX_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, _reg_PHY_CLK_WRX_SLAVE_DELAY[i], + data_l); + wdqdm_dly[ch][cs][slice][i] = data_l; + } + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x00); + data_l = ddr_getval_s(ch, slice, _reg_PHY_WDQLVL_STATUS_OBS); + wdqdm_st[ch][cs][slice] = data_l; + min_win = INT_LEAST32_MAX; + for (i = 0; i <= 8; i++) { + ddr_setval_s(ch, slice, _reg_PHY_WDQLVL_DQDM_OBS_SELECT, + i); + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_WDQLVL_DQDM_TE_DLY_OBS); + wdqdm_te[ch][cs][slice][i] = data_l; + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_WDQLVL_DQDM_LE_DLY_OBS); + wdqdm_le[ch][cs][slice][i] = data_l; + win = (int32_t)wdqdm_te[ch][cs][slice][i] - + wdqdm_le[ch][cs][slice][i]; + if (min_win > win) { + min_win = win; + } + if (data_l >= _par_WDQLVL_RETRY_THRES) { + err = 2; + } + } + wdqdm_win[ch][cs][slice] = min_win; + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, + ((ch_have_this_cs[1]) >> ch) & 0x01); + } + return err; +} +#endif/* DDR_FAST_INIT */ + +static void wdqdm_cp(uint32_t ddr_csn, uint32_t restore) +{ + uint32_t tgt_cs, src_cs; + uint32_t ch, slice; + uint32_t tmp_r; + uint32_t i; + + /* copy of training results */ + foreach_vch(ch) { + for (tgt_cs = 0U; tgt_cs < CS_CNT; tgt_cs++) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX, + tgt_cs); + src_cs = ddr_csn % 2U; + if ((ch_have_this_cs[1] & (1U << ch)) == 0U) { + src_cs = 0U; + } + for (i = 0U; i <= 4U; i += 4U) { + if (restore != 0U) { + tmp_r = rdqdm_dly[ch][tgt_cs][slice][i]; + } else { + tmp_r = rdqdm_dly[ch][src_cs][slice][i]; + } + + ddr_setval_s(ch, slice, + _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], + tmp_r); + } + } + } + } +} + +static uint32_t wdqdm_man1(void) +{ + uint32_t mr14_csab0_bak[DRAM_CH_CNT]; + uint32_t ch, cs, ddr_csn; + uint32_t data_l; + uint32_t err = 0U; +#ifndef DDR_FAST_INIT + uint32_t err_flg = 0U; +#endif/* DDR_FAST_INIT */ + + /* CLEAR PREV RESULT */ + for (cs = 0U; cs < CS_CNT; cs++) { + ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_INDEX, cs); + ddr_setval_ach_as(_reg_PHY_WDQLVL_CLR_PREV_RESULTS, 0x01U); + } + ddrphy_regif_idle(); + + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + if (((prr_product == PRR_PRODUCT_M3) && + (prr_cut == PRR_PRODUCT_10))) { + wdqdm_cp(ddr_csn, 0U); + } + + foreach_vch(ch) { + data_l = ddr_getval(ch, reg_pi_mr14_data_fx_csx[1][ddr_csn]); + ddr_setval(ch, reg_pi_mr14_data_fx_csx[1][0], data_l); + } + + /* KICK WDQLVL */ + err = swlvl1(ddr_csn, _reg_PI_WDQLVL_CS, _reg_PI_WDQLVL_REQ); + if (err != 0U) { + goto err_exit; + } + + if (ddr_csn == 0U) { + foreach_vch(ch) { + mr14_csab0_bak[ch] = ddr_getval(ch, + reg_pi_mr14_data_fx_csx[1][0]); + } + } else { + foreach_vch(ch) { + ddr_setval(ch, reg_pi_mr14_data_fx_csx[1][0], + mr14_csab0_bak[ch]); + } + } +#ifndef DDR_FAST_INIT + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn % 2U] & (1U << ch)) == 0U) { + wdqdm_clr1(ch, ddr_csn); + continue; + } + err = wdqdm_ana1(ch, ddr_csn); + if (err != 0U) { + err_flg |= (1U << (ddr_csn * 4U + ch)); + } + ddrphy_regif_idle(); + } +#endif/* DDR_FAST_INIT */ + } +err_exit: +#ifndef DDR_FAST_INIT + err |= err_flg; +#endif/* DDR_FAST_INIT */ + + return err; +} + +static uint32_t wdqdm_man(void) +{ + uint32_t datal, ch, ddr_csn, mr14_bkup[4][4]; + const uint32_t retry_max = 0x10U; + uint32_t err, retry_cnt; + + datal = RL + js2[js2_tdqsck] + (16U / 2U) + 1U - WL + 2U + 2U + 19U; + if ((mmio_read_32(DBSC_DBTR(11)) & 0xFF) > datal) { + datal = mmio_read_32(DBSC_DBTR(11)) & 0xFF; + } + ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, datal); + + ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR, + (mmio_read_32(DBSC_DBTR(12)) & 0xFF) + 10); + + ddr_setval_ach(_reg_PI_TRFC_F0, mmio_read_32(DBSC_DBTR(13)) & 0x1FF); + ddr_setval_ach(_reg_PI_TRFC_F1, mmio_read_32(DBSC_DBTR(13)) & 0x1FF); + + retry_cnt = 0U; + err = 0U; + do { + ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x01); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE, 0x01); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x0C); + dsb_sev(); + err = wdqdm_man1(); + foreach_vch(ch) { + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + mr14_bkup[ch][ddr_csn] = + ddr_getval(ch, reg_pi_mr14_data_fx_csx + [1][ddr_csn]); + dsb_sev(); + } + } + + ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x04); + + pvtcode_update(); + err = wdqdm_man1(); + foreach_vch(ch) { + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + mr14_bkup[ch][ddr_csn] = + (mr14_bkup[ch][ddr_csn] + + ddr_getval(ch, reg_pi_mr14_data_fx_csx + [1][ddr_csn])) / 2U; + ddr_setval(ch, + reg_pi_mr14_data_fx_csx[1] + [ddr_csn], + mr14_bkup[ch][ddr_csn]); + } + } + + ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_START_POINT, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT, 0x0U); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_STEPSIZE, 0x0U); + + pvtcode_update2(); + err = wdqdm_man1(); + ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x0U); + + } while ((err != 0U) && (++retry_cnt < retry_max)); + + if (prr_product == PRR_PRODUCT_M3 && prr_cut <= PRR_PRODUCT_10) { + wdqdm_cp(0U, 1U); + } + + return (retry_cnt >= retry_max); +} + +/* RDQ TRAINING */ +#ifndef DDR_FAST_INIT +static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn) +{ + uint32_t cs, slice; + uint32_t data_l; + int32_t i, k; + + /* clr of training results buffer */ + cs = ddr_csn % 2U; + data_l = board_cnf->dqdm_dly_r; + for (slice = 0U; slice < SLICE_CNT; slice++) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + for (i = 0; i <= 8; i++) { + if ((ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch)) != 0U) { + rdqdm_dly[ch][cs][slice][i] = + rdqdm_dly[ch][CS_CNT - 1 - cs][slice][i]; + rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = + rdqdm_dly[ch][CS_CNT - 1 - cs][slice + SLICE_CNT][i]; + } else { + rdqdm_dly[ch][cs][slice][i] = data_l; + rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = data_l; + } + rdqdm_le[ch][cs][slice][i] = 0U; + rdqdm_le[ch][cs][slice + SLICE_CNT][i] = 0U; + rdqdm_te[ch][cs][slice][i] = 0U; + rdqdm_te[ch][cs][slice + SLICE_CNT][i] = 0U; + rdqdm_nw[ch][cs][slice][i] = 0U; + rdqdm_nw[ch][cs][slice + SLICE_CNT][i] = 0U; + } + rdqdm_st[ch][cs][slice] = 0U; + rdqdm_win[ch][cs][slice] = 0U; + } +} + +static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn) +{ + uint32_t rdq_status_obs_select; + uint32_t cs, slice; + uint32_t data_l; + uint32_t err; + uint32_t dq; + int32_t min_win; + int8_t _adj; + int16_t adj; + int32_t min_win; + int32_t win; + int32_t i, k; + + /* analysis of training results */ + err = 0U; + for (slice = 0U; slice < SLICE_CNT; slice++) { + k = (board_cnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f; + if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2))) { + continue; + } + + cs = ddr_csn % 2U; + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs); + ddrphy_regif_idle(); + + ddr_getval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX); + ddrphy_regif_idle(); + + for (i = 0; i <= 8; i++) { + dq = slice * 8 + i; + if (i == 8) { + _adj = board_cnf->ch[ch].dm_adj_r[slice]; + } else { + _adj = board_cnf->ch[ch].dq_adj_r[dq]; + } + + adj = _f_scale_adj(_adj); + + data_l = ddr_getval_s(ch, slice, + _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, + _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], + data_l); + rdqdm_dly[ch][cs][slice][i] = data_l; + + data_l = ddr_getval_s(ch, slice, + _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, + _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i], + data_l); + rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = data_l; + } + min_win = INT_LEAST32_MAX; + for (i = 0; i <= 8; i++) { + data_l = + ddr_getval_s(ch, slice, _reg_PHY_RDLVL_STATUS_OBS); + rdqdm_st[ch][cs][slice] = data_l; + rdqdm_st[ch][cs][slice + SLICE_CNT] = data_l; + /* k : rise/fall */ + for (k = 0; k < 2; k++) { + if (i == 8) { + rdq_status_obs_select = 16 + 8 * k; + } else { + rdq_status_obs_select = i + k * 8; + } + ddr_setval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_OBS_SELECT, + rdq_status_obs_select); + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS); + rdqdm_le[ch][cs][slice + SLICE_CNT * k][i] = data_l; + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS); + rdqdm_te[ch][cs][slice + SLICE_CNT * k][i] = data_l; + + data_l = + ddr_getval_s(ch, slice, + _reg_PHY_RDLVL_RDDQS_DQ_NUM_WINDOWS_OBS); + rdqdm_nw[ch][cs][slice + SLICE_CNT * k][i] = data_l; + + win = + (int32_t)rdqdm_te[ch][cs][slice + + SLICE_CNT * + k][i] - + rdqdm_le[ch][cs][slice + SLICE_CNT * k][i]; + if (i != 8) { + if (min_win > win) { + min_win = win; + } + } + } + } + rdqdm_win[ch][cs][slice] = min_win; + if (min_win <= 0) { + err = 2; + } + } + return err; +} +#else /* DDR_FAST_INIT */ +static void rdqdm_man1_set(uint32_t ddr_csn, uint32_t ch, uint32_t slice) +{ + uint32_t i, adj, data_l; + + for (i = 0U; i <= 8U; i++) { + if (i == 8U) { + adj = _f_scale_adj(board_cnf->ch[ch].dm_adj_r[slice]); + } else { + adj = _f_scale_adj(board_cnf->ch[ch].dq_adj_r[slice * 8U + i]); + } + ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, ddr_csn); + data_l = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], data_l); + rdqdm_dly[ch][ddr_csn][slice][i] = data_l; + rdqdm_dly[ch][ddr_csn | 1U][slice][i] = data_l; + + data_l = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) + adj; + ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i], data_l); + rdqdm_dly[ch][ddr_csn][slice + SLICE_CNT][i] = data_l; + rdqdm_dly[ch][ddr_csn | 1U][slice + SLICE_CNT][i] = data_l; + } +} +#endif /* DDR_FAST_INIT */ + +static uint32_t rdqdm_man1(void) +{ + uint32_t ch; + uint32_t ddr_csn; + uint32_t val; +#ifdef DDR_FAST_INIT + uint32_t slice; +#endif/* DDR_FAST_INIT */ + uint32_t err; + + /* manual execution of training */ + err = 0U; + + for (ddr_csn = 0U; ddr_csn < CSAB_CNT; ddr_csn++) { + /* KICK RDQLVL */ + err = swlvl1(ddr_csn, _reg_PI_RDLVL_CS, _reg_PI_RDLVL_REQ); + if (err != 0U) { + goto err_exit; + } +#ifndef DDR_FAST_INIT + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn % 2] & (1U << ch)) == 0U) { + rdqdm_clr1(ch, ddr_csn); + ddrphy_regif_idle(); + continue; + } + err = rdqdm_ana1(ch, ddr_csn); + ddrphy_regif_idle(); + if (err != 0U) { + goto err_exit; + } + } +#else/* DDR_FAST_INIT */ + foreach_vch(ch) { + if ((ch_have_this_cs[ddr_csn] & (1U << ch)) != 0U) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + val = ddr_getval_s(ch, slice, _reg_PHY_RDLVL_STATUS_OBS); + if (val != 0x0D00FFFFU) { + err = (1U << ch) | (0x10U << slice); + goto err_exit; + } + } + } + if ((prr_product == PRR_PRODUCT_M3) && + (prr_cut <= PRR_PRODUCT_10)) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + rdqdm_man1_set(ddr_csn, ch, slice); + } + } + } + ddrphy_regif_idle(); + +#endif/* DDR_FAST_INIT */ + } + +err_exit: + return err; +} + +static uint32_t rdqdm_man(void) +{ + uint32_t err, retry_cnt; + const uint32_t retry_max = 0x01U; + + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE, + 0x00000004U | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE, + 0x00000004U | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT, + 0xFF0FFFFFU & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_SELECT)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT, + 0xFF0FFFFFU & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_SELECT)); + + retry_cnt = 0U; + do { + err = rdqdm_man1(); + ddrphy_regif_idle(); + } while ((err != 0U) && (++retry_cnt < retry_max)); + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_ENABLE)); + ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQ_TSEL_SELECT)); + ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT, + ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, + _reg_PHY_DQS_TSEL_SELECT)); + + return (retry_cnt >= retry_max); +} + +/* rx offset calibration */ +static int32_t _find_change(uint64_t val, uint32_t dir) +{ + int32_t i; + uint32_t startval; + uint32_t curval; + const int32_t VAL_END = 0x3fU; + + if (dir == 0U) { + startval = (val & 0x01U); + for (i = 1; i <= VAL_END; i++) { + curval = (val >> i) & 0x01U; + if (curval != startval) { + return i; + } + } + return VAL_END; + } + + startval = (val >> dir) & 0x01U; + for (i = (int32_t)dir - 1; i >= 0; i--) { + curval = (val >> i) & 0x01U; + if (curval != startval) { + return i; + } + } + + return 0; +} + +static uint32_t _rx_offset_cal_updn(uint32_t code) +{ + const uint32_t CODE_MAX = 0x40U; + uint32_t tmp; + + if (code == 0U) { + tmp = (1U << 6) | (CODE_MAX - 1U); + } else { + tmp = (code << 6) | (CODE_MAX - code); + } + + return tmp; +} + +static uint32_t rx_offset_cal(void) +{ + uint32_t index; + uint32_t code; + const uint32_t CODE_MAX = 0x40U; + const uint32_t CODE_STEP = 2U; + uint32_t ch, slice; + uint32_t tmp; + uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT]; + uint64_t val[DRAM_CH_CNT][SLICE_CNT][_reg_PHY_RX_CAL_X_NUM]; + uint64_t tmpval; + int32_t lsb, msb; + + ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x01); + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; index++) { + val[ch][slice][index] = 0U; + } + } + } + + for (code = 0U; code < CODE_MAX / CODE_STEP; code++) { + tmp = _rx_offset_cal_updn(code * CODE_STEP); + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; index++) { + ddr_setval_ach_as(_reg_PHY_RX_CAL_X[index], tmp); + } + dsb_sev(); + ddr_getval_ach_as(_reg_PHY_RX_CAL_OBS, (uint32_t *)tmp_ach_as); + + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + tmp = tmp_ach_as[ch][slice]; + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; + index++) { + if ((tmp & (1U << index)) != 0U) { + val[ch][slice][index] |= + (1ULL << code); + } else { + val[ch][slice][index] &= + ~(1ULL << code); + } + } + } + } + } + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + for (index = 0U; index < _reg_PHY_RX_CAL_X_NUM; + index++) { + tmpval = val[ch][slice][index]; + lsb = _find_change(tmpval, 0U); + msb = _find_change(tmpval, + (CODE_MAX / CODE_STEP) - 1U); + tmp = (lsb + msb) >> 1U; + + tmp = _rx_offset_cal_updn(tmp * CODE_STEP); + ddr_setval_s(ch, slice, + _reg_PHY_RX_CAL_X[index], tmp); + } + } + } + ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00); + + return 0U; +} + +static uint32_t rx_offset_cal_hw(void) +{ + uint32_t ch, slice; + uint32_t retry; + uint32_t complete; + uint32_t tmp; + uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT]; + + ddr_setval_ach_as(_reg_PHY_RX_CAL_X[9], 0x00); + ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00); + ddr_setval_ach_as(_reg_PHY_RX_CAL_SAMPLE_WAIT, 0x0f); + + retry = 0U; + while (retry < 4096U) { + if ((retry & 0xffU) == 0U) { + ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01); + } + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + tmp_ach_as[ch][slice] = + ddr_getval_s(ch, slice, + _reg_PHY_RX_CAL_X[9]); + } + } + + complete = 1U; + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice++) { + tmp = tmp_ach_as[ch][slice]; + tmp = (tmp & 0x3fU) + ((tmp >> 6) & 0x3fU); + if (tmp != 0x40U) { + complete = 0U; + } + } + } + if (complete != 0U) { + break; + } + + retry++; + } + + return (complete == 0U); +} + +/* adjust wpath latency */ +static void adjust_wpath_latency(void) +{ + uint32_t ch, cs, slice; + uint32_t dly; + uint32_t wpath_add; + const uint32_t _par_EARLY_THRESHOLD_VAL = 0x180U; + + foreach_vch(ch) { + for (slice = 0U; slice < SLICE_CNT; slice += 1U) { + for (cs = 0U; cs < CS_CNT; cs++) { + ddr_setval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX, + cs); + ddr_getval_s(ch, slice, + _reg_PHY_PER_CS_TRAINING_INDEX); + dly = + ddr_getval_s(ch, slice, + _reg_PHY_CLK_WRDQS_SLAVE_DELAY); + if (dly <= _par_EARLY_THRESHOLD_VAL) { + continue; + } + + wpath_add = + ddr_getval_s(ch, slice, + _reg_PHY_WRITE_PATH_LAT_ADD); + ddr_setval_s(ch, slice, + _reg_PHY_WRITE_PATH_LAT_ADD, + wpath_add - 1U); + } + } + } +} + +/* DDR Initialize entry */ +int32_t rzg_dram_init(void) +{ + uint32_t ch, cs; + uint32_t data_l; + uint32_t bus_mbps, bus_mbpsdiv; + uint32_t tmp_tccd; + uint32_t failcount; + uint32_t cnf_boardtype; + int32_t ret = INITDRAM_NG; + + /* Thermal sensor setting */ + data_l = mmio_read_32(CPG_MSTPSR5); + if ((data_l & BIT(22)) != 0U) { /* case THS/TSC Standby */ + data_l &= ~BIT(22); + cpg_write_32(CPG_SMSTPCR5, data_l); + while ((mmio_read_32(CPG_MSTPSR5) & BIT(22)) != 0U) { + /* wait bit=0 */ + } + } + + /* THCTR Bit6: PONM=0 , Bit0: THSST=0 */ + data_l = mmio_read_32(THS1_THCTR) & 0xFFFFFFBE; + mmio_write_32(THS1_THCTR, data_l); + + /* Judge product and cut */ +#ifdef RCAR_DDR_FIXED_LSI_TYPE +#if (RCAR_LSI == RCAR_AUTO) + prr_product = mmio_read_32(PRR) & PRR_PRODUCT_MASK; + prr_cut = mmio_read_32(PRR) & PRR_CUT_MASK; +#else /* RCAR_LSI */ +#ifndef RCAR_LSI_CUT + prr_cut = mmio_read_32(PRR) & PRR_CUT_MASK; +#endif /* RCAR_LSI_CUT */ +#endif /* RCAR_LSI */ +#else /* RCAR_DDR_FIXED_LSI_TYPE */ + prr_product = mmio_read_32(PRR) & PRR_PRODUCT_MASK; + prr_cut = mmio_read_32(PRR) & PRR_CUT_MASK; +#endif /* RCAR_DDR_FIXED_LSI_TYPE */ + + if (prr_product == PRR_PRODUCT_M3) { + p_ddr_regdef_tbl = + (const uint32_t *)&DDR_REGDEF_TBL[1][0]; + } else { + FATAL_MSG("BL2: DDR:Unknown Product\n"); + goto done; + } + + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut < PRR_PRODUCT_30)) { + /* non : G2M Ver.1.x not support */ + } else { + mmio_write_32(DBSC_DBSYSCNT0, 0x00001234U); + } + + /* Judge board type */ + cnf_boardtype = boardcnf_get_brd_type(prr_product); + if (cnf_boardtype >= (uint32_t)BOARDNUM) { + FATAL_MSG("BL2: DDR:Unknown Board\n"); + goto done; + } + board_cnf = (const struct _boardcnf *)&boardcnfs[cnf_boardtype]; + +/* RCAR_DRAM_SPLIT_2CH (2U) */ +#if RCAR_DRAM_SPLIT == 2 + ddr_phyvalid = board_cnf->phyvalid; +#else /* RCAR_DRAM_SPLIT_2CH */ + ddr_phyvalid = board_cnf->phyvalid; +#endif /* RCAR_DRAM_SPLIT_2CH */ + + max_density = 0U; + + for (cs = 0U; cs < CS_CNT; cs++) { + ch_have_this_cs[cs] = 0U; + } + + foreach_ech(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + ddr_density[ch][cs] = 0xffU; + } + } + + foreach_vch(ch) { + for (cs = 0U; cs < CS_CNT; cs++) { + data_l = board_cnf->ch[ch].ddr_density[cs]; + ddr_density[ch][cs] = data_l; + + if (data_l == 0xffU) { + continue; + } + if (data_l > max_density) { + max_density = data_l; + } + ch_have_this_cs[cs] |= (1U << ch); + } + } + + /* Judge board clock frequency (in MHz) */ + boardcnf_get_brd_clk(cnf_boardtype, &brd_clk, &brd_clkdiv); + if ((brd_clk / brd_clkdiv) > 25U) { + brd_clkdiva = 1U; + } else { + brd_clkdiva = 0U; + } + + /* Judge ddr operating frequency clock(in Mbps) */ + boardcnf_get_ddr_mbps(cnf_boardtype, &ddr_mbps, &ddr_mbpsdiv); + + ddr0800_mul = CLK_DIV(800U, 2U, brd_clk, brd_clkdiv * (brd_clkdiva + 1U)); + + ddr_mul = CLK_DIV(ddr_mbps, ddr_mbpsdiv * 2U, brd_clk, + brd_clkdiv * (brd_clkdiva + 1U)); + + /* Adjust tccd */ + data_l = (0x00006000 & mmio_read_32(RST_MODEMR)) >> 13; + bus_mbps = 0U; + bus_mbpsdiv = 0U; + switch (data_l) { + case 0: + bus_mbps = brd_clk * 0x60U * 2U; + bus_mbpsdiv = brd_clkdiv * 1U; + break; + case 1: + bus_mbps = brd_clk * 0x50U * 2U; + bus_mbpsdiv = brd_clkdiv * 1U; + break; + case 2: + bus_mbps = brd_clk * 0x40U * 2U; + bus_mbpsdiv = brd_clkdiv * 1U; + break; + case 3: + bus_mbps = brd_clk * 0x60U * 2U; + bus_mbpsdiv = brd_clkdiv * 2U; + break; + default: + bus_mbps = brd_clk * 0x60U * 2U; + bus_mbpsdiv = brd_clkdiv * 2U; + WARN("BL2: DDR using default values for adjusting tccd"); + break; + } + tmp_tccd = CLK_DIV(ddr_mbps * 8U, ddr_mbpsdiv, bus_mbps, bus_mbpsdiv); + if (8U * ddr_mbps * bus_mbpsdiv != tmp_tccd * bus_mbps * ddr_mbpsdiv) { + tmp_tccd = tmp_tccd + 1U; + } + + if (tmp_tccd < 8U) { + ddr_tccd = 8U; + } else { + ddr_tccd = tmp_tccd; + } + + NOTICE("BL2: DDR%d(%s)\n", ddr_mbps / ddr_mbpsdiv, RCAR_DDR_VERSION); + + MSG_LF("Start\n"); + + /* PLL Setting */ + pll3_control(1U); + + /* initialize DDR */ + data_l = init_ddr(); + if (data_l == ddr_phyvalid) { + failcount = 0U; + } else { + failcount = 1U; + } + + foreach_vch(ch) { + mmio_write_32(DBSC_DBPDLK(ch), 0x00000000U); + } + if ((prr_product == PRR_PRODUCT_M3) && (prr_cut < PRR_PRODUCT_30)) { + /* non : G2M Ver.1.x not support */ + } else { + mmio_write_32(DBSC_DBSYSCNT0, 0x00000000); + } + + if (failcount == 0U) { + ret = INITDRAM_OK; + } + +done: + return ret; +} + +static void pvtcode_update(void) +{ + uint32_t ch; + uint32_t data_l; + uint32_t pvtp[4], pvtn[4], pvtp_init, pvtn_init; + int32_t pvtp_tmp, pvtn_tmp; + + foreach_vch(ch) { + pvtn_init = (tcal.tcomp_cal[ch] & 0xFC0U) >> 6; + pvtp_init = (tcal.tcomp_cal[ch] & 0x03FU) >> 0; + + if (8912U * pvtp_init > 44230U) { + pvtp_tmp = (5000U + 8912U * pvtp_init - 44230U) / 10000U; + } else { + pvtp_tmp = + -((-(5000 + 8912 * pvtp_init - 44230)) / 10000); + } + pvtn_tmp = (5000U + 5776U * (uint32_t)pvtn_init + 30280U) / 10000U; + + pvtn[ch] = (uint32_t)pvtn_tmp + pvtn_init; + pvtp[ch] = (uint32_t)pvtp_tmp + pvtp_init; + + if (pvtn[ch] > 63U) { + pvtn[ch] = 63U; + pvtp[ch] = + (pvtp_tmp) * (63 - 6 * pvtn_tmp - + pvtn_init) / (pvtn_tmp) + + 6 * pvtp_tmp + pvtp_init; + } + + data_l = pvtp[ch] | (pvtn[ch] << 6) | 0x00015000U; + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM), + data_l | 0x00020000U); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM), + data_l); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM), + data_l); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM), + data_l); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_CS_TERM), + data_l); + } +} + +static void pvtcode_update2(void) +{ + uint32_t ch; + + foreach_vch(ch) { + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM), + tcal.init_cal[ch] | 0x00020000U); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM), + tcal.init_cal[ch]); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM), + tcal.init_cal[ch]); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM), + tcal.init_cal[ch]); + reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_CS_TERM), + tcal.init_cal[ch]); + } +} + +static void ddr_padcal_tcompensate_getinit(uint32_t override) +{ + uint32_t ch; + uint32_t data_l; + uint32_t pvtp, pvtn; + + tcal.init_temp = 0; + for (ch = 0U; ch < 4U; ch++) { + tcal.init_cal[ch] = 0U; + tcal.tcomp_cal[ch] = 0U; + } + + foreach_vch(ch) { + tcal.init_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]); + tcal.tcomp_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]); + } + + if (override == 0U) { + data_l = mmio_read_32(THS1_TEMP); + if (data_l < 2800U) { + tcal.init_temp = + (143 * (int32_t)data_l - 359000) / 1000; + } else { + tcal.init_temp = + (121 * (int32_t)data_l - 296300) / 1000; + } + + foreach_vch(ch) { + pvtp = (tcal.init_cal[ch] >> 0) & 0x000003FU; + pvtn = (tcal.init_cal[ch] >> 6) & 0x000003FU; + if ((int32_t)pvtp > + ((tcal.init_temp * 29 - 3625) / 1000)) { + pvtp = (int32_t)pvtp + + ((3625 - tcal.init_temp * 29) / 1000); + } else { + pvtp = 0U; + } + + if ((int32_t)pvtn > + ((tcal.init_temp * 54 - 6750) / 1000)) { + pvtn = (int32_t)pvtn + + ((6750 - tcal.init_temp * 54) / 1000); + } else { + pvtn = 0U; + } + + tcal.init_cal[ch] = 0x00015000U | (pvtn << 6) | pvtp; + } + tcal.init_temp = 125; + } +} + +#ifndef DDR_QOS_INIT_SETTING +/* For QoS init */ +uint8_t rzg_get_boardcnf_phyvalid(void) +{ + return ddr_phyvalid; +} +#endif /* DDR_QOS_INIT_SETTING */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_config.c new file mode 100644 index 000000000..345ef24c3 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_config.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define BOARDNUM 2 +#define BOARD_JUDGE_AUTO + +#ifdef BOARD_JUDGE_AUTO +static uint32_t _board_judge(uint32_t prr_product); + +static uint32_t boardcnf_get_brd_type(uint32_t prr_product) +{ + return _board_judge(prr_product); +} +#else /* BOARD_JUDGE_AUTO */ +static uint32_t boardcnf_get_brd_type(void) +{ + return 1U; +} +#endif /* BOARD_JUDGE_AUTO */ + +#define DDR_FAST_INIT + +struct _boardcnf_ch { + uint8_t ddr_density[CS_CNT]; + uint64_t ca_swap; + uint16_t dqs_swap; + uint32_t dq_swap[SLICE_CNT]; + uint8_t dm_swap[SLICE_CNT]; + uint16_t wdqlvl_patt[16]; + int8_t cacs_adj[16]; + int8_t dm_adj_w[SLICE_CNT]; + int8_t dq_adj_w[SLICE_CNT * 8U]; + int8_t dm_adj_r[SLICE_CNT]; + int8_t dq_adj_r[SLICE_CNT * 8U]; +}; + +struct _boardcnf { + uint8_t phyvalid; + uint8_t dbi_en; + uint16_t cacs_dly; + int16_t cacs_dly_adj; + uint16_t dqdm_dly_w; + uint16_t dqdm_dly_r; + struct _boardcnf_ch ch[DRAM_CH_CNT]; +}; + +#define WDQLVL_PAT {\ + 0x00AA,\ + 0x0055,\ + 0x00AA,\ + 0x0155,\ + 0x01CC,\ + 0x0133,\ + 0x00CC,\ + 0x0033,\ + 0x00F0,\ + 0x010F,\ + 0x01F0,\ + 0x010F,\ + 0x00F0,\ + 0x00F0,\ + 0x000F,\ + 0x010F} + +static const struct _boardcnf boardcnfs[BOARDNUM] = { + { +/* boardcnf[0] HopeRun HiHope RZ/G2M 16Gbit/1rank/2ch board with G2M SoC */ + .phyvalid = 0x03, + .dbi_en = 0x01, + .cacs_dly = 0x02c0, + .cacs_dly_adj = 0, + .dqdm_dly_w = 0x0300, + .dqdm_dly_r = 0x00a0, + .ch = { + { + {0x04, 0xff}, + 0x00345201U, + 0x3201, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + }, + + { + {0x04, 0xff}, + 0x00302154U, + 0x2310, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + } + } + }, +/* boardcnf[1] HopeRun HiHope RZ/G2M 8Gbit/2rank/2ch board with G2M SoC */ + { + 0x03, + 0x01, + 0x02c0, + 0, + 0x0300, + 0x00a0, + { + { + {0x02, 0x02}, + 0x00345201U, + 0x3201, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {0x02, 0x02}, + 0x00302154U, + 0x2310, + {0x01672543U, 0x45361207U, 0x45632107U, 0x60715234U}, + {0x08, 0x08, 0x08, 0x08}, + WDQLVL_PAT, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + } + } + } +}; + +void boardcnf_get_brd_clk(uint32_t brd, uint32_t *clk, uint32_t *div) +{ + uint32_t md; + + md = (mmio_read_32(RST_MODEMR) >> 13) & 0x3U; + switch (md) { + case 0x0U: + *clk = 50U; + *div = 3U; + break; + case 0x1U: + *clk = 60U; + *div = 3U; + break; + case 0x2U: + *clk = 75U; + *div = 3U; + break; + case 0x3U: + *clk = 100U; + *div = 3U; + break; + default: + break; + } + (void)brd; +} + +void boardcnf_get_ddr_mbps(uint32_t brd, uint32_t *mbps, uint32_t *div) +{ + uint32_t md; + + md = (mmio_read_32(RST_MODEMR) >> 17U) & 0x5U; + md = (md | (md >> 1U)) & 0x3U; + switch (md) { + case 0x0U: + *mbps = 3200U; + *div = 1U; + break; + case 0x1U: + *mbps = 2800U; + *div = 1U; + break; + case 0x2U: + *mbps = 2400U; + *div = 1U; + break; + case 0x3U: + *mbps = 1600U; + *div = 1U; + break; + default: + break; + } + (void)brd; +} + +#define _def_REFPERIOD 1890 + +#define M3_SAMPLE_TT_A84 0xB866CC10U, 0x3B250421U +#define M3_SAMPLE_TT_A85 0xB866CC10U, 0x3AA50421U +#define M3_SAMPLE_TT_A86 0xB866CC10U, 0x3AA48421U +#define M3_SAMPLE_FF_B45 0xB866CC10U, 0x3AB00C21U +#define M3_SAMPLE_FF_B49 0xB866CC10U, 0x39B10C21U +#define M3_SAMPLE_FF_B56 0xB866CC10U, 0x3AAF8C21U +#define M3_SAMPLE_SS_E24 0xB866CC10U, 0x3BA39421U +#define M3_SAMPLE_SS_E28 0xB866CC10U, 0x3C231421U +#define M3_SAMPLE_SS_E32 0xB866CC10U, 0x3C241421U + +static const uint32_t termcode_by_sample[20][3] = { + { M3_SAMPLE_TT_A84, 0x000158D5U }, + { M3_SAMPLE_TT_A85, 0x00015955U }, + { M3_SAMPLE_TT_A86, 0x00015955U }, + { M3_SAMPLE_FF_B45, 0x00015690U }, + { M3_SAMPLE_FF_B49, 0x00015753U }, + { M3_SAMPLE_FF_B56, 0x00015793U }, + { M3_SAMPLE_SS_E24, 0x00015996U }, + { M3_SAMPLE_SS_E28, 0x000159D7U }, + { M3_SAMPLE_SS_E32, 0x00015997U }, + { 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0001554FU} +}; + +#ifdef BOARD_JUDGE_AUTO +/* Board detect function */ +#define GPIO_INDT5 0xE605500CU +#define LPDDR4_2RANK (0x01U << 25U) + +static uint32_t _board_judge(uint32_t prr_product) +{ + uint32_t boardInfo; + uint32_t boardid = 1U; + + if (prr_product == PRR_PRODUCT_M3) { + if ((mmio_read_32(PRR) & PRR_CUT_MASK) != RCAR_M3_CUT_VER11) { + boardInfo = mmio_read_32(GPIO_INDT5); + if ((boardInfo & LPDDR4_2RANK) == 0U) { + boardid = 0U; + } + } + } + + return boardid; +} +#endif /* BOARD_JUDGE_AUTO */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h new file mode 100644 index 000000000..9f1c9368b --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/boot_init_dram_regdef.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_BOOT_INIT_DRAM_REGDEF_H +#define RZG_BOOT_INIT_DRAM_REGDEF_H + +#define RCAR_DDR_VERSION "rev.0.40" +#define DRAM_CH_CNT 0x04U +#define SLICE_CNT 0x04U +#define CS_CNT 0x02U + +/* order : CS0A, CS0B, CS1A, CS1B */ +#define CSAB_CNT (CS_CNT * 2U) + +/* 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 density setting */ +#define DBMEMCONF_REG(d3, row, bank, col, dw) \ + (((d3) << 30U) | ((row) << 24U) | ((bank) << 16U) | ((col) << 8U) | (dw)) + +#define DBMEMCONF_REGD(density) \ + (DBMEMCONF_REG((density) % 2U, ((density) + 1U) / \ + 2U + (29U - 3U - 10U - 2U), 3U, 10U, 2U)) + +#define DBMEMCONF_VAL(ch, cs) (DBMEMCONF_REGD(DBMEMCONF_DENS(ch, cs))) + +/* refresh mode */ +#define DBSC_REFINTS (0x0U) + +/* 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 + +#endif /* RZG_BOOT_INIT_DRAM_REGDEF_H */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk b/drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk new file mode 100644 index 000000000..c137f2624 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/ddr_b.mk @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BL2_SOURCES += drivers/renesas/rzg/ddr/ddr_b/boot_init_dram.c diff --git a/drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h b/drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h new file mode 100644 index 000000000..1da455f91 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/ddr_regdef.h @@ -0,0 +1,5891 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_DDR_REGDEF_H +#define RZG_DDR_REGDEF_H + +#define _reg_PHY_DQ_DM_SWIZZLE0 0x00000000U +#define _reg_PHY_DQ_DM_SWIZZLE1 0x00000001U +#define _reg_PHY_CLK_WR_BYPASS_SLAVE_DELAY 0x00000002U +#define _reg_PHY_RDDQS_GATE_BYPASS_SLAVE_DELAY 0x00000003U +#define _reg_PHY_BYPASS_TWO_CYC_PREAMBLE 0x00000004U +#define _reg_PHY_CLK_BYPASS_OVERRIDE 0x00000005U +#define _reg_PHY_SW_WRDQ0_SHIFT 0x00000006U +#define _reg_PHY_SW_WRDQ1_SHIFT 0x00000007U +#define _reg_PHY_SW_WRDQ2_SHIFT 0x00000008U +#define _reg_PHY_SW_WRDQ3_SHIFT 0x00000009U +#define _reg_PHY_SW_WRDQ4_SHIFT 0x0000000aU +#define _reg_PHY_SW_WRDQ5_SHIFT 0x0000000bU +#define _reg_PHY_SW_WRDQ6_SHIFT 0x0000000cU +#define _reg_PHY_SW_WRDQ7_SHIFT 0x0000000dU +#define _reg_PHY_SW_WRDM_SHIFT 0x0000000eU +#define _reg_PHY_SW_WRDQS_SHIFT 0x0000000fU +#define _reg_PHY_DQ_TSEL_ENABLE 0x00000010U +#define _reg_PHY_DQ_TSEL_SELECT 0x00000011U +#define _reg_PHY_DQS_TSEL_ENABLE 0x00000012U +#define _reg_PHY_DQS_TSEL_SELECT 0x00000013U +#define _reg_PHY_TWO_CYC_PREAMBLE 0x00000014U +#define _reg_PHY_DBI_MODE 0x00000015U +#define _reg_PHY_PER_RANK_CS_MAP 0x00000016U +#define _reg_PHY_PER_CS_TRAINING_MULTICAST_EN 0x00000017U +#define _reg_PHY_PER_CS_TRAINING_INDEX 0x00000018U +#define _reg_PHY_LP4_BOOT_RDDATA_EN_IE_DLY 0x00000019U +#define _reg_PHY_LP4_BOOT_RDDATA_EN_DLY 0x0000001aU +#define _reg_PHY_LP4_BOOT_RDDATA_EN_TSEL_DLY 0x0000001bU +#define _reg_PHY_LP4_BOOT_RPTR_UPDATE 0x0000001cU +#define _reg_PHY_LP4_BOOT_RDDQS_GATE_SLAVE_DELAY 0x0000001dU +#define _reg_PHY_LP4_BOOT_RDDQS_LATENCY_ADJUST 0x0000001eU +#define _reg_PHY_LP4_BOOT_WRPATH_GATE_DISABLE 0x0000001fU +#define _reg_PHY_LP4_BOOT_RDDATA_EN_OE_DLY 0x00000020U +#define _reg_PHY_LPBK_CONTROL 0x00000021U +#define _reg_PHY_LPBK_DFX_TIMEOUT_EN 0x00000022U +#define _reg_PHY_AUTO_TIMING_MARGIN_CONTROL 0x00000023U +#define _reg_PHY_AUTO_TIMING_MARGIN_OBS 0x00000024U +#define _reg_PHY_SLICE_PWR_RDC_DISABLE 0x00000025U +#define _reg_PHY_PRBS_PATTERN_START 0x00000026U +#define _reg_PHY_PRBS_PATTERN_MASK 0x00000027U +#define _reg_PHY_RDDQS_DQ_BYPASS_SLAVE_DELAY 0x00000028U +#define _reg_PHY_GATE_ERROR_DELAY_SELECT 0x00000029U +#define _reg_SC_PHY_SNAP_OBS_REGS 0x0000002aU +#define _reg_PHY_LPDDR 0x0000002bU +#define _reg_PHY_LPDDR_TYPE 0x0000002cU +#define _reg_PHY_GATE_SMPL1_SLAVE_DELAY 0x0000002dU +#define _reg_PHY_GATE_SMPL2_SLAVE_DELAY 0x0000002eU +#define _reg_ON_FLY_GATE_ADJUST_EN 0x0000002fU +#define _reg_PHY_GATE_TRACKING_OBS 0x00000030U +#define _reg_PHY_DFI40_POLARITY 0x00000031U +#define _reg_PHY_LP4_PST_AMBLE 0x00000032U +#define _reg_PHY_RDLVL_PATT8 0x00000033U +#define _reg_PHY_RDLVL_PATT9 0x00000034U +#define _reg_PHY_RDLVL_PATT10 0x00000035U +#define _reg_PHY_RDLVL_PATT11 0x00000036U +#define _reg_PHY_LP4_RDLVL_PATT8 0x00000037U +#define _reg_PHY_LP4_RDLVL_PATT9 0x00000038U +#define _reg_PHY_LP4_RDLVL_PATT10 0x00000039U +#define _reg_PHY_LP4_RDLVL_PATT11 0x0000003aU +#define _reg_PHY_SLAVE_LOOP_CNT_UPDATE 0x0000003bU +#define _reg_PHY_SW_FIFO_PTR_RST_DISABLE 0x0000003cU +#define _reg_PHY_MASTER_DLY_LOCK_OBS_SELECT 0x0000003dU +#define _reg_PHY_RDDQ_ENC_OBS_SELECT 0x0000003eU +#define _reg_PHY_RDDQS_DQ_ENC_OBS_SELECT 0x0000003fU +#define _reg_PHY_WR_ENC_OBS_SELECT 0x00000040U +#define _reg_PHY_WR_SHIFT_OBS_SELECT 0x00000041U +#define _reg_PHY_FIFO_PTR_OBS_SELECT 0x00000042U +#define _reg_PHY_LVL_DEBUG_MODE 0x00000043U +#define _reg_SC_PHY_LVL_DEBUG_CONT 0x00000044U +#define _reg_PHY_WRLVL_CAPTURE_CNT 0x00000045U +#define _reg_PHY_WRLVL_UPDT_WAIT_CNT 0x00000046U +#define _reg_PHY_WRLVL_DQ_MASK 0x00000047U +#define _reg_PHY_GTLVL_CAPTURE_CNT 0x00000048U +#define _reg_PHY_GTLVL_UPDT_WAIT_CNT 0x00000049U +#define _reg_PHY_RDLVL_CAPTURE_CNT 0x0000004aU +#define _reg_PHY_RDLVL_UPDT_WAIT_CNT 0x0000004bU +#define _reg_PHY_RDLVL_OP_MODE 0x0000004cU +#define _reg_PHY_RDLVL_RDDQS_DQ_OBS_SELECT 0x0000004dU +#define _reg_PHY_RDLVL_DATA_MASK 0x0000004eU +#define _reg_PHY_RDLVL_DATA_SWIZZLE 0x0000004fU +#define _reg_PHY_WDQLVL_BURST_CNT 0x00000050U +#define _reg_PHY_WDQLVL_PATT 0x00000051U +#define _reg_PHY_WDQLVL_DQDM_SLV_DLY_JUMP_OFFSET 0x00000052U +#define _reg_PHY_WDQLVL_UPDT_WAIT_CNT 0x00000053U +#define _reg_PHY_WDQLVL_DQDM_OBS_SELECT 0x00000054U +#define _reg_PHY_WDQLVL_QTR_DLY_STEP 0x00000055U +#define _reg_SC_PHY_WDQLVL_CLR_PREV_RESULTS 0x00000056U +#define _reg_PHY_WDQLVL_CLR_PREV_RESULTS 0x00000057U +#define _reg_PHY_WDQLVL_DATADM_MASK 0x00000058U +#define _reg_PHY_USER_PATT0 0x00000059U +#define _reg_PHY_USER_PATT1 0x0000005aU +#define _reg_PHY_USER_PATT2 0x0000005bU +#define _reg_PHY_USER_PATT3 0x0000005cU +#define _reg_PHY_USER_PATT4 0x0000005dU +#define _reg_PHY_DQ_SWIZZLING 0x0000005eU +#define _reg_PHY_CALVL_VREF_DRIVING_SLICE 0x0000005fU +#define _reg_SC_PHY_MANUAL_CLEAR 0x00000060U +#define _reg_PHY_FIFO_PTR_OBS 0x00000061U +#define _reg_PHY_LPBK_RESULT_OBS 0x00000062U +#define _reg_PHY_LPBK_ERROR_COUNT_OBS 0x00000063U +#define _reg_PHY_MASTER_DLY_LOCK_OBS 0x00000064U +#define _reg_PHY_RDDQ_SLV_DLY_ENC_OBS 0x00000065U +#define _reg_PHY_RDDQS_BASE_SLV_DLY_ENC_OBS 0x00000066U +#define _reg_PHY_RDDQS_DQ_RISE_ADDER_SLV_DLY_ENC_OBS 0x00000067U +#define _reg_PHY_RDDQS_DQ_FALL_ADDER_SLV_DLY_ENC_OBS 0x00000068U +#define _reg_PHY_RDDQS_GATE_SLV_DLY_ENC_OBS 0x00000069U +#define _reg_PHY_WRDQS_BASE_SLV_DLY_ENC_OBS 0x0000006aU +#define _reg_PHY_WRDQ_BASE_SLV_DLY_ENC_OBS 0x0000006bU +#define _reg_PHY_WR_ADDER_SLV_DLY_ENC_OBS 0x0000006cU +#define _reg_PHY_WR_SHIFT_OBS 0x0000006dU +#define _reg_PHY_WRLVL_HARD0_DELAY_OBS 0x0000006eU +#define _reg_PHY_WRLVL_HARD1_DELAY_OBS 0x0000006fU +#define _reg_PHY_WRLVL_STATUS_OBS 0x00000070U +#define _reg_PHY_GATE_SMPL1_SLV_DLY_ENC_OBS 0x00000071U +#define _reg_PHY_GATE_SMPL2_SLV_DLY_ENC_OBS 0x00000072U +#define _reg_PHY_WRLVL_ERROR_OBS 0x00000073U +#define _reg_PHY_GTLVL_HARD0_DELAY_OBS 0x00000074U +#define _reg_PHY_GTLVL_HARD1_DELAY_OBS 0x00000075U +#define _reg_PHY_GTLVL_STATUS_OBS 0x00000076U +#define _reg_PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS 0x00000077U +#define _reg_PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS 0x00000078U +#define _reg_PHY_RDLVL_RDDQS_DQ_NUM_WINDOWS_OBS 0x00000079U +#define _reg_PHY_RDLVL_STATUS_OBS 0x0000007aU +#define _reg_PHY_WDQLVL_DQDM_LE_DLY_OBS 0x0000007bU +#define _reg_PHY_WDQLVL_DQDM_TE_DLY_OBS 0x0000007cU +#define _reg_PHY_WDQLVL_STATUS_OBS 0x0000007dU +#define _reg_PHY_DDL_MODE 0x0000007eU +#define _reg_PHY_DDL_TEST_OBS 0x0000007fU +#define _reg_PHY_DDL_TEST_MSTR_DLY_OBS 0x00000080U +#define _reg_PHY_DDL_TRACK_UPD_THRESHOLD 0x00000081U +#define _reg_PHY_LP4_WDQS_OE_EXTEND 0x00000082U +#define _reg_SC_PHY_RX_CAL_START 0x00000083U +#define _reg_PHY_RX_CAL_OVERRIDE 0x00000084U +#define _reg_PHY_RX_CAL_SAMPLE_WAIT 0x00000085U +#define _reg_PHY_RX_CAL_DQ0 0x00000086U +#define _reg_PHY_RX_CAL_DQ1 0x00000087U +#define _reg_PHY_RX_CAL_DQ2 0x00000088U +#define _reg_PHY_RX_CAL_DQ3 0x00000089U +#define _reg_PHY_RX_CAL_DQ4 0x0000008aU +#define _reg_PHY_RX_CAL_DQ5 0x0000008bU +#define _reg_PHY_RX_CAL_DQ6 0x0000008cU +#define _reg_PHY_RX_CAL_DQ7 0x0000008dU +#define _reg_PHY_RX_CAL_DM 0x0000008eU +#define _reg_PHY_RX_CAL_DQS 0x0000008fU +#define _reg_PHY_RX_CAL_FDBK 0x00000090U +#define _reg_PHY_RX_CAL_OBS 0x00000091U +#define _reg_PHY_RX_CAL_LOCK_OBS 0x00000092U +#define _reg_PHY_RX_CAL_DISABLE 0x00000093U +#define _reg_PHY_CLK_WRDQ0_SLAVE_DELAY 0x00000094U +#define _reg_PHY_CLK_WRDQ1_SLAVE_DELAY 0x00000095U +#define _reg_PHY_CLK_WRDQ2_SLAVE_DELAY 0x00000096U +#define _reg_PHY_CLK_WRDQ3_SLAVE_DELAY 0x00000097U +#define _reg_PHY_CLK_WRDQ4_SLAVE_DELAY 0x00000098U +#define _reg_PHY_CLK_WRDQ5_SLAVE_DELAY 0x00000099U +#define _reg_PHY_CLK_WRDQ6_SLAVE_DELAY 0x0000009aU +#define _reg_PHY_CLK_WRDQ7_SLAVE_DELAY 0x0000009bU +#define _reg_PHY_CLK_WRDM_SLAVE_DELAY 0x0000009cU +#define _reg_PHY_CLK_WRDQS_SLAVE_DELAY 0x0000009dU +#define _reg_PHY_WRLVL_THRESHOLD_ADJUST 0x0000009eU +#define _reg_PHY_RDDQ0_SLAVE_DELAY 0x0000009fU +#define _reg_PHY_RDDQ1_SLAVE_DELAY 0x000000a0U +#define _reg_PHY_RDDQ2_SLAVE_DELAY 0x000000a1U +#define _reg_PHY_RDDQ3_SLAVE_DELAY 0x000000a2U +#define _reg_PHY_RDDQ4_SLAVE_DELAY 0x000000a3U +#define _reg_PHY_RDDQ5_SLAVE_DELAY 0x000000a4U +#define _reg_PHY_RDDQ6_SLAVE_DELAY 0x000000a5U +#define _reg_PHY_RDDQ7_SLAVE_DELAY 0x000000a6U +#define _reg_PHY_RDDM_SLAVE_DELAY 0x000000a7U +#define _reg_PHY_RDDQS_DQ0_RISE_SLAVE_DELAY 0x000000a8U +#define _reg_PHY_RDDQS_DQ0_FALL_SLAVE_DELAY 0x000000a9U +#define _reg_PHY_RDDQS_DQ1_RISE_SLAVE_DELAY 0x000000aaU +#define _reg_PHY_RDDQS_DQ1_FALL_SLAVE_DELAY 0x000000abU +#define _reg_PHY_RDDQS_DQ2_RISE_SLAVE_DELAY 0x000000acU +#define _reg_PHY_RDDQS_DQ2_FALL_SLAVE_DELAY 0x000000adU +#define _reg_PHY_RDDQS_DQ3_RISE_SLAVE_DELAY 0x000000aeU +#define _reg_PHY_RDDQS_DQ3_FALL_SLAVE_DELAY 0x000000afU +#define _reg_PHY_RDDQS_DQ4_RISE_SLAVE_DELAY 0x000000b0U +#define _reg_PHY_RDDQS_DQ4_FALL_SLAVE_DELAY 0x000000b1U +#define _reg_PHY_RDDQS_DQ5_RISE_SLAVE_DELAY 0x000000b2U +#define _reg_PHY_RDDQS_DQ5_FALL_SLAVE_DELAY 0x000000b3U +#define _reg_PHY_RDDQS_DQ6_RISE_SLAVE_DELAY 0x000000b4U +#define _reg_PHY_RDDQS_DQ6_FALL_SLAVE_DELAY 0x000000b5U +#define _reg_PHY_RDDQS_DQ7_RISE_SLAVE_DELAY 0x000000b6U +#define _reg_PHY_RDDQS_DQ7_FALL_SLAVE_DELAY 0x000000b7U +#define _reg_PHY_RDDQS_DM_RISE_SLAVE_DELAY 0x000000b8U +#define _reg_PHY_RDDQS_DM_FALL_SLAVE_DELAY 0x000000b9U +#define _reg_PHY_RDDQS_GATE_SLAVE_DELAY 0x000000baU +#define _reg_PHY_RDDQS_LATENCY_ADJUST 0x000000bbU +#define _reg_PHY_WRITE_PATH_LAT_ADD 0x000000bcU +#define _reg_PHY_WRLVL_DELAY_EARLY_THRESHOLD 0x000000bdU +#define _reg_PHY_WRLVL_DELAY_PERIOD_THRESHOLD 0x000000beU +#define _reg_PHY_WRLVL_EARLY_FORCE_ZERO 0x000000bfU +#define _reg_PHY_GTLVL_RDDQS_SLV_DLY_START 0x000000c0U +#define _reg_PHY_GTLVL_LAT_ADJ_START 0x000000c1U +#define _reg_PHY_WDQLVL_DQDM_SLV_DLY_START 0x000000c2U +#define _reg_PHY_RDLVL_RDDQS_DQ_SLV_DLY_START 0x000000c3U +#define _reg_PHY_FDBK_PWR_CTRL 0x000000c4U +#define _reg_PHY_DQ_OE_TIMING 0x000000c5U +#define _reg_PHY_DQ_TSEL_RD_TIMING 0x000000c6U +#define _reg_PHY_DQ_TSEL_WR_TIMING 0x000000c7U +#define _reg_PHY_DQS_OE_TIMING 0x000000c8U +#define _reg_PHY_DQS_TSEL_RD_TIMING 0x000000c9U +#define _reg_PHY_DQS_OE_RD_TIMING 0x000000caU +#define _reg_PHY_DQS_TSEL_WR_TIMING 0x000000cbU +#define _reg_PHY_PER_CS_TRAINING_EN 0x000000ccU +#define _reg_PHY_DQ_IE_TIMING 0x000000cdU +#define _reg_PHY_DQS_IE_TIMING 0x000000ceU +#define _reg_PHY_RDDATA_EN_IE_DLY 0x000000cfU +#define _reg_PHY_IE_MODE 0x000000d0U +#define _reg_PHY_RDDATA_EN_DLY 0x000000d1U +#define _reg_PHY_RDDATA_EN_TSEL_DLY 0x000000d2U +#define _reg_PHY_RDDATA_EN_OE_DLY 0x000000d3U +#define _reg_PHY_SW_MASTER_MODE 0x000000d4U +#define _reg_PHY_MASTER_DELAY_START 0x000000d5U +#define _reg_PHY_MASTER_DELAY_STEP 0x000000d6U +#define _reg_PHY_MASTER_DELAY_WAIT 0x000000d7U +#define _reg_PHY_MASTER_DELAY_HALF_MEASURE 0x000000d8U +#define _reg_PHY_RPTR_UPDATE 0x000000d9U +#define _reg_PHY_WRLVL_DLY_STEP 0x000000daU +#define _reg_PHY_WRLVL_RESP_WAIT_CNT 0x000000dbU +#define _reg_PHY_GTLVL_DLY_STEP 0x000000dcU +#define _reg_PHY_GTLVL_RESP_WAIT_CNT 0x000000ddU +#define _reg_PHY_GTLVL_BACK_STEP 0x000000deU +#define _reg_PHY_GTLVL_FINAL_STEP 0x000000dfU +#define _reg_PHY_WDQLVL_DLY_STEP 0x000000e0U +#define _reg_PHY_TOGGLE_PRE_SUPPORT 0x000000e1U +#define _reg_PHY_RDLVL_DLY_STEP 0x000000e2U +#define _reg_PHY_WRPATH_GATE_DISABLE 0x000000e3U +#define _reg_PHY_WRPATH_GATE_TIMING 0x000000e4U +#define _reg_PHY_ADR0_SW_WRADDR_SHIFT 0x000000e5U +#define _reg_PHY_ADR1_SW_WRADDR_SHIFT 0x000000e6U +#define _reg_PHY_ADR2_SW_WRADDR_SHIFT 0x000000e7U +#define _reg_PHY_ADR3_SW_WRADDR_SHIFT 0x000000e8U +#define _reg_PHY_ADR4_SW_WRADDR_SHIFT 0x000000e9U +#define _reg_PHY_ADR5_SW_WRADDR_SHIFT 0x000000eaU +#define _reg_PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY 0x000000ebU +#define _reg_PHY_ADR_CLK_BYPASS_OVERRIDE 0x000000ecU +#define _reg_SC_PHY_ADR_MANUAL_CLEAR 0x000000edU +#define _reg_PHY_ADR_LPBK_RESULT_OBS 0x000000eeU +#define _reg_PHY_ADR_LPBK_ERROR_COUNT_OBS 0x000000efU +#define _reg_PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT 0x000000f0U +#define _reg_PHY_ADR_MASTER_DLY_LOCK_OBS 0x000000f1U +#define _reg_PHY_ADR_BASE_SLV_DLY_ENC_OBS 0x000000f2U +#define _reg_PHY_ADR_ADDER_SLV_DLY_ENC_OBS 0x000000f3U +#define _reg_PHY_ADR_SLAVE_LOOP_CNT_UPDATE 0x000000f4U +#define _reg_PHY_ADR_SLV_DLY_ENC_OBS_SELECT 0x000000f5U +#define _reg_SC_PHY_ADR_SNAP_OBS_REGS 0x000000f6U +#define _reg_PHY_ADR_TSEL_ENABLE 0x000000f7U +#define _reg_PHY_ADR_LPBK_CONTROL 0x000000f8U +#define _reg_PHY_ADR_PRBS_PATTERN_START 0x000000f9U +#define _reg_PHY_ADR_PRBS_PATTERN_MASK 0x000000faU +#define _reg_PHY_ADR_PWR_RDC_DISABLE 0x000000fbU +#define _reg_PHY_ADR_TYPE 0x000000fcU +#define _reg_PHY_ADR_WRADDR_SHIFT_OBS 0x000000fdU +#define _reg_PHY_ADR_IE_MODE 0x000000feU +#define _reg_PHY_ADR_DDL_MODE 0x000000ffU +#define _reg_PHY_ADR_DDL_TEST_OBS 0x00000100U +#define _reg_PHY_ADR_DDL_TEST_MSTR_DLY_OBS 0x00000101U +#define _reg_PHY_ADR_CALVL_START 0x00000102U +#define _reg_PHY_ADR_CALVL_COARSE_DLY 0x00000103U +#define _reg_PHY_ADR_CALVL_QTR 0x00000104U +#define _reg_PHY_ADR_CALVL_SWIZZLE0 0x00000105U +#define _reg_PHY_ADR_CALVL_SWIZZLE1 0x00000106U +#define _reg_PHY_ADR_CALVL_SWIZZLE0_0 0x00000107U +#define _reg_PHY_ADR_CALVL_SWIZZLE1_0 0x00000108U +#define _reg_PHY_ADR_CALVL_SWIZZLE0_1 0x00000109U +#define _reg_PHY_ADR_CALVL_SWIZZLE1_1 0x0000010aU +#define _reg_PHY_ADR_CALVL_DEVICE_MAP 0x0000010bU +#define _reg_PHY_ADR_CALVL_RANK_CTRL 0x0000010cU +#define _reg_PHY_ADR_CALVL_NUM_PATTERNS 0x0000010dU +#define _reg_PHY_ADR_CALVL_CAPTURE_CNT 0x0000010eU +#define _reg_PHY_ADR_CALVL_RESP_WAIT_CNT 0x0000010fU +#define _reg_PHY_ADR_CALVL_DEBUG_MODE 0x00000110U +#define _reg_SC_PHY_ADR_CALVL_DEBUG_CONT 0x00000111U +#define _reg_SC_PHY_ADR_CALVL_ERROR_CLR 0x00000112U +#define _reg_PHY_ADR_CALVL_OBS_SELECT 0x00000113U +#define _reg_PHY_ADR_CALVL_OBS0 0x00000114U +#define _reg_PHY_ADR_CALVL_OBS1 0x00000115U +#define _reg_PHY_ADR_CALVL_RESULT 0x00000116U +#define _reg_PHY_ADR_CALVL_FG_0 0x00000117U +#define _reg_PHY_ADR_CALVL_BG_0 0x00000118U +#define _reg_PHY_ADR_CALVL_FG_1 0x00000119U +#define _reg_PHY_ADR_CALVL_BG_1 0x0000011aU +#define _reg_PHY_ADR_CALVL_FG_2 0x0000011bU +#define _reg_PHY_ADR_CALVL_BG_2 0x0000011cU +#define _reg_PHY_ADR_CALVL_FG_3 0x0000011dU +#define _reg_PHY_ADR_CALVL_BG_3 0x0000011eU +#define _reg_PHY_ADR_ADDR_SEL 0x0000011fU +#define _reg_PHY_ADR_LP4_BOOT_SLV_DELAY 0x00000120U +#define _reg_PHY_ADR_BIT_MASK 0x00000121U +#define _reg_PHY_ADR_SEG_MASK 0x00000122U +#define _reg_PHY_ADR_CALVL_TRAIN_MASK 0x00000123U +#define _reg_PHY_ADR_CSLVL_TRAIN_MASK 0x00000124U +#define _reg_PHY_ADR_SW_TXIO_CTRL 0x00000125U +#define _reg_PHY_ADR_TSEL_SELECT 0x00000126U +#define _reg_PHY_ADR0_CLK_WR_SLAVE_DELAY 0x00000127U +#define _reg_PHY_ADR1_CLK_WR_SLAVE_DELAY 0x00000128U +#define _reg_PHY_ADR2_CLK_WR_SLAVE_DELAY 0x00000129U +#define _reg_PHY_ADR3_CLK_WR_SLAVE_DELAY 0x0000012aU +#define _reg_PHY_ADR4_CLK_WR_SLAVE_DELAY 0x0000012bU +#define _reg_PHY_ADR5_CLK_WR_SLAVE_DELAY 0x0000012cU +#define _reg_PHY_ADR_SW_MASTER_MODE 0x0000012dU +#define _reg_PHY_ADR_MASTER_DELAY_START 0x0000012eU +#define _reg_PHY_ADR_MASTER_DELAY_STEP 0x0000012fU +#define _reg_PHY_ADR_MASTER_DELAY_WAIT 0x00000130U +#define _reg_PHY_ADR_MASTER_DELAY_HALF_MEASURE 0x00000131U +#define _reg_PHY_ADR_CALVL_DLY_STEP 0x00000132U +#define _reg_PHY_FREQ_SEL 0x00000133U +#define _reg_PHY_FREQ_SEL_FROM_REGIF 0x00000134U +#define _reg_PHY_FREQ_SEL_MULTICAST_EN 0x00000135U +#define _reg_PHY_FREQ_SEL_INDEX 0x00000136U +#define _reg_PHY_SW_GRP_SHIFT_0 0x00000137U +#define _reg_PHY_SW_GRP_SHIFT_1 0x00000138U +#define _reg_PHY_SW_GRP_SHIFT_2 0x00000139U +#define _reg_PHY_SW_GRP_SHIFT_3 0x0000013aU +#define _reg_PHY_GRP_BYPASS_SLAVE_DELAY 0x0000013bU +#define _reg_PHY_SW_GRP_BYPASS_SHIFT 0x0000013cU +#define _reg_PHY_GRP_BYPASS_OVERRIDE 0x0000013dU +#define _reg_SC_PHY_MANUAL_UPDATE 0x0000013eU +#define _reg_SC_PHY_MANUAL_UPDATE_PHYUPD_ENABLE 0x0000013fU +#define _reg_PHY_LP4_BOOT_DISABLE 0x00000140U +#define _reg_PHY_CSLVL_ENABLE 0x00000141U +#define _reg_PHY_CSLVL_CS_MAP 0x00000142U +#define _reg_PHY_CSLVL_START 0x00000143U +#define _reg_PHY_CSLVL_QTR 0x00000144U +#define _reg_PHY_CSLVL_COARSE_CHK 0x00000145U +#define _reg_PHY_CSLVL_CAPTURE_CNT 0x00000146U +#define _reg_PHY_CSLVL_COARSE_DLY 0x00000147U +#define _reg_PHY_CSLVL_COARSE_CAPTURE_CNT 0x00000148U +#define _reg_PHY_CSLVL_DEBUG_MODE 0x00000149U +#define _reg_SC_PHY_CSLVL_DEBUG_CONT 0x0000014aU +#define _reg_SC_PHY_CSLVL_ERROR_CLR 0x0000014bU +#define _reg_PHY_CSLVL_OBS0 0x0000014cU +#define _reg_PHY_CSLVL_OBS1 0x0000014dU +#define _reg_PHY_CALVL_CS_MAP 0x0000014eU +#define _reg_PHY_GRP_SLV_DLY_ENC_OBS_SELECT 0x0000014fU +#define _reg_PHY_GRP_SHIFT_OBS_SELECT 0x00000150U +#define _reg_PHY_GRP_SLV_DLY_ENC_OBS 0x00000151U +#define _reg_PHY_GRP_SHIFT_OBS 0x00000152U +#define _reg_PHY_ADRCTL_SLAVE_LOOP_CNT_UPDATE 0x00000153U +#define _reg_PHY_ADRCTL_SNAP_OBS_REGS 0x00000154U +#define _reg_PHY_DFI_PHYUPD_TYPE 0x00000155U +#define _reg_PHY_ADRCTL_LPDDR 0x00000156U +#define _reg_PHY_LP4_ACTIVE 0x00000157U +#define _reg_PHY_LPDDR3_CS 0x00000158U +#define _reg_PHY_CALVL_RESULT_MASK 0x00000159U +#define _reg_SC_PHY_UPDATE_CLK_CAL_VALUES 0x0000015aU +#define _reg_PHY_SW_TXIO_CTRL_0 0x0000015bU +#define _reg_PHY_SW_TXIO_CTRL_1 0x0000015cU +#define _reg_PHY_SW_TXIO_CTRL_2 0x0000015dU +#define _reg_PHY_SW_TXIO_CTRL_3 0x0000015eU +#define _reg_PHY_MEMCLK_SW_TXIO_CTRL 0x0000015fU +#define _reg_PHY_CA_SW_TXPWR_CTRL 0x00000160U +#define _reg_PHY_MEMCLK_SW_TXPWR_CTRL 0x00000161U +#define _reg_PHY_USER_DEF_REG_AC_0 0x00000162U +#define _reg_PHY_USER_DEF_REG_AC_1 0x00000163U +#define _reg_PHY_USER_DEF_REG_AC_2 0x00000164U +#define _reg_PHY_USER_DEF_REG_AC_3 0x00000165U +#define _reg_PHY_UPDATE_CLK_CAL_VALUES 0x00000166U +#define _reg_PHY_CONTINUOUS_CLK_CAL_UPDATE 0x00000167U +#define _reg_PHY_PLL_CTRL 0x00000168U +#define _reg_PHY_PLL_CTRL_TOP 0x00000169U +#define _reg_PHY_PLL_CTRL_CA 0x0000016aU +#define _reg_PHY_PLL_BYPASS 0x0000016bU +#define _reg_PHY_LOW_FREQ_SEL 0x0000016cU +#define _reg_PHY_PAD_VREF_CTRL_DQ_0 0x0000016dU +#define _reg_PHY_PAD_VREF_CTRL_DQ_1 0x0000016eU +#define _reg_PHY_PAD_VREF_CTRL_DQ_2 0x0000016fU +#define _reg_PHY_PAD_VREF_CTRL_DQ_3 0x00000170U +#define _reg_PHY_PAD_VREF_CTRL_AC 0x00000171U +#define _reg_PHY_CSLVL_DLY_STEP 0x00000172U +#define _reg_PHY_SET_DFI_INPUT_0 0x00000173U +#define _reg_PHY_SET_DFI_INPUT_1 0x00000174U +#define _reg_PHY_SET_DFI_INPUT_2 0x00000175U +#define _reg_PHY_SET_DFI_INPUT_3 0x00000176U +#define _reg_PHY_GRP_SLAVE_DELAY_0 0x00000177U +#define _reg_PHY_GRP_SLAVE_DELAY_1 0x00000178U +#define _reg_PHY_GRP_SLAVE_DELAY_2 0x00000179U +#define _reg_PHY_GRP_SLAVE_DELAY_3 0x0000017aU +#define _reg_PHY_CS_ACS_ALLOCATION_0 0x0000017bU +#define _reg_PHY_CS_ACS_ALLOCATION_1 0x0000017cU +#define _reg_PHY_CS_ACS_ALLOCATION_2 0x0000017dU +#define _reg_PHY_CS_ACS_ALLOCATION_3 0x0000017eU +#define _reg_PHY_LP4_BOOT_PLL_CTRL 0x0000017fU +#define _reg_PHY_LP4_BOOT_PLL_CTRL_CA 0x00000180U +#define _reg_PHY_LP4_BOOT_TOP_PLL_CTRL 0x00000181U +#define _reg_PHY_PLL_CTRL_OVERRIDE 0x00000182U +#define _reg_PHY_PLL_WAIT 0x00000183U +#define _reg_PHY_PLL_WAIT_TOP 0x00000184U +#define _reg_PHY_PLL_OBS_0 0x00000185U +#define _reg_PHY_PLL_OBS_1 0x00000186U +#define _reg_PHY_PLL_OBS_2 0x00000187U +#define _reg_PHY_PLL_OBS_3 0x00000188U +#define _reg_PHY_PLL_OBS_4 0x00000189U +#define _reg_PHY_PLL_TESTOUT_SEL 0x0000018aU +#define _reg_PHY_TCKSRE_WAIT 0x0000018bU +#define _reg_PHY_LP4_BOOT_LOW_FREQ_SEL 0x0000018cU +#define _reg_PHY_LP_WAKEUP 0x0000018dU +#define _reg_PHY_LS_IDLE_EN 0x0000018eU +#define _reg_PHY_LP_CTRLUPD_CNTR_CFG 0x0000018fU +#define _reg_PHY_TDFI_PHY_WRDELAY 0x00000190U +#define _reg_PHY_PAD_FDBK_DRIVE 0x00000191U +#define _reg_PHY_PAD_DATA_DRIVE 0x00000192U +#define _reg_PHY_PAD_DQS_DRIVE 0x00000193U +#define _reg_PHY_PAD_ADDR_DRIVE 0x00000194U +#define _reg_PHY_PAD_CLK_DRIVE 0x00000195U +#define _reg_PHY_PAD_FDBK_TERM 0x00000196U +#define _reg_PHY_PAD_DATA_TERM 0x00000197U +#define _reg_PHY_PAD_DQS_TERM 0x00000198U +#define _reg_PHY_PAD_ADDR_TERM 0x00000199U +#define _reg_PHY_PAD_CLK_TERM 0x0000019aU +#define _reg_PHY_PAD_CKE_DRIVE 0x0000019bU +#define _reg_PHY_PAD_CKE_TERM 0x0000019cU +#define _reg_PHY_PAD_RST_DRIVE 0x0000019dU +#define _reg_PHY_PAD_RST_TERM 0x0000019eU +#define _reg_PHY_PAD_CS_DRIVE 0x0000019fU +#define _reg_PHY_PAD_CS_TERM 0x000001a0U +#define _reg_PHY_PAD_ODT_DRIVE 0x000001a1U +#define _reg_PHY_PAD_ODT_TERM 0x000001a2U +#define _reg_PHY_ADRCTL_RX_CAL 0x000001a3U +#define _reg_PHY_ADRCTL_LP3_RX_CAL 0x000001a4U +#define _reg_PHY_TST_CLK_PAD_CTRL 0x000001a5U +#define _reg_PHY_TST_CLK_PAD_CTRL2 0x000001a6U +#define _reg_PHY_CAL_MODE_0 0x000001a7U +#define _reg_PHY_CAL_CLEAR_0 0x000001a8U +#define _reg_PHY_CAL_START_0 0x000001a9U +#define _reg_PHY_CAL_INTERVAL_COUNT_0 0x000001aaU +#define _reg_PHY_CAL_SAMPLE_WAIT_0 0x000001abU +#define _reg_PHY_LP4_BOOT_CAL_CLK_SELECT_0 0x000001acU +#define _reg_PHY_CAL_CLK_SELECT_0 0x000001adU +#define _reg_PHY_CAL_RESULT_OBS_0 0x000001aeU +#define _reg_PHY_CAL_RESULT2_OBS_0 0x000001afU +#define _reg_PHY_CAL_CPTR_CNT_0 0x000001b0U +#define _reg_PHY_CAL_SETTLING_PRD_0 0x000001b1U +#define _reg_PHY_CAL_PU_FINE_ADJ_0 0x000001b2U +#define _reg_PHY_CAL_PD_FINE_ADJ_0 0x000001b3U +#define _reg_PHY_CAL_RCV_FINE_ADJ_0 0x000001b4U +#define _reg_PHY_CAL_DBG_CFG_0 0x000001b5U +#define _reg_SC_PHY_PAD_DBG_CONT_0 0x000001b6U +#define _reg_PHY_CAL_RESULT3_OBS_0 0x000001b7U +#define _reg_PHY_ADRCTL_PVT_MAP_0 0x000001b8U +#define _reg_PHY_CAL_SLOPE_ADJ_0 0x000001b9U +#define _reg_PHY_CAL_SLOPE_ADJ_PASS2_0 0x000001baU +#define _reg_PHY_CAL_TWO_PASS_CFG_0 0x000001bbU +#define _reg_PHY_CAL_SW_CAL_CFG_0 0x000001bcU +#define _reg_PHY_CAL_RANGE_MIN_0 0x000001bdU +#define _reg_PHY_CAL_RANGE_MAX_0 0x000001beU +#define _reg_PHY_PAD_ATB_CTRL 0x000001bfU +#define _reg_PHY_ADRCTL_MANUAL_UPDATE 0x000001c0U +#define _reg_PHY_AC_LPBK_ERR_CLEAR 0x000001c1U +#define _reg_PHY_AC_LPBK_OBS_SELECT 0x000001c2U +#define _reg_PHY_AC_LPBK_ENABLE 0x000001c3U +#define _reg_PHY_AC_LPBK_CONTROL 0x000001c4U +#define _reg_PHY_AC_PRBS_PATTERN_START 0x000001c5U +#define _reg_PHY_AC_PRBS_PATTERN_MASK 0x000001c6U +#define _reg_PHY_AC_LPBK_RESULT_OBS 0x000001c7U +#define _reg_PHY_AC_CLK_LPBK_OBS_SELECT 0x000001c8U +#define _reg_PHY_AC_CLK_LPBK_ENABLE 0x000001c9U +#define _reg_PHY_AC_CLK_LPBK_CONTROL 0x000001caU +#define _reg_PHY_AC_CLK_LPBK_RESULT_OBS 0x000001cbU +#define _reg_PHY_AC_PWR_RDC_DISABLE 0x000001ccU +#define _reg_PHY_DATA_BYTE_ORDER_SEL 0x000001cdU +#define _reg_PHY_DATA_BYTE_ORDER_SEL_HIGH 0x000001ceU +#define _reg_PHY_LPDDR4_CONNECT 0x000001cfU +#define _reg_PHY_CALVL_DEVICE_MAP 0x000001d0U +#define _reg_PHY_ADR_DISABLE 0x000001d1U +#define _reg_PHY_ADRCTL_MSTR_DLY_ENC_SEL 0x000001d2U +#define _reg_PHY_CS_DLY_UPT_PER_AC_SLICE 0x000001d3U +#define _reg_PHY_DDL_AC_ENABLE 0x000001d4U +#define _reg_PHY_DDL_AC_MODE 0x000001d5U +#define _reg_PHY_PAD_BACKGROUND_CAL 0x000001d6U +#define _reg_PHY_INIT_UPDATE_CONFIG 0x000001d7U +#define _reg_PHY_DDL_TRACK_UPD_THRESHOLD_AC 0x000001d8U +#define _reg_PHY_DLL_RST_EN 0x000001d9U +#define _reg_PHY_AC_INIT_COMPLETE_OBS 0x000001daU +#define _reg_PHY_DS_INIT_COMPLETE_OBS 0x000001dbU +#define _reg_PHY_UPDATE_MASK 0x000001dcU +#define _reg_PHY_PLL_SWITCH_CNT 0x000001ddU +#define _reg_PI_START 0x000001deU +#define _reg_PI_DRAM_CLASS 0x000001dfU +#define _reg_PI_VERSION 0x000001e0U +#define _reg_PI_NORMAL_LVL_SEQ 0x000001e1U +#define _reg_PI_INIT_LVL_EN 0x000001e2U +#define _reg_PI_NOTCARE_PHYUPD 0x000001e3U +#define _reg_PI_ONBUS_MBIST 0x000001e4U +#define _reg_PI_TCMD_GAP 0x000001e5U +#define _reg_PI_MASTER_ACK_DURATION_MIN 0x000001e6U +#define _reg_PI_DFI_VERSION 0x000001e7U +#define _reg_PI_TDFI_PHYMSTR_TYPE0 0x000001e8U +#define _reg_PI_TDFI_PHYMSTR_TYPE1 0x000001e9U +#define _reg_PI_TDFI_PHYMSTR_TYPE2 0x000001eaU +#define _reg_PI_TDFI_PHYMSTR_TYPE3 0x000001ebU +#define _reg_PI_DFI_PHYMSTR_TYPE 0x000001ecU +#define _reg_PI_DFI_PHYMSTR_CS_STATE_R 0x000001edU +#define _reg_PI_DFI_PHYMSTR_STATE_SEL_R 0x000001eeU +#define _reg_PI_TDFI_PHYMSTR_MAX_F0 0x000001efU +#define _reg_PI_TDFI_PHYMSTR_RESP_F0 0x000001f0U +#define _reg_PI_TDFI_PHYMSTR_MAX_F1 0x000001f1U +#define _reg_PI_TDFI_PHYMSTR_RESP_F1 0x000001f2U +#define _reg_PI_TDFI_PHYMSTR_MAX_F2 0x000001f3U +#define _reg_PI_TDFI_PHYMSTR_RESP_F2 0x000001f4U +#define _reg_PI_TDFI_PHYUPD_RESP_F0 0x000001f5U +#define _reg_PI_TDFI_PHYUPD_TYPE0_F0 0x000001f6U +#define _reg_PI_TDFI_PHYUPD_TYPE1_F0 0x000001f7U +#define _reg_PI_TDFI_PHYUPD_TYPE2_F0 0x000001f8U +#define _reg_PI_TDFI_PHYUPD_TYPE3_F0 0x000001f9U +#define _reg_PI_TDFI_PHYUPD_RESP_F1 0x000001faU +#define _reg_PI_TDFI_PHYUPD_TYPE0_F1 0x000001fbU +#define _reg_PI_TDFI_PHYUPD_TYPE1_F1 0x000001fcU +#define _reg_PI_TDFI_PHYUPD_TYPE2_F1 0x000001fdU +#define _reg_PI_TDFI_PHYUPD_TYPE3_F1 0x000001feU +#define _reg_PI_TDFI_PHYUPD_RESP_F2 0x000001ffU +#define _reg_PI_TDFI_PHYUPD_TYPE0_F2 0x00000200U +#define _reg_PI_TDFI_PHYUPD_TYPE1_F2 0x00000201U +#define _reg_PI_TDFI_PHYUPD_TYPE2_F2 0x00000202U +#define _reg_PI_TDFI_PHYUPD_TYPE3_F2 0x00000203U +#define _reg_PI_CONTROL_ERROR_STATUS 0x00000204U +#define _reg_PI_EXIT_AFTER_INIT_CALVL 0x00000205U +#define _reg_PI_FREQ_MAP 0x00000206U +#define _reg_PI_INIT_WORK_FREQ 0x00000207U +#define _reg_PI_INIT_DFS_CALVL_ONLY 0x00000208U +#define _reg_PI_POWER_ON_SEQ_BYPASS_ARRAY 0x00000209U +#define _reg_PI_POWER_ON_SEQ_END_ARRAY 0x0000020aU +#define _reg_PI_SEQ1_PAT 0x0000020bU +#define _reg_PI_SEQ1_PAT_MASK 0x0000020cU +#define _reg_PI_SEQ2_PAT 0x0000020dU +#define _reg_PI_SEQ2_PAT_MASK 0x0000020eU +#define _reg_PI_SEQ3_PAT 0x0000020fU +#define _reg_PI_SEQ3_PAT_MASK 0x00000210U +#define _reg_PI_SEQ4_PAT 0x00000211U +#define _reg_PI_SEQ4_PAT_MASK 0x00000212U +#define _reg_PI_SEQ5_PAT 0x00000213U +#define _reg_PI_SEQ5_PAT_MASK 0x00000214U +#define _reg_PI_SEQ6_PAT 0x00000215U +#define _reg_PI_SEQ6_PAT_MASK 0x00000216U +#define _reg_PI_SEQ7_PAT 0x00000217U +#define _reg_PI_SEQ7_PAT_MASK 0x00000218U +#define _reg_PI_SEQ8_PAT 0x00000219U +#define _reg_PI_SEQ8_PAT_MASK 0x0000021aU +#define _reg_PI_WDT_DISABLE 0x0000021bU +#define _reg_PI_SW_RST_N 0x0000021cU +#define _reg_RESERVED_R0 0x0000021dU +#define _reg_PI_CS_MAP 0x0000021eU +#define _reg_PI_TDELAY_RDWR_2_BUS_IDLE_F0 0x0000021fU +#define _reg_PI_TDELAY_RDWR_2_BUS_IDLE_F1 0x00000220U +#define _reg_PI_TDELAY_RDWR_2_BUS_IDLE_F2 0x00000221U +#define _reg_PI_TMRR 0x00000222U +#define _reg_PI_WRLAT_F0 0x00000223U +#define _reg_PI_ADDITIVE_LAT_F0 0x00000224U +#define _reg_PI_CASLAT_LIN_F0 0x00000225U +#define _reg_PI_WRLAT_F1 0x00000226U +#define _reg_PI_ADDITIVE_LAT_F1 0x00000227U +#define _reg_PI_CASLAT_LIN_F1 0x00000228U +#define _reg_PI_WRLAT_F2 0x00000229U +#define _reg_PI_ADDITIVE_LAT_F2 0x0000022aU +#define _reg_PI_CASLAT_LIN_F2 0x0000022bU +#define _reg_PI_PREAMBLE_SUPPORT 0x0000022cU +#define _reg_PI_AREFRESH 0x0000022dU +#define _reg_PI_MCAREF_FORWARD_ONLY 0x0000022eU +#define _reg_PI_TRFC_F0 0x0000022fU +#define _reg_PI_TREF_F0 0x00000230U +#define _reg_PI_TRFC_F1 0x00000231U +#define _reg_PI_TREF_F1 0x00000232U +#define _reg_PI_TRFC_F2 0x00000233U +#define _reg_PI_TREF_F2 0x00000234U +#define _reg_RESERVED_H3VER2 0x00000235U +#define _reg_PI_TREF_INTERVAL 0x00000236U +#define _reg_PI_FREQ_CHANGE_REG_COPY 0x00000237U +#define _reg_PI_FREQ_SEL_FROM_REGIF 0x00000238U +#define _reg_PI_SWLVL_LOAD 0x00000239U +#define _reg_PI_SWLVL_OP_DONE 0x0000023aU +#define _reg_PI_SW_WRLVL_RESP_0 0x0000023bU +#define _reg_PI_SW_WRLVL_RESP_1 0x0000023cU +#define _reg_PI_SW_WRLVL_RESP_2 0x0000023dU +#define _reg_PI_SW_WRLVL_RESP_3 0x0000023eU +#define _reg_PI_SW_RDLVL_RESP_0 0x0000023fU +#define _reg_PI_SW_RDLVL_RESP_1 0x00000240U +#define _reg_PI_SW_RDLVL_RESP_2 0x00000241U +#define _reg_PI_SW_RDLVL_RESP_3 0x00000242U +#define _reg_PI_SW_CALVL_RESP_0 0x00000243U +#define _reg_PI_SW_LEVELING_MODE 0x00000244U +#define _reg_PI_SWLVL_START 0x00000245U +#define _reg_PI_SWLVL_EXIT 0x00000246U +#define _reg_PI_SWLVL_WR_SLICE_0 0x00000247U +#define _reg_PI_SWLVL_RD_SLICE_0 0x00000248U +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_0 0x00000249U +#define _reg_PI_SW_WDQLVL_RESP_0 0x0000024aU +#define _reg_PI_SWLVL_WR_SLICE_1 0x0000024bU +#define _reg_PI_SWLVL_RD_SLICE_1 0x0000024cU +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_1 0x0000024dU +#define _reg_PI_SW_WDQLVL_RESP_1 0x0000024eU +#define _reg_PI_SWLVL_WR_SLICE_2 0x0000024fU +#define _reg_PI_SWLVL_RD_SLICE_2 0x00000250U +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_2 0x00000251U +#define _reg_PI_SW_WDQLVL_RESP_2 0x00000252U +#define _reg_PI_SWLVL_WR_SLICE_3 0x00000253U +#define _reg_PI_SWLVL_RD_SLICE_3 0x00000254U +#define _reg_PI_SWLVL_VREF_UPDATE_SLICE_3 0x00000255U +#define _reg_PI_SW_WDQLVL_RESP_3 0x00000256U +#define _reg_PI_SW_WDQLVL_VREF 0x00000257U +#define _reg_PI_SWLVL_SM2_START 0x00000258U +#define _reg_PI_SWLVL_SM2_WR 0x00000259U +#define _reg_PI_SWLVL_SM2_RD 0x0000025aU +#define _reg_PI_SEQUENTIAL_LVL_REQ 0x0000025bU +#define _reg_PI_DFS_PERIOD_EN 0x0000025cU +#define _reg_PI_SRE_PERIOD_EN 0x0000025dU +#define _reg_PI_DFI40_POLARITY 0x0000025eU +#define _reg_PI_16BIT_DRAM_CONNECT 0x0000025fU +#define _reg_PI_TDFI_CTRL_DELAY_F0 0x00000260U +#define _reg_PI_TDFI_CTRL_DELAY_F1 0x00000261U +#define _reg_PI_TDFI_CTRL_DELAY_F2 0x00000262U +#define _reg_PI_WRLVL_REQ 0x00000263U +#define _reg_PI_WRLVL_CS 0x00000264U +#define _reg_PI_WLDQSEN 0x00000265U +#define _reg_PI_WLMRD 0x00000266U +#define _reg_PI_WRLVL_EN_F0 0x00000267U +#define _reg_PI_WRLVL_EN_F1 0x00000268U +#define _reg_PI_WRLVL_EN_F2 0x00000269U +#define _reg_PI_WRLVL_EN 0x0000026aU +#define _reg_PI_WRLVL_INTERVAL 0x0000026bU +#define _reg_PI_WRLVL_PERIODIC 0x0000026cU +#define _reg_PI_WRLVL_ON_SREF_EXIT 0x0000026dU +#define _reg_PI_WRLVL_DISABLE_DFS 0x0000026eU +#define _reg_PI_WRLVL_RESP_MASK 0x0000026fU +#define _reg_PI_WRLVL_ROTATE 0x00000270U +#define _reg_PI_WRLVL_CS_MAP 0x00000271U +#define _reg_PI_WRLVL_ERROR_STATUS 0x00000272U +#define _reg_PI_TDFI_WRLVL_EN 0x00000273U +#define _reg_PI_TDFI_WRLVL_WW_F0 0x00000274U +#define _reg_PI_TDFI_WRLVL_WW_F1 0x00000275U +#define _reg_PI_TDFI_WRLVL_WW_F2 0x00000276U +#define _reg_PI_TDFI_WRLVL_WW 0x00000277U +#define _reg_PI_TDFI_WRLVL_RESP 0x00000278U +#define _reg_PI_TDFI_WRLVL_MAX 0x00000279U +#define _reg_PI_WRLVL_STROBE_NUM 0x0000027aU +#define _reg_PI_WRLVL_MRR_DQ_RETURN_HIZ 0x0000027bU +#define _reg_PI_WRLVL_EN_DEASSERT_2_MRR 0x0000027cU +#define _reg_PI_TODTL_2CMD_F0 0x0000027dU +#define _reg_PI_ODT_EN_F0 0x0000027eU +#define _reg_PI_TODTL_2CMD_F1 0x0000027fU +#define _reg_PI_ODT_EN_F1 0x00000280U +#define _reg_PI_TODTL_2CMD_F2 0x00000281U +#define _reg_PI_ODT_EN_F2 0x00000282U +#define _reg_PI_TODTH_WR 0x00000283U +#define _reg_PI_TODTH_RD 0x00000284U +#define _reg_PI_ODT_RD_MAP_CS0 0x00000285U +#define _reg_PI_ODT_WR_MAP_CS0 0x00000286U +#define _reg_PI_ODT_RD_MAP_CS1 0x00000287U +#define _reg_PI_ODT_WR_MAP_CS1 0x00000288U +#define _reg_PI_ODT_RD_MAP_CS2 0x00000289U +#define _reg_PI_ODT_WR_MAP_CS2 0x0000028aU +#define _reg_PI_ODT_RD_MAP_CS3 0x0000028bU +#define _reg_PI_ODT_WR_MAP_CS3 0x0000028cU +#define _reg_PI_EN_ODT_ASSERT_EXCEPT_RD 0x0000028dU +#define _reg_PI_ODTLON_F0 0x0000028eU +#define _reg_PI_TODTON_MIN_F0 0x0000028fU +#define _reg_PI_ODTLON_F1 0x00000290U +#define _reg_PI_TODTON_MIN_F1 0x00000291U +#define _reg_PI_ODTLON_F2 0x00000292U +#define _reg_PI_TODTON_MIN_F2 0x00000293U +#define _reg_PI_WR_TO_ODTH_F0 0x00000294U +#define _reg_PI_WR_TO_ODTH_F1 0x00000295U +#define _reg_PI_WR_TO_ODTH_F2 0x00000296U +#define _reg_PI_RD_TO_ODTH_F0 0x00000297U +#define _reg_PI_RD_TO_ODTH_F1 0x00000298U +#define _reg_PI_RD_TO_ODTH_F2 0x00000299U +#define _reg_PI_ADDRESS_MIRRORING 0x0000029aU +#define _reg_PI_RDLVL_REQ 0x0000029bU +#define _reg_PI_RDLVL_GATE_REQ 0x0000029cU +#define _reg_PI_RDLVL_CS 0x0000029dU +#define _reg_PI_RDLVL_PAT_0 0x0000029eU +#define _reg_PI_RDLVL_PAT_1 0x0000029fU +#define _reg_PI_RDLVL_PAT_2 0x000002a0U +#define _reg_PI_RDLVL_PAT_3 0x000002a1U +#define _reg_PI_RDLVL_PAT_4 0x000002a2U +#define _reg_PI_RDLVL_PAT_5 0x000002a3U +#define _reg_PI_RDLVL_PAT_6 0x000002a4U +#define _reg_PI_RDLVL_PAT_7 0x000002a5U +#define _reg_PI_RDLVL_SEQ_EN 0x000002a6U +#define _reg_PI_RDLVL_GATE_SEQ_EN 0x000002a7U +#define _reg_PI_RDLVL_PERIODIC 0x000002a8U +#define _reg_PI_RDLVL_ON_SREF_EXIT 0x000002a9U +#define _reg_PI_RDLVL_DISABLE_DFS 0x000002aaU +#define _reg_PI_RDLVL_GATE_PERIODIC 0x000002abU +#define _reg_PI_RDLVL_GATE_ON_SREF_EXIT 0x000002acU +#define _reg_PI_RDLVL_GATE_DISABLE_DFS 0x000002adU +#define _reg_RESERVED_R1 0x000002aeU +#define _reg_PI_RDLVL_ROTATE 0x000002afU +#define _reg_PI_RDLVL_GATE_ROTATE 0x000002b0U +#define _reg_PI_RDLVL_CS_MAP 0x000002b1U +#define _reg_PI_RDLVL_GATE_CS_MAP 0x000002b2U +#define _reg_PI_TDFI_RDLVL_RR 0x000002b3U +#define _reg_PI_TDFI_RDLVL_RESP 0x000002b4U +#define _reg_PI_RDLVL_RESP_MASK 0x000002b5U +#define _reg_PI_TDFI_RDLVL_EN 0x000002b6U +#define _reg_PI_RDLVL_EN_F0 0x000002b7U +#define _reg_PI_RDLVL_GATE_EN_F0 0x000002b8U +#define _reg_PI_RDLVL_EN_F1 0x000002b9U +#define _reg_PI_RDLVL_GATE_EN_F1 0x000002baU +#define _reg_PI_RDLVL_EN_F2 0x000002bbU +#define _reg_PI_RDLVL_GATE_EN_F2 0x000002bcU +#define _reg_PI_RDLVL_EN 0x000002bdU +#define _reg_PI_RDLVL_GATE_EN 0x000002beU +#define _reg_PI_TDFI_RDLVL_MAX 0x000002bfU +#define _reg_PI_RDLVL_ERROR_STATUS 0x000002c0U +#define _reg_PI_RDLVL_INTERVAL 0x000002c1U +#define _reg_PI_RDLVL_GATE_INTERVAL 0x000002c2U +#define _reg_PI_RDLVL_PATTERN_START 0x000002c3U +#define _reg_PI_RDLVL_PATTERN_NUM 0x000002c4U +#define _reg_PI_RDLVL_STROBE_NUM 0x000002c5U +#define _reg_PI_RDLVL_GATE_STROBE_NUM 0x000002c6U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_8 0x000002c7U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_9 0x000002c8U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_10 0x000002c9U +#define _reg_PI_LPDDR4_RDLVL_PATTERN_11 0x000002caU +#define _reg_PI_RD_PREAMBLE_TRAINING_EN 0x000002cbU +#define _reg_PI_REG_DIMM_ENABLE 0x000002ccU +#define _reg_PI_RDLAT_ADJ_F0 0x000002cdU +#define _reg_PI_RDLAT_ADJ_F1 0x000002ceU +#define _reg_PI_RDLAT_ADJ_F2 0x000002cfU +#define _reg_PI_TDFI_RDDATA_EN 0x000002d0U +#define _reg_PI_WRLAT_ADJ_F0 0x000002d1U +#define _reg_PI_WRLAT_ADJ_F1 0x000002d2U +#define _reg_PI_WRLAT_ADJ_F2 0x000002d3U +#define _reg_PI_TDFI_PHY_WRLAT 0x000002d4U +#define _reg_PI_TDFI_WRCSLAT_F0 0x000002d5U +#define _reg_PI_TDFI_WRCSLAT_F1 0x000002d6U +#define _reg_PI_TDFI_WRCSLAT_F2 0x000002d7U +#define _reg_PI_TDFI_RDCSLAT_F0 0x000002d8U +#define _reg_PI_TDFI_RDCSLAT_F1 0x000002d9U +#define _reg_PI_TDFI_RDCSLAT_F2 0x000002daU +#define _reg_PI_TDFI_PHY_WRDATA_F0 0x000002dbU +#define _reg_PI_TDFI_PHY_WRDATA_F1 0x000002dcU +#define _reg_PI_TDFI_PHY_WRDATA_F2 0x000002ddU +#define _reg_PI_TDFI_PHY_WRDATA 0x000002deU +#define _reg_PI_CALVL_REQ 0x000002dfU +#define _reg_PI_CALVL_CS 0x000002e0U +#define _reg_RESERVED_R2 0x000002e1U +#define _reg_RESERVED_R3 0x000002e2U +#define _reg_PI_CALVL_SEQ_EN 0x000002e3U +#define _reg_PI_CALVL_PERIODIC 0x000002e4U +#define _reg_PI_CALVL_ON_SREF_EXIT 0x000002e5U +#define _reg_PI_CALVL_DISABLE_DFS 0x000002e6U +#define _reg_PI_CALVL_ROTATE 0x000002e7U +#define _reg_PI_CALVL_CS_MAP 0x000002e8U +#define _reg_PI_TDFI_CALVL_EN 0x000002e9U +#define _reg_PI_TDFI_CALVL_CC_F0 0x000002eaU +#define _reg_PI_TDFI_CALVL_CAPTURE_F0 0x000002ebU +#define _reg_PI_TDFI_CALVL_CC_F1 0x000002ecU +#define _reg_PI_TDFI_CALVL_CAPTURE_F1 0x000002edU +#define _reg_PI_TDFI_CALVL_CC_F2 0x000002eeU +#define _reg_PI_TDFI_CALVL_CAPTURE_F2 0x000002efU +#define _reg_PI_TDFI_CALVL_RESP 0x000002f0U +#define _reg_PI_TDFI_CALVL_MAX 0x000002f1U +#define _reg_PI_CALVL_RESP_MASK 0x000002f2U +#define _reg_PI_CALVL_EN_F0 0x000002f3U +#define _reg_PI_CALVL_EN_F1 0x000002f4U +#define _reg_PI_CALVL_EN_F2 0x000002f5U +#define _reg_PI_CALVL_EN 0x000002f6U +#define _reg_PI_CALVL_ERROR_STATUS 0x000002f7U +#define _reg_PI_CALVL_INTERVAL 0x000002f8U +#define _reg_PI_TCACKEL 0x000002f9U +#define _reg_PI_TCAMRD 0x000002faU +#define _reg_PI_TCACKEH 0x000002fbU +#define _reg_PI_TMRZ_F0 0x000002fcU +#define _reg_PI_TCAENT_F0 0x000002fdU +#define _reg_PI_TMRZ_F1 0x000002feU +#define _reg_PI_TCAENT_F1 0x000002ffU +#define _reg_PI_TMRZ_F2 0x00000300U +#define _reg_PI_TCAENT_F2 0x00000301U +#define _reg_PI_TCAEXT 0x00000302U +#define _reg_PI_CA_TRAIN_VREF_EN 0x00000303U +#define _reg_PI_TDFI_CACSCA_F0 0x00000304U +#define _reg_PI_TDFI_CASEL_F0 0x00000305U +#define _reg_PI_TVREF_SHORT_F0 0x00000306U +#define _reg_PI_TVREF_LONG_F0 0x00000307U +#define _reg_PI_TDFI_CACSCA_F1 0x00000308U +#define _reg_PI_TDFI_CASEL_F1 0x00000309U +#define _reg_PI_TVREF_SHORT_F1 0x0000030aU +#define _reg_PI_TVREF_LONG_F1 0x0000030bU +#define _reg_PI_TDFI_CACSCA_F2 0x0000030cU +#define _reg_PI_TDFI_CASEL_F2 0x0000030dU +#define _reg_PI_TVREF_SHORT_F2 0x0000030eU +#define _reg_PI_TVREF_LONG_F2 0x0000030fU +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT_F0 0x00000310U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT_F0 0x00000311U +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT_F1 0x00000312U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT_F1 0x00000313U +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT_F2 0x00000314U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT_F2 0x00000315U +#define _reg_PI_CALVL_VREF_INITIAL_START_POINT 0x00000316U +#define _reg_PI_CALVL_VREF_INITIAL_STOP_POINT 0x00000317U +#define _reg_PI_CALVL_VREF_INITIAL_STEPSIZE 0x00000318U +#define _reg_PI_CALVL_VREF_NORMAL_STEPSIZE 0x00000319U +#define _reg_PI_CALVL_VREF_DELTA_F0 0x0000031aU +#define _reg_PI_CALVL_VREF_DELTA_F1 0x0000031bU +#define _reg_PI_CALVL_VREF_DELTA_F2 0x0000031cU +#define _reg_PI_CALVL_VREF_DELTA 0x0000031dU +#define _reg_PI_TDFI_INIT_START_MIN 0x0000031eU +#define _reg_PI_TDFI_INIT_COMPLETE_MIN 0x0000031fU +#define _reg_PI_TDFI_CALVL_STROBE_F0 0x00000320U +#define _reg_PI_TXP_F0 0x00000321U +#define _reg_PI_TMRWCKEL_F0 0x00000322U +#define _reg_PI_TCKELCK_F0 0x00000323U +#define _reg_PI_TDFI_CALVL_STROBE_F1 0x00000324U +#define _reg_PI_TXP_F1 0x00000325U +#define _reg_PI_TMRWCKEL_F1 0x00000326U +#define _reg_PI_TCKELCK_F1 0x00000327U +#define _reg_PI_TDFI_CALVL_STROBE_F2 0x00000328U +#define _reg_PI_TXP_F2 0x00000329U +#define _reg_PI_TMRWCKEL_F2 0x0000032aU +#define _reg_PI_TCKELCK_F2 0x0000032bU +#define _reg_PI_TCKCKEH 0x0000032cU +#define _reg_PI_CALVL_STROBE_NUM 0x0000032dU +#define _reg_PI_SW_CA_TRAIN_VREF 0x0000032eU +#define _reg_PI_TDFI_INIT_START_F0 0x0000032fU +#define _reg_PI_TDFI_INIT_COMPLETE_F0 0x00000330U +#define _reg_PI_TDFI_INIT_START_F1 0x00000331U +#define _reg_PI_TDFI_INIT_COMPLETE_F1 0x00000332U +#define _reg_PI_TDFI_INIT_START_F2 0x00000333U +#define _reg_PI_TDFI_INIT_COMPLETE_F2 0x00000334U +#define _reg_PI_CLKDISABLE_2_INIT_START 0x00000335U +#define _reg_PI_INIT_STARTORCOMPLETE_2_CLKDISABLE 0x00000336U +#define _reg_PI_DRAM_CLK_DISABLE_DEASSERT_SEL 0x00000337U +#define _reg_PI_REFRESH_BETWEEN_SEGMENT_DISABLE 0x00000338U +#define _reg_PI_TCKEHDQS_F0 0x00000339U +#define _reg_PI_TCKEHDQS_F1 0x0000033aU +#define _reg_PI_TCKEHDQS_F2 0x0000033bU +#define _reg_PI_MC_DFS_PI_SET_VREF_ENABLE 0x0000033cU +#define _reg_PI_WDQLVL_VREF_EN 0x0000033dU +#define _reg_PI_WDQLVL_BST_NUM 0x0000033eU +#define _reg_PI_TDFI_WDQLVL_WR_F0 0x0000033fU +#define _reg_PI_TDFI_WDQLVL_WR_F1 0x00000340U +#define _reg_PI_TDFI_WDQLVL_WR_F2 0x00000341U +#define _reg_PI_TDFI_WDQLVL_WR 0x00000342U +#define _reg_PI_TDFI_WDQLVL_RW 0x00000343U +#define _reg_PI_WDQLVL_RESP_MASK 0x00000344U +#define _reg_PI_WDQLVL_ROTATE 0x00000345U +#define _reg_PI_WDQLVL_CS_MAP 0x00000346U +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F0 0x00000347U +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F0 0x00000348U +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F1 0x00000349U +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1 0x0000034aU +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F2 0x0000034bU +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F2 0x0000034cU +#define _reg_PI_WDQLVL_VREF_INITIAL_START_POINT 0x0000034dU +#define _reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT 0x0000034eU +#define _reg_PI_WDQLVL_VREF_INITIAL_STEPSIZE 0x0000034fU +#define _reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE 0x00000350U +#define _reg_PI_WDQLVL_VREF_DELTA_F0 0x00000351U +#define _reg_PI_WDQLVL_VREF_DELTA_F1 0x00000352U +#define _reg_PI_WDQLVL_VREF_DELTA_F2 0x00000353U +#define _reg_PI_WDQLVL_VREF_DELTA 0x00000354U +#define _reg_PI_WDQLVL_PERIODIC 0x00000355U +#define _reg_PI_WDQLVL_REQ 0x00000356U +#define _reg_PI_WDQLVL_CS 0x00000357U +#define _reg_PI_TDFI_WDQLVL_EN 0x00000358U +#define _reg_PI_TDFI_WDQLVL_RESP 0x00000359U +#define _reg_PI_TDFI_WDQLVL_MAX 0x0000035aU +#define _reg_PI_WDQLVL_INTERVAL 0x0000035bU +#define _reg_PI_WDQLVL_EN_F0 0x0000035cU +#define _reg_PI_WDQLVL_EN_F1 0x0000035dU +#define _reg_PI_WDQLVL_EN_F2 0x0000035eU +#define _reg_PI_WDQLVL_EN 0x0000035fU +#define _reg_PI_WDQLVL_ON_SREF_EXIT 0x00000360U +#define _reg_PI_WDQLVL_DISABLE_DFS 0x00000361U +#define _reg_PI_WDQLVL_ERROR_STATUS 0x00000362U +#define _reg_PI_MR1_DATA_F0_0 0x00000363U +#define _reg_PI_MR2_DATA_F0_0 0x00000364U +#define _reg_PI_MR3_DATA_F0_0 0x00000365U +#define _reg_PI_MR11_DATA_F0_0 0x00000366U +#define _reg_PI_MR12_DATA_F0_0 0x00000367U +#define _reg_PI_MR14_DATA_F0_0 0x00000368U +#define _reg_PI_MR22_DATA_F0_0 0x00000369U +#define _reg_PI_MR1_DATA_F1_0 0x0000036aU +#define _reg_PI_MR2_DATA_F1_0 0x0000036bU +#define _reg_PI_MR3_DATA_F1_0 0x0000036cU +#define _reg_PI_MR11_DATA_F1_0 0x0000036dU +#define _reg_PI_MR12_DATA_F1_0 0x0000036eU +#define _reg_PI_MR14_DATA_F1_0 0x0000036fU +#define _reg_PI_MR22_DATA_F1_0 0x00000370U +#define _reg_PI_MR1_DATA_F2_0 0x00000371U +#define _reg_PI_MR2_DATA_F2_0 0x00000372U +#define _reg_PI_MR3_DATA_F2_0 0x00000373U +#define _reg_PI_MR11_DATA_F2_0 0x00000374U +#define _reg_PI_MR12_DATA_F2_0 0x00000375U +#define _reg_PI_MR14_DATA_F2_0 0x00000376U +#define _reg_PI_MR22_DATA_F2_0 0x00000377U +#define _reg_PI_MR13_DATA_0 0x00000378U +#define _reg_PI_MR1_DATA_F0_1 0x00000379U +#define _reg_PI_MR2_DATA_F0_1 0x0000037aU +#define _reg_PI_MR3_DATA_F0_1 0x0000037bU +#define _reg_PI_MR11_DATA_F0_1 0x0000037cU +#define _reg_PI_MR12_DATA_F0_1 0x0000037dU +#define _reg_PI_MR14_DATA_F0_1 0x0000037eU +#define _reg_PI_MR22_DATA_F0_1 0x0000037fU +#define _reg_PI_MR1_DATA_F1_1 0x00000380U +#define _reg_PI_MR2_DATA_F1_1 0x00000381U +#define _reg_PI_MR3_DATA_F1_1 0x00000382U +#define _reg_PI_MR11_DATA_F1_1 0x00000383U +#define _reg_PI_MR12_DATA_F1_1 0x00000384U +#define _reg_PI_MR14_DATA_F1_1 0x00000385U +#define _reg_PI_MR22_DATA_F1_1 0x00000386U +#define _reg_PI_MR1_DATA_F2_1 0x00000387U +#define _reg_PI_MR2_DATA_F2_1 0x00000388U +#define _reg_PI_MR3_DATA_F2_1 0x00000389U +#define _reg_PI_MR11_DATA_F2_1 0x0000038aU +#define _reg_PI_MR12_DATA_F2_1 0x0000038bU +#define _reg_PI_MR14_DATA_F2_1 0x0000038cU +#define _reg_PI_MR22_DATA_F2_1 0x0000038dU +#define _reg_PI_MR13_DATA_1 0x0000038eU +#define _reg_PI_MR1_DATA_F0_2 0x0000038fU +#define _reg_PI_MR2_DATA_F0_2 0x00000390U +#define _reg_PI_MR3_DATA_F0_2 0x00000391U +#define _reg_PI_MR11_DATA_F0_2 0x00000392U +#define _reg_PI_MR12_DATA_F0_2 0x00000393U +#define _reg_PI_MR14_DATA_F0_2 0x00000394U +#define _reg_PI_MR22_DATA_F0_2 0x00000395U +#define _reg_PI_MR1_DATA_F1_2 0x00000396U +#define _reg_PI_MR2_DATA_F1_2 0x00000397U +#define _reg_PI_MR3_DATA_F1_2 0x00000398U +#define _reg_PI_MR11_DATA_F1_2 0x00000399U +#define _reg_PI_MR12_DATA_F1_2 0x0000039aU +#define _reg_PI_MR14_DATA_F1_2 0x0000039bU +#define _reg_PI_MR22_DATA_F1_2 0x0000039cU +#define _reg_PI_MR1_DATA_F2_2 0x0000039dU +#define _reg_PI_MR2_DATA_F2_2 0x0000039eU +#define _reg_PI_MR3_DATA_F2_2 0x0000039fU +#define _reg_PI_MR11_DATA_F2_2 0x000003a0U +#define _reg_PI_MR12_DATA_F2_2 0x000003a1U +#define _reg_PI_MR14_DATA_F2_2 0x000003a2U +#define _reg_PI_MR22_DATA_F2_2 0x000003a3U +#define _reg_PI_MR13_DATA_2 0x000003a4U +#define _reg_PI_MR1_DATA_F0_3 0x000003a5U +#define _reg_PI_MR2_DATA_F0_3 0x000003a6U +#define _reg_PI_MR3_DATA_F0_3 0x000003a7U +#define _reg_PI_MR11_DATA_F0_3 0x000003a8U +#define _reg_PI_MR12_DATA_F0_3 0x000003a9U +#define _reg_PI_MR14_DATA_F0_3 0x000003aaU +#define _reg_PI_MR22_DATA_F0_3 0x000003abU +#define _reg_PI_MR1_DATA_F1_3 0x000003acU +#define _reg_PI_MR2_DATA_F1_3 0x000003adU +#define _reg_PI_MR3_DATA_F1_3 0x000003aeU +#define _reg_PI_MR11_DATA_F1_3 0x000003afU +#define _reg_PI_MR12_DATA_F1_3 0x000003b0U +#define _reg_PI_MR14_DATA_F1_3 0x000003b1U +#define _reg_PI_MR22_DATA_F1_3 0x000003b2U +#define _reg_PI_MR1_DATA_F2_3 0x000003b3U +#define _reg_PI_MR2_DATA_F2_3 0x000003b4U +#define _reg_PI_MR3_DATA_F2_3 0x000003b5U +#define _reg_PI_MR11_DATA_F2_3 0x000003b6U +#define _reg_PI_MR12_DATA_F2_3 0x000003b7U +#define _reg_PI_MR14_DATA_F2_3 0x000003b8U +#define _reg_PI_MR22_DATA_F2_3 0x000003b9U +#define _reg_PI_MR13_DATA_3 0x000003baU +#define _reg_PI_BANK_DIFF 0x000003bbU +#define _reg_PI_ROW_DIFF 0x000003bcU +#define _reg_PI_TFC_F0 0x000003bdU +#define _reg_PI_TFC_F1 0x000003beU +#define _reg_PI_TFC_F2 0x000003bfU +#define _reg_PI_TCCD 0x000003c0U +#define _reg_PI_TRTP_F0 0x000003c1U +#define _reg_PI_TRP_F0 0x000003c2U +#define _reg_PI_TRCD_F0 0x000003c3U +#define _reg_PI_TWTR_F0 0x000003c4U +#define _reg_PI_TWR_F0 0x000003c5U +#define _reg_PI_TRAS_MAX_F0 0x000003c6U +#define _reg_PI_TRAS_MIN_F0 0x000003c7U +#define _reg_PI_TDQSCK_MAX_F0 0x000003c8U +#define _reg_PI_TCCDMW_F0 0x000003c9U +#define _reg_PI_TSR_F0 0x000003caU +#define _reg_PI_TMRD_F0 0x000003cbU +#define _reg_PI_TMRW_F0 0x000003ccU +#define _reg_PI_TMOD_F0 0x000003cdU +#define _reg_PI_TRTP_F1 0x000003ceU +#define _reg_PI_TRP_F1 0x000003cfU +#define _reg_PI_TRCD_F1 0x000003d0U +#define _reg_PI_TWTR_F1 0x000003d1U +#define _reg_PI_TWR_F1 0x000003d2U +#define _reg_PI_TRAS_MAX_F1 0x000003d3U +#define _reg_PI_TRAS_MIN_F1 0x000003d4U +#define _reg_PI_TDQSCK_MAX_F1 0x000003d5U +#define _reg_PI_TCCDMW_F1 0x000003d6U +#define _reg_PI_TSR_F1 0x000003d7U +#define _reg_PI_TMRD_F1 0x000003d8U +#define _reg_PI_TMRW_F1 0x000003d9U +#define _reg_PI_TMOD_F1 0x000003daU +#define _reg_PI_TRTP_F2 0x000003dbU +#define _reg_PI_TRP_F2 0x000003dcU +#define _reg_PI_TRCD_F2 0x000003ddU +#define _reg_PI_TWTR_F2 0x000003deU +#define _reg_PI_TWR_F2 0x000003dfU +#define _reg_PI_TRAS_MAX_F2 0x000003e0U +#define _reg_PI_TRAS_MIN_F2 0x000003e1U +#define _reg_PI_TDQSCK_MAX_F2 0x000003e2U +#define _reg_PI_TCCDMW_F2 0x000003e3U +#define _reg_PI_TSR_F2 0x000003e4U +#define _reg_PI_TMRD_F2 0x000003e5U +#define _reg_PI_TMRW_F2 0x000003e6U +#define _reg_PI_TMOD_F2 0x000003e7U +#define _reg_RESERVED_R4 0x000003e8U +#define _reg_RESERVED_R5 0x000003e9U +#define _reg_RESERVED_R6 0x000003eaU +#define _reg_RESERVED_R7 0x000003ebU +#define _reg_RESERVED_R8 0x000003ecU +#define _reg_RESERVED_R9 0x000003edU +#define _reg_RESERVED_R10 0x000003eeU +#define _reg_RESERVED_R11 0x000003efU +#define _reg_RESERVED_R12 0x000003f0U +#define _reg_RESERVED_R13 0x000003f1U +#define _reg_RESERVED_R14 0x000003f2U +#define _reg_RESERVED_R15 0x000003f3U +#define _reg_RESERVED_R16 0x000003f4U +#define _reg_RESERVED_R17 0x000003f5U +#define _reg_RESERVED_R18 0x000003f6U +#define _reg_RESERVED_R19 0x000003f7U +#define _reg_RESERVED_R20 0x000003f8U +#define _reg_RESERVED_R21 0x000003f9U +#define _reg_RESERVED_R22 0x000003faU +#define _reg_RESERVED_R23 0x000003fbU +#define _reg_PI_INT_STATUS 0x000003fcU +#define _reg_PI_INT_ACK 0x000003fdU +#define _reg_PI_INT_MASK 0x000003feU +#define _reg_PI_BIST_EXP_DATA_P0 0x000003ffU +#define _reg_PI_BIST_EXP_DATA_P1 0x00000400U +#define _reg_PI_BIST_EXP_DATA_P2 0x00000401U +#define _reg_PI_BIST_EXP_DATA_P3 0x00000402U +#define _reg_PI_BIST_FAIL_DATA_P0 0x00000403U +#define _reg_PI_BIST_FAIL_DATA_P1 0x00000404U +#define _reg_PI_BIST_FAIL_DATA_P2 0x00000405U +#define _reg_PI_BIST_FAIL_DATA_P3 0x00000406U +#define _reg_PI_BIST_FAIL_ADDR_P0 0x00000407U +#define _reg_PI_BIST_FAIL_ADDR_P1 0x00000408U +#define _reg_PI_BSTLEN 0x00000409U +#define _reg_PI_LONG_COUNT_MASK 0x0000040aU +#define _reg_PI_CMD_SWAP_EN 0x0000040bU +#define _reg_PI_CKE_MUX_0 0x0000040cU +#define _reg_PI_CKE_MUX_1 0x0000040dU +#define _reg_PI_CKE_MUX_2 0x0000040eU +#define _reg_PI_CKE_MUX_3 0x0000040fU +#define _reg_PI_CS_MUX_0 0x00000410U +#define _reg_PI_CS_MUX_1 0x00000411U +#define _reg_PI_CS_MUX_2 0x00000412U +#define _reg_PI_CS_MUX_3 0x00000413U +#define _reg_PI_RAS_N_MUX 0x00000414U +#define _reg_PI_CAS_N_MUX 0x00000415U +#define _reg_PI_WE_N_MUX 0x00000416U +#define _reg_PI_BANK_MUX_0 0x00000417U +#define _reg_PI_BANK_MUX_1 0x00000418U +#define _reg_PI_BANK_MUX_2 0x00000419U +#define _reg_PI_ODT_MUX_0 0x0000041aU +#define _reg_PI_ODT_MUX_1 0x0000041bU +#define _reg_PI_ODT_MUX_2 0x0000041cU +#define _reg_PI_ODT_MUX_3 0x0000041dU +#define _reg_PI_RESET_N_MUX_0 0x0000041eU +#define _reg_PI_RESET_N_MUX_1 0x0000041fU +#define _reg_PI_RESET_N_MUX_2 0x00000420U +#define _reg_PI_RESET_N_MUX_3 0x00000421U +#define _reg_PI_DATA_BYTE_SWAP_EN 0x00000422U +#define _reg_PI_DATA_BYTE_SWAP_SLICE0 0x00000423U +#define _reg_PI_DATA_BYTE_SWAP_SLICE1 0x00000424U +#define _reg_PI_DATA_BYTE_SWAP_SLICE2 0x00000425U +#define _reg_PI_DATA_BYTE_SWAP_SLICE3 0x00000426U +#define _reg_PI_CTRLUPD_REQ_PER_AREF_EN 0x00000427U +#define _reg_PI_TDFI_CTRLUPD_MIN 0x00000428U +#define _reg_PI_TDFI_CTRLUPD_MAX_F0 0x00000429U +#define _reg_PI_TDFI_CTRLUPD_INTERVAL_F0 0x0000042aU +#define _reg_PI_TDFI_CTRLUPD_MAX_F1 0x0000042bU +#define _reg_PI_TDFI_CTRLUPD_INTERVAL_F1 0x0000042cU +#define _reg_PI_TDFI_CTRLUPD_MAX_F2 0x0000042dU +#define _reg_PI_TDFI_CTRLUPD_INTERVAL_F2 0x0000042eU +#define _reg_PI_UPDATE_ERROR_STATUS 0x0000042fU +#define _reg_PI_BIST_GO 0x00000430U +#define _reg_PI_BIST_RESULT 0x00000431U +#define _reg_PI_ADDR_SPACE 0x00000432U +#define _reg_PI_BIST_DATA_CHECK 0x00000433U +#define _reg_PI_BIST_ADDR_CHECK 0x00000434U +#define _reg_PI_BIST_START_ADDRESS_P0 0x00000435U +#define _reg_PI_BIST_START_ADDRESS_P1 0x00000436U +#define _reg_PI_BIST_DATA_MASK_P0 0x00000437U +#define _reg_PI_BIST_DATA_MASK_P1 0x00000438U +#define _reg_PI_BIST_ERR_COUNT 0x00000439U +#define _reg_PI_BIST_ERR_STOP 0x0000043aU +#define _reg_PI_BIST_ADDR_MASK_0_P0 0x0000043bU +#define _reg_PI_BIST_ADDR_MASK_0_P1 0x0000043cU +#define _reg_PI_BIST_ADDR_MASK_1_P0 0x0000043dU +#define _reg_PI_BIST_ADDR_MASK_1_P1 0x0000043eU +#define _reg_PI_BIST_ADDR_MASK_2_P0 0x0000043fU +#define _reg_PI_BIST_ADDR_MASK_2_P1 0x00000440U +#define _reg_PI_BIST_ADDR_MASK_3_P0 0x00000441U +#define _reg_PI_BIST_ADDR_MASK_3_P1 0x00000442U +#define _reg_PI_BIST_ADDR_MASK_4_P0 0x00000443U +#define _reg_PI_BIST_ADDR_MASK_4_P1 0x00000444U +#define _reg_PI_BIST_ADDR_MASK_5_P0 0x00000445U +#define _reg_PI_BIST_ADDR_MASK_5_P1 0x00000446U +#define _reg_PI_BIST_ADDR_MASK_6_P0 0x00000447U +#define _reg_PI_BIST_ADDR_MASK_6_P1 0x00000448U +#define _reg_PI_BIST_ADDR_MASK_7_P0 0x00000449U +#define _reg_PI_BIST_ADDR_MASK_7_P1 0x0000044aU +#define _reg_PI_BIST_ADDR_MASK_8_P0 0x0000044bU +#define _reg_PI_BIST_ADDR_MASK_8_P1 0x0000044cU +#define _reg_PI_BIST_ADDR_MASK_9_P0 0x0000044dU +#define _reg_PI_BIST_ADDR_MASK_9_P1 0x0000044eU +#define _reg_PI_BIST_MODE 0x0000044fU +#define _reg_PI_BIST_ADDR_MODE 0x00000450U +#define _reg_PI_BIST_PAT_MODE 0x00000451U +#define _reg_PI_BIST_USER_PAT_P0 0x00000452U +#define _reg_PI_BIST_USER_PAT_P1 0x00000453U +#define _reg_PI_BIST_USER_PAT_P2 0x00000454U +#define _reg_PI_BIST_USER_PAT_P3 0x00000455U +#define _reg_PI_BIST_PAT_NUM 0x00000456U +#define _reg_PI_BIST_STAGE_0 0x00000457U +#define _reg_PI_BIST_STAGE_1 0x00000458U +#define _reg_PI_BIST_STAGE_2 0x00000459U +#define _reg_PI_BIST_STAGE_3 0x0000045aU +#define _reg_PI_BIST_STAGE_4 0x0000045bU +#define _reg_PI_BIST_STAGE_5 0x0000045cU +#define _reg_PI_BIST_STAGE_6 0x0000045dU +#define _reg_PI_BIST_STAGE_7 0x0000045eU +#define _reg_PI_COL_DIFF 0x0000045fU +#define _reg_PI_SELF_REFRESH_EN 0x00000460U +#define _reg_PI_TXSR_F0 0x00000461U +#define _reg_PI_TXSR_F1 0x00000462U +#define _reg_PI_TXSR_F2 0x00000463U +#define _reg_PI_MONITOR_SRC_SEL_0 0x00000464U +#define _reg_PI_MONITOR_CAP_SEL_0 0x00000465U +#define _reg_PI_MONITOR_0 0x00000466U +#define _reg_PI_MONITOR_SRC_SEL_1 0x00000467U +#define _reg_PI_MONITOR_CAP_SEL_1 0x00000468U +#define _reg_PI_MONITOR_1 0x00000469U +#define _reg_PI_MONITOR_SRC_SEL_2 0x0000046aU +#define _reg_PI_MONITOR_CAP_SEL_2 0x0000046bU +#define _reg_PI_MONITOR_2 0x0000046cU +#define _reg_PI_MONITOR_SRC_SEL_3 0x0000046dU +#define _reg_PI_MONITOR_CAP_SEL_3 0x0000046eU +#define _reg_PI_MONITOR_3 0x0000046fU +#define _reg_PI_MONITOR_SRC_SEL_4 0x00000470U +#define _reg_PI_MONITOR_CAP_SEL_4 0x00000471U +#define _reg_PI_MONITOR_4 0x00000472U +#define _reg_PI_MONITOR_SRC_SEL_5 0x00000473U +#define _reg_PI_MONITOR_CAP_SEL_5 0x00000474U +#define _reg_PI_MONITOR_5 0x00000475U +#define _reg_PI_MONITOR_SRC_SEL_6 0x00000476U +#define _reg_PI_MONITOR_CAP_SEL_6 0x00000477U +#define _reg_PI_MONITOR_6 0x00000478U +#define _reg_PI_MONITOR_SRC_SEL_7 0x00000479U +#define _reg_PI_MONITOR_CAP_SEL_7 0x0000047aU +#define _reg_PI_MONITOR_7 0x0000047bU +#define _reg_PI_MONITOR_STROBE 0x0000047cU +#define _reg_PI_DLL_LOCK 0x0000047dU +#define _reg_PI_FREQ_NUMBER_STATUS 0x0000047eU +#define _reg_RESERVED_R24 0x0000047fU +#define _reg_PI_PHYMSTR_TYPE 0x00000480U +#define _reg_PI_POWER_REDUC_EN 0x00000481U +#define _reg_RESERVED_R25 0x00000482U +#define _reg_RESERVED_R26 0x00000483U +#define _reg_RESERVED_R27 0x00000484U +#define _reg_RESERVED_R28 0x00000485U +#define _reg_RESERVED_R29 0x00000486U +#define _reg_RESERVED_R30 0x00000487U +#define _reg_RESERVED_R31 0x00000488U +#define _reg_RESERVED_R32 0x00000489U +#define _reg_RESERVED_R33 0x0000048aU +#define _reg_RESERVED_R34 0x0000048bU +#define _reg_RESERVED_R35 0x0000048cU +#define _reg_RESERVED_R36 0x0000048dU +#define _reg_RESERVED_R37 0x0000048eU +#define _reg_RESERVED_R38 0x0000048fU +#define _reg_RESERVED_R39 0x00000490U +#define _reg_PI_WRLVL_MAX_STROBE_PEND 0x00000491U +#define _reg_PI_TSDO_F0 0x00000492U +#define _reg_PI_TSDO_F1 0x00000493U +#define _reg_PI_TSDO_F2 0x00000494U + +#define DDR_REGDEF_ADR(regdef) ((regdef) & 0xffffU) +#define DDR_REGDEF_LEN(regdef) (((regdef) >> 16) & 0xffU) +#define DDR_REGDEF_LSB(regdef) (((regdef) >> 24) & 0xffU) + +static const uint32_t DDR_REGDEF_TBL[4][1173] = { + { +/*0000*/ 0xffffffffU, +/*0001*/ 0xffffffffU, +/*0002*/ 0x000b0400U, +/*0003*/ 0xffffffffU, +/*0004*/ 0xffffffffU, +/*0005*/ 0x10010400U, +/*0006*/ 0x18050400U, +/*0007*/ 0x00050401U, +/*0008*/ 0x08050401U, +/*0009*/ 0x10050401U, +/*000a*/ 0x18050401U, +/*000b*/ 0x00050402U, +/*000c*/ 0x08050402U, +/*000d*/ 0x10050402U, +/*000e*/ 0x18050402U, +/*000f*/ 0x00040403U, +/*0010*/ 0x08030403U, +/*0011*/ 0x00180404U, +/*0012*/ 0x18030404U, +/*0013*/ 0x00180405U, +/*0014*/ 0x18020405U, +/*0015*/ 0x00010406U, +/*0016*/ 0x08020406U, +/*0017*/ 0x10010406U, +/*0018*/ 0x18010406U, +/*0019*/ 0x00020407U, +/*001a*/ 0x08040407U, +/*001b*/ 0x10040407U, +/*001c*/ 0x18040407U, +/*001d*/ 0x000a0408U, +/*001e*/ 0x10040408U, +/*001f*/ 0xffffffffU, +/*0020*/ 0xffffffffU, +/*0021*/ 0x18070408U, +/*0022*/ 0xffffffffU, +/*0023*/ 0xffffffffU, +/*0024*/ 0xffffffffU, +/*0025*/ 0xffffffffU, +/*0026*/ 0xffffffffU, +/*0027*/ 0xffffffffU, +/*0028*/ 0x000a0409U, +/*0029*/ 0x10040409U, +/*002a*/ 0x18010409U, +/*002b*/ 0x0001040aU, +/*002c*/ 0x0802040aU, +/*002d*/ 0x1009040aU, +/*002e*/ 0x0009040bU, +/*002f*/ 0x1002040bU, +/*0030*/ 0x0020040cU, +/*0031*/ 0xffffffffU, +/*0032*/ 0x0001040dU, +/*0033*/ 0xffffffffU, +/*0034*/ 0xffffffffU, +/*0035*/ 0xffffffffU, +/*0036*/ 0xffffffffU, +/*0037*/ 0x0020040eU, +/*0038*/ 0x0020040fU, +/*0039*/ 0x00200410U, +/*003a*/ 0x00200411U, +/*003b*/ 0x00030412U, +/*003c*/ 0x08010412U, +/*003d*/ 0x10030412U, +/*003e*/ 0x18030412U, +/*003f*/ 0x00040413U, +/*0040*/ 0x08040413U, +/*0041*/ 0x10040413U, +/*0042*/ 0x18040413U, +/*0043*/ 0x00010414U, +/*0044*/ 0x08010414U, +/*0045*/ 0x10060414U, +/*0046*/ 0x18040414U, +/*0047*/ 0xffffffffU, +/*0048*/ 0x00060415U, +/*0049*/ 0x08040415U, +/*004a*/ 0x10060415U, +/*004b*/ 0x18040415U, +/*004c*/ 0x00020416U, +/*004d*/ 0x08050416U, +/*004e*/ 0x10080416U, +/*004f*/ 0x00200417U, +/*0050*/ 0x00060418U, +/*0051*/ 0x08030418U, +/*0052*/ 0x100b0418U, +/*0053*/ 0x00040419U, +/*0054*/ 0x08040419U, +/*0055*/ 0x10040419U, +/*0056*/ 0xffffffffU, +/*0057*/ 0x18010419U, +/*0058*/ 0x0009041aU, +/*0059*/ 0x0020041bU, +/*005a*/ 0x0020041cU, +/*005b*/ 0x0020041dU, +/*005c*/ 0x0020041eU, +/*005d*/ 0x0010041fU, +/*005e*/ 0x00200420U, +/*005f*/ 0x00010421U, +/*0060*/ 0x08060421U, +/*0061*/ 0x10080421U, +/*0062*/ 0x00200422U, +/*0063*/ 0xffffffffU, +/*0064*/ 0x000a0423U, +/*0065*/ 0x10060423U, +/*0066*/ 0x18070423U, +/*0067*/ 0x00080424U, +/*0068*/ 0x08080424U, +/*0069*/ 0x100a0424U, +/*006a*/ 0x00070425U, +/*006b*/ 0x08080425U, +/*006c*/ 0x10080425U, +/*006d*/ 0x18030425U, +/*006e*/ 0x000a0426U, +/*006f*/ 0x100a0426U, +/*0070*/ 0x00110427U, +/*0071*/ 0x00090428U, +/*0072*/ 0x10090428U, +/*0073*/ 0x00100429U, +/*0074*/ 0x100e0429U, +/*0075*/ 0x000e042aU, +/*0076*/ 0x100c042aU, +/*0077*/ 0x000a042bU, +/*0078*/ 0x100a042bU, +/*0079*/ 0x0002042cU, +/*007a*/ 0x0020042dU, +/*007b*/ 0x000b042eU, +/*007c*/ 0x100b042eU, +/*007d*/ 0x0020042fU, +/*007e*/ 0x00120430U, +/*007f*/ 0x00200431U, +/*0080*/ 0x00200432U, +/*0081*/ 0xffffffffU, +/*0082*/ 0xffffffffU, +/*0083*/ 0x00010433U, +/*0084*/ 0x08010433U, +/*0085*/ 0x10080433U, +/*0086*/ 0x000c0434U, +/*0087*/ 0x100c0434U, +/*0088*/ 0x000c0435U, +/*0089*/ 0x100c0435U, +/*008a*/ 0x000c0436U, +/*008b*/ 0x100c0436U, +/*008c*/ 0x000c0437U, +/*008d*/ 0x100c0437U, +/*008e*/ 0x000c0438U, +/*008f*/ 0x100c0438U, +/*0090*/ 0x000c0439U, +/*0091*/ 0x100b0439U, +/*0092*/ 0xffffffffU, +/*0093*/ 0xffffffffU, +/*0094*/ 0x000b043aU, +/*0095*/ 0x100b043aU, +/*0096*/ 0x000b043bU, +/*0097*/ 0x100b043bU, +/*0098*/ 0x000b043cU, +/*0099*/ 0x100b043cU, +/*009a*/ 0x000b043dU, +/*009b*/ 0x100b043dU, +/*009c*/ 0x000b043eU, +/*009d*/ 0x100a043eU, +/*009e*/ 0xffffffffU, +/*009f*/ 0x000a043fU, +/*00a0*/ 0x100a043fU, +/*00a1*/ 0x000a0440U, +/*00a2*/ 0x100a0440U, +/*00a3*/ 0x000a0441U, +/*00a4*/ 0x100a0441U, +/*00a5*/ 0x000a0442U, +/*00a6*/ 0x100a0442U, +/*00a7*/ 0xffffffffU, +/*00a8*/ 0x000a0443U, +/*00a9*/ 0x100a0443U, +/*00aa*/ 0x000a0444U, +/*00ab*/ 0x100a0444U, +/*00ac*/ 0x000a0445U, +/*00ad*/ 0x100a0445U, +/*00ae*/ 0x000a0446U, +/*00af*/ 0x100a0446U, +/*00b0*/ 0x000a0447U, +/*00b1*/ 0x100a0447U, +/*00b2*/ 0x000a0448U, +/*00b3*/ 0x100a0448U, +/*00b4*/ 0x000a0449U, +/*00b5*/ 0x100a0449U, +/*00b6*/ 0x000a044aU, +/*00b7*/ 0x100a044aU, +/*00b8*/ 0x000a044bU, +/*00b9*/ 0x100a044bU, +/*00ba*/ 0x000a044cU, +/*00bb*/ 0x1004044cU, +/*00bc*/ 0x1803044cU, +/*00bd*/ 0x000a044dU, +/*00be*/ 0x100a044dU, +/*00bf*/ 0x0001044eU, +/*00c0*/ 0x080a044eU, +/*00c1*/ 0x1804044eU, +/*00c2*/ 0x000b044fU, +/*00c3*/ 0x100a044fU, +/*00c4*/ 0xffffffffU, +/*00c5*/ 0x00080450U, +/*00c6*/ 0x08080450U, +/*00c7*/ 0x10080450U, +/*00c8*/ 0x18080450U, +/*00c9*/ 0x00080451U, +/*00ca*/ 0xffffffffU, +/*00cb*/ 0x08080451U, +/*00cc*/ 0x10010451U, +/*00cd*/ 0x18080451U, +/*00ce*/ 0x00080452U, +/*00cf*/ 0x08020452U, +/*00d0*/ 0x10020452U, +/*00d1*/ 0x18040452U, +/*00d2*/ 0x00040453U, +/*00d3*/ 0xffffffffU, +/*00d4*/ 0x08040453U, +/*00d5*/ 0x100a0453U, +/*00d6*/ 0x00060454U, +/*00d7*/ 0x08080454U, +/*00d8*/ 0xffffffffU, +/*00d9*/ 0x10040454U, +/*00da*/ 0x18040454U, +/*00db*/ 0x00050455U, +/*00dc*/ 0x08040455U, +/*00dd*/ 0x10050455U, +/*00de*/ 0x000a0456U, +/*00df*/ 0x100a0456U, +/*00e0*/ 0x00080457U, +/*00e1*/ 0xffffffffU, +/*00e2*/ 0x08040457U, +/*00e3*/ 0xffffffffU, +/*00e4*/ 0xffffffffU, +/*00e5*/ 0x00050600U, +/*00e6*/ 0x08050600U, +/*00e7*/ 0x10050600U, +/*00e8*/ 0x18050600U, +/*00e9*/ 0x00050601U, +/*00ea*/ 0x08050601U, +/*00eb*/ 0x100b0601U, +/*00ec*/ 0x00010602U, +/*00ed*/ 0x08030602U, +/*00ee*/ 0x00200603U, +/*00ef*/ 0xffffffffU, +/*00f0*/ 0x00030604U, +/*00f1*/ 0x080a0604U, +/*00f2*/ 0xffffffffU, +/*00f3*/ 0xffffffffU, +/*00f4*/ 0x18030604U, +/*00f5*/ 0x00030605U, +/*00f6*/ 0x08010605U, +/*00f7*/ 0x10010605U, +/*00f8*/ 0x18060605U, +/*00f9*/ 0xffffffffU, +/*00fa*/ 0xffffffffU, +/*00fb*/ 0xffffffffU, +/*00fc*/ 0x00020606U, +/*00fd*/ 0x08030606U, +/*00fe*/ 0x10010606U, +/*00ff*/ 0x000f0607U, +/*0100*/ 0x00200608U, +/*0101*/ 0x00200609U, +/*0102*/ 0x000b060aU, +/*0103*/ 0x100b060aU, +/*0104*/ 0x000b060bU, +/*0105*/ 0xffffffffU, +/*0106*/ 0xffffffffU, +/*0107*/ 0x0018060cU, +/*0108*/ 0x0018060dU, +/*0109*/ 0x0018060eU, +/*010a*/ 0x0018060fU, +/*010b*/ 0x1804060fU, +/*010c*/ 0x00050610U, +/*010d*/ 0x08020610U, +/*010e*/ 0x10040610U, +/*010f*/ 0x18040610U, +/*0110*/ 0x00010611U, +/*0111*/ 0x08010611U, +/*0112*/ 0x10010611U, +/*0113*/ 0x18030611U, +/*0114*/ 0x00200612U, +/*0115*/ 0x00200613U, +/*0116*/ 0x00010614U, +/*0117*/ 0x08140614U, +/*0118*/ 0x00140615U, +/*0119*/ 0x00140616U, +/*011a*/ 0x00140617U, +/*011b*/ 0x00140618U, +/*011c*/ 0x00140619U, +/*011d*/ 0x0014061aU, +/*011e*/ 0x0014061bU, +/*011f*/ 0x0018061cU, +/*0120*/ 0x000a061dU, +/*0121*/ 0x1006061dU, +/*0122*/ 0x1806061dU, +/*0123*/ 0x0006061eU, +/*0124*/ 0xffffffffU, +/*0125*/ 0xffffffffU, +/*0126*/ 0x0008061fU, +/*0127*/ 0x080b061fU, +/*0128*/ 0x000b0620U, +/*0129*/ 0x100b0620U, +/*012a*/ 0x000b0621U, +/*012b*/ 0x100b0621U, +/*012c*/ 0x000b0622U, +/*012d*/ 0x10040622U, +/*012e*/ 0x000a0623U, +/*012f*/ 0x10060623U, +/*0130*/ 0x18080623U, +/*0131*/ 0xffffffffU, +/*0132*/ 0x00040624U, +/*0133*/ 0xffffffffU, +/*0134*/ 0xffffffffU, +/*0135*/ 0x00010700U, +/*0136*/ 0x08020700U, +/*0137*/ 0x10050700U, +/*0138*/ 0x18050700U, +/*0139*/ 0x00050701U, +/*013a*/ 0x08050701U, +/*013b*/ 0x100b0701U, +/*013c*/ 0x00050702U, +/*013d*/ 0x08010702U, +/*013e*/ 0x10010702U, +/*013f*/ 0xffffffffU, +/*0140*/ 0x18010702U, +/*0141*/ 0x00010703U, +/*0142*/ 0x08040703U, +/*0143*/ 0x100b0703U, +/*0144*/ 0x000b0704U, +/*0145*/ 0xffffffffU, +/*0146*/ 0x10040704U, +/*0147*/ 0x000b0705U, +/*0148*/ 0x10040705U, +/*0149*/ 0x18010705U, +/*014a*/ 0x00010706U, +/*014b*/ 0x08010706U, +/*014c*/ 0x00200707U, +/*014d*/ 0x00200708U, +/*014e*/ 0x00080709U, +/*014f*/ 0x080a0709U, +/*0150*/ 0x18050709U, +/*0151*/ 0x000a070aU, +/*0152*/ 0x1003070aU, +/*0153*/ 0x1803070aU, +/*0154*/ 0x0001070bU, +/*0155*/ 0x0802070bU, +/*0156*/ 0x1001070bU, +/*0157*/ 0x1801070bU, +/*0158*/ 0x0001070cU, +/*0159*/ 0x0802070cU, +/*015a*/ 0xffffffffU, +/*015b*/ 0xffffffffU, +/*015c*/ 0xffffffffU, +/*015d*/ 0xffffffffU, +/*015e*/ 0xffffffffU, +/*015f*/ 0xffffffffU, +/*0160*/ 0xffffffffU, +/*0161*/ 0xffffffffU, +/*0162*/ 0xffffffffU, +/*0163*/ 0xffffffffU, +/*0164*/ 0xffffffffU, +/*0165*/ 0xffffffffU, +/*0166*/ 0x1001070cU, +/*0167*/ 0x1801070cU, +/*0168*/ 0x000d070dU, +/*0169*/ 0xffffffffU, +/*016a*/ 0xffffffffU, +/*016b*/ 0x0005070eU, +/*016c*/ 0x0001070fU, +/*016d*/ 0x080e070fU, +/*016e*/ 0x000e0710U, +/*016f*/ 0x100e0710U, +/*0170*/ 0x000e0711U, +/*0171*/ 0x100e0711U, +/*0172*/ 0x00040712U, +/*0173*/ 0xffffffffU, +/*0174*/ 0xffffffffU, +/*0175*/ 0xffffffffU, +/*0176*/ 0xffffffffU, +/*0177*/ 0x080b0712U, +/*0178*/ 0x000b0713U, +/*0179*/ 0x100b0713U, +/*017a*/ 0x000b0714U, +/*017b*/ 0xffffffffU, +/*017c*/ 0xffffffffU, +/*017d*/ 0xffffffffU, +/*017e*/ 0xffffffffU, +/*017f*/ 0x000d0715U, +/*0180*/ 0xffffffffU, +/*0181*/ 0xffffffffU, +/*0182*/ 0x10100715U, +/*0183*/ 0x00080716U, +/*0184*/ 0xffffffffU, +/*0185*/ 0x08100716U, +/*0186*/ 0x00100717U, +/*0187*/ 0x10100717U, +/*0188*/ 0x00100718U, +/*0189*/ 0x10100718U, +/*018a*/ 0x00030719U, +/*018b*/ 0x08040719U, +/*018c*/ 0x10010719U, +/*018d*/ 0x18040719U, +/*018e*/ 0xffffffffU, +/*018f*/ 0xffffffffU, +/*0190*/ 0x0001071aU, +/*0191*/ 0x0812071aU, +/*0192*/ 0x000a071bU, +/*0193*/ 0x100c071bU, +/*0194*/ 0x0012071cU, +/*0195*/ 0x0014071dU, +/*0196*/ 0x0012071eU, +/*0197*/ 0x0011071fU, +/*0198*/ 0x00110720U, +/*0199*/ 0x00120721U, +/*019a*/ 0x00120722U, +/*019b*/ 0x00120723U, +/*019c*/ 0x00120724U, +/*019d*/ 0x00120725U, +/*019e*/ 0x00120726U, +/*019f*/ 0x00120727U, +/*01a0*/ 0x00120728U, +/*01a1*/ 0xffffffffU, +/*01a2*/ 0xffffffffU, +/*01a3*/ 0x00190729U, +/*01a4*/ 0x0019072aU, +/*01a5*/ 0x0020072bU, +/*01a6*/ 0x0017072cU, +/*01a7*/ 0x1808072cU, +/*01a8*/ 0x0001072dU, +/*01a9*/ 0x0801072dU, +/*01aa*/ 0x0020072eU, +/*01ab*/ 0x0008072fU, +/*01ac*/ 0xffffffffU, +/*01ad*/ 0x0803072fU, +/*01ae*/ 0x00180730U, +/*01af*/ 0x00180731U, +/*01b0*/ 0xffffffffU, +/*01b1*/ 0xffffffffU, +/*01b2*/ 0xffffffffU, +/*01b3*/ 0xffffffffU, +/*01b4*/ 0xffffffffU, +/*01b5*/ 0xffffffffU, +/*01b6*/ 0xffffffffU, +/*01b7*/ 0xffffffffU, +/*01b8*/ 0xffffffffU, +/*01b9*/ 0xffffffffU, +/*01ba*/ 0xffffffffU, +/*01bb*/ 0xffffffffU, +/*01bc*/ 0xffffffffU, +/*01bd*/ 0xffffffffU, +/*01be*/ 0xffffffffU, +/*01bf*/ 0x00100732U, +/*01c0*/ 0x10010732U, +/*01c1*/ 0x18010732U, +/*01c2*/ 0x00050733U, +/*01c3*/ 0x00200734U, +/*01c4*/ 0x00090735U, +/*01c5*/ 0xffffffffU, +/*01c6*/ 0xffffffffU, +/*01c7*/ 0x00200736U, +/*01c8*/ 0x00040737U, +/*01c9*/ 0x08100737U, +/*01ca*/ 0x18060737U, +/*01cb*/ 0x00100738U, +/*01cc*/ 0xffffffffU, +/*01cd*/ 0xffffffffU, +/*01ce*/ 0xffffffffU, +/*01cf*/ 0xffffffffU, +/*01d0*/ 0xffffffffU, +/*01d1*/ 0xffffffffU, +/*01d2*/ 0xffffffffU, +/*01d3*/ 0xffffffffU, +/*01d4*/ 0x00200739U, +/*01d5*/ 0x000b073aU, +/*01d6*/ 0xffffffffU, +/*01d7*/ 0xffffffffU, +/*01d8*/ 0xffffffffU, +/*01d9*/ 0xffffffffU, +/*01da*/ 0xffffffffU, +/*01db*/ 0xffffffffU, +/*01dc*/ 0xffffffffU, +/*01dd*/ 0xffffffffU, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0xffffffffU, +/*01e4*/ 0xffffffffU, +/*01e5*/ 0x10100201U, +/*01e6*/ 0xffffffffU, +/*01e7*/ 0xffffffffU, +/*01e8*/ 0xffffffffU, +/*01e9*/ 0xffffffffU, +/*01ea*/ 0xffffffffU, +/*01eb*/ 0xffffffffU, +/*01ec*/ 0xffffffffU, +/*01ed*/ 0xffffffffU, +/*01ee*/ 0xffffffffU, +/*01ef*/ 0x00200202U, +/*01f0*/ 0x00100203U, +/*01f1*/ 0x00200204U, +/*01f2*/ 0x00100205U, +/*01f3*/ 0x00200206U, +/*01f4*/ 0x00100207U, +/*01f5*/ 0x10100207U, +/*01f6*/ 0x00200208U, +/*01f7*/ 0x00200209U, +/*01f8*/ 0x0020020aU, +/*01f9*/ 0x0020020bU, +/*01fa*/ 0x0010020cU, +/*01fb*/ 0x0020020dU, +/*01fc*/ 0x0020020eU, +/*01fd*/ 0x0020020fU, +/*01fe*/ 0x00200210U, +/*01ff*/ 0x00100211U, +/*0200*/ 0x00200212U, +/*0201*/ 0x00200213U, +/*0202*/ 0x00200214U, +/*0203*/ 0x00200215U, +/*0204*/ 0x00090216U, +/*0205*/ 0x10010216U, +/*0206*/ 0x00200217U, +/*0207*/ 0x00050218U, +/*0208*/ 0x08010218U, +/*0209*/ 0x10080218U, +/*020a*/ 0x18080218U, +/*020b*/ 0x001c0219U, +/*020c*/ 0x001c021aU, +/*020d*/ 0x001c021bU, +/*020e*/ 0x001c021cU, +/*020f*/ 0x001c021dU, +/*0210*/ 0x001c021eU, +/*0211*/ 0x001c021fU, +/*0212*/ 0x001c0220U, +/*0213*/ 0x001c0221U, +/*0214*/ 0x001c0222U, +/*0215*/ 0x001c0223U, +/*0216*/ 0x001c0224U, +/*0217*/ 0x001c0225U, +/*0218*/ 0x001c0226U, +/*0219*/ 0x001c0227U, +/*021a*/ 0x001c0228U, +/*021b*/ 0x00010229U, +/*021c*/ 0x08010229U, +/*021d*/ 0x10010229U, +/*021e*/ 0x18040229U, +/*021f*/ 0x0008022aU, +/*0220*/ 0x0808022aU, +/*0221*/ 0x1008022aU, +/*0222*/ 0x1804022aU, +/*0223*/ 0x0006022bU, +/*0224*/ 0xffffffffU, +/*0225*/ 0x0807022bU, +/*0226*/ 0x1006022bU, +/*0227*/ 0xffffffffU, +/*0228*/ 0x1807022bU, +/*0229*/ 0x0006022cU, +/*022a*/ 0xffffffffU, +/*022b*/ 0x0807022cU, +/*022c*/ 0x1002022cU, +/*022d*/ 0x1801022cU, +/*022e*/ 0xffffffffU, +/*022f*/ 0x000a022dU, +/*0230*/ 0x1010022dU, +/*0231*/ 0x000a022eU, +/*0232*/ 0x1010022eU, +/*0233*/ 0x000a022fU, +/*0234*/ 0x1010022fU, +/*0235*/ 0xffffffffU, +/*0236*/ 0x00100230U, +/*0237*/ 0xffffffffU, +/*0238*/ 0xffffffffU, +/*0239*/ 0x10010230U, +/*023a*/ 0x18010230U, +/*023b*/ 0x00010231U, +/*023c*/ 0x08010231U, +/*023d*/ 0x10010231U, +/*023e*/ 0x18010231U, +/*023f*/ 0x00020232U, +/*0240*/ 0x08020232U, +/*0241*/ 0x10020232U, +/*0242*/ 0x18020232U, +/*0243*/ 0x00020233U, +/*0244*/ 0x08030233U, +/*0245*/ 0x10010233U, +/*0246*/ 0x18010233U, +/*0247*/ 0x00010234U, +/*0248*/ 0x08010234U, +/*0249*/ 0xffffffffU, +/*024a*/ 0x10020234U, +/*024b*/ 0x18010234U, +/*024c*/ 0x00010235U, +/*024d*/ 0xffffffffU, +/*024e*/ 0x08020235U, +/*024f*/ 0x10010235U, +/*0250*/ 0x18010235U, +/*0251*/ 0xffffffffU, +/*0252*/ 0x00020236U, +/*0253*/ 0x08010236U, +/*0254*/ 0x10010236U, +/*0255*/ 0xffffffffU, +/*0256*/ 0x18020236U, +/*0257*/ 0x00070237U, +/*0258*/ 0x08010237U, +/*0259*/ 0x10010237U, +/*025a*/ 0x18010237U, +/*025b*/ 0x00010238U, +/*025c*/ 0x08010238U, +/*025d*/ 0x10010238U, +/*025e*/ 0xffffffffU, +/*025f*/ 0x18010238U, +/*0260*/ 0x00040239U, +/*0261*/ 0x08040239U, +/*0262*/ 0x10040239U, +/*0263*/ 0x18010239U, +/*0264*/ 0x0002023aU, +/*0265*/ 0x0806023aU, +/*0266*/ 0x1006023aU, +/*0267*/ 0xffffffffU, +/*0268*/ 0xffffffffU, +/*0269*/ 0xffffffffU, +/*026a*/ 0x1802023aU, +/*026b*/ 0x0010023bU, +/*026c*/ 0x1001023bU, +/*026d*/ 0x1801023bU, +/*026e*/ 0xffffffffU, +/*026f*/ 0x0004023cU, +/*0270*/ 0x0801023cU, +/*0271*/ 0x1004023cU, +/*0272*/ 0x1802023cU, +/*0273*/ 0x0008023dU, +/*0274*/ 0xffffffffU, +/*0275*/ 0xffffffffU, +/*0276*/ 0xffffffffU, +/*0277*/ 0x080a023dU, +/*0278*/ 0x0020023eU, +/*0279*/ 0x0020023fU, +/*027a*/ 0x00050240U, +/*027b*/ 0x08010240U, +/*027c*/ 0x10050240U, +/*027d*/ 0x18080240U, +/*027e*/ 0x00010241U, +/*027f*/ 0x08080241U, +/*0280*/ 0x10010241U, +/*0281*/ 0x18080241U, +/*0282*/ 0x00010242U, +/*0283*/ 0x08040242U, +/*0284*/ 0x10040242U, +/*0285*/ 0x18040242U, +/*0286*/ 0x00040243U, +/*0287*/ 0x08040243U, +/*0288*/ 0x10040243U, +/*0289*/ 0x18040243U, +/*028a*/ 0x00040244U, +/*028b*/ 0x08040244U, +/*028c*/ 0x10040244U, +/*028d*/ 0x18010244U, +/*028e*/ 0x00040245U, +/*028f*/ 0x08040245U, +/*0290*/ 0x10040245U, +/*0291*/ 0x18040245U, +/*0292*/ 0x00040246U, +/*0293*/ 0x08040246U, +/*0294*/ 0x10060246U, +/*0295*/ 0x18060246U, +/*0296*/ 0x00060247U, +/*0297*/ 0x08060247U, +/*0298*/ 0x10060247U, +/*0299*/ 0x18060247U, +/*029a*/ 0xffffffffU, +/*029b*/ 0x00010248U, +/*029c*/ 0x08010248U, +/*029d*/ 0x10020248U, +/*029e*/ 0xffffffffU, +/*029f*/ 0xffffffffU, +/*02a0*/ 0xffffffffU, +/*02a1*/ 0xffffffffU, +/*02a2*/ 0xffffffffU, +/*02a3*/ 0xffffffffU, +/*02a4*/ 0xffffffffU, +/*02a5*/ 0xffffffffU, +/*02a6*/ 0x18040248U, +/*02a7*/ 0x00040249U, +/*02a8*/ 0x08010249U, +/*02a9*/ 0x10010249U, +/*02aa*/ 0xffffffffU, +/*02ab*/ 0x18010249U, +/*02ac*/ 0x0001024aU, +/*02ad*/ 0xffffffffU, +/*02ae*/ 0x0801024aU, +/*02af*/ 0x1001024aU, +/*02b0*/ 0x1801024aU, +/*02b1*/ 0x0004024bU, +/*02b2*/ 0x0804024bU, +/*02b3*/ 0x100a024bU, +/*02b4*/ 0x0020024cU, +/*02b5*/ 0x0004024dU, +/*02b6*/ 0x0808024dU, +/*02b7*/ 0xffffffffU, +/*02b8*/ 0xffffffffU, +/*02b9*/ 0xffffffffU, +/*02ba*/ 0xffffffffU, +/*02bb*/ 0xffffffffU, +/*02bc*/ 0xffffffffU, +/*02bd*/ 0x1002024dU, +/*02be*/ 0x1802024dU, +/*02bf*/ 0x0020024eU, +/*02c0*/ 0x0002024fU, +/*02c1*/ 0x0810024fU, +/*02c2*/ 0x00100250U, +/*02c3*/ 0x10040250U, +/*02c4*/ 0x18040250U, +/*02c5*/ 0x00050251U, +/*02c6*/ 0x08050251U, +/*02c7*/ 0xffffffffU, +/*02c8*/ 0xffffffffU, +/*02c9*/ 0xffffffffU, +/*02ca*/ 0xffffffffU, +/*02cb*/ 0x10010251U, +/*02cc*/ 0x18010251U, +/*02cd*/ 0x00070252U, +/*02ce*/ 0x08070252U, +/*02cf*/ 0x10070252U, +/*02d0*/ 0x18070252U, +/*02d1*/ 0x00070253U, +/*02d2*/ 0x08070253U, +/*02d3*/ 0x10070253U, +/*02d4*/ 0x18070253U, +/*02d5*/ 0x00070254U, +/*02d6*/ 0x08070254U, +/*02d7*/ 0x10070254U, +/*02d8*/ 0xffffffffU, +/*02d9*/ 0xffffffffU, +/*02da*/ 0xffffffffU, +/*02db*/ 0xffffffffU, +/*02dc*/ 0xffffffffU, +/*02dd*/ 0xffffffffU, +/*02de*/ 0x18030254U, +/*02df*/ 0x00010255U, +/*02e0*/ 0x08020255U, +/*02e1*/ 0x10010255U, +/*02e2*/ 0x18040255U, +/*02e3*/ 0x00020256U, +/*02e4*/ 0x08010256U, +/*02e5*/ 0x10010256U, +/*02e6*/ 0xffffffffU, +/*02e7*/ 0x18010256U, +/*02e8*/ 0x00040257U, +/*02e9*/ 0x08080257U, +/*02ea*/ 0x100a0257U, +/*02eb*/ 0x000a0258U, +/*02ec*/ 0x100a0258U, +/*02ed*/ 0x000a0259U, +/*02ee*/ 0x100a0259U, +/*02ef*/ 0x000a025aU, +/*02f0*/ 0x0020025bU, +/*02f1*/ 0x0020025cU, +/*02f2*/ 0x0001025dU, +/*02f3*/ 0xffffffffU, +/*02f4*/ 0xffffffffU, +/*02f5*/ 0xffffffffU, +/*02f6*/ 0x0802025dU, +/*02f7*/ 0x1002025dU, +/*02f8*/ 0x0010025eU, +/*02f9*/ 0x1005025eU, +/*02fa*/ 0x1806025eU, +/*02fb*/ 0x0005025fU, +/*02fc*/ 0x0805025fU, +/*02fd*/ 0x100e025fU, +/*02fe*/ 0x00050260U, +/*02ff*/ 0x080e0260U, +/*0300*/ 0x18050260U, +/*0301*/ 0x000e0261U, +/*0302*/ 0x10050261U, +/*0303*/ 0x18010261U, +/*0304*/ 0x00050262U, +/*0305*/ 0x08050262U, +/*0306*/ 0x100a0262U, +/*0307*/ 0x000a0263U, +/*0308*/ 0x10050263U, +/*0309*/ 0x18050263U, +/*030a*/ 0x000a0264U, +/*030b*/ 0x100a0264U, +/*030c*/ 0x00050265U, +/*030d*/ 0x08050265U, +/*030e*/ 0x100a0265U, +/*030f*/ 0x000a0266U, +/*0310*/ 0xffffffffU, +/*0311*/ 0xffffffffU, +/*0312*/ 0xffffffffU, +/*0313*/ 0xffffffffU, +/*0314*/ 0xffffffffU, +/*0315*/ 0xffffffffU, +/*0316*/ 0x10070266U, +/*0317*/ 0x18070266U, +/*0318*/ 0x00040267U, +/*0319*/ 0x08040267U, +/*031a*/ 0xffffffffU, +/*031b*/ 0xffffffffU, +/*031c*/ 0xffffffffU, +/*031d*/ 0x10040267U, +/*031e*/ 0x18080267U, +/*031f*/ 0x00080268U, +/*0320*/ 0x08040268U, +/*0321*/ 0xffffffffU, +/*0322*/ 0xffffffffU, +/*0323*/ 0xffffffffU, +/*0324*/ 0x10040268U, +/*0325*/ 0xffffffffU, +/*0326*/ 0xffffffffU, +/*0327*/ 0xffffffffU, +/*0328*/ 0x18040268U, +/*0329*/ 0xffffffffU, +/*032a*/ 0xffffffffU, +/*032b*/ 0xffffffffU, +/*032c*/ 0x00040269U, +/*032d*/ 0x08050269U, +/*032e*/ 0x10070269U, +/*032f*/ 0x18080269U, +/*0330*/ 0x0010026aU, +/*0331*/ 0x1008026aU, +/*0332*/ 0x0010026bU, +/*0333*/ 0x1008026bU, +/*0334*/ 0x0010026cU, +/*0335*/ 0x1008026cU, +/*0336*/ 0x1808026cU, +/*0337*/ 0x0001026dU, +/*0338*/ 0x0801026dU, +/*0339*/ 0x1006026dU, +/*033a*/ 0x1806026dU, +/*033b*/ 0x0006026eU, +/*033c*/ 0xffffffffU, +/*033d*/ 0x0801026eU, +/*033e*/ 0x1003026eU, +/*033f*/ 0xffffffffU, +/*0340*/ 0xffffffffU, +/*0341*/ 0xffffffffU, +/*0342*/ 0x000a026fU, +/*0343*/ 0x100a026fU, +/*0344*/ 0x00040270U, +/*0345*/ 0x08010270U, +/*0346*/ 0x10040270U, +/*0347*/ 0xffffffffU, +/*0348*/ 0xffffffffU, +/*0349*/ 0xffffffffU, +/*034a*/ 0xffffffffU, +/*034b*/ 0xffffffffU, +/*034c*/ 0xffffffffU, +/*034d*/ 0x18070270U, +/*034e*/ 0x00070271U, +/*034f*/ 0x08050271U, +/*0350*/ 0x10050271U, +/*0351*/ 0xffffffffU, +/*0352*/ 0xffffffffU, +/*0353*/ 0xffffffffU, +/*0354*/ 0x18040271U, +/*0355*/ 0x00010272U, +/*0356*/ 0x08010272U, +/*0357*/ 0x10020272U, +/*0358*/ 0x18080272U, +/*0359*/ 0x00200273U, +/*035a*/ 0x00200274U, +/*035b*/ 0x00100275U, +/*035c*/ 0xffffffffU, +/*035d*/ 0xffffffffU, +/*035e*/ 0xffffffffU, +/*035f*/ 0x10020275U, +/*0360*/ 0x18010275U, +/*0361*/ 0xffffffffU, +/*0362*/ 0x00020276U, +/*0363*/ 0x08080276U, +/*0364*/ 0x10080276U, +/*0365*/ 0x18080276U, +/*0366*/ 0x00080277U, +/*0367*/ 0x08080277U, +/*0368*/ 0x10080277U, +/*0369*/ 0xffffffffU, +/*036a*/ 0x18080277U, +/*036b*/ 0x00080278U, +/*036c*/ 0x08080278U, +/*036d*/ 0x10080278U, +/*036e*/ 0x18080278U, +/*036f*/ 0x00080279U, +/*0370*/ 0xffffffffU, +/*0371*/ 0x08080279U, +/*0372*/ 0x10080279U, +/*0373*/ 0x18080279U, +/*0374*/ 0x0008027aU, +/*0375*/ 0x0808027aU, +/*0376*/ 0x1008027aU, +/*0377*/ 0xffffffffU, +/*0378*/ 0x1808027aU, +/*0379*/ 0x0008027bU, +/*037a*/ 0x0808027bU, +/*037b*/ 0x1008027bU, +/*037c*/ 0x1808027bU, +/*037d*/ 0x0008027cU, +/*037e*/ 0x0808027cU, +/*037f*/ 0xffffffffU, +/*0380*/ 0x1008027cU, +/*0381*/ 0x1808027cU, +/*0382*/ 0x0008027dU, +/*0383*/ 0x0808027dU, +/*0384*/ 0x1008027dU, +/*0385*/ 0x1808027dU, +/*0386*/ 0xffffffffU, +/*0387*/ 0x0008027eU, +/*0388*/ 0x0808027eU, +/*0389*/ 0x1008027eU, +/*038a*/ 0x1808027eU, +/*038b*/ 0x0008027fU, +/*038c*/ 0x0808027fU, +/*038d*/ 0xffffffffU, +/*038e*/ 0x1008027fU, +/*038f*/ 0x1808027fU, +/*0390*/ 0x00080280U, +/*0391*/ 0x08080280U, +/*0392*/ 0x10080280U, +/*0393*/ 0x18080280U, +/*0394*/ 0x00080281U, +/*0395*/ 0xffffffffU, +/*0396*/ 0x08080281U, +/*0397*/ 0x10080281U, +/*0398*/ 0x18080281U, +/*0399*/ 0x00080282U, +/*039a*/ 0x08080282U, +/*039b*/ 0x10080282U, +/*039c*/ 0xffffffffU, +/*039d*/ 0x18080282U, +/*039e*/ 0x00080283U, +/*039f*/ 0x08080283U, +/*03a0*/ 0x10080283U, +/*03a1*/ 0x18080283U, +/*03a2*/ 0x00080284U, +/*03a3*/ 0xffffffffU, +/*03a4*/ 0x08080284U, +/*03a5*/ 0x10080284U, +/*03a6*/ 0x18080284U, +/*03a7*/ 0x00080285U, +/*03a8*/ 0x08080285U, +/*03a9*/ 0x10080285U, +/*03aa*/ 0x18080285U, +/*03ab*/ 0xffffffffU, +/*03ac*/ 0x00080286U, +/*03ad*/ 0x08080286U, +/*03ae*/ 0x10080286U, +/*03af*/ 0x18080286U, +/*03b0*/ 0x00080287U, +/*03b1*/ 0x08080287U, +/*03b2*/ 0xffffffffU, +/*03b3*/ 0x10080287U, +/*03b4*/ 0x18080287U, +/*03b5*/ 0x00080288U, +/*03b6*/ 0x08080288U, +/*03b7*/ 0x10080288U, +/*03b8*/ 0x18080288U, +/*03b9*/ 0xffffffffU, +/*03ba*/ 0x00080289U, +/*03bb*/ 0x08020289U, +/*03bc*/ 0x10030289U, +/*03bd*/ 0x000a028aU, +/*03be*/ 0x100a028aU, +/*03bf*/ 0x000a028bU, +/*03c0*/ 0x1005028bU, +/*03c1*/ 0x1804028bU, +/*03c2*/ 0x0008028cU, +/*03c3*/ 0x0808028cU, +/*03c4*/ 0x1006028cU, +/*03c5*/ 0x1806028cU, +/*03c6*/ 0x0011028dU, +/*03c7*/ 0x1808028dU, +/*03c8*/ 0x0004028eU, +/*03c9*/ 0x0806028eU, +/*03ca*/ 0xffffffffU, +/*03cb*/ 0x1006028eU, +/*03cc*/ 0x1808028eU, +/*03cd*/ 0xffffffffU, +/*03ce*/ 0x0004028fU, +/*03cf*/ 0x0808028fU, +/*03d0*/ 0x1008028fU, +/*03d1*/ 0x1806028fU, +/*03d2*/ 0x00060290U, +/*03d3*/ 0x08110290U, +/*03d4*/ 0x00080291U, +/*03d5*/ 0x08040291U, +/*03d6*/ 0x10060291U, +/*03d7*/ 0xffffffffU, +/*03d8*/ 0x18060291U, +/*03d9*/ 0x00080292U, +/*03da*/ 0xffffffffU, +/*03db*/ 0x08040292U, +/*03dc*/ 0x10080292U, +/*03dd*/ 0x18080292U, +/*03de*/ 0x00060293U, +/*03df*/ 0x08060293U, +/*03e0*/ 0x00110294U, +/*03e1*/ 0x18080294U, +/*03e2*/ 0x00040295U, +/*03e3*/ 0x08060295U, +/*03e4*/ 0xffffffffU, +/*03e5*/ 0x10060295U, +/*03e6*/ 0x18080295U, +/*03e7*/ 0xffffffffU, +/*03e8*/ 0x00040296U, +/*03e9*/ 0x08040296U, +/*03ea*/ 0x10040296U, +/*03eb*/ 0x18040296U, +/*03ec*/ 0x00040297U, +/*03ed*/ 0x08040297U, +/*03ee*/ 0x10040297U, +/*03ef*/ 0x18040297U, +/*03f0*/ 0x00040298U, +/*03f1*/ 0x08040298U, +/*03f2*/ 0x10040298U, +/*03f3*/ 0x18040298U, +/*03f4*/ 0x00040299U, +/*03f5*/ 0x08040299U, +/*03f6*/ 0x10040299U, +/*03f7*/ 0x18040299U, +/*03f8*/ 0x0004029aU, +/*03f9*/ 0x0804029aU, +/*03fa*/ 0x1004029aU, +/*03fb*/ 0x1804029aU, +/*03fc*/ 0x0011029bU, +/*03fd*/ 0x0010029cU, +/*03fe*/ 0x0011029dU, +/*03ff*/ 0x0020029eU, +/*0400*/ 0x0020029fU, +/*0401*/ 0x002002a0U, +/*0402*/ 0x002002a1U, +/*0403*/ 0x002002a2U, +/*0404*/ 0x002002a3U, +/*0405*/ 0x002002a4U, +/*0406*/ 0x002002a5U, +/*0407*/ 0x002002a6U, +/*0408*/ 0x000202a7U, +/*0409*/ 0x080502a7U, +/*040a*/ 0x100502a7U, +/*040b*/ 0xffffffffU, +/*040c*/ 0xffffffffU, +/*040d*/ 0xffffffffU, +/*040e*/ 0xffffffffU, +/*040f*/ 0xffffffffU, +/*0410*/ 0xffffffffU, +/*0411*/ 0xffffffffU, +/*0412*/ 0xffffffffU, +/*0413*/ 0xffffffffU, +/*0414*/ 0xffffffffU, +/*0415*/ 0xffffffffU, +/*0416*/ 0xffffffffU, +/*0417*/ 0xffffffffU, +/*0418*/ 0xffffffffU, +/*0419*/ 0xffffffffU, +/*041a*/ 0xffffffffU, +/*041b*/ 0xffffffffU, +/*041c*/ 0xffffffffU, +/*041d*/ 0xffffffffU, +/*041e*/ 0xffffffffU, +/*041f*/ 0xffffffffU, +/*0420*/ 0xffffffffU, +/*0421*/ 0xffffffffU, +/*0422*/ 0xffffffffU, +/*0423*/ 0xffffffffU, +/*0424*/ 0xffffffffU, +/*0425*/ 0xffffffffU, +/*0426*/ 0xffffffffU, +/*0427*/ 0x180102a7U, +/*0428*/ 0x000402a8U, +/*0429*/ 0x081002a8U, +/*042a*/ 0x002002a9U, +/*042b*/ 0x001002aaU, +/*042c*/ 0x002002abU, +/*042d*/ 0x001002acU, +/*042e*/ 0x002002adU, +/*042f*/ 0x000702aeU, +/*0430*/ 0x080102aeU, +/*0431*/ 0x100202aeU, +/*0432*/ 0x180602aeU, +/*0433*/ 0x000102afU, +/*0434*/ 0x080102afU, +/*0435*/ 0x002002b0U, +/*0436*/ 0x000202b1U, +/*0437*/ 0x002002b2U, +/*0438*/ 0x002002b3U, +/*0439*/ 0xffffffffU, +/*043a*/ 0xffffffffU, +/*043b*/ 0xffffffffU, +/*043c*/ 0xffffffffU, +/*043d*/ 0xffffffffU, +/*043e*/ 0xffffffffU, +/*043f*/ 0xffffffffU, +/*0440*/ 0xffffffffU, +/*0441*/ 0xffffffffU, +/*0442*/ 0xffffffffU, +/*0443*/ 0xffffffffU, +/*0444*/ 0xffffffffU, +/*0445*/ 0xffffffffU, +/*0446*/ 0xffffffffU, +/*0447*/ 0xffffffffU, +/*0448*/ 0xffffffffU, +/*0449*/ 0xffffffffU, +/*044a*/ 0xffffffffU, +/*044b*/ 0xffffffffU, +/*044c*/ 0xffffffffU, +/*044d*/ 0xffffffffU, +/*044e*/ 0xffffffffU, +/*044f*/ 0xffffffffU, +/*0450*/ 0xffffffffU, +/*0451*/ 0xffffffffU, +/*0452*/ 0xffffffffU, +/*0453*/ 0xffffffffU, +/*0454*/ 0xffffffffU, +/*0455*/ 0xffffffffU, +/*0456*/ 0xffffffffU, +/*0457*/ 0xffffffffU, +/*0458*/ 0xffffffffU, +/*0459*/ 0xffffffffU, +/*045a*/ 0xffffffffU, +/*045b*/ 0xffffffffU, +/*045c*/ 0xffffffffU, +/*045d*/ 0xffffffffU, +/*045e*/ 0xffffffffU, +/*045f*/ 0x000402b4U, +/*0460*/ 0xffffffffU, +/*0461*/ 0xffffffffU, +/*0462*/ 0xffffffffU, +/*0463*/ 0xffffffffU, +/*0464*/ 0xffffffffU, +/*0465*/ 0xffffffffU, +/*0466*/ 0xffffffffU, +/*0467*/ 0xffffffffU, +/*0468*/ 0xffffffffU, +/*0469*/ 0xffffffffU, +/*046a*/ 0xffffffffU, +/*046b*/ 0xffffffffU, +/*046c*/ 0xffffffffU, +/*046d*/ 0xffffffffU, +/*046e*/ 0xffffffffU, +/*046f*/ 0xffffffffU, +/*0470*/ 0xffffffffU, +/*0471*/ 0xffffffffU, +/*0472*/ 0xffffffffU, +/*0473*/ 0xffffffffU, +/*0474*/ 0xffffffffU, +/*0475*/ 0xffffffffU, +/*0476*/ 0xffffffffU, +/*0477*/ 0xffffffffU, +/*0478*/ 0xffffffffU, +/*0479*/ 0xffffffffU, +/*047a*/ 0xffffffffU, +/*047b*/ 0xffffffffU, +/*047c*/ 0xffffffffU, +/*047d*/ 0xffffffffU, +/*047e*/ 0xffffffffU, +/*047f*/ 0xffffffffU, +/*0480*/ 0xffffffffU, +/*0481*/ 0xffffffffU, +/*0482*/ 0xffffffffU, +/*0483*/ 0xffffffffU, +/*0484*/ 0xffffffffU, +/*0485*/ 0xffffffffU, +/*0486*/ 0xffffffffU, +/*0487*/ 0xffffffffU, +/*0488*/ 0xffffffffU, +/*0489*/ 0xffffffffU, +/*048a*/ 0xffffffffU, +/*048b*/ 0xffffffffU, +/*048c*/ 0xffffffffU, +/*048d*/ 0xffffffffU, +/*048e*/ 0xffffffffU, +/*048f*/ 0xffffffffU, +/*0490*/ 0xffffffffU, +/*0491*/ 0xffffffffU, +/*0492*/ 0xffffffffU, +/*0493*/ 0xffffffffU, +/*0494*/ 0xffffffffU, + }, + { +/*0000*/ 0x00200800U, +/*0001*/ 0x00040801U, +/*0002*/ 0x080b0801U, +/*0003*/ 0xffffffffU, +/*0004*/ 0xffffffffU, +/*0005*/ 0x18010801U, +/*0006*/ 0x00050802U, +/*0007*/ 0x08050802U, +/*0008*/ 0x10050802U, +/*0009*/ 0x18050802U, +/*000a*/ 0x00050803U, +/*000b*/ 0x08050803U, +/*000c*/ 0x10050803U, +/*000d*/ 0x18050803U, +/*000e*/ 0x00050804U, +/*000f*/ 0x08040804U, +/*0010*/ 0x10030804U, +/*0011*/ 0x00180805U, +/*0012*/ 0x18030805U, +/*0013*/ 0x00180806U, +/*0014*/ 0x18020806U, +/*0015*/ 0x00010807U, +/*0016*/ 0x08020807U, +/*0017*/ 0x10010807U, +/*0018*/ 0x18010807U, +/*0019*/ 0x00020808U, +/*001a*/ 0x08040808U, +/*001b*/ 0x10040808U, +/*001c*/ 0x18040808U, +/*001d*/ 0x000a0809U, +/*001e*/ 0x10040809U, +/*001f*/ 0xffffffffU, +/*0020*/ 0xffffffffU, +/*0021*/ 0x18070809U, +/*0022*/ 0xffffffffU, +/*0023*/ 0xffffffffU, +/*0024*/ 0xffffffffU, +/*0025*/ 0xffffffffU, +/*0026*/ 0xffffffffU, +/*0027*/ 0xffffffffU, +/*0028*/ 0x000a080aU, +/*0029*/ 0x1005080aU, +/*002a*/ 0x1801080aU, +/*002b*/ 0x0001080bU, +/*002c*/ 0x0802080bU, +/*002d*/ 0x1009080bU, +/*002e*/ 0x0009080cU, +/*002f*/ 0x1002080cU, +/*0030*/ 0x0020080dU, +/*0031*/ 0xffffffffU, +/*0032*/ 0x0001080eU, +/*0033*/ 0xffffffffU, +/*0034*/ 0xffffffffU, +/*0035*/ 0xffffffffU, +/*0036*/ 0xffffffffU, +/*0037*/ 0x0020080fU, +/*0038*/ 0x00200810U, +/*0039*/ 0x00200811U, +/*003a*/ 0x00200812U, +/*003b*/ 0x00030813U, +/*003c*/ 0x08010813U, +/*003d*/ 0x10030813U, +/*003e*/ 0x18030813U, +/*003f*/ 0x00040814U, +/*0040*/ 0x08040814U, +/*0041*/ 0x10040814U, +/*0042*/ 0x18040814U, +/*0043*/ 0x00010815U, +/*0044*/ 0x08010815U, +/*0045*/ 0x10060815U, +/*0046*/ 0x18040815U, +/*0047*/ 0xffffffffU, +/*0048*/ 0x00060816U, +/*0049*/ 0x08040816U, +/*004a*/ 0x10060816U, +/*004b*/ 0x18040816U, +/*004c*/ 0x00020817U, +/*004d*/ 0x08050817U, +/*004e*/ 0x10080817U, +/*004f*/ 0x00200818U, +/*0050*/ 0x00060819U, +/*0051*/ 0x08030819U, +/*0052*/ 0x100b0819U, +/*0053*/ 0x0004081aU, +/*0054*/ 0x0804081aU, +/*0055*/ 0x1004081aU, +/*0056*/ 0xffffffffU, +/*0057*/ 0x1801081aU, +/*0058*/ 0x0009081bU, +/*0059*/ 0x0020081cU, +/*005a*/ 0x0020081dU, +/*005b*/ 0x0020081eU, +/*005c*/ 0x0020081fU, +/*005d*/ 0x00100820U, +/*005e*/ 0xffffffffU, +/*005f*/ 0x10010820U, +/*0060*/ 0x18060820U, +/*0061*/ 0x00080821U, +/*0062*/ 0x00200822U, +/*0063*/ 0xffffffffU, +/*0064*/ 0x000a0823U, +/*0065*/ 0x10060823U, +/*0066*/ 0x18070823U, +/*0067*/ 0x00080824U, +/*0068*/ 0x08080824U, +/*0069*/ 0x100a0824U, +/*006a*/ 0x00070825U, +/*006b*/ 0x08080825U, +/*006c*/ 0x10080825U, +/*006d*/ 0x18030825U, +/*006e*/ 0x000a0826U, +/*006f*/ 0x100a0826U, +/*0070*/ 0x00110827U, +/*0071*/ 0x00090828U, +/*0072*/ 0x10090828U, +/*0073*/ 0x00100829U, +/*0074*/ 0x100e0829U, +/*0075*/ 0x000e082aU, +/*0076*/ 0x100c082aU, +/*0077*/ 0x000a082bU, +/*0078*/ 0x100a082bU, +/*0079*/ 0x0002082cU, +/*007a*/ 0x0020082dU, +/*007b*/ 0x000b082eU, +/*007c*/ 0x100b082eU, +/*007d*/ 0x0020082fU, +/*007e*/ 0x00120830U, +/*007f*/ 0x00200831U, +/*0080*/ 0x00200832U, +/*0081*/ 0xffffffffU, +/*0082*/ 0xffffffffU, +/*0083*/ 0x00010833U, +/*0084*/ 0x08010833U, +/*0085*/ 0x10080833U, +/*0086*/ 0x000c0834U, +/*0087*/ 0x100c0834U, +/*0088*/ 0x000c0835U, +/*0089*/ 0x100c0835U, +/*008a*/ 0x000c0836U, +/*008b*/ 0x100c0836U, +/*008c*/ 0x000c0837U, +/*008d*/ 0x100c0837U, +/*008e*/ 0x000c0838U, +/*008f*/ 0x100c0838U, +/*0090*/ 0x000c0839U, +/*0091*/ 0x100b0839U, +/*0092*/ 0xffffffffU, +/*0093*/ 0xffffffffU, +/*0094*/ 0x000b083aU, +/*0095*/ 0x100b083aU, +/*0096*/ 0x000b083bU, +/*0097*/ 0x100b083bU, +/*0098*/ 0x000b083cU, +/*0099*/ 0x100b083cU, +/*009a*/ 0x000b083dU, +/*009b*/ 0x100b083dU, +/*009c*/ 0x000b083eU, +/*009d*/ 0x100a083eU, +/*009e*/ 0xffffffffU, +/*009f*/ 0x000a083fU, +/*00a0*/ 0x100a083fU, +/*00a1*/ 0x000a0840U, +/*00a2*/ 0x100a0840U, +/*00a3*/ 0x000a0841U, +/*00a4*/ 0x100a0841U, +/*00a5*/ 0x000a0842U, +/*00a6*/ 0x100a0842U, +/*00a7*/ 0x000a0843U, +/*00a8*/ 0x100a0843U, +/*00a9*/ 0x000a0844U, +/*00aa*/ 0x100a0844U, +/*00ab*/ 0x000a0845U, +/*00ac*/ 0x100a0845U, +/*00ad*/ 0x000a0846U, +/*00ae*/ 0x100a0846U, +/*00af*/ 0x000a0847U, +/*00b0*/ 0x100a0847U, +/*00b1*/ 0x000a0848U, +/*00b2*/ 0x100a0848U, +/*00b3*/ 0x000a0849U, +/*00b4*/ 0x100a0849U, +/*00b5*/ 0x000a084aU, +/*00b6*/ 0x100a084aU, +/*00b7*/ 0x000a084bU, +/*00b8*/ 0x100a084bU, +/*00b9*/ 0x000a084cU, +/*00ba*/ 0x100a084cU, +/*00bb*/ 0x0004084dU, +/*00bc*/ 0x0803084dU, +/*00bd*/ 0x100a084dU, +/*00be*/ 0x000a084eU, +/*00bf*/ 0x1001084eU, +/*00c0*/ 0x000a084fU, +/*00c1*/ 0x1004084fU, +/*00c2*/ 0x000b0850U, +/*00c3*/ 0x100a0850U, +/*00c4*/ 0xffffffffU, +/*00c5*/ 0x00080851U, +/*00c6*/ 0x08080851U, +/*00c7*/ 0x10080851U, +/*00c8*/ 0x18080851U, +/*00c9*/ 0x00080852U, +/*00ca*/ 0xffffffffU, +/*00cb*/ 0x08080852U, +/*00cc*/ 0x10010852U, +/*00cd*/ 0x18080852U, +/*00ce*/ 0x00080853U, +/*00cf*/ 0x08020853U, +/*00d0*/ 0x10020853U, +/*00d1*/ 0x18040853U, +/*00d2*/ 0x00040854U, +/*00d3*/ 0xffffffffU, +/*00d4*/ 0x08040854U, +/*00d5*/ 0x100a0854U, +/*00d6*/ 0x00060855U, +/*00d7*/ 0x08080855U, +/*00d8*/ 0xffffffffU, +/*00d9*/ 0x10040855U, +/*00da*/ 0x18040855U, +/*00db*/ 0x00050856U, +/*00dc*/ 0x08040856U, +/*00dd*/ 0x10050856U, +/*00de*/ 0x000a0857U, +/*00df*/ 0x100a0857U, +/*00e0*/ 0x00080858U, +/*00e1*/ 0xffffffffU, +/*00e2*/ 0x08040858U, +/*00e3*/ 0xffffffffU, +/*00e4*/ 0xffffffffU, +/*00e5*/ 0x00050a00U, +/*00e6*/ 0x08050a00U, +/*00e7*/ 0x10050a00U, +/*00e8*/ 0x18050a00U, +/*00e9*/ 0x00050a01U, +/*00ea*/ 0x08050a01U, +/*00eb*/ 0x100b0a01U, +/*00ec*/ 0x00010a02U, +/*00ed*/ 0x08030a02U, +/*00ee*/ 0x00200a03U, +/*00ef*/ 0xffffffffU, +/*00f0*/ 0x00030a04U, +/*00f1*/ 0x080a0a04U, +/*00f2*/ 0xffffffffU, +/*00f3*/ 0xffffffffU, +/*00f4*/ 0x18030a04U, +/*00f5*/ 0x00030a05U, +/*00f6*/ 0x08010a05U, +/*00f7*/ 0x10010a05U, +/*00f8*/ 0x18060a05U, +/*00f9*/ 0xffffffffU, +/*00fa*/ 0xffffffffU, +/*00fb*/ 0xffffffffU, +/*00fc*/ 0x00020a06U, +/*00fd*/ 0x08030a06U, +/*00fe*/ 0x10010a06U, +/*00ff*/ 0x000f0a07U, +/*0100*/ 0x00200a08U, +/*0101*/ 0x00200a09U, +/*0102*/ 0x000b0a0aU, +/*0103*/ 0x100b0a0aU, +/*0104*/ 0x000b0a0bU, +/*0105*/ 0xffffffffU, +/*0106*/ 0xffffffffU, +/*0107*/ 0x00180a0cU, +/*0108*/ 0x00180a0dU, +/*0109*/ 0x00180a0eU, +/*010a*/ 0x00180a0fU, +/*010b*/ 0x18040a0fU, +/*010c*/ 0x00020a10U, +/*010d*/ 0x08020a10U, +/*010e*/ 0x10040a10U, +/*010f*/ 0x18040a10U, +/*0110*/ 0x00010a11U, +/*0111*/ 0x08010a11U, +/*0112*/ 0x10010a11U, +/*0113*/ 0x18030a11U, +/*0114*/ 0x00200a12U, +/*0115*/ 0x00200a13U, +/*0116*/ 0xffffffffU, +/*0117*/ 0x00140a14U, +/*0118*/ 0x00140a15U, +/*0119*/ 0x00140a16U, +/*011a*/ 0x00140a17U, +/*011b*/ 0x00140a18U, +/*011c*/ 0x00140a19U, +/*011d*/ 0x00140a1aU, +/*011e*/ 0x00140a1bU, +/*011f*/ 0x001e0a1cU, +/*0120*/ 0x000a0a1dU, +/*0121*/ 0x10060a1dU, +/*0122*/ 0x18060a1dU, +/*0123*/ 0x00060a1eU, +/*0124*/ 0xffffffffU, +/*0125*/ 0x08060a1eU, +/*0126*/ 0x00080a1fU, +/*0127*/ 0x080b0a1fU, +/*0128*/ 0x000b0a20U, +/*0129*/ 0x100b0a20U, +/*012a*/ 0x000b0a21U, +/*012b*/ 0x100b0a21U, +/*012c*/ 0x000b0a22U, +/*012d*/ 0x10040a22U, +/*012e*/ 0x000a0a23U, +/*012f*/ 0x10060a23U, +/*0130*/ 0x18080a23U, +/*0131*/ 0xffffffffU, +/*0132*/ 0x00040a24U, +/*0133*/ 0xffffffffU, +/*0134*/ 0xffffffffU, +/*0135*/ 0x00010b80U, +/*0136*/ 0x08020b80U, +/*0137*/ 0x10050b80U, +/*0138*/ 0x18050b80U, +/*0139*/ 0x00050b81U, +/*013a*/ 0x08050b81U, +/*013b*/ 0x100b0b81U, +/*013c*/ 0x00050b82U, +/*013d*/ 0x08010b82U, +/*013e*/ 0x10010b82U, +/*013f*/ 0xffffffffU, +/*0140*/ 0x18010b82U, +/*0141*/ 0x00010b83U, +/*0142*/ 0x08040b83U, +/*0143*/ 0x100b0b83U, +/*0144*/ 0x000b0b84U, +/*0145*/ 0xffffffffU, +/*0146*/ 0x10040b84U, +/*0147*/ 0x000b0b85U, +/*0148*/ 0x10040b85U, +/*0149*/ 0x18010b85U, +/*014a*/ 0x00010b86U, +/*014b*/ 0x08010b86U, +/*014c*/ 0x00200b87U, +/*014d*/ 0x00200b88U, +/*014e*/ 0x00080b89U, +/*014f*/ 0x080a0b89U, +/*0150*/ 0x18050b89U, +/*0151*/ 0x000a0b8aU, +/*0152*/ 0x10030b8aU, +/*0153*/ 0x18030b8aU, +/*0154*/ 0x00010b8bU, +/*0155*/ 0x08020b8bU, +/*0156*/ 0x10010b8bU, +/*0157*/ 0x18010b8bU, +/*0158*/ 0x00010b8cU, +/*0159*/ 0x08030b8cU, +/*015a*/ 0xffffffffU, +/*015b*/ 0x10040b8cU, +/*015c*/ 0x18040b8cU, +/*015d*/ 0x00040b8dU, +/*015e*/ 0x08040b8dU, +/*015f*/ 0xffffffffU, +/*0160*/ 0xffffffffU, +/*0161*/ 0xffffffffU, +/*0162*/ 0xffffffffU, +/*0163*/ 0xffffffffU, +/*0164*/ 0xffffffffU, +/*0165*/ 0xffffffffU, +/*0166*/ 0xffffffffU, +/*0167*/ 0xffffffffU, +/*0168*/ 0x000d0b8eU, +/*0169*/ 0x100d0b8eU, +/*016a*/ 0x000d0b8fU, +/*016b*/ 0x00050b90U, +/*016c*/ 0x00010b91U, +/*016d*/ 0x080e0b91U, +/*016e*/ 0x000e0b92U, +/*016f*/ 0x100e0b92U, +/*0170*/ 0x000e0b93U, +/*0171*/ 0x100e0b93U, +/*0172*/ 0x00040b94U, +/*0173*/ 0x08040b94U, +/*0174*/ 0x10040b94U, +/*0175*/ 0x18040b94U, +/*0176*/ 0x00040b95U, +/*0177*/ 0x080b0b95U, +/*0178*/ 0x000b0b96U, +/*0179*/ 0x100b0b96U, +/*017a*/ 0x000b0b97U, +/*017b*/ 0xffffffffU, +/*017c*/ 0xffffffffU, +/*017d*/ 0xffffffffU, +/*017e*/ 0xffffffffU, +/*017f*/ 0x000d0b98U, +/*0180*/ 0x100d0b98U, +/*0181*/ 0x000d0b99U, +/*0182*/ 0x10100b99U, +/*0183*/ 0x10080b8dU, +/*0184*/ 0x18080b8dU, +/*0185*/ 0x00100b9aU, +/*0186*/ 0x10100b9aU, +/*0187*/ 0x00100b9bU, +/*0188*/ 0x10100b9bU, +/*0189*/ 0x00100b9cU, +/*018a*/ 0x10030b9cU, +/*018b*/ 0x18040b9cU, +/*018c*/ 0x00010b9dU, +/*018d*/ 0x08040b9dU, +/*018e*/ 0xffffffffU, +/*018f*/ 0xffffffffU, +/*0190*/ 0x10010b9dU, +/*0191*/ 0x00140b9eU, +/*0192*/ 0x000a0b9fU, +/*0193*/ 0x100c0b9fU, +/*0194*/ 0x00120ba0U, +/*0195*/ 0x00140ba1U, +/*0196*/ 0x00120ba2U, +/*0197*/ 0x00110ba3U, +/*0198*/ 0x00110ba4U, +/*0199*/ 0x00120ba5U, +/*019a*/ 0x00120ba6U, +/*019b*/ 0x00120ba7U, +/*019c*/ 0x00120ba8U, +/*019d*/ 0x00120ba9U, +/*019e*/ 0x00120baaU, +/*019f*/ 0x00120babU, +/*01a0*/ 0x00120bacU, +/*01a1*/ 0xffffffffU, +/*01a2*/ 0xffffffffU, +/*01a3*/ 0x00190badU, +/*01a4*/ 0x00190baeU, +/*01a5*/ 0x00200bafU, +/*01a6*/ 0x00170bb0U, +/*01a7*/ 0x18080bb0U, +/*01a8*/ 0x00010bb1U, +/*01a9*/ 0x08010bb1U, +/*01aa*/ 0x00200bb2U, +/*01ab*/ 0x00080bb3U, +/*01ac*/ 0xffffffffU, +/*01ad*/ 0x08030bb3U, +/*01ae*/ 0x00180bb4U, +/*01af*/ 0x00180bb5U, +/*01b0*/ 0xffffffffU, +/*01b1*/ 0xffffffffU, +/*01b2*/ 0xffffffffU, +/*01b3*/ 0xffffffffU, +/*01b4*/ 0xffffffffU, +/*01b5*/ 0xffffffffU, +/*01b6*/ 0xffffffffU, +/*01b7*/ 0xffffffffU, +/*01b8*/ 0xffffffffU, +/*01b9*/ 0xffffffffU, +/*01ba*/ 0xffffffffU, +/*01bb*/ 0xffffffffU, +/*01bc*/ 0xffffffffU, +/*01bd*/ 0xffffffffU, +/*01be*/ 0xffffffffU, +/*01bf*/ 0x00100bb6U, +/*01c0*/ 0x10010bb6U, +/*01c1*/ 0x18010bb6U, +/*01c2*/ 0x00050bb7U, +/*01c3*/ 0x00200bb8U, +/*01c4*/ 0x00090bb9U, +/*01c5*/ 0xffffffffU, +/*01c6*/ 0xffffffffU, +/*01c7*/ 0x00200bbaU, +/*01c8*/ 0x00040bbbU, +/*01c9*/ 0x08100bbbU, +/*01ca*/ 0x18060bbbU, +/*01cb*/ 0x00100bbcU, +/*01cc*/ 0xffffffffU, +/*01cd*/ 0x10080bbcU, +/*01ce*/ 0xffffffffU, +/*01cf*/ 0xffffffffU, +/*01d0*/ 0xffffffffU, +/*01d1*/ 0x18030bbcU, +/*01d2*/ 0x00020bbdU, +/*01d3*/ 0xffffffffU, +/*01d4*/ 0x00200bbeU, +/*01d5*/ 0x000b0bbfU, +/*01d6*/ 0xffffffffU, +/*01d7*/ 0xffffffffU, +/*01d8*/ 0xffffffffU, +/*01d9*/ 0x10020bbfU, +/*01da*/ 0xffffffffU, +/*01db*/ 0xffffffffU, +/*01dc*/ 0xffffffffU, +/*01dd*/ 0xffffffffU, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0xffffffffU, +/*01e4*/ 0xffffffffU, +/*01e5*/ 0x10100201U, +/*01e6*/ 0xffffffffU, +/*01e7*/ 0xffffffffU, +/*01e8*/ 0xffffffffU, +/*01e9*/ 0xffffffffU, +/*01ea*/ 0xffffffffU, +/*01eb*/ 0xffffffffU, +/*01ec*/ 0xffffffffU, +/*01ed*/ 0xffffffffU, +/*01ee*/ 0xffffffffU, +/*01ef*/ 0x00200202U, +/*01f0*/ 0x00100203U, +/*01f1*/ 0x00200204U, +/*01f2*/ 0x00100205U, +/*01f3*/ 0x00200206U, +/*01f4*/ 0x00100207U, +/*01f5*/ 0x10100207U, +/*01f6*/ 0x00200208U, +/*01f7*/ 0x00200209U, +/*01f8*/ 0x0020020aU, +/*01f9*/ 0x0020020bU, +/*01fa*/ 0x0010020cU, +/*01fb*/ 0x0020020dU, +/*01fc*/ 0x0020020eU, +/*01fd*/ 0x0020020fU, +/*01fe*/ 0x00200210U, +/*01ff*/ 0x00100211U, +/*0200*/ 0x00200212U, +/*0201*/ 0x00200213U, +/*0202*/ 0x00200214U, +/*0203*/ 0x00200215U, +/*0204*/ 0x00090216U, +/*0205*/ 0x10010216U, +/*0206*/ 0x00200217U, +/*0207*/ 0x00050218U, +/*0208*/ 0x08010218U, +/*0209*/ 0x10080218U, +/*020a*/ 0x18080218U, +/*020b*/ 0x001e0219U, +/*020c*/ 0x001e021aU, +/*020d*/ 0x001e021bU, +/*020e*/ 0x001e021cU, +/*020f*/ 0x001e021dU, +/*0210*/ 0x001e021eU, +/*0211*/ 0x001e021fU, +/*0212*/ 0x001e0220U, +/*0213*/ 0x001e0221U, +/*0214*/ 0x001e0222U, +/*0215*/ 0x001e0223U, +/*0216*/ 0x001e0224U, +/*0217*/ 0x001e0225U, +/*0218*/ 0x001e0226U, +/*0219*/ 0x001e0227U, +/*021a*/ 0x001e0228U, +/*021b*/ 0x00010229U, +/*021c*/ 0x08010229U, +/*021d*/ 0x10010229U, +/*021e*/ 0x18040229U, +/*021f*/ 0x0008022aU, +/*0220*/ 0x0808022aU, +/*0221*/ 0x1008022aU, +/*0222*/ 0x1804022aU, +/*0223*/ 0x0005022bU, +/*0224*/ 0x0806022bU, +/*0225*/ 0x1007022bU, +/*0226*/ 0x1805022bU, +/*0227*/ 0x0006022cU, +/*0228*/ 0x0807022cU, +/*0229*/ 0x1005022cU, +/*022a*/ 0x1806022cU, +/*022b*/ 0x0007022dU, +/*022c*/ 0x0802022dU, +/*022d*/ 0x1001022dU, +/*022e*/ 0xffffffffU, +/*022f*/ 0x000a022eU, +/*0230*/ 0x1010022eU, +/*0231*/ 0x000a022fU, +/*0232*/ 0x1010022fU, +/*0233*/ 0x000a0230U, +/*0234*/ 0x10100230U, +/*0235*/ 0xffffffffU, +/*0236*/ 0x00100231U, +/*0237*/ 0xffffffffU, +/*0238*/ 0xffffffffU, +/*0239*/ 0x10010231U, +/*023a*/ 0x18010231U, +/*023b*/ 0x00010232U, +/*023c*/ 0x08010232U, +/*023d*/ 0x10010232U, +/*023e*/ 0x18010232U, +/*023f*/ 0x00020233U, +/*0240*/ 0x08020233U, +/*0241*/ 0x10020233U, +/*0242*/ 0x18020233U, +/*0243*/ 0x00020234U, +/*0244*/ 0x08030234U, +/*0245*/ 0x10010234U, +/*0246*/ 0x18010234U, +/*0247*/ 0x00010235U, +/*0248*/ 0x08010235U, +/*0249*/ 0xffffffffU, +/*024a*/ 0x10020235U, +/*024b*/ 0x18010235U, +/*024c*/ 0x00010236U, +/*024d*/ 0xffffffffU, +/*024e*/ 0x08020236U, +/*024f*/ 0x10010236U, +/*0250*/ 0x18010236U, +/*0251*/ 0xffffffffU, +/*0252*/ 0x00020237U, +/*0253*/ 0x08010237U, +/*0254*/ 0x10010237U, +/*0255*/ 0xffffffffU, +/*0256*/ 0x18020237U, +/*0257*/ 0x00070238U, +/*0258*/ 0x08010238U, +/*0259*/ 0x10010238U, +/*025a*/ 0x18010238U, +/*025b*/ 0x00010239U, +/*025c*/ 0x08010239U, +/*025d*/ 0x10010239U, +/*025e*/ 0xffffffffU, +/*025f*/ 0x18010239U, +/*0260*/ 0x0004023aU, +/*0261*/ 0x0804023aU, +/*0262*/ 0x1004023aU, +/*0263*/ 0x1801023aU, +/*0264*/ 0x0002023bU, +/*0265*/ 0x0806023bU, +/*0266*/ 0x1006023bU, +/*0267*/ 0xffffffffU, +/*0268*/ 0xffffffffU, +/*0269*/ 0xffffffffU, +/*026a*/ 0x1802023bU, +/*026b*/ 0x0010023cU, +/*026c*/ 0x1001023cU, +/*026d*/ 0x1801023cU, +/*026e*/ 0xffffffffU, +/*026f*/ 0x0004023dU, +/*0270*/ 0x0801023dU, +/*0271*/ 0x1004023dU, +/*0272*/ 0x1802023dU, +/*0273*/ 0x0008023eU, +/*0274*/ 0xffffffffU, +/*0275*/ 0xffffffffU, +/*0276*/ 0xffffffffU, +/*0277*/ 0x080a023eU, +/*0278*/ 0x0020023fU, +/*0279*/ 0x00200240U, +/*027a*/ 0x00050241U, +/*027b*/ 0x08010241U, +/*027c*/ 0x10050241U, +/*027d*/ 0x18080241U, +/*027e*/ 0x00010242U, +/*027f*/ 0x08080242U, +/*0280*/ 0x10010242U, +/*0281*/ 0x18080242U, +/*0282*/ 0x00010243U, +/*0283*/ 0x08040243U, +/*0284*/ 0x10040243U, +/*0285*/ 0x18040243U, +/*0286*/ 0x00040244U, +/*0287*/ 0x08040244U, +/*0288*/ 0x10040244U, +/*0289*/ 0x18040244U, +/*028a*/ 0x00040245U, +/*028b*/ 0x08040245U, +/*028c*/ 0x10040245U, +/*028d*/ 0x18010245U, +/*028e*/ 0x00040246U, +/*028f*/ 0x08040246U, +/*0290*/ 0x10040246U, +/*0291*/ 0x18040246U, +/*0292*/ 0x00040247U, +/*0293*/ 0x08040247U, +/*0294*/ 0x10060247U, +/*0295*/ 0x18060247U, +/*0296*/ 0x00060248U, +/*0297*/ 0x08060248U, +/*0298*/ 0x10060248U, +/*0299*/ 0x18060248U, +/*029a*/ 0x00040249U, +/*029b*/ 0x08010249U, +/*029c*/ 0x10010249U, +/*029d*/ 0x18020249U, +/*029e*/ 0xffffffffU, +/*029f*/ 0xffffffffU, +/*02a0*/ 0xffffffffU, +/*02a1*/ 0xffffffffU, +/*02a2*/ 0xffffffffU, +/*02a3*/ 0xffffffffU, +/*02a4*/ 0xffffffffU, +/*02a5*/ 0xffffffffU, +/*02a6*/ 0x0004024aU, +/*02a7*/ 0x0804024aU, +/*02a8*/ 0x1001024aU, +/*02a9*/ 0x1801024aU, +/*02aa*/ 0xffffffffU, +/*02ab*/ 0x0001024bU, +/*02ac*/ 0x0801024bU, +/*02ad*/ 0xffffffffU, +/*02ae*/ 0x1001024bU, +/*02af*/ 0x1801024bU, +/*02b0*/ 0x0001024cU, +/*02b1*/ 0x0804024cU, +/*02b2*/ 0x1004024cU, +/*02b3*/ 0x000a024dU, +/*02b4*/ 0x0020024eU, +/*02b5*/ 0x0004024fU, +/*02b6*/ 0x0808024fU, +/*02b7*/ 0xffffffffU, +/*02b8*/ 0xffffffffU, +/*02b9*/ 0xffffffffU, +/*02ba*/ 0xffffffffU, +/*02bb*/ 0xffffffffU, +/*02bc*/ 0xffffffffU, +/*02bd*/ 0x1002024fU, +/*02be*/ 0x1802024fU, +/*02bf*/ 0x00200250U, +/*02c0*/ 0x00020251U, +/*02c1*/ 0x08100251U, +/*02c2*/ 0x00100252U, +/*02c3*/ 0x10040252U, +/*02c4*/ 0x18040252U, +/*02c5*/ 0x00050253U, +/*02c6*/ 0x08050253U, +/*02c7*/ 0xffffffffU, +/*02c8*/ 0xffffffffU, +/*02c9*/ 0xffffffffU, +/*02ca*/ 0xffffffffU, +/*02cb*/ 0x10010253U, +/*02cc*/ 0x18010253U, +/*02cd*/ 0x00080254U, +/*02ce*/ 0x08080254U, +/*02cf*/ 0x10080254U, +/*02d0*/ 0x18080254U, +/*02d1*/ 0x00080255U, +/*02d2*/ 0x08080255U, +/*02d3*/ 0x10080255U, +/*02d4*/ 0x18080255U, +/*02d5*/ 0x00080256U, +/*02d6*/ 0x08080256U, +/*02d7*/ 0x10080256U, +/*02d8*/ 0xffffffffU, +/*02d9*/ 0xffffffffU, +/*02da*/ 0xffffffffU, +/*02db*/ 0xffffffffU, +/*02dc*/ 0xffffffffU, +/*02dd*/ 0xffffffffU, +/*02de*/ 0x18030256U, +/*02df*/ 0x00010257U, +/*02e0*/ 0x08020257U, +/*02e1*/ 0x10010257U, +/*02e2*/ 0x18040257U, +/*02e3*/ 0x00020258U, +/*02e4*/ 0x08010258U, +/*02e5*/ 0x10010258U, +/*02e6*/ 0xffffffffU, +/*02e7*/ 0x18010258U, +/*02e8*/ 0x00040259U, +/*02e9*/ 0x08080259U, +/*02ea*/ 0x100a0259U, +/*02eb*/ 0x000a025aU, +/*02ec*/ 0x100a025aU, +/*02ed*/ 0x000a025bU, +/*02ee*/ 0x100a025bU, +/*02ef*/ 0x000a025cU, +/*02f0*/ 0x0020025dU, +/*02f1*/ 0x0020025eU, +/*02f2*/ 0x0001025fU, +/*02f3*/ 0xffffffffU, +/*02f4*/ 0xffffffffU, +/*02f5*/ 0xffffffffU, +/*02f6*/ 0x0802025fU, +/*02f7*/ 0x1002025fU, +/*02f8*/ 0x00100260U, +/*02f9*/ 0x10050260U, +/*02fa*/ 0x18060260U, +/*02fb*/ 0x00050261U, +/*02fc*/ 0x08050261U, +/*02fd*/ 0x100e0261U, +/*02fe*/ 0x00050262U, +/*02ff*/ 0x080e0262U, +/*0300*/ 0x18050262U, +/*0301*/ 0x000e0263U, +/*0302*/ 0x10050263U, +/*0303*/ 0x18010263U, +/*0304*/ 0x00050264U, +/*0305*/ 0x08050264U, +/*0306*/ 0x100a0264U, +/*0307*/ 0x000a0265U, +/*0308*/ 0x10050265U, +/*0309*/ 0x18050265U, +/*030a*/ 0x000a0266U, +/*030b*/ 0x100a0266U, +/*030c*/ 0x00050267U, +/*030d*/ 0x08050267U, +/*030e*/ 0x100a0267U, +/*030f*/ 0x000a0268U, +/*0310*/ 0xffffffffU, +/*0311*/ 0xffffffffU, +/*0312*/ 0xffffffffU, +/*0313*/ 0xffffffffU, +/*0314*/ 0xffffffffU, +/*0315*/ 0xffffffffU, +/*0316*/ 0x10070268U, +/*0317*/ 0x18070268U, +/*0318*/ 0x00040269U, +/*0319*/ 0x08040269U, +/*031a*/ 0xffffffffU, +/*031b*/ 0xffffffffU, +/*031c*/ 0xffffffffU, +/*031d*/ 0x10040269U, +/*031e*/ 0x18080269U, +/*031f*/ 0x0008026aU, +/*0320*/ 0x0804026aU, +/*0321*/ 0xffffffffU, +/*0322*/ 0xffffffffU, +/*0323*/ 0xffffffffU, +/*0324*/ 0x1004026aU, +/*0325*/ 0xffffffffU, +/*0326*/ 0xffffffffU, +/*0327*/ 0xffffffffU, +/*0328*/ 0x1804026aU, +/*0329*/ 0xffffffffU, +/*032a*/ 0xffffffffU, +/*032b*/ 0xffffffffU, +/*032c*/ 0x0004026bU, +/*032d*/ 0x0805026bU, +/*032e*/ 0x1007026bU, +/*032f*/ 0x1808026bU, +/*0330*/ 0x0010026cU, +/*0331*/ 0x1008026cU, +/*0332*/ 0x0010026dU, +/*0333*/ 0x1008026dU, +/*0334*/ 0x0010026eU, +/*0335*/ 0x1008026eU, +/*0336*/ 0x1808026eU, +/*0337*/ 0x0001026fU, +/*0338*/ 0x0801026fU, +/*0339*/ 0x1006026fU, +/*033a*/ 0x1806026fU, +/*033b*/ 0x00060270U, +/*033c*/ 0xffffffffU, +/*033d*/ 0x08010270U, +/*033e*/ 0x10030270U, +/*033f*/ 0xffffffffU, +/*0340*/ 0xffffffffU, +/*0341*/ 0xffffffffU, +/*0342*/ 0x000a0271U, +/*0343*/ 0x100a0271U, +/*0344*/ 0x00040272U, +/*0345*/ 0x08010272U, +/*0346*/ 0x10040272U, +/*0347*/ 0xffffffffU, +/*0348*/ 0xffffffffU, +/*0349*/ 0xffffffffU, +/*034a*/ 0xffffffffU, +/*034b*/ 0xffffffffU, +/*034c*/ 0xffffffffU, +/*034d*/ 0x18070272U, +/*034e*/ 0x00070273U, +/*034f*/ 0x08050273U, +/*0350*/ 0x10050273U, +/*0351*/ 0xffffffffU, +/*0352*/ 0xffffffffU, +/*0353*/ 0xffffffffU, +/*0354*/ 0x18040273U, +/*0355*/ 0x00010274U, +/*0356*/ 0x08010274U, +/*0357*/ 0x10020274U, +/*0358*/ 0x18080274U, +/*0359*/ 0x00200275U, +/*035a*/ 0x00200276U, +/*035b*/ 0x00100277U, +/*035c*/ 0xffffffffU, +/*035d*/ 0xffffffffU, +/*035e*/ 0xffffffffU, +/*035f*/ 0x10020277U, +/*0360*/ 0x18010277U, +/*0361*/ 0xffffffffU, +/*0362*/ 0x00020278U, +/*0363*/ 0x08100278U, +/*0364*/ 0x00100279U, +/*0365*/ 0x10100279U, +/*0366*/ 0x0008027aU, +/*0367*/ 0x0808027aU, +/*0368*/ 0x1008027aU, +/*0369*/ 0xffffffffU, +/*036a*/ 0x0010027bU, +/*036b*/ 0x1010027bU, +/*036c*/ 0x0010027cU, +/*036d*/ 0x1008027cU, +/*036e*/ 0x1808027cU, +/*036f*/ 0x0008027dU, +/*0370*/ 0xffffffffU, +/*0371*/ 0x0810027dU, +/*0372*/ 0x0010027eU, +/*0373*/ 0x1010027eU, +/*0374*/ 0x0008027fU, +/*0375*/ 0x0808027fU, +/*0376*/ 0x1008027fU, +/*0377*/ 0xffffffffU, +/*0378*/ 0x1808027fU, +/*0379*/ 0x00100280U, +/*037a*/ 0x10100280U, +/*037b*/ 0x00100281U, +/*037c*/ 0x10080281U, +/*037d*/ 0x18080281U, +/*037e*/ 0x00080282U, +/*037f*/ 0xffffffffU, +/*0380*/ 0x08100282U, +/*0381*/ 0x00100283U, +/*0382*/ 0x10100283U, +/*0383*/ 0x00080284U, +/*0384*/ 0x08080284U, +/*0385*/ 0x10080284U, +/*0386*/ 0xffffffffU, +/*0387*/ 0x00100285U, +/*0388*/ 0x10100285U, +/*0389*/ 0x00100286U, +/*038a*/ 0x10080286U, +/*038b*/ 0x18080286U, +/*038c*/ 0x00080287U, +/*038d*/ 0xffffffffU, +/*038e*/ 0x08080287U, +/*038f*/ 0x10100287U, +/*0390*/ 0x00100288U, +/*0391*/ 0x10100288U, +/*0392*/ 0x00080289U, +/*0393*/ 0x08080289U, +/*0394*/ 0x10080289U, +/*0395*/ 0xffffffffU, +/*0396*/ 0x0010028aU, +/*0397*/ 0x1010028aU, +/*0398*/ 0x0010028bU, +/*0399*/ 0x1008028bU, +/*039a*/ 0x1808028bU, +/*039b*/ 0x0008028cU, +/*039c*/ 0xffffffffU, +/*039d*/ 0x0810028cU, +/*039e*/ 0x0010028dU, +/*039f*/ 0x1010028dU, +/*03a0*/ 0x0008028eU, +/*03a1*/ 0x0808028eU, +/*03a2*/ 0x1008028eU, +/*03a3*/ 0xffffffffU, +/*03a4*/ 0x1808028eU, +/*03a5*/ 0x0010028fU, +/*03a6*/ 0x1010028fU, +/*03a7*/ 0x00100290U, +/*03a8*/ 0x10080290U, +/*03a9*/ 0x18080290U, +/*03aa*/ 0x00080291U, +/*03ab*/ 0xffffffffU, +/*03ac*/ 0x08100291U, +/*03ad*/ 0x00100292U, +/*03ae*/ 0x10100292U, +/*03af*/ 0x00080293U, +/*03b0*/ 0x08080293U, +/*03b1*/ 0x10080293U, +/*03b2*/ 0xffffffffU, +/*03b3*/ 0x00100294U, +/*03b4*/ 0x10100294U, +/*03b5*/ 0x00100295U, +/*03b6*/ 0x10080295U, +/*03b7*/ 0x18080295U, +/*03b8*/ 0x00080296U, +/*03b9*/ 0xffffffffU, +/*03ba*/ 0x08080296U, +/*03bb*/ 0x10020296U, +/*03bc*/ 0x18030296U, +/*03bd*/ 0x000a0297U, +/*03be*/ 0x100a0297U, +/*03bf*/ 0x000a0298U, +/*03c0*/ 0x10050298U, +/*03c1*/ 0x18040298U, +/*03c2*/ 0x00080299U, +/*03c3*/ 0x08080299U, +/*03c4*/ 0x10060299U, +/*03c5*/ 0x18060299U, +/*03c6*/ 0x0011029aU, +/*03c7*/ 0x1808029aU, +/*03c8*/ 0x0004029bU, +/*03c9*/ 0x0806029bU, +/*03ca*/ 0xffffffffU, +/*03cb*/ 0x1006029bU, +/*03cc*/ 0x1808029bU, +/*03cd*/ 0x0008029cU, +/*03ce*/ 0x0804029cU, +/*03cf*/ 0x1008029cU, +/*03d0*/ 0x1808029cU, +/*03d1*/ 0x0006029dU, +/*03d2*/ 0x0806029dU, +/*03d3*/ 0x0011029eU, +/*03d4*/ 0x1808029eU, +/*03d5*/ 0x0004029fU, +/*03d6*/ 0x0806029fU, +/*03d7*/ 0xffffffffU, +/*03d8*/ 0x1006029fU, +/*03d9*/ 0x1808029fU, +/*03da*/ 0x000802a0U, +/*03db*/ 0x080402a0U, +/*03dc*/ 0x100802a0U, +/*03dd*/ 0x180802a0U, +/*03de*/ 0x000602a1U, +/*03df*/ 0x080602a1U, +/*03e0*/ 0x001102a2U, +/*03e1*/ 0x180802a2U, +/*03e2*/ 0x000402a3U, +/*03e3*/ 0x080602a3U, +/*03e4*/ 0xffffffffU, +/*03e5*/ 0x100602a3U, +/*03e6*/ 0x180802a3U, +/*03e7*/ 0x000802a4U, +/*03e8*/ 0x080402a4U, +/*03e9*/ 0x100402a4U, +/*03ea*/ 0x180402a4U, +/*03eb*/ 0x000402a5U, +/*03ec*/ 0x080402a5U, +/*03ed*/ 0x100402a5U, +/*03ee*/ 0x180402a5U, +/*03ef*/ 0x000402a6U, +/*03f0*/ 0x080402a6U, +/*03f1*/ 0x100402a6U, +/*03f2*/ 0x180402a6U, +/*03f3*/ 0x000402a7U, +/*03f4*/ 0x080402a7U, +/*03f5*/ 0x100402a7U, +/*03f6*/ 0x180402a7U, +/*03f7*/ 0x000402a8U, +/*03f8*/ 0x080402a8U, +/*03f9*/ 0x100402a8U, +/*03fa*/ 0x180402a8U, +/*03fb*/ 0x000402a9U, +/*03fc*/ 0x081202a9U, +/*03fd*/ 0x001102aaU, +/*03fe*/ 0x001202abU, +/*03ff*/ 0x002002acU, +/*0400*/ 0x002002adU, +/*0401*/ 0x002002aeU, +/*0402*/ 0x002002afU, +/*0403*/ 0x002002b0U, +/*0404*/ 0x002002b1U, +/*0405*/ 0x002002b2U, +/*0406*/ 0x002002b3U, +/*0407*/ 0x002002b4U, +/*0408*/ 0x000302b5U, +/*0409*/ 0x080502b5U, +/*040a*/ 0x100502b5U, +/*040b*/ 0x180102b5U, +/*040c*/ 0x000502b6U, +/*040d*/ 0x080502b6U, +/*040e*/ 0x100502b6U, +/*040f*/ 0x180502b6U, +/*0410*/ 0x000502b7U, +/*0411*/ 0x080502b7U, +/*0412*/ 0x100502b7U, +/*0413*/ 0x180502b7U, +/*0414*/ 0x000502b8U, +/*0415*/ 0x080502b8U, +/*0416*/ 0x100502b8U, +/*0417*/ 0x180502b8U, +/*0418*/ 0x000502b9U, +/*0419*/ 0x080502b9U, +/*041a*/ 0x100502b9U, +/*041b*/ 0x180502b9U, +/*041c*/ 0x000502baU, +/*041d*/ 0x080502baU, +/*041e*/ 0x100502baU, +/*041f*/ 0x180502baU, +/*0420*/ 0x000502bbU, +/*0421*/ 0x080502bbU, +/*0422*/ 0x100102bbU, +/*0423*/ 0x180202bbU, +/*0424*/ 0x000202bcU, +/*0425*/ 0x080202bcU, +/*0426*/ 0x100202bcU, +/*0427*/ 0x180102bcU, +/*0428*/ 0x000402bdU, +/*0429*/ 0x081002bdU, +/*042a*/ 0x002002beU, +/*042b*/ 0x001002bfU, +/*042c*/ 0x002002c0U, +/*042d*/ 0x001002c1U, +/*042e*/ 0x002002c2U, +/*042f*/ 0x000702c3U, +/*0430*/ 0x080102c3U, +/*0431*/ 0x100202c3U, +/*0432*/ 0x180602c3U, +/*0433*/ 0x000102c4U, +/*0434*/ 0x080102c4U, +/*0435*/ 0x002002c5U, +/*0436*/ 0x000302c6U, +/*0437*/ 0x002002c7U, +/*0438*/ 0x002002c8U, +/*0439*/ 0xffffffffU, +/*043a*/ 0xffffffffU, +/*043b*/ 0xffffffffU, +/*043c*/ 0xffffffffU, +/*043d*/ 0xffffffffU, +/*043e*/ 0xffffffffU, +/*043f*/ 0xffffffffU, +/*0440*/ 0xffffffffU, +/*0441*/ 0xffffffffU, +/*0442*/ 0xffffffffU, +/*0443*/ 0xffffffffU, +/*0444*/ 0xffffffffU, +/*0445*/ 0xffffffffU, +/*0446*/ 0xffffffffU, +/*0447*/ 0xffffffffU, +/*0448*/ 0xffffffffU, +/*0449*/ 0xffffffffU, +/*044a*/ 0xffffffffU, +/*044b*/ 0xffffffffU, +/*044c*/ 0xffffffffU, +/*044d*/ 0xffffffffU, +/*044e*/ 0xffffffffU, +/*044f*/ 0xffffffffU, +/*0450*/ 0xffffffffU, +/*0451*/ 0xffffffffU, +/*0452*/ 0xffffffffU, +/*0453*/ 0xffffffffU, +/*0454*/ 0xffffffffU, +/*0455*/ 0xffffffffU, +/*0456*/ 0xffffffffU, +/*0457*/ 0xffffffffU, +/*0458*/ 0xffffffffU, +/*0459*/ 0xffffffffU, +/*045a*/ 0xffffffffU, +/*045b*/ 0xffffffffU, +/*045c*/ 0xffffffffU, +/*045d*/ 0xffffffffU, +/*045e*/ 0xffffffffU, +/*045f*/ 0x000402c9U, +/*0460*/ 0xffffffffU, +/*0461*/ 0xffffffffU, +/*0462*/ 0xffffffffU, +/*0463*/ 0xffffffffU, +/*0464*/ 0xffffffffU, +/*0465*/ 0xffffffffU, +/*0466*/ 0xffffffffU, +/*0467*/ 0xffffffffU, +/*0468*/ 0xffffffffU, +/*0469*/ 0xffffffffU, +/*046a*/ 0xffffffffU, +/*046b*/ 0xffffffffU, +/*046c*/ 0xffffffffU, +/*046d*/ 0xffffffffU, +/*046e*/ 0xffffffffU, +/*046f*/ 0xffffffffU, +/*0470*/ 0xffffffffU, +/*0471*/ 0xffffffffU, +/*0472*/ 0xffffffffU, +/*0473*/ 0xffffffffU, +/*0474*/ 0xffffffffU, +/*0475*/ 0xffffffffU, +/*0476*/ 0xffffffffU, +/*0477*/ 0xffffffffU, +/*0478*/ 0xffffffffU, +/*0479*/ 0xffffffffU, +/*047a*/ 0xffffffffU, +/*047b*/ 0xffffffffU, +/*047c*/ 0xffffffffU, +/*047d*/ 0xffffffffU, +/*047e*/ 0xffffffffU, +/*047f*/ 0xffffffffU, +/*0480*/ 0xffffffffU, +/*0481*/ 0xffffffffU, +/*0482*/ 0xffffffffU, +/*0483*/ 0xffffffffU, +/*0484*/ 0xffffffffU, +/*0485*/ 0xffffffffU, +/*0486*/ 0xffffffffU, +/*0487*/ 0xffffffffU, +/*0488*/ 0xffffffffU, +/*0489*/ 0xffffffffU, +/*048a*/ 0xffffffffU, +/*048b*/ 0xffffffffU, +/*048c*/ 0xffffffffU, +/*048d*/ 0xffffffffU, +/*048e*/ 0xffffffffU, +/*048f*/ 0xffffffffU, +/*0490*/ 0xffffffffU, +/*0491*/ 0xffffffffU, +/*0492*/ 0xffffffffU, +/*0493*/ 0xffffffffU, +/*0494*/ 0xffffffffU, + }, + { +/*0000*/ 0x00200400U, +/*0001*/ 0x00040401U, +/*0002*/ 0x080b0401U, +/*0003*/ 0x000a0402U, +/*0004*/ 0x10020402U, +/*0005*/ 0x18010402U, +/*0006*/ 0x00050403U, +/*0007*/ 0x08050403U, +/*0008*/ 0x10050403U, +/*0009*/ 0x18050403U, +/*000a*/ 0x00050404U, +/*000b*/ 0x08050404U, +/*000c*/ 0x10050404U, +/*000d*/ 0x18050404U, +/*000e*/ 0x00050405U, +/*000f*/ 0x08040405U, +/*0010*/ 0x10030405U, +/*0011*/ 0x00180406U, +/*0012*/ 0x18030406U, +/*0013*/ 0x00180407U, +/*0014*/ 0x18020407U, +/*0015*/ 0x00010408U, +/*0016*/ 0x08020408U, +/*0017*/ 0x10010408U, +/*0018*/ 0x18010408U, +/*0019*/ 0x00020409U, +/*001a*/ 0x08040409U, +/*001b*/ 0x10040409U, +/*001c*/ 0x18040409U, +/*001d*/ 0xffffffffU, +/*001e*/ 0x0004040aU, +/*001f*/ 0xffffffffU, +/*0020*/ 0xffffffffU, +/*0021*/ 0x0809040aU, +/*0022*/ 0x1801040aU, +/*0023*/ 0x0020040bU, +/*0024*/ 0x001c040cU, +/*0025*/ 0x0001040dU, +/*0026*/ 0x0807040dU, +/*0027*/ 0x1009040dU, +/*0028*/ 0x000a040eU, +/*0029*/ 0x1005040eU, +/*002a*/ 0x1801040eU, +/*002b*/ 0x1001040fU, +/*002c*/ 0x1802040fU, +/*002d*/ 0x0009040fU, +/*002e*/ 0x00090410U, +/*002f*/ 0x10020410U, +/*0030*/ 0x00200411U, +/*0031*/ 0x00010412U, +/*0032*/ 0x08020412U, +/*0033*/ 0xffffffffU, +/*0034*/ 0xffffffffU, +/*0035*/ 0xffffffffU, +/*0036*/ 0xffffffffU, +/*0037*/ 0x00200413U, +/*0038*/ 0x00200414U, +/*0039*/ 0x00200415U, +/*003a*/ 0x00200416U, +/*003b*/ 0x00030417U, +/*003c*/ 0x08010417U, +/*003d*/ 0x10040417U, +/*003e*/ 0x18030417U, +/*003f*/ 0x00040418U, +/*0040*/ 0x08040418U, +/*0041*/ 0x10040418U, +/*0042*/ 0x18040418U, +/*0043*/ 0x00010419U, +/*0044*/ 0x08010419U, +/*0045*/ 0x10060419U, +/*0046*/ 0x18040419U, +/*0047*/ 0xffffffffU, +/*0048*/ 0x0006041aU, +/*0049*/ 0x0804041aU, +/*004a*/ 0x1006041aU, +/*004b*/ 0x1804041aU, +/*004c*/ 0x0002041bU, +/*004d*/ 0x0805041bU, +/*004e*/ 0x1008041bU, +/*004f*/ 0xffffffffU, +/*0050*/ 0x1806041bU, +/*0051*/ 0x0003041cU, +/*0052*/ 0x080b041cU, +/*0053*/ 0x1804041cU, +/*0054*/ 0x0004041dU, +/*0055*/ 0x0804041dU, +/*0056*/ 0x1001041dU, +/*0057*/ 0xffffffffU, +/*0058*/ 0x0009041eU, +/*0059*/ 0x0020041fU, +/*005a*/ 0x00200420U, +/*005b*/ 0x00200421U, +/*005c*/ 0x00200422U, +/*005d*/ 0x00100423U, +/*005e*/ 0xffffffffU, +/*005f*/ 0x10010423U, +/*0060*/ 0x18060423U, +/*0061*/ 0x00080424U, +/*0062*/ 0x00200425U, +/*0063*/ 0x00100426U, +/*0064*/ 0x100a0426U, +/*0065*/ 0x00060427U, +/*0066*/ 0x08070427U, +/*0067*/ 0x10080427U, +/*0068*/ 0x18080427U, +/*0069*/ 0x000a0428U, +/*006a*/ 0x10070428U, +/*006b*/ 0x18080428U, +/*006c*/ 0x00080429U, +/*006d*/ 0x08030429U, +/*006e*/ 0x100a0429U, +/*006f*/ 0x000a042aU, +/*0070*/ 0x0011042bU, +/*0071*/ 0x0009042cU, +/*0072*/ 0x1009042cU, +/*0073*/ 0x0010042dU, +/*0074*/ 0x100e042dU, +/*0075*/ 0x000e042eU, +/*0076*/ 0x0012042fU, +/*0077*/ 0x000a0430U, +/*0078*/ 0x100a0430U, +/*0079*/ 0x00020431U, +/*007a*/ 0x00200432U, +/*007b*/ 0x000b0433U, +/*007c*/ 0x100b0433U, +/*007d*/ 0x00200434U, +/*007e*/ 0x00120435U, +/*007f*/ 0x00200436U, +/*0080*/ 0x00200437U, +/*0081*/ 0x00080438U, +/*0082*/ 0x08010438U, +/*0083*/ 0x10010438U, +/*0084*/ 0x18010438U, +/*0085*/ 0x00080439U, +/*0086*/ 0x080c0439U, +/*0087*/ 0x000c043aU, +/*0088*/ 0x100c043aU, +/*0089*/ 0x000c043bU, +/*008a*/ 0x100c043bU, +/*008b*/ 0x000c043cU, +/*008c*/ 0x100c043cU, +/*008d*/ 0x000c043dU, +/*008e*/ 0x100c043dU, +/*008f*/ 0x000c043eU, +/*0090*/ 0x100c043eU, +/*0091*/ 0x000b043fU, +/*0092*/ 0x1009043fU, +/*0093*/ 0x00010440U, +/*0094*/ 0x000b0441U, +/*0095*/ 0x100b0441U, +/*0096*/ 0x000b0442U, +/*0097*/ 0x100b0442U, +/*0098*/ 0x000b0443U, +/*0099*/ 0x100b0443U, +/*009a*/ 0x000b0444U, +/*009b*/ 0x100b0444U, +/*009c*/ 0x000b0445U, +/*009d*/ 0x100a0445U, +/*009e*/ 0x00020446U, +/*009f*/ 0x080a0446U, +/*00a0*/ 0x000a0447U, +/*00a1*/ 0x100a0447U, +/*00a2*/ 0x000a0448U, +/*00a3*/ 0x100a0448U, +/*00a4*/ 0x000a0449U, +/*00a5*/ 0x100a0449U, +/*00a6*/ 0x000a044aU, +/*00a7*/ 0x100a044aU, +/*00a8*/ 0x000a044bU, +/*00a9*/ 0x100a044bU, +/*00aa*/ 0x000a044cU, +/*00ab*/ 0x100a044cU, +/*00ac*/ 0x000a044dU, +/*00ad*/ 0x100a044dU, +/*00ae*/ 0x000a044eU, +/*00af*/ 0x100a044eU, +/*00b0*/ 0x000a044fU, +/*00b1*/ 0x100a044fU, +/*00b2*/ 0x000a0450U, +/*00b3*/ 0x100a0450U, +/*00b4*/ 0x000a0451U, +/*00b5*/ 0x100a0451U, +/*00b6*/ 0x000a0452U, +/*00b7*/ 0x100a0452U, +/*00b8*/ 0x000a0453U, +/*00b9*/ 0x100a0453U, +/*00ba*/ 0x000a0454U, +/*00bb*/ 0x10040454U, +/*00bc*/ 0x18030454U, +/*00bd*/ 0x000a0455U, +/*00be*/ 0x100a0455U, +/*00bf*/ 0x00010456U, +/*00c0*/ 0x080a0456U, +/*00c1*/ 0x18040456U, +/*00c2*/ 0x000b0457U, +/*00c3*/ 0x100a0457U, +/*00c4*/ 0x00030458U, +/*00c5*/ 0x00080459U, +/*00c6*/ 0x08080459U, +/*00c7*/ 0x10080459U, +/*00c8*/ 0x18080459U, +/*00c9*/ 0x0008045aU, +/*00ca*/ 0xffffffffU, +/*00cb*/ 0x0808045aU, +/*00cc*/ 0x1001045aU, +/*00cd*/ 0x1808045aU, +/*00ce*/ 0x0008045bU, +/*00cf*/ 0x0802045bU, +/*00d0*/ 0x1002045bU, +/*00d1*/ 0x1805045bU, +/*00d2*/ 0x0005045cU, +/*00d3*/ 0xffffffffU, +/*00d4*/ 0x0804045cU, +/*00d5*/ 0x100a045cU, +/*00d6*/ 0x0006045dU, +/*00d7*/ 0x0808045dU, +/*00d8*/ 0x1008045dU, +/*00d9*/ 0x1804045dU, +/*00da*/ 0x0004045eU, +/*00db*/ 0x0805045eU, +/*00dc*/ 0x1004045eU, +/*00dd*/ 0x1805045eU, +/*00de*/ 0x000a045fU, +/*00df*/ 0x100a045fU, +/*00e0*/ 0x00080460U, +/*00e1*/ 0xffffffffU, +/*00e2*/ 0x08040460U, +/*00e3*/ 0xffffffffU, +/*00e4*/ 0xffffffffU, +/*00e5*/ 0x00050600U, +/*00e6*/ 0x08050600U, +/*00e7*/ 0x10050600U, +/*00e8*/ 0x18050600U, +/*00e9*/ 0x00050601U, +/*00ea*/ 0x08050601U, +/*00eb*/ 0x100b0601U, +/*00ec*/ 0x00010602U, +/*00ed*/ 0x08030602U, +/*00ee*/ 0x00200603U, +/*00ef*/ 0x00100604U, +/*00f0*/ 0x10040604U, +/*00f1*/ 0x000a0605U, +/*00f2*/ 0x10090605U, +/*00f3*/ 0x00080606U, +/*00f4*/ 0x08030606U, +/*00f5*/ 0x10030606U, +/*00f6*/ 0x18010606U, +/*00f7*/ 0x00010607U, +/*00f8*/ 0x08070607U, +/*00f9*/ 0x10070607U, +/*00fa*/ 0x18050607U, +/*00fb*/ 0x00010608U, +/*00fc*/ 0x08020608U, +/*00fd*/ 0x10030608U, +/*00fe*/ 0x18010608U, +/*00ff*/ 0x000f0609U, +/*0100*/ 0x0020060aU, +/*0101*/ 0x0020060bU, +/*0102*/ 0x000b060cU, +/*0103*/ 0x100b060cU, +/*0104*/ 0x000b060dU, +/*0105*/ 0x0018060eU, +/*0106*/ 0x0018060fU, +/*0107*/ 0xffffffffU, +/*0108*/ 0xffffffffU, +/*0109*/ 0xffffffffU, +/*010a*/ 0xffffffffU, +/*010b*/ 0xffffffffU, +/*010c*/ 0x1802060fU, +/*010d*/ 0x00020610U, +/*010e*/ 0x08040610U, +/*010f*/ 0x10040610U, +/*0110*/ 0x18010610U, +/*0111*/ 0x00010611U, +/*0112*/ 0x08010611U, +/*0113*/ 0x10030611U, +/*0114*/ 0x00200612U, +/*0115*/ 0x00200613U, +/*0116*/ 0xffffffffU, +/*0117*/ 0x00140614U, +/*0118*/ 0x00140615U, +/*0119*/ 0x00140616U, +/*011a*/ 0x00140617U, +/*011b*/ 0x00140618U, +/*011c*/ 0x00140619U, +/*011d*/ 0x0014061aU, +/*011e*/ 0x0014061bU, +/*011f*/ 0x0018061cU, +/*0120*/ 0x000a061dU, +/*0121*/ 0x1006061dU, +/*0122*/ 0x1806061dU, +/*0123*/ 0x0006061eU, +/*0124*/ 0xffffffffU, +/*0125*/ 0x0806061eU, +/*0126*/ 0x0008061fU, +/*0127*/ 0x080b061fU, +/*0128*/ 0x000b0620U, +/*0129*/ 0x100b0620U, +/*012a*/ 0x000b0621U, +/*012b*/ 0x100b0621U, +/*012c*/ 0x000b0622U, +/*012d*/ 0x10040622U, +/*012e*/ 0x000a0623U, +/*012f*/ 0x10060623U, +/*0130*/ 0x18080623U, +/*0131*/ 0x00080624U, +/*0132*/ 0x08040624U, +/*0133*/ 0x00020680U, +/*0134*/ 0x00010681U, +/*0135*/ 0x08010681U, +/*0136*/ 0x10020681U, +/*0137*/ 0x18050681U, +/*0138*/ 0x00050682U, +/*0139*/ 0x08050682U, +/*013a*/ 0x10050682U, +/*013b*/ 0x000b0683U, +/*013c*/ 0x10050683U, +/*013d*/ 0x18010683U, +/*013e*/ 0x00010684U, +/*013f*/ 0xffffffffU, +/*0140*/ 0x08010684U, +/*0141*/ 0x10010684U, +/*0142*/ 0x18040684U, +/*0143*/ 0x000b0685U, +/*0144*/ 0x100b0685U, +/*0145*/ 0x000b0686U, +/*0146*/ 0x10040686U, +/*0147*/ 0x000b0687U, +/*0148*/ 0x10040687U, +/*0149*/ 0x18010687U, +/*014a*/ 0x00010688U, +/*014b*/ 0x08010688U, +/*014c*/ 0x00200689U, +/*014d*/ 0x0020068aU, +/*014e*/ 0x0008068bU, +/*014f*/ 0x080a068bU, +/*0150*/ 0x1805068bU, +/*0151*/ 0x000a068cU, +/*0152*/ 0x1003068cU, +/*0153*/ 0x1803068cU, +/*0154*/ 0x0001068dU, +/*0155*/ 0x0802068dU, +/*0156*/ 0x1001068dU, +/*0157*/ 0x1801068dU, +/*0158*/ 0x0001068eU, +/*0159*/ 0x0802068eU, +/*015a*/ 0x1001068eU, +/*015b*/ 0x0004068fU, +/*015c*/ 0x0804068fU, +/*015d*/ 0x1004068fU, +/*015e*/ 0x1804068fU, +/*015f*/ 0x00010690U, +/*0160*/ 0x08010690U, +/*0161*/ 0x10010690U, +/*0162*/ 0x00200691U, +/*0163*/ 0x00200692U, +/*0164*/ 0x00200693U, +/*0165*/ 0x00200694U, +/*0166*/ 0xffffffffU, +/*0167*/ 0x1801068eU, +/*0168*/ 0x000d0696U, +/*0169*/ 0x100d0696U, +/*016a*/ 0x000d0697U, +/*016b*/ 0x00050698U, +/*016c*/ 0x00010699U, +/*016d*/ 0x080e0699U, +/*016e*/ 0x000e069aU, +/*016f*/ 0x100e069aU, +/*0170*/ 0x000e069bU, +/*0171*/ 0x100e069bU, +/*0172*/ 0x0004069cU, +/*0173*/ 0x0804069cU, +/*0174*/ 0x1004069cU, +/*0175*/ 0x1804069cU, +/*0176*/ 0x0004069dU, +/*0177*/ 0x080b069dU, +/*0178*/ 0x000b069eU, +/*0179*/ 0x100b069eU, +/*017a*/ 0x000b069fU, +/*017b*/ 0xffffffffU, +/*017c*/ 0xffffffffU, +/*017d*/ 0xffffffffU, +/*017e*/ 0xffffffffU, +/*017f*/ 0x000d06a0U, +/*0180*/ 0x100d06a0U, +/*0181*/ 0x000d06a1U, +/*0182*/ 0x101006a1U, +/*0183*/ 0x00080695U, +/*0184*/ 0x08080695U, +/*0185*/ 0x001006a2U, +/*0186*/ 0x101006a2U, +/*0187*/ 0x001006a3U, +/*0188*/ 0x101006a3U, +/*0189*/ 0x001006a4U, +/*018a*/ 0x100306a4U, +/*018b*/ 0x180406a4U, +/*018c*/ 0x000106a5U, +/*018d*/ 0x080806a5U, +/*018e*/ 0x100106a5U, +/*018f*/ 0x180506a5U, +/*0190*/ 0x000106a6U, +/*0191*/ 0x081406a6U, +/*0192*/ 0x000a06a7U, +/*0193*/ 0x100c06a7U, +/*0194*/ 0x001206a8U, +/*0195*/ 0x001406a9U, +/*0196*/ 0x001206aaU, +/*0197*/ 0x001106abU, +/*0198*/ 0x001106acU, +/*0199*/ 0x001206adU, +/*019a*/ 0x001206aeU, +/*019b*/ 0x001206afU, +/*019c*/ 0x001206b0U, +/*019d*/ 0x001206b1U, +/*019e*/ 0x001206b2U, +/*019f*/ 0x001206b3U, +/*01a0*/ 0x001206b4U, +/*01a1*/ 0x001206b5U, +/*01a2*/ 0x001206b6U, +/*01a3*/ 0x000e06b7U, +/*01a4*/ 0x100d06b7U, +/*01a5*/ 0x002006b8U, +/*01a6*/ 0x001706b9U, +/*01a7*/ 0x000906baU, +/*01a8*/ 0x100106baU, +/*01a9*/ 0x180106baU, +/*01aa*/ 0x002006bbU, +/*01ab*/ 0x000806bcU, +/*01ac*/ 0x080306bcU, +/*01ad*/ 0x100306bcU, +/*01ae*/ 0x001806bdU, +/*01af*/ 0x001806beU, +/*01b0*/ 0x180706beU, +/*01b1*/ 0x000506bfU, +/*01b2*/ 0x080806bfU, +/*01b3*/ 0x100806bfU, +/*01b4*/ 0x180806bfU, +/*01b5*/ 0x000106c0U, +/*01b6*/ 0x080106c0U, +/*01b7*/ 0x002006c1U, +/*01b8*/ 0xffffffffU, +/*01b9*/ 0xffffffffU, +/*01ba*/ 0xffffffffU, +/*01bb*/ 0xffffffffU, +/*01bc*/ 0xffffffffU, +/*01bd*/ 0xffffffffU, +/*01be*/ 0xffffffffU, +/*01bf*/ 0x001006c2U, +/*01c0*/ 0x100106c2U, +/*01c1*/ 0x180106c2U, +/*01c2*/ 0x000206c3U, +/*01c3*/ 0x080406c3U, +/*01c4*/ 0x100906c3U, +/*01c5*/ 0x000706c4U, +/*01c6*/ 0x080406c4U, +/*01c7*/ 0x002006c5U, +/*01c8*/ 0x000106c6U, +/*01c9*/ 0x080206c6U, +/*01ca*/ 0x100606c6U, +/*01cb*/ 0x001006c7U, +/*01cc*/ 0x100106c7U, +/*01cd*/ 0x002006c8U, +/*01ce*/ 0x000806c9U, +/*01cf*/ 0x080106c9U, +/*01d0*/ 0x100506c9U, +/*01d1*/ 0xffffffffU, +/*01d2*/ 0x180206c9U, +/*01d3*/ 0x000106caU, +/*01d4*/ 0x002006cbU, +/*01d5*/ 0x000b06ccU, +/*01d6*/ 0x100106ccU, +/*01d7*/ 0x180306ccU, +/*01d8*/ 0x000806cdU, +/*01d9*/ 0x080206cdU, +/*01da*/ 0x100c06cdU, +/*01db*/ 0x000406ceU, +/*01dc*/ 0x080106ceU, +/*01dd*/ 0xffffffffU, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0x10010201U, +/*01e4*/ 0xffffffffU, +/*01e5*/ 0x00100202U, +/*01e6*/ 0x10080202U, +/*01e7*/ 0xffffffffU, +/*01e8*/ 0xffffffffU, +/*01e9*/ 0xffffffffU, +/*01ea*/ 0xffffffffU, +/*01eb*/ 0xffffffffU, +/*01ec*/ 0xffffffffU, +/*01ed*/ 0xffffffffU, +/*01ee*/ 0xffffffffU, +/*01ef*/ 0x00200203U, +/*01f0*/ 0x00100204U, +/*01f1*/ 0x00200205U, +/*01f2*/ 0x00100206U, +/*01f3*/ 0x00200207U, +/*01f4*/ 0x00100208U, +/*01f5*/ 0x00140209U, +/*01f6*/ 0x0020020aU, +/*01f7*/ 0x0020020bU, +/*01f8*/ 0x0020020cU, +/*01f9*/ 0x0020020dU, +/*01fa*/ 0x0014020eU, +/*01fb*/ 0x0020020fU, +/*01fc*/ 0x00200210U, +/*01fd*/ 0x00200211U, +/*01fe*/ 0x00200212U, +/*01ff*/ 0x00140213U, +/*0200*/ 0x00200214U, +/*0201*/ 0x00200215U, +/*0202*/ 0x00200216U, +/*0203*/ 0x00200217U, +/*0204*/ 0x00090218U, +/*0205*/ 0x10010218U, +/*0206*/ 0x00200219U, +/*0207*/ 0x0005021aU, +/*0208*/ 0x0801021aU, +/*0209*/ 0x1008021aU, +/*020a*/ 0x1808021aU, +/*020b*/ 0x001c021bU, +/*020c*/ 0x001c021cU, +/*020d*/ 0x001c021dU, +/*020e*/ 0x001c021eU, +/*020f*/ 0x001c021fU, +/*0210*/ 0x001c0220U, +/*0211*/ 0x001c0221U, +/*0212*/ 0x001c0222U, +/*0213*/ 0x001c0223U, +/*0214*/ 0x001c0224U, +/*0215*/ 0x001c0225U, +/*0216*/ 0x001c0226U, +/*0217*/ 0x001c0227U, +/*0218*/ 0x001c0228U, +/*0219*/ 0x001c0229U, +/*021a*/ 0x001c022aU, +/*021b*/ 0x0001022bU, +/*021c*/ 0x0801022bU, +/*021d*/ 0x1001022bU, +/*021e*/ 0x1804022bU, +/*021f*/ 0x0008022cU, +/*0220*/ 0x0808022cU, +/*0221*/ 0x1008022cU, +/*0222*/ 0x1804022cU, +/*0223*/ 0x0007022dU, +/*0224*/ 0xffffffffU, +/*0225*/ 0x0807022dU, +/*0226*/ 0x1007022dU, +/*0227*/ 0xffffffffU, +/*0228*/ 0x1807022dU, +/*0229*/ 0x0007022eU, +/*022a*/ 0xffffffffU, +/*022b*/ 0x0807022eU, +/*022c*/ 0x1002022eU, +/*022d*/ 0x1801022eU, +/*022e*/ 0x0001022fU, +/*022f*/ 0x080a022fU, +/*0230*/ 0x00140230U, +/*0231*/ 0x000a0231U, +/*0232*/ 0x00140232U, +/*0233*/ 0x000a0233U, +/*0234*/ 0x00140234U, +/*0235*/ 0x18010234U, +/*0236*/ 0x00100235U, +/*0237*/ 0x10050235U, +/*0238*/ 0x18010235U, +/*0239*/ 0x00010236U, +/*023a*/ 0x08010236U, +/*023b*/ 0x10010236U, +/*023c*/ 0x18010236U, +/*023d*/ 0x00010237U, +/*023e*/ 0x08010237U, +/*023f*/ 0x10020237U, +/*0240*/ 0x18020237U, +/*0241*/ 0x00020238U, +/*0242*/ 0x08020238U, +/*0243*/ 0x10020238U, +/*0244*/ 0x18030238U, +/*0245*/ 0x00010239U, +/*0246*/ 0x08010239U, +/*0247*/ 0x10010239U, +/*0248*/ 0x18010239U, +/*0249*/ 0xffffffffU, +/*024a*/ 0x0002023aU, +/*024b*/ 0x0801023aU, +/*024c*/ 0x1001023aU, +/*024d*/ 0xffffffffU, +/*024e*/ 0x1802023aU, +/*024f*/ 0x0001023bU, +/*0250*/ 0x0801023bU, +/*0251*/ 0xffffffffU, +/*0252*/ 0x1002023bU, +/*0253*/ 0x1801023bU, +/*0254*/ 0x0001023cU, +/*0255*/ 0xffffffffU, +/*0256*/ 0x0802023cU, +/*0257*/ 0x1007023cU, +/*0258*/ 0x1801023cU, +/*0259*/ 0x0001023dU, +/*025a*/ 0x0801023dU, +/*025b*/ 0x1001023dU, +/*025c*/ 0x1801023dU, +/*025d*/ 0x0001023eU, +/*025e*/ 0x0801023eU, +/*025f*/ 0x1001023eU, +/*0260*/ 0x1804023eU, +/*0261*/ 0x0004023fU, +/*0262*/ 0x0804023fU, +/*0263*/ 0x1001023fU, +/*0264*/ 0x1802023fU, +/*0265*/ 0x00060240U, +/*0266*/ 0x08060240U, +/*0267*/ 0x10020240U, +/*0268*/ 0x18020240U, +/*0269*/ 0x00020241U, +/*026a*/ 0xffffffffU, +/*026b*/ 0x08100241U, +/*026c*/ 0x18010241U, +/*026d*/ 0x00010242U, +/*026e*/ 0x08010242U, +/*026f*/ 0x10040242U, +/*0270*/ 0x18010242U, +/*0271*/ 0x00040243U, +/*0272*/ 0x08020243U, +/*0273*/ 0x10080243U, +/*0274*/ 0xffffffffU, +/*0275*/ 0xffffffffU, +/*0276*/ 0xffffffffU, +/*0277*/ 0x000a0244U, +/*0278*/ 0x00200245U, +/*0279*/ 0x00200246U, +/*027a*/ 0x00050247U, +/*027b*/ 0x08010247U, +/*027c*/ 0x10050247U, +/*027d*/ 0x18080247U, +/*027e*/ 0x00010248U, +/*027f*/ 0x08080248U, +/*0280*/ 0x10010248U, +/*0281*/ 0x18080248U, +/*0282*/ 0x00010249U, +/*0283*/ 0x08040249U, +/*0284*/ 0x10040249U, +/*0285*/ 0x18040249U, +/*0286*/ 0x0004024aU, +/*0287*/ 0x0804024aU, +/*0288*/ 0x1004024aU, +/*0289*/ 0x1804024aU, +/*028a*/ 0x0004024bU, +/*028b*/ 0x0804024bU, +/*028c*/ 0x1004024bU, +/*028d*/ 0x1801024bU, +/*028e*/ 0x0004024cU, +/*028f*/ 0x0804024cU, +/*0290*/ 0x1004024cU, +/*0291*/ 0x1804024cU, +/*0292*/ 0x0004024dU, +/*0293*/ 0x0804024dU, +/*0294*/ 0x1006024dU, +/*0295*/ 0x1806024dU, +/*0296*/ 0x0006024eU, +/*0297*/ 0x0806024eU, +/*0298*/ 0x1006024eU, +/*0299*/ 0x1806024eU, +/*029a*/ 0xffffffffU, +/*029b*/ 0x0001024fU, +/*029c*/ 0x0801024fU, +/*029d*/ 0x1002024fU, +/*029e*/ 0xffffffffU, +/*029f*/ 0xffffffffU, +/*02a0*/ 0xffffffffU, +/*02a1*/ 0xffffffffU, +/*02a2*/ 0xffffffffU, +/*02a3*/ 0xffffffffU, +/*02a4*/ 0xffffffffU, +/*02a5*/ 0xffffffffU, +/*02a6*/ 0x1804024fU, +/*02a7*/ 0x00040250U, +/*02a8*/ 0x08010250U, +/*02a9*/ 0x10010250U, +/*02aa*/ 0x18010250U, +/*02ab*/ 0x00010251U, +/*02ac*/ 0x08010251U, +/*02ad*/ 0x10010251U, +/*02ae*/ 0x18010251U, +/*02af*/ 0x00010252U, +/*02b0*/ 0x08010252U, +/*02b1*/ 0x10040252U, +/*02b2*/ 0x18040252U, +/*02b3*/ 0x000a0253U, +/*02b4*/ 0x00200254U, +/*02b5*/ 0x00040255U, +/*02b6*/ 0x08080255U, +/*02b7*/ 0x10020255U, +/*02b8*/ 0x18020255U, +/*02b9*/ 0x00020256U, +/*02ba*/ 0x08020256U, +/*02bb*/ 0x10020256U, +/*02bc*/ 0x18020256U, +/*02bd*/ 0xffffffffU, +/*02be*/ 0xffffffffU, +/*02bf*/ 0x00200257U, +/*02c0*/ 0x00020258U, +/*02c1*/ 0x08100258U, +/*02c2*/ 0x00100259U, +/*02c3*/ 0x10040259U, +/*02c4*/ 0x18040259U, +/*02c5*/ 0x0005025aU, +/*02c6*/ 0x0805025aU, +/*02c7*/ 0x0020025bU, +/*02c8*/ 0x0020025cU, +/*02c9*/ 0x0020025dU, +/*02ca*/ 0x0020025eU, +/*02cb*/ 0x0001025fU, +/*02cc*/ 0x0801025fU, +/*02cd*/ 0x1007025fU, +/*02ce*/ 0x1807025fU, +/*02cf*/ 0x00070260U, +/*02d0*/ 0x08070260U, +/*02d1*/ 0x10070260U, +/*02d2*/ 0x18070260U, +/*02d3*/ 0x00070261U, +/*02d4*/ 0x08070261U, +/*02d5*/ 0x10070261U, +/*02d6*/ 0x18070261U, +/*02d7*/ 0x00070262U, +/*02d8*/ 0x08070262U, +/*02d9*/ 0x10070262U, +/*02da*/ 0x18070262U, +/*02db*/ 0x00030263U, +/*02dc*/ 0x08030263U, +/*02dd*/ 0x10030263U, +/*02de*/ 0xffffffffU, +/*02df*/ 0x18010263U, +/*02e0*/ 0x00020264U, +/*02e1*/ 0x08010264U, +/*02e2*/ 0x10040264U, +/*02e3*/ 0x18020264U, +/*02e4*/ 0x00010265U, +/*02e5*/ 0x08010265U, +/*02e6*/ 0x10010265U, +/*02e7*/ 0x18010265U, +/*02e8*/ 0x00040266U, +/*02e9*/ 0x08080266U, +/*02ea*/ 0x100a0266U, +/*02eb*/ 0x000a0267U, +/*02ec*/ 0x100a0267U, +/*02ed*/ 0x000a0268U, +/*02ee*/ 0x100a0268U, +/*02ef*/ 0x000a0269U, +/*02f0*/ 0x0020026aU, +/*02f1*/ 0x0020026bU, +/*02f2*/ 0x0001026cU, +/*02f3*/ 0x0802026cU, +/*02f4*/ 0x1002026cU, +/*02f5*/ 0x1802026cU, +/*02f6*/ 0xffffffffU, +/*02f7*/ 0x0002026dU, +/*02f8*/ 0x0810026dU, +/*02f9*/ 0x1805026dU, +/*02fa*/ 0x0006026eU, +/*02fb*/ 0x0805026eU, +/*02fc*/ 0x1005026eU, +/*02fd*/ 0x000e026fU, +/*02fe*/ 0x1005026fU, +/*02ff*/ 0x000e0270U, +/*0300*/ 0x10050270U, +/*0301*/ 0x000e0271U, +/*0302*/ 0x10050271U, +/*0303*/ 0x18010271U, +/*0304*/ 0x00050272U, +/*0305*/ 0x08050272U, +/*0306*/ 0x100a0272U, +/*0307*/ 0x000a0273U, +/*0308*/ 0x10050273U, +/*0309*/ 0x18050273U, +/*030a*/ 0x000a0274U, +/*030b*/ 0x100a0274U, +/*030c*/ 0x00050275U, +/*030d*/ 0x08050275U, +/*030e*/ 0x100a0275U, +/*030f*/ 0x000a0276U, +/*0310*/ 0xffffffffU, +/*0311*/ 0xffffffffU, +/*0312*/ 0xffffffffU, +/*0313*/ 0xffffffffU, +/*0314*/ 0xffffffffU, +/*0315*/ 0xffffffffU, +/*0316*/ 0x10070276U, +/*0317*/ 0x18070276U, +/*0318*/ 0x00040277U, +/*0319*/ 0x08040277U, +/*031a*/ 0xffffffffU, +/*031b*/ 0xffffffffU, +/*031c*/ 0xffffffffU, +/*031d*/ 0x10040277U, +/*031e*/ 0x18080277U, +/*031f*/ 0x00080278U, +/*0320*/ 0x08040278U, +/*0321*/ 0xffffffffU, +/*0322*/ 0xffffffffU, +/*0323*/ 0xffffffffU, +/*0324*/ 0x10040278U, +/*0325*/ 0xffffffffU, +/*0326*/ 0xffffffffU, +/*0327*/ 0xffffffffU, +/*0328*/ 0x18040278U, +/*0329*/ 0xffffffffU, +/*032a*/ 0xffffffffU, +/*032b*/ 0xffffffffU, +/*032c*/ 0x00040279U, +/*032d*/ 0x08050279U, +/*032e*/ 0x10070279U, +/*032f*/ 0x18080279U, +/*0330*/ 0x0010027aU, +/*0331*/ 0x1008027aU, +/*0332*/ 0x0010027bU, +/*0333*/ 0x1008027bU, +/*0334*/ 0x0010027cU, +/*0335*/ 0x1008027cU, +/*0336*/ 0x1808027cU, +/*0337*/ 0x0001027dU, +/*0338*/ 0x0801027dU, +/*0339*/ 0x1006027dU, +/*033a*/ 0x1806027dU, +/*033b*/ 0x0006027eU, +/*033c*/ 0x0801027eU, +/*033d*/ 0x1001027eU, +/*033e*/ 0x1803027eU, +/*033f*/ 0x000a027fU, +/*0340*/ 0x100a027fU, +/*0341*/ 0x000a0280U, +/*0342*/ 0xffffffffU, +/*0343*/ 0x100a0280U, +/*0344*/ 0x00040281U, +/*0345*/ 0x08010281U, +/*0346*/ 0x10040281U, +/*0347*/ 0xffffffffU, +/*0348*/ 0xffffffffU, +/*0349*/ 0xffffffffU, +/*034a*/ 0xffffffffU, +/*034b*/ 0xffffffffU, +/*034c*/ 0xffffffffU, +/*034d*/ 0x18070281U, +/*034e*/ 0x00070282U, +/*034f*/ 0x08050282U, +/*0350*/ 0x10050282U, +/*0351*/ 0xffffffffU, +/*0352*/ 0xffffffffU, +/*0353*/ 0xffffffffU, +/*0354*/ 0x18040282U, +/*0355*/ 0x00010283U, +/*0356*/ 0x08010283U, +/*0357*/ 0x10020283U, +/*0358*/ 0x18080283U, +/*0359*/ 0x00200284U, +/*035a*/ 0x00200285U, +/*035b*/ 0x00100286U, +/*035c*/ 0x10020286U, +/*035d*/ 0x18020286U, +/*035e*/ 0x00020287U, +/*035f*/ 0xffffffffU, +/*0360*/ 0x08010287U, +/*0361*/ 0x10010287U, +/*0362*/ 0x18020287U, +/*0363*/ 0x00080288U, +/*0364*/ 0x08080288U, +/*0365*/ 0x10080288U, +/*0366*/ 0x18080288U, +/*0367*/ 0x00080289U, +/*0368*/ 0x08080289U, +/*0369*/ 0xffffffffU, +/*036a*/ 0x10080289U, +/*036b*/ 0x18080289U, +/*036c*/ 0x0008028aU, +/*036d*/ 0x0808028aU, +/*036e*/ 0x1008028aU, +/*036f*/ 0x1808028aU, +/*0370*/ 0xffffffffU, +/*0371*/ 0x0008028bU, +/*0372*/ 0x0808028bU, +/*0373*/ 0x1008028bU, +/*0374*/ 0x1808028bU, +/*0375*/ 0x0008028cU, +/*0376*/ 0x0808028cU, +/*0377*/ 0xffffffffU, +/*0378*/ 0x1008028cU, +/*0379*/ 0x1808028cU, +/*037a*/ 0x0008028dU, +/*037b*/ 0x0808028dU, +/*037c*/ 0x1008028dU, +/*037d*/ 0x1808028dU, +/*037e*/ 0x0008028eU, +/*037f*/ 0xffffffffU, +/*0380*/ 0x0808028eU, +/*0381*/ 0x1008028eU, +/*0382*/ 0x1808028eU, +/*0383*/ 0x0008028fU, +/*0384*/ 0x0808028fU, +/*0385*/ 0x1008028fU, +/*0386*/ 0xffffffffU, +/*0387*/ 0x1808028fU, +/*0388*/ 0x00080290U, +/*0389*/ 0x08080290U, +/*038a*/ 0x10080290U, +/*038b*/ 0x18080290U, +/*038c*/ 0x00080291U, +/*038d*/ 0xffffffffU, +/*038e*/ 0x08080291U, +/*038f*/ 0x10080291U, +/*0390*/ 0x18080291U, +/*0391*/ 0x00080292U, +/*0392*/ 0x08080292U, +/*0393*/ 0x10080292U, +/*0394*/ 0x18080292U, +/*0395*/ 0xffffffffU, +/*0396*/ 0x00080293U, +/*0397*/ 0x08080293U, +/*0398*/ 0x10080293U, +/*0399*/ 0x18080293U, +/*039a*/ 0x00080294U, +/*039b*/ 0x08080294U, +/*039c*/ 0xffffffffU, +/*039d*/ 0x10080294U, +/*039e*/ 0x18080294U, +/*039f*/ 0x00080295U, +/*03a0*/ 0x08080295U, +/*03a1*/ 0x10080295U, +/*03a2*/ 0x18080295U, +/*03a3*/ 0xffffffffU, +/*03a4*/ 0x00080296U, +/*03a5*/ 0x08080296U, +/*03a6*/ 0x10080296U, +/*03a7*/ 0x18080296U, +/*03a8*/ 0x00080297U, +/*03a9*/ 0x08080297U, +/*03aa*/ 0x10080297U, +/*03ab*/ 0xffffffffU, +/*03ac*/ 0x18080297U, +/*03ad*/ 0x00080298U, +/*03ae*/ 0x08080298U, +/*03af*/ 0x10080298U, +/*03b0*/ 0x18080298U, +/*03b1*/ 0x00080299U, +/*03b2*/ 0xffffffffU, +/*03b3*/ 0x08080299U, +/*03b4*/ 0x10080299U, +/*03b5*/ 0x18080299U, +/*03b6*/ 0x0008029aU, +/*03b7*/ 0x0808029aU, +/*03b8*/ 0x1008029aU, +/*03b9*/ 0xffffffffU, +/*03ba*/ 0x1808029aU, +/*03bb*/ 0x0002029bU, +/*03bc*/ 0x0803029bU, +/*03bd*/ 0x100a029bU, +/*03be*/ 0x000a029cU, +/*03bf*/ 0x100a029cU, +/*03c0*/ 0x0005029dU, +/*03c1*/ 0x0808029dU, +/*03c2*/ 0x1008029dU, +/*03c3*/ 0x1808029dU, +/*03c4*/ 0x0006029eU, +/*03c5*/ 0x0806029eU, +/*03c6*/ 0x0011029fU, +/*03c7*/ 0x1808029fU, +/*03c8*/ 0x000402a0U, +/*03c9*/ 0x080602a0U, +/*03ca*/ 0xffffffffU, +/*03cb*/ 0x100602a0U, +/*03cc*/ 0x180802a0U, +/*03cd*/ 0xffffffffU, +/*03ce*/ 0x000802a1U, +/*03cf*/ 0x080802a1U, +/*03d0*/ 0x100802a1U, +/*03d1*/ 0x180602a1U, +/*03d2*/ 0x000602a2U, +/*03d3*/ 0x081102a2U, +/*03d4*/ 0x000802a3U, +/*03d5*/ 0x080402a3U, +/*03d6*/ 0x100602a3U, +/*03d7*/ 0xffffffffU, +/*03d8*/ 0x180602a3U, +/*03d9*/ 0x000802a4U, +/*03da*/ 0xffffffffU, +/*03db*/ 0x080802a4U, +/*03dc*/ 0x100802a4U, +/*03dd*/ 0x180802a4U, +/*03de*/ 0x000602a5U, +/*03df*/ 0x080602a5U, +/*03e0*/ 0x001102a6U, +/*03e1*/ 0x180802a6U, +/*03e2*/ 0x000402a7U, +/*03e3*/ 0x080602a7U, +/*03e4*/ 0xffffffffU, +/*03e5*/ 0x100602a7U, +/*03e6*/ 0x180802a7U, +/*03e7*/ 0xffffffffU, +/*03e8*/ 0x000402a8U, +/*03e9*/ 0x080402a8U, +/*03ea*/ 0x100402a8U, +/*03eb*/ 0x180402a8U, +/*03ec*/ 0x000402a9U, +/*03ed*/ 0x080402a9U, +/*03ee*/ 0x100402a9U, +/*03ef*/ 0x180402a9U, +/*03f0*/ 0x000402aaU, +/*03f1*/ 0x080402aaU, +/*03f2*/ 0x100402aaU, +/*03f3*/ 0x180402aaU, +/*03f4*/ 0x000402abU, +/*03f5*/ 0x080402abU, +/*03f6*/ 0x100402abU, +/*03f7*/ 0x180402abU, +/*03f8*/ 0x000402acU, +/*03f9*/ 0x080402acU, +/*03fa*/ 0x100402acU, +/*03fb*/ 0x180402acU, +/*03fc*/ 0x001202adU, +/*03fd*/ 0x001102aeU, +/*03fe*/ 0x001202afU, +/*03ff*/ 0x002002b0U, +/*0400*/ 0x002002b1U, +/*0401*/ 0x002002b2U, +/*0402*/ 0x002002b3U, +/*0403*/ 0x002002b4U, +/*0404*/ 0x002002b5U, +/*0405*/ 0x002002b6U, +/*0406*/ 0x002002b7U, +/*0407*/ 0x002002b8U, +/*0408*/ 0x000202b9U, +/*0409*/ 0x080502b9U, +/*040a*/ 0x100502b9U, +/*040b*/ 0x180102b9U, +/*040c*/ 0x000402baU, +/*040d*/ 0x080402baU, +/*040e*/ 0x100402baU, +/*040f*/ 0x180402baU, +/*0410*/ 0x000402bbU, +/*0411*/ 0x080402bbU, +/*0412*/ 0x100402bbU, +/*0413*/ 0x180402bbU, +/*0414*/ 0xffffffffU, +/*0415*/ 0xffffffffU, +/*0416*/ 0xffffffffU, +/*0417*/ 0xffffffffU, +/*0418*/ 0xffffffffU, +/*0419*/ 0xffffffffU, +/*041a*/ 0x000402bcU, +/*041b*/ 0x080402bcU, +/*041c*/ 0x100402bcU, +/*041d*/ 0x180402bcU, +/*041e*/ 0x000402bdU, +/*041f*/ 0x080402bdU, +/*0420*/ 0x100402bdU, +/*0421*/ 0x180402bdU, +/*0422*/ 0x000102beU, +/*0423*/ 0x080202beU, +/*0424*/ 0x100202beU, +/*0425*/ 0x180202beU, +/*0426*/ 0x000202bfU, +/*0427*/ 0x080102bfU, +/*0428*/ 0x100402bfU, +/*0429*/ 0x001002c0U, +/*042a*/ 0x002002c1U, +/*042b*/ 0x001002c2U, +/*042c*/ 0x002002c3U, +/*042d*/ 0x001002c4U, +/*042e*/ 0x002002c5U, +/*042f*/ 0x000702c6U, +/*0430*/ 0x080102c6U, +/*0431*/ 0x100202c6U, +/*0432*/ 0x180602c6U, +/*0433*/ 0x000102c7U, +/*0434*/ 0x080102c7U, +/*0435*/ 0x002002c8U, +/*0436*/ 0x000202c9U, +/*0437*/ 0x002002caU, +/*0438*/ 0x002002cbU, +/*0439*/ 0x000c02ccU, +/*043a*/ 0x100c02ccU, +/*043b*/ 0x002002cdU, +/*043c*/ 0x000302ceU, +/*043d*/ 0x002002cfU, +/*043e*/ 0x000302d0U, +/*043f*/ 0x002002d1U, +/*0440*/ 0x000302d2U, +/*0441*/ 0x002002d3U, +/*0442*/ 0x000302d4U, +/*0443*/ 0x002002d5U, +/*0444*/ 0x000302d6U, +/*0445*/ 0x002002d7U, +/*0446*/ 0x000302d8U, +/*0447*/ 0x002002d9U, +/*0448*/ 0x000302daU, +/*0449*/ 0x002002dbU, +/*044a*/ 0x000302dcU, +/*044b*/ 0x002002ddU, +/*044c*/ 0x000302deU, +/*044d*/ 0x002002dfU, +/*044e*/ 0x000302e0U, +/*044f*/ 0x080302e0U, +/*0450*/ 0x100202e0U, +/*0451*/ 0x180202e0U, +/*0452*/ 0x002002e1U, +/*0453*/ 0x002002e2U, +/*0454*/ 0x002002e3U, +/*0455*/ 0x002002e4U, +/*0456*/ 0x000402e5U, +/*0457*/ 0x001e02e6U, +/*0458*/ 0x001e02e7U, +/*0459*/ 0x001e02e8U, +/*045a*/ 0x001e02e9U, +/*045b*/ 0x001e02eaU, +/*045c*/ 0x001e02ebU, +/*045d*/ 0x001e02ecU, +/*045e*/ 0x001e02edU, +/*045f*/ 0x000402eeU, +/*0460*/ 0xffffffffU, +/*0461*/ 0xffffffffU, +/*0462*/ 0xffffffffU, +/*0463*/ 0xffffffffU, +/*0464*/ 0x080402eeU, +/*0465*/ 0x100102eeU, +/*0466*/ 0x180802eeU, +/*0467*/ 0x000402efU, +/*0468*/ 0x080102efU, +/*0469*/ 0x100802efU, +/*046a*/ 0x180402efU, +/*046b*/ 0x000102f0U, +/*046c*/ 0x080802f0U, +/*046d*/ 0x100402f0U, +/*046e*/ 0x180102f0U, +/*046f*/ 0x000802f1U, +/*0470*/ 0x080402f1U, +/*0471*/ 0x100102f1U, +/*0472*/ 0x180802f1U, +/*0473*/ 0x000402f2U, +/*0474*/ 0x080102f2U, +/*0475*/ 0x100802f2U, +/*0476*/ 0x180402f2U, +/*0477*/ 0x000102f3U, +/*0478*/ 0x080802f3U, +/*0479*/ 0x100402f3U, +/*047a*/ 0x180102f3U, +/*047b*/ 0x000802f4U, +/*047c*/ 0x080802f4U, +/*047d*/ 0x100102f4U, +/*047e*/ 0x180502f4U, +/*047f*/ 0xffffffffU, +/*0480*/ 0xffffffffU, +/*0481*/ 0xffffffffU, +/*0482*/ 0xffffffffU, +/*0483*/ 0xffffffffU, +/*0484*/ 0xffffffffU, +/*0485*/ 0xffffffffU, +/*0486*/ 0xffffffffU, +/*0487*/ 0xffffffffU, +/*0488*/ 0xffffffffU, +/*0489*/ 0xffffffffU, +/*048a*/ 0xffffffffU, +/*048b*/ 0xffffffffU, +/*048c*/ 0xffffffffU, +/*048d*/ 0xffffffffU, +/*048e*/ 0xffffffffU, +/*048f*/ 0xffffffffU, +/*0490*/ 0xffffffffU, +/*0491*/ 0xffffffffU, +/*0492*/ 0xffffffffU, +/*0493*/ 0xffffffffU, +/*0494*/ 0xffffffffU, + }, + { +/*0000*/ 0x00200800U, +/*0001*/ 0x00040801U, +/*0002*/ 0x080b0801U, +/*0003*/ 0x000a0802U, +/*0004*/ 0x10020802U, +/*0005*/ 0x18010802U, +/*0006*/ 0x00060803U, +/*0007*/ 0x08060803U, +/*0008*/ 0x10060803U, +/*0009*/ 0x18060803U, +/*000a*/ 0x00060804U, +/*000b*/ 0x08060804U, +/*000c*/ 0x10050804U, +/*000d*/ 0x18060804U, +/*000e*/ 0x00060805U, +/*000f*/ 0x08040805U, +/*0010*/ 0x10030805U, +/*0011*/ 0x00180806U, +/*0012*/ 0x18030806U, +/*0013*/ 0x00180807U, +/*0014*/ 0x18020807U, +/*0015*/ 0x0801085eU, +/*0016*/ 0x00020808U, +/*0017*/ 0x08010808U, +/*0018*/ 0x10010808U, +/*0019*/ 0x18020808U, +/*001a*/ 0x00050809U, +/*001b*/ 0x08050809U, +/*001c*/ 0x10040809U, +/*001d*/ 0xffffffffU, +/*001e*/ 0x18040809U, +/*001f*/ 0x0002080aU, +/*0020*/ 0x0805080aU, +/*0021*/ 0x1009080aU, +/*0022*/ 0x0001080bU, +/*0023*/ 0x0020080cU, +/*0024*/ 0x001c080dU, +/*0025*/ 0x0001080eU, +/*0026*/ 0x0807080eU, +/*0027*/ 0x1009080eU, +/*0028*/ 0x000a080fU, +/*0029*/ 0x1005080fU, +/*002a*/ 0x1801080fU, +/*002b*/ 0x10010810U, +/*002c*/ 0x18020810U, +/*002d*/ 0x00090810U, +/*002e*/ 0x00090811U, +/*002f*/ 0x10020811U, +/*0030*/ 0x00200812U, +/*0031*/ 0x00010813U, +/*0032*/ 0x08020813U, +/*0033*/ 0x00200814U, +/*0034*/ 0x00200815U, +/*0035*/ 0x00200816U, +/*0036*/ 0x00200817U, +/*0037*/ 0xffffffffU, +/*0038*/ 0xffffffffU, +/*0039*/ 0xffffffffU, +/*003a*/ 0xffffffffU, +/*003b*/ 0x00030818U, +/*003c*/ 0x08010818U, +/*003d*/ 0x10040818U, +/*003e*/ 0x18030818U, +/*003f*/ 0x00040819U, +/*0040*/ 0x08040819U, +/*0041*/ 0x10040819U, +/*0042*/ 0x18040819U, +/*0043*/ 0x0001081aU, +/*0044*/ 0x0801081aU, +/*0045*/ 0x1006081aU, +/*0046*/ 0x1804081aU, +/*0047*/ 0x0008081bU, +/*0048*/ 0x0806081bU, +/*0049*/ 0x1004081bU, +/*004a*/ 0x1806081bU, +/*004b*/ 0x0004081cU, +/*004c*/ 0x0802081cU, +/*004d*/ 0x1005081cU, +/*004e*/ 0x1808081cU, +/*004f*/ 0xffffffffU, +/*0050*/ 0x0006081dU, +/*0051*/ 0x0803081dU, +/*0052*/ 0x100b081dU, +/*0053*/ 0x0004081eU, +/*0054*/ 0x0804081eU, +/*0055*/ 0x1004081eU, +/*0056*/ 0x1801081eU, +/*0057*/ 0xffffffffU, +/*0058*/ 0x0009081fU, +/*0059*/ 0x00200820U, +/*005a*/ 0x00200821U, +/*005b*/ 0x00200822U, +/*005c*/ 0x00200823U, +/*005d*/ 0x00100824U, +/*005e*/ 0xffffffffU, +/*005f*/ 0x10010824U, +/*0060*/ 0x18060824U, +/*0061*/ 0x00080825U, +/*0062*/ 0x00200826U, +/*0063*/ 0x00100827U, +/*0064*/ 0x100b0827U, +/*0065*/ 0x00070828U, +/*0066*/ 0x08070828U, +/*0067*/ 0x10090828U, +/*0068*/ 0x00090829U, +/*0069*/ 0x100b0829U, +/*006a*/ 0x0007082aU, +/*006b*/ 0x0808082aU, +/*006c*/ 0x1009082aU, +/*006d*/ 0x0003082bU, +/*006e*/ 0x080a082bU, +/*006f*/ 0x000a082cU, +/*0070*/ 0x0011082dU, +/*0071*/ 0x000a082eU, +/*0072*/ 0x100a082eU, +/*0073*/ 0x0010082fU, +/*0074*/ 0x100e082fU, +/*0075*/ 0x000e0830U, +/*0076*/ 0x00120831U, +/*0077*/ 0x000a0832U, +/*0078*/ 0x100a0832U, +/*0079*/ 0x00020833U, +/*007a*/ 0x00200834U, +/*007b*/ 0x000b0835U, +/*007c*/ 0x100b0835U, +/*007d*/ 0x00200836U, +/*007e*/ 0x00130837U, +/*007f*/ 0x00200838U, +/*0080*/ 0x00200839U, +/*0081*/ 0x0008083aU, +/*0082*/ 0x0801083aU, +/*0083*/ 0x1001083aU, +/*0084*/ 0x1801083aU, +/*0085*/ 0x0008083bU, +/*0086*/ 0x080c083bU, +/*0087*/ 0x000c083cU, +/*0088*/ 0x100c083cU, +/*0089*/ 0x000c083dU, +/*008a*/ 0x100c083dU, +/*008b*/ 0x000c083eU, +/*008c*/ 0x100c083eU, +/*008d*/ 0x000c083fU, +/*008e*/ 0x100c083fU, +/*008f*/ 0x000c0840U, +/*0090*/ 0x100c0840U, +/*0091*/ 0x000b0841U, +/*0092*/ 0x10090841U, +/*0093*/ 0x00010842U, +/*0094*/ 0x000b0843U, +/*0095*/ 0x100b0843U, +/*0096*/ 0x000b0844U, +/*0097*/ 0x100b0844U, +/*0098*/ 0x000b0845U, +/*0099*/ 0x100b0845U, +/*009a*/ 0x000b0846U, +/*009b*/ 0x100b0846U, +/*009c*/ 0x000b0847U, +/*009d*/ 0x100a0847U, +/*009e*/ 0x00020848U, +/*009f*/ 0x080a0848U, +/*00a0*/ 0x000a0849U, +/*00a1*/ 0x100a0849U, +/*00a2*/ 0x000a084aU, +/*00a3*/ 0x100a084aU, +/*00a4*/ 0x000a084bU, +/*00a5*/ 0x100a084bU, +/*00a6*/ 0x000a084cU, +/*00a7*/ 0x100a084cU, +/*00a8*/ 0x000a084dU, +/*00a9*/ 0x100a084dU, +/*00aa*/ 0x000a084eU, +/*00ab*/ 0x100a084eU, +/*00ac*/ 0x000a084fU, +/*00ad*/ 0x100a084fU, +/*00ae*/ 0x000a0850U, +/*00af*/ 0x100a0850U, +/*00b0*/ 0x000a0851U, +/*00b1*/ 0x100a0851U, +/*00b2*/ 0x000a0852U, +/*00b3*/ 0x100a0852U, +/*00b4*/ 0x000a0853U, +/*00b5*/ 0x100a0853U, +/*00b6*/ 0x000a0854U, +/*00b7*/ 0x100a0854U, +/*00b8*/ 0x000a0855U, +/*00b9*/ 0x100a0855U, +/*00ba*/ 0x000a0856U, +/*00bb*/ 0x10040856U, +/*00bc*/ 0x18030856U, +/*00bd*/ 0x000a0857U, +/*00be*/ 0x100a0857U, +/*00bf*/ 0x00010858U, +/*00c0*/ 0x080a0858U, +/*00c1*/ 0x18040858U, +/*00c2*/ 0x000b0859U, +/*00c3*/ 0x100a0859U, +/*00c4*/ 0x0003085aU, +/*00c5*/ 0x0008085bU, +/*00c6*/ 0x0808085bU, +/*00c7*/ 0x1008085bU, +/*00c8*/ 0x1808085bU, +/*00c9*/ 0x0008085cU, +/*00ca*/ 0x0808085cU, +/*00cb*/ 0x1008085cU, +/*00cc*/ 0x1801085cU, +/*00cd*/ 0x0008085dU, +/*00ce*/ 0x0808085dU, +/*00cf*/ 0x1002085dU, +/*00d0*/ 0x1802085dU, +/*00d1*/ 0x0005085eU, +/*00d2*/ 0x1005085eU, +/*00d3*/ 0x1805085eU, +/*00d4*/ 0x0004085fU, +/*00d5*/ 0x080b085fU, +/*00d6*/ 0x1806085fU, +/*00d7*/ 0x00080860U, +/*00d8*/ 0x08080860U, +/*00d9*/ 0x10040860U, +/*00da*/ 0x18040860U, +/*00db*/ 0x00060861U, +/*00dc*/ 0x08040861U, +/*00dd*/ 0x10050861U, +/*00de*/ 0x000a0862U, +/*00df*/ 0x100a0862U, +/*00e0*/ 0x00080863U, +/*00e1*/ 0x08010863U, +/*00e2*/ 0x10040863U, +/*00e3*/ 0x00020864U, +/*00e4*/ 0x08030864U, +/*00e5*/ 0x00050a00U, +/*00e6*/ 0x08050a00U, +/*00e7*/ 0x10050a00U, +/*00e8*/ 0x18050a00U, +/*00e9*/ 0x00050a01U, +/*00ea*/ 0x08050a01U, +/*00eb*/ 0x100b0a01U, +/*00ec*/ 0x00010a02U, +/*00ed*/ 0x08030a02U, +/*00ee*/ 0x00200a03U, +/*00ef*/ 0x00100a04U, +/*00f0*/ 0x10040a04U, +/*00f1*/ 0x000b0a05U, +/*00f2*/ 0x10070a05U, +/*00f3*/ 0x00090a06U, +/*00f4*/ 0x10030a06U, +/*00f5*/ 0x18030a06U, +/*00f6*/ 0x00010a07U, +/*00f7*/ 0x08010a07U, +/*00f8*/ 0x10070a07U, +/*00f9*/ 0x18070a07U, +/*00fa*/ 0x00050a08U, +/*00fb*/ 0x08010a08U, +/*00fc*/ 0x10020a08U, +/*00fd*/ 0x18030a08U, +/*00fe*/ 0x00010a09U, +/*00ff*/ 0x080f0a09U, +/*0100*/ 0x00200a0aU, +/*0101*/ 0x00200a0bU, +/*0102*/ 0x000b0a0cU, +/*0103*/ 0x100b0a0cU, +/*0104*/ 0x000b0a0dU, +/*0105*/ 0x00180a0eU, +/*0106*/ 0x00180a0fU, +/*0107*/ 0xffffffffU, +/*0108*/ 0xffffffffU, +/*0109*/ 0xffffffffU, +/*010a*/ 0xffffffffU, +/*010b*/ 0xffffffffU, +/*010c*/ 0x18020a0fU, +/*010d*/ 0x00020a10U, +/*010e*/ 0x08040a10U, +/*010f*/ 0x10040a10U, +/*0110*/ 0x18010a10U, +/*0111*/ 0x00010a11U, +/*0112*/ 0x08010a11U, +/*0113*/ 0x10030a11U, +/*0114*/ 0x00200a12U, +/*0115*/ 0x00200a13U, +/*0116*/ 0xffffffffU, +/*0117*/ 0x00140a14U, +/*0118*/ 0x00140a15U, +/*0119*/ 0x00140a16U, +/*011a*/ 0x00140a17U, +/*011b*/ 0x00140a18U, +/*011c*/ 0x00140a19U, +/*011d*/ 0x00140a1aU, +/*011e*/ 0x00140a1bU, +/*011f*/ 0x001e0a1cU, +/*0120*/ 0x000a0a1dU, +/*0121*/ 0x10060a1dU, +/*0122*/ 0x18060a1dU, +/*0123*/ 0x00060a1eU, +/*0124*/ 0x08060a1eU, +/*0125*/ 0x10060a1eU, +/*0126*/ 0x00080a1fU, +/*0127*/ 0x080b0a1fU, +/*0128*/ 0x000b0a20U, +/*0129*/ 0x100b0a20U, +/*012a*/ 0x000b0a21U, +/*012b*/ 0x100b0a21U, +/*012c*/ 0x000b0a22U, +/*012d*/ 0x10040a22U, +/*012e*/ 0x000b0a23U, +/*012f*/ 0x10060a23U, +/*0130*/ 0x18080a23U, +/*0131*/ 0x00080a24U, +/*0132*/ 0x08040a24U, +/*0133*/ 0x00020b80U, +/*0134*/ 0x00010b81U, +/*0135*/ 0x08010b81U, +/*0136*/ 0x10020b81U, +/*0137*/ 0x18050b81U, +/*0138*/ 0x00050b82U, +/*0139*/ 0x08050b82U, +/*013a*/ 0x10050b82U, +/*013b*/ 0x000b0b83U, +/*013c*/ 0x10050b83U, +/*013d*/ 0x18010b83U, +/*013e*/ 0x00010b84U, +/*013f*/ 0x08010b84U, +/*0140*/ 0x10010b84U, +/*0141*/ 0x18010b84U, +/*0142*/ 0x00040b85U, +/*0143*/ 0x080b0b85U, +/*0144*/ 0x000b0b86U, +/*0145*/ 0x100b0b86U, +/*0146*/ 0x00040b87U, +/*0147*/ 0x080b0b87U, +/*0148*/ 0x18040b87U, +/*0149*/ 0x00010b88U, +/*014a*/ 0x08010b88U, +/*014b*/ 0x10010b88U, +/*014c*/ 0x00200b89U, +/*014d*/ 0x00200b8aU, +/*014e*/ 0x00080b8bU, +/*014f*/ 0x080a0b8bU, +/*0150*/ 0x18050b8bU, +/*0151*/ 0x000b0b8cU, +/*0152*/ 0x10030b8cU, +/*0153*/ 0x18030b8cU, +/*0154*/ 0x00010b8dU, +/*0155*/ 0x08020b8dU, +/*0156*/ 0x10010b8dU, +/*0157*/ 0x18010b8dU, +/*0158*/ 0x00010b8eU, +/*0159*/ 0xffffffffU, +/*015a*/ 0x08010b8eU, +/*015b*/ 0x18040b8eU, +/*015c*/ 0x00040b8fU, +/*015d*/ 0x08040b8fU, +/*015e*/ 0x10040b8fU, +/*015f*/ 0x18010b8fU, +/*0160*/ 0x00010b90U, +/*0161*/ 0x08010b90U, +/*0162*/ 0x00200b91U, +/*0163*/ 0x00200b92U, +/*0164*/ 0x00200b93U, +/*0165*/ 0x00200b94U, +/*0166*/ 0xffffffffU, +/*0167*/ 0x10010b8eU, +/*0168*/ 0x000d0b96U, +/*0169*/ 0x100d0b96U, +/*016a*/ 0x000d0b97U, +/*016b*/ 0x00050b98U, +/*016c*/ 0x00010b99U, +/*016d*/ 0x080e0b99U, +/*016e*/ 0x000e0b9aU, +/*016f*/ 0x100e0b9aU, +/*0170*/ 0x000e0b9bU, +/*0171*/ 0x100e0b9bU, +/*0172*/ 0x00040b9cU, +/*0173*/ 0x08040b9cU, +/*0174*/ 0x10040b9cU, +/*0175*/ 0x18040b9cU, +/*0176*/ 0x00040b9dU, +/*0177*/ 0x080b0b9dU, +/*0178*/ 0x000b0b9eU, +/*0179*/ 0x100b0b9eU, +/*017a*/ 0x000b0b9fU, +/*017b*/ 0x00040ba0U, +/*017c*/ 0x08040ba0U, +/*017d*/ 0x10040ba0U, +/*017e*/ 0x18040ba0U, +/*017f*/ 0x000d0ba1U, +/*0180*/ 0x100d0ba1U, +/*0181*/ 0x000d0ba2U, +/*0182*/ 0x10100ba2U, +/*0183*/ 0x00080b95U, +/*0184*/ 0x08080b95U, +/*0185*/ 0x00100ba3U, +/*0186*/ 0x10100ba3U, +/*0187*/ 0x00100ba4U, +/*0188*/ 0x10100ba4U, +/*0189*/ 0x00100ba5U, +/*018a*/ 0x10030ba5U, +/*018b*/ 0x18040ba5U, +/*018c*/ 0x00010ba6U, +/*018d*/ 0x08080ba6U, +/*018e*/ 0x10010ba6U, +/*018f*/ 0x000a0ba7U, +/*0190*/ 0x10010ba7U, +/*0191*/ 0x00140ba8U, +/*0192*/ 0x000b0ba9U, +/*0193*/ 0x100c0ba9U, +/*0194*/ 0x00120baaU, +/*0195*/ 0x00140babU, +/*0196*/ 0x00120bacU, +/*0197*/ 0x00110badU, +/*0198*/ 0x00110baeU, +/*0199*/ 0x00120bafU, +/*019a*/ 0x00120bb0U, +/*019b*/ 0x00120bb1U, +/*019c*/ 0x00120bb2U, +/*019d*/ 0x00120bb3U, +/*019e*/ 0x00120bb4U, +/*019f*/ 0x00120bb5U, +/*01a0*/ 0x00120bb6U, +/*01a1*/ 0x00120bb7U, +/*01a2*/ 0x00120bb8U, +/*01a3*/ 0x000e0bb9U, +/*01a4*/ 0x100d0bb9U, +/*01a5*/ 0x00200bbaU, +/*01a6*/ 0x00170bbbU, +/*01a7*/ 0x000d0bbcU, +/*01a8*/ 0x10010bbcU, +/*01a9*/ 0x18010bbcU, +/*01aa*/ 0x00200bbdU, +/*01ab*/ 0x00080bbeU, +/*01ac*/ 0x08030bbeU, +/*01ad*/ 0x10030bbeU, +/*01ae*/ 0x00180bbfU, +/*01af*/ 0x00180bc0U, +/*01b0*/ 0x18070bc0U, +/*01b1*/ 0x00070bc1U, +/*01b2*/ 0x08080bc1U, +/*01b3*/ 0x10080bc1U, +/*01b4*/ 0x18080bc1U, +/*01b5*/ 0x00010bc2U, +/*01b6*/ 0x08010bc2U, +/*01b7*/ 0x00200bc3U, +/*01b8*/ 0x00070bc4U, +/*01b9*/ 0x08140bc4U, +/*01ba*/ 0x00140bc5U, +/*01bb*/ 0x00190bc6U, +/*01bc*/ 0x00170bc7U, +/*01bd*/ 0x00110bc8U, +/*01be*/ 0x00110bc9U, +/*01bf*/ 0x00100bcaU, +/*01c0*/ 0x10010bcaU, +/*01c1*/ 0x18010bcaU, +/*01c2*/ 0x00020bcbU, +/*01c3*/ 0x08040bcbU, +/*01c4*/ 0x10090bcbU, +/*01c5*/ 0x00070bccU, +/*01c6*/ 0x08040bccU, +/*01c7*/ 0x00200bcdU, +/*01c8*/ 0x00010bceU, +/*01c9*/ 0x08020bceU, +/*01ca*/ 0x10060bceU, +/*01cb*/ 0x00100bcfU, +/*01cc*/ 0x10010bcfU, +/*01cd*/ 0x00200bd0U, +/*01ce*/ 0x00080bd1U, +/*01cf*/ 0x08010bd1U, +/*01d0*/ 0x10050bd1U, +/*01d1*/ 0x18030bd1U, +/*01d2*/ 0x00020bd2U, +/*01d3*/ 0xffffffffU, +/*01d4*/ 0x00200bd3U, +/*01d5*/ 0x000b0bd4U, +/*01d6*/ 0xffffffffU, +/*01d7*/ 0x10030bd4U, +/*01d8*/ 0x18080bd4U, +/*01d9*/ 0x00020bd5U, +/*01da*/ 0x080c0bd5U, +/*01db*/ 0x18040bd5U, +/*01dc*/ 0x00010bd6U, +/*01dd*/ 0x08050bd6U, +/*01de*/ 0x00010200U, +/*01df*/ 0x08040200U, +/*01e0*/ 0x10100200U, +/*01e1*/ 0x00010201U, +/*01e2*/ 0x08010201U, +/*01e3*/ 0x10010201U, +/*01e4*/ 0x18010201U, +/*01e5*/ 0x00100202U, +/*01e6*/ 0x10080202U, +/*01e7*/ 0x18010202U, +/*01e8*/ 0x00200203U, +/*01e9*/ 0x00200204U, +/*01ea*/ 0x00200205U, +/*01eb*/ 0x00200206U, +/*01ec*/ 0x00020207U, +/*01ed*/ 0x08010207U, +/*01ee*/ 0x10010207U, +/*01ef*/ 0x00200208U, +/*01f0*/ 0x00140209U, +/*01f1*/ 0x0020020aU, +/*01f2*/ 0x0014020bU, +/*01f3*/ 0x0020020cU, +/*01f4*/ 0x0014020dU, +/*01f5*/ 0x0014020eU, +/*01f6*/ 0x0020020fU, +/*01f7*/ 0x00200210U, +/*01f8*/ 0x00200211U, +/*01f9*/ 0x00200212U, +/*01fa*/ 0x00140213U, +/*01fb*/ 0x00200214U, +/*01fc*/ 0x00200215U, +/*01fd*/ 0x00200216U, +/*01fe*/ 0x00200217U, +/*01ff*/ 0x00140218U, +/*0200*/ 0x00200219U, +/*0201*/ 0x0020021aU, +/*0202*/ 0x0020021bU, +/*0203*/ 0x0020021cU, +/*0204*/ 0x0009021dU, +/*0205*/ 0x1001021dU, +/*0206*/ 0x0020021eU, +/*0207*/ 0x0005021fU, +/*0208*/ 0x0801021fU, +/*0209*/ 0x1008021fU, +/*020a*/ 0x1808021fU, +/*020b*/ 0x001e0220U, +/*020c*/ 0x001e0221U, +/*020d*/ 0x001e0222U, +/*020e*/ 0x001e0223U, +/*020f*/ 0x001e0224U, +/*0210*/ 0x001e0225U, +/*0211*/ 0x001e0226U, +/*0212*/ 0x001e0227U, +/*0213*/ 0x001e0228U, +/*0214*/ 0x001e0229U, +/*0215*/ 0x001e022aU, +/*0216*/ 0x001e022bU, +/*0217*/ 0x001e022cU, +/*0218*/ 0x001e022dU, +/*0219*/ 0x001e022eU, +/*021a*/ 0x001e022fU, +/*021b*/ 0x00010230U, +/*021c*/ 0x08010230U, +/*021d*/ 0x10010230U, +/*021e*/ 0x18040230U, +/*021f*/ 0x00080231U, +/*0220*/ 0x08080231U, +/*0221*/ 0x10080231U, +/*0222*/ 0x18040231U, +/*0223*/ 0x00070232U, +/*0224*/ 0x08060232U, +/*0225*/ 0x10070232U, +/*0226*/ 0x18070232U, +/*0227*/ 0x00060233U, +/*0228*/ 0x08070233U, +/*0229*/ 0x10070233U, +/*022a*/ 0x18060233U, +/*022b*/ 0x00070234U, +/*022c*/ 0x08020234U, +/*022d*/ 0x10010234U, +/*022e*/ 0x18010234U, +/*022f*/ 0x000a0235U, +/*0230*/ 0x00140236U, +/*0231*/ 0x000a0237U, +/*0232*/ 0x00140238U, +/*0233*/ 0x000a0239U, +/*0234*/ 0x0014023aU, +/*0235*/ 0xffffffffU, +/*0236*/ 0xffffffffU, +/*0237*/ 0x0005023bU, +/*0238*/ 0x0001023cU, +/*0239*/ 0x1001023cU, +/*023a*/ 0x1801023cU, +/*023b*/ 0x0001023dU, +/*023c*/ 0x0801023dU, +/*023d*/ 0x1001023dU, +/*023e*/ 0x1801023dU, +/*023f*/ 0x0002023eU, +/*0240*/ 0x0802023eU, +/*0241*/ 0x1002023eU, +/*0242*/ 0x1802023eU, +/*0243*/ 0x0002023fU, +/*0244*/ 0x0803023fU, +/*0245*/ 0x1001023fU, +/*0246*/ 0x1801023fU, +/*0247*/ 0x00010240U, +/*0248*/ 0x08010240U, +/*0249*/ 0x10010240U, +/*024a*/ 0x18020240U, +/*024b*/ 0x00010241U, +/*024c*/ 0x08010241U, +/*024d*/ 0x10010241U, +/*024e*/ 0x18020241U, +/*024f*/ 0x00010242U, +/*0250*/ 0x08010242U, +/*0251*/ 0x10010242U, +/*0252*/ 0x18020242U, +/*0253*/ 0x00010243U, +/*0254*/ 0x08010243U, +/*0255*/ 0x10010243U, +/*0256*/ 0x18020243U, +/*0257*/ 0xffffffffU, +/*0258*/ 0x00010244U, +/*0259*/ 0x08010244U, +/*025a*/ 0x10010244U, +/*025b*/ 0x18010244U, +/*025c*/ 0x00010245U, +/*025d*/ 0x08010245U, +/*025e*/ 0x10010245U, +/*025f*/ 0x18010245U, +/*0260*/ 0x00040246U, +/*0261*/ 0x08040246U, +/*0262*/ 0x10040246U, +/*0263*/ 0x18010246U, +/*0264*/ 0x00020247U, +/*0265*/ 0x08060247U, +/*0266*/ 0x10060247U, +/*0267*/ 0x18020247U, +/*0268*/ 0x00020248U, +/*0269*/ 0x08020248U, +/*026a*/ 0xffffffffU, +/*026b*/ 0x10100248U, +/*026c*/ 0x00010249U, +/*026d*/ 0x08010249U, +/*026e*/ 0x10010249U, +/*026f*/ 0x18040249U, +/*0270*/ 0x0001024aU, +/*0271*/ 0x0804024aU, +/*0272*/ 0x1003024aU, +/*0273*/ 0x1808024aU, +/*0274*/ 0x000a024bU, +/*0275*/ 0x100a024bU, +/*0276*/ 0x000a024cU, +/*0277*/ 0xffffffffU, +/*0278*/ 0x0020024dU, +/*0279*/ 0x0020024eU, +/*027a*/ 0x0005024fU, +/*027b*/ 0x1801023aU, +/*027c*/ 0x0805023cU, +/*027d*/ 0x0808024fU, +/*027e*/ 0x1001024fU, +/*027f*/ 0x1808024fU, +/*0280*/ 0x00010250U, +/*0281*/ 0x08080250U, +/*0282*/ 0x10010250U, +/*0283*/ 0x18040250U, +/*0284*/ 0x00040251U, +/*0285*/ 0x08040251U, +/*0286*/ 0x10040251U, +/*0287*/ 0x18040251U, +/*0288*/ 0x00040252U, +/*0289*/ 0x08040252U, +/*028a*/ 0x10040252U, +/*028b*/ 0x18040252U, +/*028c*/ 0x00040253U, +/*028d*/ 0x08010253U, +/*028e*/ 0x10040253U, +/*028f*/ 0x18040253U, +/*0290*/ 0x00040254U, +/*0291*/ 0x08040254U, +/*0292*/ 0x10040254U, +/*0293*/ 0x18040254U, +/*0294*/ 0x00060255U, +/*0295*/ 0x08060255U, +/*0296*/ 0x10060255U, +/*0297*/ 0x18060255U, +/*0298*/ 0x00060256U, +/*0299*/ 0x08060256U, +/*029a*/ 0x10040256U, +/*029b*/ 0x18010256U, +/*029c*/ 0x00010257U, +/*029d*/ 0x08020257U, +/*029e*/ 0x00200258U, +/*029f*/ 0x00200259U, +/*02a0*/ 0x0020025aU, +/*02a1*/ 0x0020025bU, +/*02a2*/ 0x0020025cU, +/*02a3*/ 0x0020025dU, +/*02a4*/ 0x0020025eU, +/*02a5*/ 0x0020025fU, +/*02a6*/ 0x00040260U, +/*02a7*/ 0x08040260U, +/*02a8*/ 0x10010260U, +/*02a9*/ 0x18010260U, +/*02aa*/ 0x00010261U, +/*02ab*/ 0x08010261U, +/*02ac*/ 0x10010261U, +/*02ad*/ 0x18010261U, +/*02ae*/ 0x00010262U, +/*02af*/ 0x08010262U, +/*02b0*/ 0x10010262U, +/*02b1*/ 0x18040262U, +/*02b2*/ 0x00040263U, +/*02b3*/ 0x080a0263U, +/*02b4*/ 0x00200264U, +/*02b5*/ 0x00040265U, +/*02b6*/ 0x08080265U, +/*02b7*/ 0x10020265U, +/*02b8*/ 0x18020265U, +/*02b9*/ 0x00020266U, +/*02ba*/ 0x08020266U, +/*02bb*/ 0x10020266U, +/*02bc*/ 0x18020266U, +/*02bd*/ 0xffffffffU, +/*02be*/ 0xffffffffU, +/*02bf*/ 0x00200267U, +/*02c0*/ 0x00030268U, +/*02c1*/ 0x08100268U, +/*02c2*/ 0x00100269U, +/*02c3*/ 0x10040269U, +/*02c4*/ 0x18040269U, +/*02c5*/ 0x0005026aU, +/*02c6*/ 0x0805026aU, +/*02c7*/ 0xffffffffU, +/*02c8*/ 0xffffffffU, +/*02c9*/ 0xffffffffU, +/*02ca*/ 0xffffffffU, +/*02cb*/ 0x1001026aU, +/*02cc*/ 0x1801026aU, +/*02cd*/ 0x0008026bU, +/*02ce*/ 0x0808026bU, +/*02cf*/ 0x1008026bU, +/*02d0*/ 0x1808026bU, +/*02d1*/ 0x0008026cU, +/*02d2*/ 0x0808026cU, +/*02d3*/ 0x1008026cU, +/*02d4*/ 0x1808026cU, +/*02d5*/ 0x0008026dU, +/*02d6*/ 0x0808026dU, +/*02d7*/ 0x1008026dU, +/*02d8*/ 0x1808026dU, +/*02d9*/ 0x0008026eU, +/*02da*/ 0x0808026eU, +/*02db*/ 0x1003026eU, +/*02dc*/ 0x1803026eU, +/*02dd*/ 0x0003026fU, +/*02de*/ 0xffffffffU, +/*02df*/ 0x0801026fU, +/*02e0*/ 0x1002026fU, +/*02e1*/ 0x1801026fU, +/*02e2*/ 0x00040270U, +/*02e3*/ 0x08020270U, +/*02e4*/ 0x10010270U, +/*02e5*/ 0x18010270U, +/*02e6*/ 0x00010271U, +/*02e7*/ 0x08010271U, +/*02e8*/ 0x10040271U, +/*02e9*/ 0x18080271U, +/*02ea*/ 0x000a0272U, +/*02eb*/ 0x100a0272U, +/*02ec*/ 0x000a0273U, +/*02ed*/ 0x100a0273U, +/*02ee*/ 0x000a0274U, +/*02ef*/ 0x100a0274U, +/*02f0*/ 0x00200275U, +/*02f1*/ 0x00200276U, +/*02f2*/ 0x00010277U, +/*02f3*/ 0x08020277U, +/*02f4*/ 0x10020277U, +/*02f5*/ 0x18020277U, +/*02f6*/ 0xffffffffU, +/*02f7*/ 0x00020278U, +/*02f8*/ 0x08100278U, +/*02f9*/ 0x18050278U, +/*02fa*/ 0x00060279U, +/*02fb*/ 0x08050279U, +/*02fc*/ 0x10050279U, +/*02fd*/ 0x000e027aU, +/*02fe*/ 0x1005027aU, +/*02ff*/ 0x000e027bU, +/*0300*/ 0x1005027bU, +/*0301*/ 0x000e027cU, +/*0302*/ 0x1005027cU, +/*0303*/ 0x1801027cU, +/*0304*/ 0x0005027dU, +/*0305*/ 0x0805027dU, +/*0306*/ 0x100a027dU, +/*0307*/ 0x000a027eU, +/*0308*/ 0x1005027eU, +/*0309*/ 0x1805027eU, +/*030a*/ 0x000a027fU, +/*030b*/ 0x100a027fU, +/*030c*/ 0x00050280U, +/*030d*/ 0x08050280U, +/*030e*/ 0x100a0280U, +/*030f*/ 0x000a0281U, +/*0310*/ 0x10070281U, +/*0311*/ 0x18070281U, +/*0312*/ 0x00070282U, +/*0313*/ 0x08070282U, +/*0314*/ 0x10070282U, +/*0315*/ 0x18070282U, +/*0316*/ 0xffffffffU, +/*0317*/ 0xffffffffU, +/*0318*/ 0x00040283U, +/*0319*/ 0x08040283U, +/*031a*/ 0x10040283U, +/*031b*/ 0x18040283U, +/*031c*/ 0x00040284U, +/*031d*/ 0xffffffffU, +/*031e*/ 0x08080284U, +/*031f*/ 0x10080284U, +/*0320*/ 0x18040284U, +/*0321*/ 0x00050285U, +/*0322*/ 0x08080285U, +/*0323*/ 0x10050285U, +/*0324*/ 0x18040285U, +/*0325*/ 0x00050286U, +/*0326*/ 0x08080286U, +/*0327*/ 0x10050286U, +/*0328*/ 0x18040286U, +/*0329*/ 0x00050287U, +/*032a*/ 0x08080287U, +/*032b*/ 0x10050287U, +/*032c*/ 0x18040287U, +/*032d*/ 0x00050288U, +/*032e*/ 0x08070288U, +/*032f*/ 0x10080288U, +/*0330*/ 0x00100289U, +/*0331*/ 0x10080289U, +/*0332*/ 0x0010028aU, +/*0333*/ 0x1008028aU, +/*0334*/ 0x0010028bU, +/*0335*/ 0x1008028bU, +/*0336*/ 0x1808028bU, +/*0337*/ 0x0001028cU, +/*0338*/ 0x0801028cU, +/*0339*/ 0x1006028cU, +/*033a*/ 0x1806028cU, +/*033b*/ 0x0006028dU, +/*033c*/ 0x0801028dU, +/*033d*/ 0x1001028dU, +/*033e*/ 0x1803028dU, +/*033f*/ 0x000a028eU, +/*0340*/ 0x100a028eU, +/*0341*/ 0x000a028fU, +/*0342*/ 0xffffffffU, +/*0343*/ 0x100a028fU, +/*0344*/ 0x00040290U, +/*0345*/ 0x08010290U, +/*0346*/ 0x10040290U, +/*0347*/ 0x18070290U, +/*0348*/ 0x00070291U, +/*0349*/ 0x08070291U, +/*034a*/ 0x10070291U, +/*034b*/ 0x18070291U, +/*034c*/ 0x00070292U, +/*034d*/ 0xffffffffU, +/*034e*/ 0xffffffffU, +/*034f*/ 0x08050292U, +/*0350*/ 0x10050292U, +/*0351*/ 0x18040292U, +/*0352*/ 0x00040293U, +/*0353*/ 0x08040293U, +/*0354*/ 0xffffffffU, +/*0355*/ 0x10010293U, +/*0356*/ 0x18010293U, +/*0357*/ 0x00020294U, +/*0358*/ 0x08080294U, +/*0359*/ 0x00200295U, +/*035a*/ 0x00200296U, +/*035b*/ 0x00100297U, +/*035c*/ 0x10020297U, +/*035d*/ 0x18020297U, +/*035e*/ 0x00020298U, +/*035f*/ 0xffffffffU, +/*0360*/ 0x08010298U, +/*0361*/ 0x10010298U, +/*0362*/ 0x18020298U, +/*0363*/ 0x00100299U, +/*0364*/ 0x10100299U, +/*0365*/ 0x0010029aU, +/*0366*/ 0x1008029aU, +/*0367*/ 0x1808029aU, +/*0368*/ 0x0008029bU, +/*0369*/ 0x0808029bU, +/*036a*/ 0x1010029bU, +/*036b*/ 0x0010029cU, +/*036c*/ 0x1010029cU, +/*036d*/ 0x0008029dU, +/*036e*/ 0x0808029dU, +/*036f*/ 0x1008029dU, +/*0370*/ 0x1808029dU, +/*0371*/ 0x0010029eU, +/*0372*/ 0x1010029eU, +/*0373*/ 0x0010029fU, +/*0374*/ 0x1008029fU, +/*0375*/ 0x1808029fU, +/*0376*/ 0x000802a0U, +/*0377*/ 0x080802a0U, +/*0378*/ 0x100802a0U, +/*0379*/ 0x001002a1U, +/*037a*/ 0x101002a1U, +/*037b*/ 0x001002a2U, +/*037c*/ 0x100802a2U, +/*037d*/ 0x180802a2U, +/*037e*/ 0x000802a3U, +/*037f*/ 0x080802a3U, +/*0380*/ 0x101002a3U, +/*0381*/ 0x001002a4U, +/*0382*/ 0x101002a4U, +/*0383*/ 0x000802a5U, +/*0384*/ 0x080802a5U, +/*0385*/ 0x100802a5U, +/*0386*/ 0x180802a5U, +/*0387*/ 0x001002a6U, +/*0388*/ 0x101002a6U, +/*0389*/ 0x001002a7U, +/*038a*/ 0x100802a7U, +/*038b*/ 0x180802a7U, +/*038c*/ 0x000802a8U, +/*038d*/ 0x080802a8U, +/*038e*/ 0x100802a8U, +/*038f*/ 0x001002a9U, +/*0390*/ 0x101002a9U, +/*0391*/ 0x001002aaU, +/*0392*/ 0x100802aaU, +/*0393*/ 0x180802aaU, +/*0394*/ 0x000802abU, +/*0395*/ 0x080802abU, +/*0396*/ 0x101002abU, +/*0397*/ 0x001002acU, +/*0398*/ 0x101002acU, +/*0399*/ 0x000802adU, +/*039a*/ 0x080802adU, +/*039b*/ 0x100802adU, +/*039c*/ 0x180802adU, +/*039d*/ 0x001002aeU, +/*039e*/ 0x101002aeU, +/*039f*/ 0x001002afU, +/*03a0*/ 0x100802afU, +/*03a1*/ 0x180802afU, +/*03a2*/ 0x000802b0U, +/*03a3*/ 0x080802b0U, +/*03a4*/ 0x100802b0U, +/*03a5*/ 0x001002b1U, +/*03a6*/ 0x101002b1U, +/*03a7*/ 0x001002b2U, +/*03a8*/ 0x100802b2U, +/*03a9*/ 0x180802b2U, +/*03aa*/ 0x000802b3U, +/*03ab*/ 0x080802b3U, +/*03ac*/ 0x101002b3U, +/*03ad*/ 0x001002b4U, +/*03ae*/ 0x101002b4U, +/*03af*/ 0x000802b5U, +/*03b0*/ 0x080802b5U, +/*03b1*/ 0x100802b5U, +/*03b2*/ 0x180802b5U, +/*03b3*/ 0x001002b6U, +/*03b4*/ 0x101002b6U, +/*03b5*/ 0x001002b7U, +/*03b6*/ 0x100802b7U, +/*03b7*/ 0x180802b7U, +/*03b8*/ 0x000802b8U, +/*03b9*/ 0x080802b8U, +/*03ba*/ 0x100802b8U, +/*03bb*/ 0x180202b8U, +/*03bc*/ 0x000302b9U, +/*03bd*/ 0x080a02b9U, +/*03be*/ 0x000a02baU, +/*03bf*/ 0x100a02baU, +/*03c0*/ 0x000502bbU, +/*03c1*/ 0x080802bbU, +/*03c2*/ 0x100802bbU, +/*03c3*/ 0x180802bbU, +/*03c4*/ 0x000602bcU, +/*03c5*/ 0x080602bcU, +/*03c6*/ 0x001102bdU, +/*03c7*/ 0x180802bdU, +/*03c8*/ 0x000402beU, +/*03c9*/ 0x080602beU, +/*03ca*/ 0x100802beU, +/*03cb*/ 0x180802beU, +/*03cc*/ 0x000802bfU, +/*03cd*/ 0x080802bfU, +/*03ce*/ 0x100802bfU, +/*03cf*/ 0x180802bfU, +/*03d0*/ 0x000802c0U, +/*03d1*/ 0x080602c0U, +/*03d2*/ 0x100602c0U, +/*03d3*/ 0x001102c1U, +/*03d4*/ 0x180802c1U, +/*03d5*/ 0x000402c2U, +/*03d6*/ 0x080602c2U, +/*03d7*/ 0x100802c2U, +/*03d8*/ 0x180802c2U, +/*03d9*/ 0x000802c3U, +/*03da*/ 0x080802c3U, +/*03db*/ 0x100802c3U, +/*03dc*/ 0x180802c3U, +/*03dd*/ 0x000802c4U, +/*03de*/ 0x080602c4U, +/*03df*/ 0x100602c4U, +/*03e0*/ 0x001102c5U, +/*03e1*/ 0x180802c5U, +/*03e2*/ 0x000402c6U, +/*03e3*/ 0x080602c6U, +/*03e4*/ 0x100802c6U, +/*03e5*/ 0x180802c6U, +/*03e6*/ 0x000802c7U, +/*03e7*/ 0x080802c7U, +/*03e8*/ 0x100402c7U, +/*03e9*/ 0x180402c7U, +/*03ea*/ 0x000402c8U, +/*03eb*/ 0x080402c8U, +/*03ec*/ 0x100402c8U, +/*03ed*/ 0x180402c8U, +/*03ee*/ 0x000402c9U, +/*03ef*/ 0x080402c9U, +/*03f0*/ 0x100402c9U, +/*03f1*/ 0x180402c9U, +/*03f2*/ 0x000402caU, +/*03f3*/ 0x080402caU, +/*03f4*/ 0x100402caU, +/*03f5*/ 0x180402caU, +/*03f6*/ 0x000402cbU, +/*03f7*/ 0x080402cbU, +/*03f8*/ 0x100402cbU, +/*03f9*/ 0x180402cbU, +/*03fa*/ 0x000402ccU, +/*03fb*/ 0x080402ccU, +/*03fc*/ 0x001702cdU, +/*03fd*/ 0x001602ceU, +/*03fe*/ 0x001702cfU, +/*03ff*/ 0x002002d0U, +/*0400*/ 0x002002d1U, +/*0401*/ 0x002002d2U, +/*0402*/ 0x002002d3U, +/*0403*/ 0x002002d4U, +/*0404*/ 0x002002d5U, +/*0405*/ 0x002002d6U, +/*0406*/ 0x002002d7U, +/*0407*/ 0x002002d8U, +/*0408*/ 0x000202d9U, +/*0409*/ 0x080502d9U, +/*040a*/ 0x100502d9U, +/*040b*/ 0x180102d9U, +/*040c*/ 0x000502daU, +/*040d*/ 0x080502daU, +/*040e*/ 0x100502daU, +/*040f*/ 0x180502daU, +/*0410*/ 0x000502dbU, +/*0411*/ 0x080502dbU, +/*0412*/ 0x100502dbU, +/*0413*/ 0x180502dbU, +/*0414*/ 0x000502dcU, +/*0415*/ 0x080502dcU, +/*0416*/ 0x100502dcU, +/*0417*/ 0x180502dcU, +/*0418*/ 0x000502ddU, +/*0419*/ 0x080502ddU, +/*041a*/ 0x100502ddU, +/*041b*/ 0x180502ddU, +/*041c*/ 0x000502deU, +/*041d*/ 0x080502deU, +/*041e*/ 0x100502deU, +/*041f*/ 0x180502deU, +/*0420*/ 0x000502dfU, +/*0421*/ 0x080502dfU, +/*0422*/ 0x100102dfU, +/*0423*/ 0x180202dfU, +/*0424*/ 0x000202e0U, +/*0425*/ 0x080202e0U, +/*0426*/ 0x100202e0U, +/*0427*/ 0x180102e0U, +/*0428*/ 0x000802e1U, +/*0429*/ 0x081502e1U, +/*042a*/ 0x002002e2U, +/*042b*/ 0x001502e3U, +/*042c*/ 0x002002e4U, +/*042d*/ 0x001502e5U, +/*042e*/ 0x002002e6U, +/*042f*/ 0x000702e7U, +/*0430*/ 0x080102e7U, +/*0431*/ 0x100202e7U, +/*0432*/ 0x180602e7U, +/*0433*/ 0x000102e8U, +/*0434*/ 0x080102e8U, +/*0435*/ 0x002002e9U, +/*0436*/ 0x000202eaU, +/*0437*/ 0x002002ebU, +/*0438*/ 0x002002ecU, +/*0439*/ 0x000c02edU, +/*043a*/ 0x100c02edU, +/*043b*/ 0x002002eeU, +/*043c*/ 0x000302efU, +/*043d*/ 0x002002f0U, +/*043e*/ 0x000302f1U, +/*043f*/ 0x002002f2U, +/*0440*/ 0x000302f3U, +/*0441*/ 0x002002f4U, +/*0442*/ 0x000302f5U, +/*0443*/ 0x002002f6U, +/*0444*/ 0x000302f7U, +/*0445*/ 0x002002f8U, +/*0446*/ 0x000302f9U, +/*0447*/ 0x002002faU, +/*0448*/ 0x000302fbU, +/*0449*/ 0x002002fcU, +/*044a*/ 0x000302fdU, +/*044b*/ 0x002002feU, +/*044c*/ 0x000302ffU, +/*044d*/ 0x00200300U, +/*044e*/ 0x00030301U, +/*044f*/ 0x08030301U, +/*0450*/ 0x10020301U, +/*0451*/ 0x18020301U, +/*0452*/ 0x00200302U, +/*0453*/ 0x00200303U, +/*0454*/ 0x00200304U, +/*0455*/ 0x00200305U, +/*0456*/ 0x00040306U, +/*0457*/ 0x001e0307U, +/*0458*/ 0x001e0308U, +/*0459*/ 0x001e0309U, +/*045a*/ 0x001e030aU, +/*045b*/ 0x001e030bU, +/*045c*/ 0x001e030cU, +/*045d*/ 0x001e030dU, +/*045e*/ 0x001e030eU, +/*045f*/ 0x0004030fU, +/*0460*/ 0x0801030fU, +/*0461*/ 0x1010030fU, +/*0462*/ 0x00100310U, +/*0463*/ 0x10100310U, +/*0464*/ 0x00040311U, +/*0465*/ 0x08010311U, +/*0466*/ 0x10080311U, +/*0467*/ 0x18040311U, +/*0468*/ 0x00010312U, +/*0469*/ 0x08080312U, +/*046a*/ 0x10040312U, +/*046b*/ 0x18010312U, +/*046c*/ 0x00080313U, +/*046d*/ 0x08040313U, +/*046e*/ 0x10010313U, +/*046f*/ 0x18080313U, +/*0470*/ 0x00040314U, +/*0471*/ 0x08010314U, +/*0472*/ 0x10080314U, +/*0473*/ 0x18040314U, +/*0474*/ 0x00010315U, +/*0475*/ 0x08080315U, +/*0476*/ 0x10040315U, +/*0477*/ 0x18010315U, +/*0478*/ 0x00080316U, +/*0479*/ 0x08040316U, +/*047a*/ 0x10010316U, +/*047b*/ 0x18080316U, +/*047c*/ 0x00080317U, +/*047d*/ 0x00010318U, +/*047e*/ 0x08050318U, +/*047f*/ 0x10010318U, +/*0480*/ 0x18020318U, +/*0481*/ 0x00010319U, +/*0482*/ 0x08010319U, +/*0483*/ 0x10010319U, +/*0484*/ 0x18010319U, +/*0485*/ 0x0001031aU, +/*0486*/ 0x0801031aU, +/*0487*/ 0x1001031aU, +/*0488*/ 0x1801031aU, +/*0489*/ 0x0001031bU, +/*048a*/ 0x0801031bU, +/*048b*/ 0x1001031bU, +/*048c*/ 0x1801031bU, +/*048d*/ 0x0001031cU, +/*048e*/ 0x0801031cU, +/*048f*/ 0x1001031cU, +/*0490*/ 0x1801031cU, +/*0491*/ 0x0008031dU, +/*0492*/ 0x0808031dU, +/*0493*/ 0x1008031dU, +/*0494*/ 0x1808031dU, + } +}; + +#endif /* RZG_DDR_REGDEF_H */ diff --git a/drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h b/drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h new file mode 100644 index 000000000..e10162a66 --- /dev/null +++ b/drivers/renesas/rzg/ddr/ddr_b/init_dram_tbl_g2m.h @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2020U, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_INIT_DRAM_TABLE_G2M_H +#define RZG_INIT_DRAM_TABLE_G2M_H + +#define DDR_PHY_SLICE_REGSET_OFS_G2M 0x0800U +#define DDR_PHY_ADR_V_REGSET_OFS_G2M 0x0a00U +#define DDR_PHY_ADR_I_REGSET_OFS_G2M 0x0a80U +#define DDR_PHY_ADR_G_REGSET_OFS_G2M 0x0b80U +#define DDR_PI_REGSET_OFS_G2M 0x0200U + +#define DDR_PHY_SLICE_REGSET_SIZE_G2M 0x80U +#define DDR_PHY_ADR_V_REGSET_SIZE_G2M 0x80U +#define DDR_PHY_ADR_I_REGSET_SIZE_G2M 0x80U +#define DDR_PHY_ADR_G_REGSET_SIZE_G2M 0x80U +#define DDR_PI_REGSET_SIZE_G2M 0x100U + +#define DDR_PHY_SLICE_REGSET_NUM_G2M 89 +#define DDR_PHY_ADR_V_REGSET_NUM_G2M 37 +#define DDR_PHY_ADR_I_REGSET_NUM_G2M 37 +#define DDR_PHY_ADR_G_REGSET_NUM_G2M 64 +#define DDR_PI_REGSET_NUM_G2M 202 + +static const uint32_t DDR_PHY_SLICE_REGSET_G2M[DDR_PHY_SLICE_REGSET_NUM_G2M] = { + /*0800*/ 0x76543210U, + /*0801*/ 0x0004f008U, + /*0802*/ 0x00000000U, + /*0803*/ 0x00000000U, + /*0804*/ 0x00010000U, + /*0805*/ 0x036e6e0eU, + /*0806*/ 0x026e6e0eU, + /*0807*/ 0x00010300U, + /*0808*/ 0x04000100U, + /*0809*/ 0x00000300U, + /*080a*/ 0x001700c0U, + /*080b*/ 0x00b00201U, + /*080c*/ 0x00030020U, + /*080d*/ 0x00000000U, + /*080e*/ 0x00000000U, + /*080f*/ 0x00000000U, + /*0810*/ 0x00000000U, + /*0811*/ 0x00000000U, + /*0812*/ 0x00000000U, + /*0813*/ 0x00000000U, + /*0814*/ 0x09000000U, + /*0815*/ 0x04080000U, + /*0816*/ 0x04080400U, + /*0817*/ 0x00000000U, + /*0818*/ 0x32103210U, + /*0819*/ 0x00800708U, + /*081a*/ 0x000f000cU, + /*081b*/ 0x00000100U, + /*081c*/ 0x55aa55aaU, + /*081d*/ 0x33cc33ccU, + /*081e*/ 0x0ff00ff0U, + /*081f*/ 0x0f0ff0f0U, + /*0820*/ 0x00018e38U, + /*0821*/ 0x00000000U, + /*0822*/ 0x00000000U, + /*0823*/ 0x00000000U, + /*0824*/ 0x00000000U, + /*0825*/ 0x00000000U, + /*0826*/ 0x00000000U, + /*0827*/ 0x00000000U, + /*0828*/ 0x00000000U, + /*0829*/ 0x00000000U, + /*082a*/ 0x00000000U, + /*082b*/ 0x00000000U, + /*082c*/ 0x00000000U, + /*082d*/ 0x00000000U, + /*082e*/ 0x00000000U, + /*082f*/ 0x00000000U, + /*0830*/ 0x00000000U, + /*0831*/ 0x00000000U, + /*0832*/ 0x00000000U, + /*0833*/ 0x00200000U, + /*0834*/ 0x08200820U, + /*0835*/ 0x08200820U, + /*0836*/ 0x08200820U, + /*0837*/ 0x08200820U, + /*0838*/ 0x08200820U, + /*0839*/ 0x00000820U, + /*083a*/ 0x03000300U, + /*083b*/ 0x03000300U, + /*083c*/ 0x03000300U, + /*083d*/ 0x03000300U, + /*083e*/ 0x00000300U, + /*083f*/ 0x00000000U, + /*0840*/ 0x00000000U, + /*0841*/ 0x00000000U, + /*0842*/ 0x00000000U, + /*0843*/ 0x00a00000U, + /*0844*/ 0x00a000a0U, + /*0845*/ 0x00a000a0U, + /*0846*/ 0x00a000a0U, + /*0847*/ 0x00a000a0U, + /*0848*/ 0x00a000a0U, + /*0849*/ 0x00a000a0U, + /*084a*/ 0x00a000a0U, + /*084b*/ 0x00a000a0U, + /*084c*/ 0x010900a0U, + /*084d*/ 0x02000104U, + /*084e*/ 0x00000000U, + /*084f*/ 0x00010000U, + /*0850*/ 0x00000200U, + /*0851*/ 0x4041a151U, + /*0852*/ 0xc00141a0U, + /*0853*/ 0x0e0100c0U, + /*0854*/ 0x0010000cU, + /*0855*/ 0x0c064208U, + /*0856*/ 0x000f0c18U, + /*0857*/ 0x00e00140U, + /*0858*/ 0x00000c20U +}; + +static const uint32_t DDR_PHY_ADR_V_REGSET_G2M[DDR_PHY_ADR_V_REGSET_NUM_G2M] = { + /*0a00*/ 0x00000000U, + /*0a01*/ 0x00000000U, + /*0a02*/ 0x00000000U, + /*0a03*/ 0x00000000U, + /*0a04*/ 0x00000000U, + /*0a05*/ 0x00000000U, + /*0a06*/ 0x00000002U, + /*0a07*/ 0x00000000U, + /*0a08*/ 0x00000000U, + /*0a09*/ 0x00000000U, + /*0a0a*/ 0x00400320U, + /*0a0b*/ 0x00000040U, + /*0a0c*/ 0x00dcba98U, + /*0a0d*/ 0x00000000U, + /*0a0e*/ 0x00dcba98U, + /*0a0f*/ 0x01000000U, + /*0a10*/ 0x00020003U, + /*0a11*/ 0x00000000U, + /*0a12*/ 0x00000000U, + /*0a13*/ 0x00000000U, + /*0a14*/ 0x0000002aU, + /*0a15*/ 0x00000015U, + /*0a16*/ 0x00000015U, + /*0a17*/ 0x0000002aU, + /*0a18*/ 0x00000033U, + /*0a19*/ 0x0000000cU, + /*0a1a*/ 0x0000000cU, + /*0a1b*/ 0x00000033U, + /*0a1c*/ 0x0a418820U, + /*0a1d*/ 0x003f0000U, + /*0a1e*/ 0x0000003fU, + /*0a1f*/ 0x0002c06eU, + /*0a20*/ 0x02c002c0U, + /*0a21*/ 0x02c002c0U, + /*0a22*/ 0x000002c0U, + /*0a23*/ 0x42080010U, + /*0a24*/ 0x00000003U +}; + +static const uint32_t DDR_PHY_ADR_I_REGSET_G2M[DDR_PHY_ADR_I_REGSET_NUM_G2M] = { + /*0a80*/ 0x04040404U, + /*0a81*/ 0x00000404U, + /*0a82*/ 0x00000000U, + /*0a83*/ 0x00000000U, + /*0a84*/ 0x00000000U, + /*0a85*/ 0x00000000U, + /*0a86*/ 0x00000002U, + /*0a87*/ 0x00000000U, + /*0a88*/ 0x00000000U, + /*0a89*/ 0x00000000U, + /*0a8a*/ 0x00400320U, + /*0a8b*/ 0x00000040U, + /*0a8c*/ 0x00000000U, + /*0a8d*/ 0x00000000U, + /*0a8e*/ 0x00000000U, + /*0a8f*/ 0x01000000U, + /*0a90*/ 0x00020003U, + /*0a91*/ 0x00000000U, + /*0a92*/ 0x00000000U, + /*0a93*/ 0x00000000U, + /*0a94*/ 0x0000002aU, + /*0a95*/ 0x00000015U, + /*0a96*/ 0x00000015U, + /*0a97*/ 0x0000002aU, + /*0a98*/ 0x00000033U, + /*0a99*/ 0x0000000cU, + /*0a9a*/ 0x0000000cU, + /*0a9b*/ 0x00000033U, + /*0a9c*/ 0x00000000U, + /*0a9d*/ 0x00000000U, + /*0a9e*/ 0x00000000U, + /*0a9f*/ 0x0002c06eU, + /*0aa0*/ 0x02c002c0U, + /*0aa1*/ 0x02c002c0U, + /*0aa2*/ 0x000002c0U, + /*0aa3*/ 0x42080010U, + /*0aa4*/ 0x00000003U +}; + +static const uint32_t DDR_PHY_ADR_G_REGSET_G2M[DDR_PHY_ADR_G_REGSET_NUM_G2M] = { + /*0b80*/ 0x00000001U, + /*0b81*/ 0x00000000U, + /*0b82*/ 0x00000005U, + /*0b83*/ 0x04000f00U, + /*0b84*/ 0x00020080U, + /*0b85*/ 0x00020055U, + /*0b86*/ 0x00000000U, + /*0b87*/ 0x00000000U, + /*0b88*/ 0x00000000U, + /*0b89*/ 0x00000050U, + /*0b8a*/ 0x00000000U, + /*0b8b*/ 0x01010100U, + /*0b8c*/ 0x00000600U, + /*0b8d*/ 0x50640000U, + /*0b8e*/ 0x01421142U, + /*0b8f*/ 0x00000142U, + /*0b90*/ 0x00000000U, + /*0b91*/ 0x000f1600U, + /*0b92*/ 0x0f160f16U, + /*0b93*/ 0x0f160f16U, + /*0b94*/ 0x00000003U, + /*0b95*/ 0x0002c000U, + /*0b96*/ 0x02c002c0U, + /*0b97*/ 0x000002c0U, + /*0b98*/ 0x03421342U, + /*0b99*/ 0x00000342U, + /*0b9a*/ 0x00000000U, + /*0b9b*/ 0x00000000U, + /*0b9c*/ 0x05020000U, + /*0b9d*/ 0x00000000U, + /*0b9e*/ 0x00027f6eU, + /*0b9f*/ 0x047f027fU, + /*0ba0*/ 0x00027f6eU, + /*0ba1*/ 0x00047f6eU, + /*0ba2*/ 0x0003554fU, + /*0ba3*/ 0x0001554fU, + /*0ba4*/ 0x0001554fU, + /*0ba5*/ 0x0001554fU, + /*0ba6*/ 0x0001554fU, + /*0ba7*/ 0x00003feeU, + /*0ba8*/ 0x0001554fU, + /*0ba9*/ 0x00003feeU, + /*0baa*/ 0x0001554fU, + /*0bab*/ 0x00027f6eU, + /*0bac*/ 0x0001554fU, + /*0bad*/ 0x00000000U, + /*0bae*/ 0x00000000U, + /*0baf*/ 0x00000000U, + /*0bb0*/ 0x65000000U, + /*0bb1*/ 0x00000000U, + /*0bb2*/ 0x00000000U, + /*0bb3*/ 0x00000201U, + /*0bb4*/ 0x00000000U, + /*0bb5*/ 0x00000000U, + /*0bb6*/ 0x00000000U, + /*0bb7*/ 0x00000000U, + /*0bb8*/ 0x00000000U, + /*0bb9*/ 0x00000000U, + /*0bba*/ 0x00000000U, + /*0bbb*/ 0x00000000U, + /*0bbc*/ 0x06e40000U, + /*0bbd*/ 0x00000000U, + /*0bbe*/ 0x00000000U, + /*0bbf*/ 0x00010000U +}; + +static const uint32_t DDR_PI_REGSET_G2M[DDR_PI_REGSET_NUM_G2M] = { + /*0200*/ 0x00000b00U, + /*0201*/ 0x00000100U, + /*0202*/ 0x00000000U, + /*0203*/ 0x0000ffffU, + /*0204*/ 0x00000000U, + /*0205*/ 0x0000ffffU, + /*0206*/ 0x00000000U, + /*0207*/ 0x304cffffU, + /*0208*/ 0x00000200U, + /*0209*/ 0x00000200U, + /*020a*/ 0x00000200U, + /*020b*/ 0x00000200U, + /*020c*/ 0x0000304cU, + /*020d*/ 0x00000200U, + /*020e*/ 0x00000200U, + /*020f*/ 0x00000200U, + /*0210*/ 0x00000200U, + /*0211*/ 0x0000304cU, + /*0212*/ 0x00000200U, + /*0213*/ 0x00000200U, + /*0214*/ 0x00000200U, + /*0215*/ 0x00000200U, + /*0216*/ 0x00010000U, + /*0217*/ 0x00000003U, + /*0218*/ 0x01000001U, + /*0219*/ 0x00000000U, + /*021a*/ 0x00000000U, + /*021b*/ 0x00000000U, + /*021c*/ 0x00000000U, + /*021d*/ 0x00000000U, + /*021e*/ 0x00000000U, + /*021f*/ 0x00000000U, + /*0220*/ 0x00000000U, + /*0221*/ 0x00000000U, + /*0222*/ 0x00000000U, + /*0223*/ 0x00000000U, + /*0224*/ 0x00000000U, + /*0225*/ 0x00000000U, + /*0226*/ 0x00000000U, + /*0227*/ 0x00000000U, + /*0228*/ 0x00000000U, + /*0229*/ 0x0f000101U, + /*022a*/ 0x08492d25U, + /*022b*/ 0x0e0c0004U, + /*022c*/ 0x000e5000U, + /*022d*/ 0x00000250U, + /*022e*/ 0x00460003U, + /*022f*/ 0x182600cfU, + /*0230*/ 0x182600cfU, + /*0231*/ 0x00000005U, + /*0232*/ 0x00000000U, + /*0233*/ 0x00000000U, + /*0234*/ 0x00000000U, + /*0235*/ 0x00000000U, + /*0236*/ 0x00000000U, + /*0237*/ 0x00000000U, + /*0238*/ 0x00000000U, + /*0239*/ 0x01000000U, + /*023a*/ 0x00040404U, + /*023b*/ 0x01280a00U, + /*023c*/ 0x00000000U, + /*023d*/ 0x000f0000U, + /*023e*/ 0x00001803U, + /*023f*/ 0x00000000U, + /*0240*/ 0x00000000U, + /*0241*/ 0x00060002U, + /*0242*/ 0x00010001U, + /*0243*/ 0x01000101U, + /*0244*/ 0x04020201U, + /*0245*/ 0x00080804U, + /*0246*/ 0x00000000U, + /*0247*/ 0x08030000U, + /*0248*/ 0x15150408U, + /*0249*/ 0x00000000U, + /*024a*/ 0x00000000U, + /*024b*/ 0x00000000U, + /*024c*/ 0x000f0f00U, + /*024d*/ 0x0000001eU, + /*024e*/ 0x00000000U, + /*024f*/ 0x01000300U, + /*0250*/ 0x00000000U, + /*0251*/ 0x00000000U, + /*0252*/ 0x01000000U, + /*0253*/ 0x00010101U, + /*0254*/ 0x000e0e0eU, + /*0255*/ 0x000c0c0cU, + /*0256*/ 0x02060601U, + /*0257*/ 0x00000000U, + /*0258*/ 0x00000003U, + /*0259*/ 0x00181703U, + /*025a*/ 0x00280006U, + /*025b*/ 0x00280016U, + /*025c*/ 0x00000016U, + /*025d*/ 0x00000000U, + /*025e*/ 0x00000000U, + /*025f*/ 0x00000000U, + /*0260*/ 0x140a0000U, + /*0261*/ 0x0005010aU, + /*0262*/ 0x03018d03U, + /*0263*/ 0x000a018dU, + /*0264*/ 0x00060100U, + /*0265*/ 0x01000006U, + /*0266*/ 0x018e018eU, + /*0267*/ 0x018e0100U, + /*0268*/ 0x1111018eU, + /*0269*/ 0x10010204U, + /*026a*/ 0x09090650U, + /*026b*/ 0x20110202U, + /*026c*/ 0x00201000U, + /*026d*/ 0x00201000U, + /*026e*/ 0x04041000U, + /*026f*/ 0x18020100U, + /*0270*/ 0x00010118U, + /*0271*/ 0x004b004aU, + /*0272*/ 0x050f0000U, + /*0273*/ 0x0c01021eU, + /*0274*/ 0x34000000U, + /*0275*/ 0x00000000U, + /*0276*/ 0x00000000U, + /*0277*/ 0x00000000U, + /*0278*/ 0x0000d400U, + /*0279*/ 0x0031002eU, + /*027a*/ 0x00111136U, + /*027b*/ 0x002e00d4U, + /*027c*/ 0x11360031U, + /*027d*/ 0x0000d411U, + /*027e*/ 0x0031002eU, + /*027f*/ 0x00111136U, + /*0280*/ 0x002e00d4U, + /*0281*/ 0x11360031U, + /*0282*/ 0x0000d411U, + /*0283*/ 0x0031002eU, + /*0284*/ 0x00111136U, + /*0285*/ 0x002e00d4U, + /*0286*/ 0x11360031U, + /*0287*/ 0x00d40011U, + /*0288*/ 0x0031002eU, + /*0289*/ 0x00111136U, + /*028a*/ 0x002e00d4U, + /*028b*/ 0x11360031U, + /*028c*/ 0x0000d411U, + /*028d*/ 0x0031002eU, + /*028e*/ 0x00111136U, + /*028f*/ 0x002e00d4U, + /*0290*/ 0x11360031U, + /*0291*/ 0x0000d411U, + /*0292*/ 0x0031002eU, + /*0293*/ 0x00111136U, + /*0294*/ 0x002e00d4U, + /*0295*/ 0x11360031U, + /*0296*/ 0x02000011U, + /*0297*/ 0x018d018dU, + /*0298*/ 0x0c08018dU, + /*0299*/ 0x1f121d22U, + /*029a*/ 0x4301b344U, + /*029b*/ 0x10172006U, + /*029c*/ 0x1d220c10U, + /*029d*/ 0x00001f12U, + /*029e*/ 0x4301b344U, + /*029f*/ 0x10172006U, + /*02a0*/ 0x1d220c10U, + /*02a1*/ 0x00001f12U, + /*02a2*/ 0x4301b344U, + /*02a3*/ 0x10172006U, + /*02a4*/ 0x02000210U, + /*02a5*/ 0x02000200U, + /*02a6*/ 0x02000200U, + /*02a7*/ 0x02000200U, + /*02a8*/ 0x02000200U, + /*02a9*/ 0x00000000U, + /*02aa*/ 0x00000000U, + /*02ab*/ 0x00000000U, + /*02ac*/ 0x00000000U, + /*02ad*/ 0x00000000U, + /*02ae*/ 0x00000000U, + /*02af*/ 0x00000000U, + /*02b0*/ 0x00000000U, + /*02b1*/ 0x00000000U, + /*02b2*/ 0x00000000U, + /*02b3*/ 0x00000000U, + /*02b4*/ 0x00000000U, + /*02b5*/ 0x00000400U, + /*02b6*/ 0x15141312U, + /*02b7*/ 0x11100f0eU, + /*02b8*/ 0x080b0c0dU, + /*02b9*/ 0x05040a09U, + /*02ba*/ 0x01000706U, + /*02bb*/ 0x00000302U, + /*02bc*/ 0x01030201U, + /*02bd*/ 0x00304c00U, + /*02be*/ 0x0001e2f8U, + /*02bf*/ 0x0000304cU, + /*02c0*/ 0x0001e2f8U, + /*02c1*/ 0x0000304cU, + /*02c2*/ 0x0001e2f8U, + /*02c3*/ 0x08000000U, + /*02c4*/ 0x00000100U, + /*02c5*/ 0x00000000U, + /*02c6*/ 0x00000000U, + /*02c7*/ 0x00000000U, + /*02c8*/ 0x00000000U, + /*02c9*/ 0x00000002U +}; + +#endif /* RZG_INIT_DRAM_TABLE_G2M_H */ diff --git a/drivers/renesas/rzg/ddr/dram_sub_func.h b/drivers/renesas/rzg/ddr/dram_sub_func.h new file mode 100644 index 000000000..7affb6156 --- /dev/null +++ b/drivers/renesas/rzg/ddr/dram_sub_func.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020, 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 + +#endif /* DRAM_SUB_FUNC_H */ diff --git a/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c new file mode 100644 index 000000000..f76b83f9a --- /dev/null +++ b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c @@ -0,0 +1,1300 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> /* for uint32_t */ + +#include <lib/mmio.h> + +#include "pfc_init_g2m.h" +#include "rcar_def.h" +#include "rcar_private.h" +#include "pfc_regs.h" + +#define GPSR0_D15 BIT(15) +#define GPSR0_D14 BIT(14) +#define GPSR0_D13 BIT(13) +#define GPSR0_D12 BIT(12) +#define GPSR0_D11 BIT(11) +#define GPSR0_D10 BIT(10) +#define GPSR0_D9 BIT(9) +#define GPSR0_D8 BIT(8) +#define GPSR0_D7 BIT(7) +#define GPSR0_D6 BIT(6) +#define GPSR0_D5 BIT(5) +#define GPSR0_D4 BIT(4) +#define GPSR0_D3 BIT(3) +#define GPSR0_D2 BIT(2) +#define GPSR0_D1 BIT(1) +#define GPSR0_D0 BIT(0) +#define GPSR1_CLKOUT BIT(28) +#define GPSR1_EX_WAIT0_A BIT(27) +#define GPSR1_WE1 BIT(26) +#define GPSR1_WE0 BIT(25) +#define GPSR1_RD_WR BIT(24) +#define GPSR1_RD BIT(23) +#define GPSR1_BS BIT(22) +#define GPSR1_CS1_A26 BIT(21) +#define GPSR1_CS0 BIT(20) +#define GPSR1_A19 BIT(19) +#define GPSR1_A18 BIT(18) +#define GPSR1_A17 BIT(17) +#define GPSR1_A16 BIT(16) +#define GPSR1_A15 BIT(15) +#define GPSR1_A14 BIT(14) +#define GPSR1_A13 BIT(13) +#define GPSR1_A12 BIT(12) +#define GPSR1_A11 BIT(11) +#define GPSR1_A10 BIT(10) +#define GPSR1_A9 BIT(9) +#define GPSR1_A8 BIT(8) +#define GPSR1_A7 BIT(7) +#define GPSR1_A6 BIT(6) +#define GPSR1_A5 BIT(5) +#define GPSR1_A4 BIT(4) +#define GPSR1_A3 BIT(3) +#define GPSR1_A2 BIT(2) +#define GPSR1_A1 BIT(1) +#define GPSR1_A0 BIT(0) +#define GPSR2_AVB_AVTP_CAPTURE_A BIT(14) +#define GPSR2_AVB_AVTP_MATCH_A BIT(13) +#define GPSR2_AVB_LINK BIT(12) +#define GPSR2_AVB_PHY_INT BIT(11) +#define GPSR2_AVB_MAGIC BIT(10) +#define GPSR2_AVB_MDC BIT(9) +#define GPSR2_PWM2_A BIT(8) +#define GPSR2_PWM1_A BIT(7) +#define GPSR2_PWM0 BIT(6) +#define GPSR2_IRQ5 BIT(5) +#define GPSR2_IRQ4 BIT(4) +#define GPSR2_IRQ3 BIT(3) +#define GPSR2_IRQ2 BIT(2) +#define GPSR2_IRQ1 BIT(1) +#define GPSR2_IRQ0 BIT(0) +#define GPSR3_SD1_WP BIT(15) +#define GPSR3_SD1_CD BIT(14) +#define GPSR3_SD0_WP BIT(13) +#define GPSR3_SD0_CD BIT(12) +#define GPSR3_SD1_DAT3 BIT(11) +#define GPSR3_SD1_DAT2 BIT(10) +#define GPSR3_SD1_DAT1 BIT(9) +#define GPSR3_SD1_DAT0 BIT(8) +#define GPSR3_SD1_CMD BIT(7) +#define GPSR3_SD1_CLK BIT(6) +#define GPSR3_SD0_DAT3 BIT(5) +#define GPSR3_SD0_DAT2 BIT(4) +#define GPSR3_SD0_DAT1 BIT(3) +#define GPSR3_SD0_DAT0 BIT(2) +#define GPSR3_SD0_CMD BIT(1) +#define GPSR3_SD0_CLK BIT(0) +#define GPSR4_SD3_DS BIT(17) +#define GPSR4_SD3_DAT7 BIT(16) +#define GPSR4_SD3_DAT6 BIT(15) +#define GPSR4_SD3_DAT5 BIT(14) +#define GPSR4_SD3_DAT4 BIT(13) +#define GPSR4_SD3_DAT3 BIT(12) +#define GPSR4_SD3_DAT2 BIT(11) +#define GPSR4_SD3_DAT1 BIT(10) +#define GPSR4_SD3_DAT0 BIT(9) +#define GPSR4_SD3_CMD BIT(8) +#define GPSR4_SD3_CLK BIT(7) +#define GPSR4_SD2_DS BIT(6) +#define GPSR4_SD2_DAT3 BIT(5) +#define GPSR4_SD2_DAT2 BIT(4) +#define GPSR4_SD2_DAT1 BIT(3) +#define GPSR4_SD2_DAT0 BIT(2) +#define GPSR4_SD2_CMD BIT(1) +#define GPSR4_SD2_CLK BIT(0) +#define GPSR5_MLB_DAT BIT(25) +#define GPSR5_MLB_SIG BIT(24) +#define GPSR5_MLB_CLK BIT(23) +#define GPSR5_MSIOF0_RXD BIT(22) +#define GPSR5_MSIOF0_SS2 BIT(21) +#define GPSR5_MSIOF0_TXD BIT(20) +#define GPSR5_MSIOF0_SS1 BIT(19) +#define GPSR5_MSIOF0_SYNC BIT(18) +#define GPSR5_MSIOF0_SCK BIT(17) +#define GPSR5_HRTS0 BIT(16) +#define GPSR5_HCTS0 BIT(15) +#define GPSR5_HTX0 BIT(14) +#define GPSR5_HRX0 BIT(13) +#define GPSR5_HSCK0 BIT(12) +#define GPSR5_RX2_A BIT(11) +#define GPSR5_TX2_A BIT(10) +#define GPSR5_SCK2 BIT(9) +#define GPSR5_RTS1 BIT(8) +#define GPSR5_CTS1 BIT(7) +#define GPSR5_TX1_A BIT(6) +#define GPSR5_RX1_A BIT(5) +#define GPSR5_RTS0 BIT(4) +#define GPSR5_CTS0 BIT(3) +#define GPSR5_TX0 BIT(2) +#define GPSR5_RX0 BIT(1) +#define GPSR5_SCK0 BIT(0) +#define GPSR6_USB31_OVC BIT(31) +#define GPSR6_USB31_PWEN BIT(30) +#define GPSR6_USB30_OVC BIT(29) +#define GPSR6_USB30_PWEN BIT(28) +#define GPSR6_USB1_OVC BIT(27) +#define GPSR6_USB1_PWEN BIT(26) +#define GPSR6_USB0_OVC BIT(25) +#define GPSR6_USB0_PWEN BIT(24) +#define GPSR6_AUDIO_CLKB_B BIT(23) +#define GPSR6_AUDIO_CLKA_A BIT(22) +#define GPSR6_SSI_SDATA9_A BIT(21) +#define GPSR6_SSI_SDATA8 BIT(20) +#define GPSR6_SSI_SDATA7 BIT(19) +#define GPSR6_SSI_WS78 BIT(18) +#define GPSR6_SSI_SCK78 BIT(17) +#define GPSR6_SSI_SDATA6 BIT(16) +#define GPSR6_SSI_WS6 BIT(15) +#define GPSR6_SSI_SCK6 BIT(14) +#define GPSR6_SSI_SDATA5 BIT(13) +#define GPSR6_SSI_WS5 BIT(12) +#define GPSR6_SSI_SCK5 BIT(11) +#define GPSR6_SSI_SDATA4 BIT(10) +#define GPSR6_SSI_WS4 BIT(9) +#define GPSR6_SSI_SCK4 BIT(8) +#define GPSR6_SSI_SDATA3 BIT(7) +#define GPSR6_SSI_WS34 BIT(6) +#define GPSR6_SSI_SCK34 BIT(5) +#define GPSR6_SSI_SDATA2_A BIT(4) +#define GPSR6_SSI_SDATA1_A BIT(3) +#define GPSR6_SSI_SDATA0 BIT(2) +#define GPSR6_SSI_WS0129 BIT(1) +#define GPSR6_SSI_SCK0129 BIT(0) +#define GPSR7_AVS2 BIT(1) +#define GPSR7_AVS1 BIT(0) + +#define IPSR_28_FUNC(x) ((uint32_t)(x) << 28U) +#define IPSR_24_FUNC(x) ((uint32_t)(x) << 24U) +#define IPSR_20_FUNC(x) ((uint32_t)(x) << 20U) +#define IPSR_16_FUNC(x) ((uint32_t)(x) << 16U) +#define IPSR_12_FUNC(x) ((uint32_t)(x) << 12U) +#define IPSR_8_FUNC(x) ((uint32_t)(x) << 8U) +#define IPSR_4_FUNC(x) ((uint32_t)(x) << 4U) +#define IPSR_0_FUNC(x) ((uint32_t)(x) << 0U) + +#define POC_SD3_DS_33V BIT(29) +#define POC_SD3_DAT7_33V BIT(28) +#define POC_SD3_DAT6_33V BIT(27) +#define POC_SD3_DAT5_33V BIT(26) +#define POC_SD3_DAT4_33V BIT(25) +#define POC_SD3_DAT3_33V BIT(24) +#define POC_SD3_DAT2_33V BIT(23) +#define POC_SD3_DAT1_33V BIT(22) +#define POC_SD3_DAT0_33V BIT(21) +#define POC_SD3_CMD_33V BIT(20) +#define POC_SD3_CLK_33V BIT(19) +#define POC_SD2_DS_33V BIT(18) +#define POC_SD2_DAT3_33V BIT(17) +#define POC_SD2_DAT2_33V BIT(16) +#define POC_SD2_DAT1_33V BIT(15) +#define POC_SD2_DAT0_33V BIT(14) +#define POC_SD2_CMD_33V BIT(13) +#define POC_SD2_CLK_33V BIT(12) +#define POC_SD1_DAT3_33V BIT(11) +#define POC_SD1_DAT2_33V BIT(10) +#define POC_SD1_DAT1_33V BIT(9) +#define POC_SD1_DAT0_33V BIT(8) +#define POC_SD1_CMD_33V BIT(7) +#define POC_SD1_CLK_33V BIT(6) +#define POC_SD0_DAT3_33V BIT(5) +#define POC_SD0_DAT2_33V BIT(4) +#define POC_SD0_DAT1_33V BIT(3) +#define POC_SD0_DAT0_33V BIT(2) +#define POC_SD0_CMD_33V BIT(1) +#define POC_SD0_CLK_33V BIT(0) + +#define DRVCTRL0_MASK (0xCCCCCCCCU) +#define DRVCTRL1_MASK (0xCCCCCCC8U) +#define DRVCTRL2_MASK (0x88888888U) +#define DRVCTRL3_MASK (0x88888888U) +#define DRVCTRL4_MASK (0x88888888U) +#define DRVCTRL5_MASK (0x88888888U) +#define DRVCTRL6_MASK (0x88888888U) +#define DRVCTRL7_MASK (0x88888888U) +#define DRVCTRL8_MASK (0x88888888U) +#define DRVCTRL9_MASK (0x88888888U) +#define DRVCTRL10_MASK (0x88888888U) +#define DRVCTRL11_MASK (0x888888CCU) +#define DRVCTRL12_MASK (0xCCCFFFCFU) +#define DRVCTRL13_MASK (0xCC888888U) +#define DRVCTRL14_MASK (0x88888888U) +#define DRVCTRL15_MASK (0x88888888U) +#define DRVCTRL16_MASK (0x88888888U) +#define DRVCTRL17_MASK (0x88888888U) +#define DRVCTRL18_MASK (0x88888888U) +#define DRVCTRL19_MASK (0x88888888U) +#define DRVCTRL20_MASK (0x88888888U) +#define DRVCTRL21_MASK (0x88888888U) +#define DRVCTRL22_MASK (0x88888888U) +#define DRVCTRL23_MASK (0x88888888U) +#define DRVCTRL24_MASK (0x8888888FU) + +#define DRVCTRL0_QSPI0_SPCLK(x) ((uint32_t)(x) << 28U) +#define DRVCTRL0_QSPI0_MOSI_IO0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL0_QSPI0_MISO_IO1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL0_QSPI0_IO2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL0_QSPI0_IO3(x) ((uint32_t)(x) << 12U) +#define DRVCTRL0_QSPI0_SSL(x) ((uint32_t)(x) << 8U) +#define DRVCTRL0_QSPI1_SPCLK(x) ((uint32_t)(x) << 4U) +#define DRVCTRL0_QSPI1_MOSI_IO0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL1_QSPI1_MISO_IO1(x) ((uint32_t)(x) << 28U) +#define DRVCTRL1_QSPI1_IO2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL1_QSPI1_IO3(x) ((uint32_t)(x) << 20U) +#define DRVCTRL1_QSPI1_SS(x) ((uint32_t)(x) << 16U) +#define DRVCTRL1_RPC_INT(x) ((uint32_t)(x) << 12U) +#define DRVCTRL1_RPC_WP(x) ((uint32_t)(x) << 8U) +#define DRVCTRL1_RPC_RESET(x) ((uint32_t)(x) << 4U) +#define DRVCTRL1_AVB_RX_CTL(x) ((uint32_t)(x) << 0U) +#define DRVCTRL2_AVB_RXC(x) ((uint32_t)(x) << 28U) +#define DRVCTRL2_AVB_RD0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL2_AVB_RD1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL2_AVB_RD2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL2_AVB_RD3(x) ((uint32_t)(x) << 12U) +#define DRVCTRL2_AVB_TX_CTL(x) ((uint32_t)(x) << 8U) +#define DRVCTRL2_AVB_TXC(x) ((uint32_t)(x) << 4U) +#define DRVCTRL2_AVB_TD0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL3_AVB_TD1(x) ((uint32_t)(x) << 28U) +#define DRVCTRL3_AVB_TD2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL3_AVB_TD3(x) ((uint32_t)(x) << 20U) +#define DRVCTRL3_AVB_TXCREFCLK(x) ((uint32_t)(x) << 16U) +#define DRVCTRL3_AVB_MDIO(x) ((uint32_t)(x) << 12U) +#define DRVCTRL3_AVB_MDC(x) ((uint32_t)(x) << 8U) +#define DRVCTRL3_AVB_MAGIC(x) ((uint32_t)(x) << 4U) +#define DRVCTRL3_AVB_PHY_INT(x) ((uint32_t)(x) << 0U) +#define DRVCTRL4_AVB_LINK(x) ((uint32_t)(x) << 28U) +#define DRVCTRL4_AVB_AVTP_MATCH(x) ((uint32_t)(x) << 24U) +#define DRVCTRL4_AVB_AVTP_CAPTURE(x) ((uint32_t)(x) << 20U) +#define DRVCTRL4_IRQ0(x) ((uint32_t)(x) << 16U) +#define DRVCTRL4_IRQ1(x) ((uint32_t)(x) << 12U) +#define DRVCTRL4_IRQ2(x) ((uint32_t)(x) << 8U) +#define DRVCTRL4_IRQ3(x) ((uint32_t)(x) << 4U) +#define DRVCTRL4_IRQ4(x) ((uint32_t)(x) << 0U) +#define DRVCTRL5_IRQ5(x) ((uint32_t)(x) << 28U) +#define DRVCTRL5_PWM0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL5_PWM1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL5_PWM2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL5_A0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL5_A1(x) ((uint32_t)(x) << 8U) +#define DRVCTRL5_A2(x) ((uint32_t)(x) << 4U) +#define DRVCTRL5_A3(x) ((uint32_t)(x) << 0U) +#define DRVCTRL6_A4(x) ((uint32_t)(x) << 28U) +#define DRVCTRL6_A5(x) ((uint32_t)(x) << 24U) +#define DRVCTRL6_A6(x) ((uint32_t)(x) << 20U) +#define DRVCTRL6_A7(x) ((uint32_t)(x) << 16U) +#define DRVCTRL6_A8(x) ((uint32_t)(x) << 12U) +#define DRVCTRL6_A9(x) ((uint32_t)(x) << 8U) +#define DRVCTRL6_A10(x) ((uint32_t)(x) << 4U) +#define DRVCTRL6_A11(x) ((uint32_t)(x) << 0U) +#define DRVCTRL7_A12(x) ((uint32_t)(x) << 28U) +#define DRVCTRL7_A13(x) ((uint32_t)(x) << 24U) +#define DRVCTRL7_A14(x) ((uint32_t)(x) << 20U) +#define DRVCTRL7_A15(x) ((uint32_t)(x) << 16U) +#define DRVCTRL7_A16(x) ((uint32_t)(x) << 12U) +#define DRVCTRL7_A17(x) ((uint32_t)(x) << 8U) +#define DRVCTRL7_A18(x) ((uint32_t)(x) << 4U) +#define DRVCTRL7_A19(x) ((uint32_t)(x) << 0U) +#define DRVCTRL8_CLKOUT(x) ((uint32_t)(x) << 28U) +#define DRVCTRL8_CS0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL8_CS1_A2(x) ((uint32_t)(x) << 20U) +#define DRVCTRL8_BS(x) ((uint32_t)(x) << 16U) +#define DRVCTRL8_RD(x) ((uint32_t)(x) << 12U) +#define DRVCTRL8_RD_W(x) ((uint32_t)(x) << 8U) +#define DRVCTRL8_WE0(x) ((uint32_t)(x) << 4U) +#define DRVCTRL8_WE1(x) ((uint32_t)(x) << 0U) +#define DRVCTRL9_EX_WAIT0(x) ((uint32_t)(x) << 28U) +#define DRVCTRL9_PRESETOU(x) ((uint32_t)(x) << 24U) +#define DRVCTRL9_D0(x) ((uint32_t)(x) << 20U) +#define DRVCTRL9_D1(x) ((uint32_t)(x) << 16U) +#define DRVCTRL9_D2(x) ((uint32_t)(x) << 12U) +#define DRVCTRL9_D3(x) ((uint32_t)(x) << 8U) +#define DRVCTRL9_D4(x) ((uint32_t)(x) << 4U) +#define DRVCTRL9_D5(x) ((uint32_t)(x) << 0U) +#define DRVCTRL10_D6(x) ((uint32_t)(x) << 28U) +#define DRVCTRL10_D7(x) ((uint32_t)(x) << 24U) +#define DRVCTRL10_D8(x) ((uint32_t)(x) << 20U) +#define DRVCTRL10_D9(x) ((uint32_t)(x) << 16U) +#define DRVCTRL10_D10(x) ((uint32_t)(x) << 12U) +#define DRVCTRL10_D11(x) ((uint32_t)(x) << 8U) +#define DRVCTRL10_D12(x) ((uint32_t)(x) << 4U) +#define DRVCTRL10_D13(x) ((uint32_t)(x) << 0U) +#define DRVCTRL11_D14(x) ((uint32_t)(x) << 28U) +#define DRVCTRL11_D15(x) ((uint32_t)(x) << 24U) +#define DRVCTRL11_AVS1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL11_AVS2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL11_GP7_02(x) ((uint32_t)(x) << 12U) +#define DRVCTRL11_GP7_03(x) ((uint32_t)(x) << 8U) +#define DRVCTRL11_DU_DOTCLKIN0(x) ((uint32_t)(x) << 4U) +#define DRVCTRL11_DU_DOTCLKIN1(x) ((uint32_t)(x) << 0U) +#define DRVCTRL12_DU_DOTCLKIN2(x) ((uint32_t)(x) << 28U) +#define DRVCTRL12_DU_DOTCLKIN3(x) ((uint32_t)(x) << 24U) +#define DRVCTRL12_DU_FSCLKST(x) ((uint32_t)(x) << 20U) +#define DRVCTRL12_DU_TMS(x) ((uint32_t)(x) << 4U) +#define DRVCTRL13_TDO(x) ((uint32_t)(x) << 28U) +#define DRVCTRL13_ASEBRK(x) ((uint32_t)(x) << 24U) +#define DRVCTRL13_SD0_CLK(x) ((uint32_t)(x) << 20U) +#define DRVCTRL13_SD0_CMD(x) ((uint32_t)(x) << 16U) +#define DRVCTRL13_SD0_DAT0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL13_SD0_DAT1(x) ((uint32_t)(x) << 8U) +#define DRVCTRL13_SD0_DAT2(x) ((uint32_t)(x) << 4U) +#define DRVCTRL13_SD0_DAT3(x) ((uint32_t)(x) << 0U) +#define DRVCTRL14_SD1_CLK(x) ((uint32_t)(x) << 28U) +#define DRVCTRL14_SD1_CMD(x) ((uint32_t)(x) << 24U) +#define DRVCTRL14_SD1_DAT0(x) ((uint32_t)(x) << 20U) +#define DRVCTRL14_SD1_DAT1(x) ((uint32_t)(x) << 16U) +#define DRVCTRL14_SD1_DAT2(x) ((uint32_t)(x) << 12U) +#define DRVCTRL14_SD1_DAT3(x) ((uint32_t)(x) << 8U) +#define DRVCTRL14_SD2_CLK(x) ((uint32_t)(x) << 4U) +#define DRVCTRL14_SD2_CMD(x) ((uint32_t)(x) << 0U) +#define DRVCTRL15_SD2_DAT0(x) ((uint32_t)(x) << 28U) +#define DRVCTRL15_SD2_DAT1(x) ((uint32_t)(x) << 24U) +#define DRVCTRL15_SD2_DAT2(x) ((uint32_t)(x) << 20U) +#define DRVCTRL15_SD2_DAT3(x) ((uint32_t)(x) << 16U) +#define DRVCTRL15_SD2_DS(x) ((uint32_t)(x) << 12U) +#define DRVCTRL15_SD3_CLK(x) ((uint32_t)(x) << 8U) +#define DRVCTRL15_SD3_CMD(x) ((uint32_t)(x) << 4U) +#define DRVCTRL15_SD3_DAT0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL16_SD3_DAT1(x) ((uint32_t)(x) << 28U) +#define DRVCTRL16_SD3_DAT2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL16_SD3_DAT3(x) ((uint32_t)(x) << 20U) +#define DRVCTRL16_SD3_DAT4(x) ((uint32_t)(x) << 16U) +#define DRVCTRL16_SD3_DAT5(x) ((uint32_t)(x) << 12U) +#define DRVCTRL16_SD3_DAT6(x) ((uint32_t)(x) << 8U) +#define DRVCTRL16_SD3_DAT7(x) ((uint32_t)(x) << 4U) +#define DRVCTRL16_SD3_DS(x) ((uint32_t)(x) << 0U) +#define DRVCTRL17_SD0_CD(x) ((uint32_t)(x) << 28U) +#define DRVCTRL17_SD0_WP(x) ((uint32_t)(x) << 24U) +#define DRVCTRL17_SD1_CD(x) ((uint32_t)(x) << 20U) +#define DRVCTRL17_SD1_WP(x) ((uint32_t)(x) << 16U) +#define DRVCTRL17_SCK0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL17_RX0(x) ((uint32_t)(x) << 8U) +#define DRVCTRL17_TX0(x) ((uint32_t)(x) << 4U) +#define DRVCTRL17_CTS0(x) ((uint32_t)(x) << 0U) +#define DRVCTRL18_RTS0_TANS(x) ((uint32_t)(x) << 28U) +#define DRVCTRL18_RX1(x) ((uint32_t)(x) << 24U) +#define DRVCTRL18_TX1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL18_CTS1(x) ((uint32_t)(x) << 16U) +#define DRVCTRL18_RTS1_TANS(x) ((uint32_t)(x) << 12U) +#define DRVCTRL18_SCK2(x) ((uint32_t)(x) << 8U) +#define DRVCTRL18_TX2(x) ((uint32_t)(x) << 4U) +#define DRVCTRL18_RX2(x) ((uint32_t)(x) << 0U) +#define DRVCTRL19_HSCK0(x) ((uint32_t)(x) << 28U) +#define DRVCTRL19_HRX0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL19_HTX0(x) ((uint32_t)(x) << 20U) +#define DRVCTRL19_HCTS0(x) ((uint32_t)(x) << 16U) +#define DRVCTRL19_HRTS0(x) ((uint32_t)(x) << 12U) +#define DRVCTRL19_MSIOF0_SCK(x) ((uint32_t)(x) << 8U) +#define DRVCTRL19_MSIOF0_SYNC(x) ((uint32_t)(x) << 4U) +#define DRVCTRL19_MSIOF0_SS1(x) ((uint32_t)(x) << 0U) +#define DRVCTRL20_MSIOF0_TXD(x) ((uint32_t)(x) << 28U) +#define DRVCTRL20_MSIOF0_SS2(x) ((uint32_t)(x) << 24U) +#define DRVCTRL20_MSIOF0_RXD(x) ((uint32_t)(x) << 20U) +#define DRVCTRL20_MLB_CLK(x) ((uint32_t)(x) << 16U) +#define DRVCTRL20_MLB_SIG(x) ((uint32_t)(x) << 12U) +#define DRVCTRL20_MLB_DAT(x) ((uint32_t)(x) << 8U) +#define DRVCTRL20_MLB_REF(x) ((uint32_t)(x) << 4U) +#define DRVCTRL20_SSI_SCK0129(x) ((uint32_t)(x) << 0U) +#define DRVCTRL21_SSI_WS0129(x) ((uint32_t)(x) << 28U) +#define DRVCTRL21_SSI_SDATA0(x) ((uint32_t)(x) << 24U) +#define DRVCTRL21_SSI_SDATA1(x) ((uint32_t)(x) << 20U) +#define DRVCTRL21_SSI_SDATA2(x) ((uint32_t)(x) << 16U) +#define DRVCTRL21_SSI_SCK34(x) ((uint32_t)(x) << 12U) +#define DRVCTRL21_SSI_WS34(x) ((uint32_t)(x) << 8U) +#define DRVCTRL21_SSI_SDATA3(x) ((uint32_t)(x) << 4U) +#define DRVCTRL21_SSI_SCK4(x) ((uint32_t)(x) << 0U) +#define DRVCTRL22_SSI_WS4(x) ((uint32_t)(x) << 28U) +#define DRVCTRL22_SSI_SDATA4(x) ((uint32_t)(x) << 24U) +#define DRVCTRL22_SSI_SCK5(x) ((uint32_t)(x) << 20U) +#define DRVCTRL22_SSI_WS5(x) ((uint32_t)(x) << 16U) +#define DRVCTRL22_SSI_SDATA5(x) ((uint32_t)(x) << 12U) +#define DRVCTRL22_SSI_SCK6(x) ((uint32_t)(x) << 8U) +#define DRVCTRL22_SSI_WS6(x) ((uint32_t)(x) << 4U) +#define DRVCTRL22_SSI_SDATA6(x) ((uint32_t)(x) << 0U) +#define DRVCTRL23_SSI_SCK78(x) ((uint32_t)(x) << 28U) +#define DRVCTRL23_SSI_WS78(x) ((uint32_t)(x) << 24U) +#define DRVCTRL23_SSI_SDATA7(x) ((uint32_t)(x) << 20U) +#define DRVCTRL23_SSI_SDATA8(x) ((uint32_t)(x) << 16U) +#define DRVCTRL23_SSI_SDATA9(x) ((uint32_t)(x) << 12U) +#define DRVCTRL23_AUDIO_CLKA(x) ((uint32_t)(x) << 8U) +#define DRVCTRL23_AUDIO_CLKB(x) ((uint32_t)(x) << 4U) +#define DRVCTRL23_USB0_PWEN(x) ((uint32_t)(x) << 0U) +#define DRVCTRL24_USB0_OVC(x) ((uint32_t)(x) << 28U) +#define DRVCTRL24_USB1_PWEN(x) ((uint32_t)(x) << 24U) +#define DRVCTRL24_USB1_OVC(x) ((uint32_t)(x) << 20U) +#define DRVCTRL24_USB30_PWEN(x) ((uint32_t)(x) << 16U) +#define DRVCTRL24_USB30_OVC(x) ((uint32_t)(x) << 12U) +#define DRVCTRL24_USB31_PWEN(x) ((uint32_t)(x) << 8U) +#define DRVCTRL24_USB31_OVC(x) ((uint32_t)(x) << 4U) + +#define MOD_SEL0_MSIOF3_A ((uint32_t)0U << 29U) +#define MOD_SEL0_MSIOF3_B ((uint32_t)1U << 29U) +#define MOD_SEL0_MSIOF3_C ((uint32_t)2U << 29U) +#define MOD_SEL0_MSIOF3_D ((uint32_t)3U << 29U) +#define MOD_SEL0_MSIOF3_E ((uint32_t)4U << 29U) +#define MOD_SEL0_MSIOF2_A ((uint32_t)0U << 27U) +#define MOD_SEL0_MSIOF2_B ((uint32_t)1U << 27U) +#define MOD_SEL0_MSIOF2_C ((uint32_t)2U << 27U) +#define MOD_SEL0_MSIOF2_D ((uint32_t)3U << 27U) +#define MOD_SEL0_MSIOF1_A ((uint32_t)0U << 24U) +#define MOD_SEL0_MSIOF1_B ((uint32_t)1U << 24U) +#define MOD_SEL0_MSIOF1_C ((uint32_t)2U << 24U) +#define MOD_SEL0_MSIOF1_D ((uint32_t)3U << 24U) +#define MOD_SEL0_MSIOF1_E ((uint32_t)4U << 24U) +#define MOD_SEL0_MSIOF1_F ((uint32_t)5U << 24U) +#define MOD_SEL0_MSIOF1_G ((uint32_t)6U << 24U) +#define MOD_SEL0_LBSC_A ((uint32_t)0U << 23U) +#define MOD_SEL0_LBSC_B ((uint32_t)1U << 23U) +#define MOD_SEL0_IEBUS_A ((uint32_t)0U << 22U) +#define MOD_SEL0_IEBUS_B ((uint32_t)1U << 22U) +#define MOD_SEL0_I2C2_A ((uint32_t)0U << 21U) +#define MOD_SEL0_I2C2_B ((uint32_t)1U << 21U) +#define MOD_SEL0_I2C1_A ((uint32_t)0U << 20U) +#define MOD_SEL0_I2C1_B ((uint32_t)1U << 20U) +#define MOD_SEL0_HSCIF4_A ((uint32_t)0U << 19U) +#define MOD_SEL0_HSCIF4_B ((uint32_t)1U << 19U) +#define MOD_SEL0_HSCIF3_A ((uint32_t)0U << 17U) +#define MOD_SEL0_HSCIF3_B ((uint32_t)1U << 17U) +#define MOD_SEL0_HSCIF3_C ((uint32_t)2U << 17U) +#define MOD_SEL0_HSCIF3_D ((uint32_t)3U << 17U) +#define MOD_SEL0_HSCIF1_A ((uint32_t)0U << 16U) +#define MOD_SEL0_HSCIF1_B ((uint32_t)1U << 16U) +#define MOD_SEL0_FSO_A ((uint32_t)0U << 15U) +#define MOD_SEL0_FSO_B ((uint32_t)1U << 15U) +#define MOD_SEL0_HSCIF2_A ((uint32_t)0U << 13U) +#define MOD_SEL0_HSCIF2_B ((uint32_t)1U << 13U) +#define MOD_SEL0_HSCIF2_C ((uint32_t)2U << 13U) +#define MOD_SEL0_ETHERAVB_A ((uint32_t)0U << 12U) +#define MOD_SEL0_ETHERAVB_B ((uint32_t)1U << 12U) +#define MOD_SEL0_DRIF3_A ((uint32_t)0U << 11U) +#define MOD_SEL0_DRIF3_B ((uint32_t)1U << 11U) +#define MOD_SEL0_DRIF2_A ((uint32_t)0U << 10U) +#define MOD_SEL0_DRIF2_B ((uint32_t)1U << 10U) +#define MOD_SEL0_DRIF1_A ((uint32_t)0U << 8U) +#define MOD_SEL0_DRIF1_B ((uint32_t)1U << 8U) +#define MOD_SEL0_DRIF1_C ((uint32_t)2U << 8U) +#define MOD_SEL0_DRIF0_A ((uint32_t)0U << 6U) +#define MOD_SEL0_DRIF0_B ((uint32_t)1U << 6U) +#define MOD_SEL0_DRIF0_C ((uint32_t)2U << 6U) +#define MOD_SEL0_CANFD0_A ((uint32_t)0U << 5U) +#define MOD_SEL0_CANFD0_B ((uint32_t)1U << 5U) +#define MOD_SEL0_ADG_A_A ((uint32_t)0U << 3U) +#define MOD_SEL0_ADG_A_B ((uint32_t)1U << 3U) +#define MOD_SEL0_ADG_A_C ((uint32_t)2U << 3U) +#define MOD_SEL1_TSIF1_A ((uint32_t)0U << 30U) +#define MOD_SEL1_TSIF1_B ((uint32_t)1U << 30U) +#define MOD_SEL1_TSIF1_C ((uint32_t)2U << 30U) +#define MOD_SEL1_TSIF1_D ((uint32_t)3U << 30U) +#define MOD_SEL1_TSIF0_A ((uint32_t)0U << 27U) +#define MOD_SEL1_TSIF0_B ((uint32_t)1U << 27U) +#define MOD_SEL1_TSIF0_C ((uint32_t)2U << 27U) +#define MOD_SEL1_TSIF0_D ((uint32_t)3U << 27U) +#define MOD_SEL1_TSIF0_E ((uint32_t)4U << 27U) +#define MOD_SEL1_TIMER_TMU_A ((uint32_t)0U << 26U) +#define MOD_SEL1_TIMER_TMU_B ((uint32_t)1U << 26U) +#define MOD_SEL1_SSP1_1_A ((uint32_t)0U << 24U) +#define MOD_SEL1_SSP1_1_B ((uint32_t)1U << 24U) +#define MOD_SEL1_SSP1_1_C ((uint32_t)2U << 24U) +#define MOD_SEL1_SSP1_1_D ((uint32_t)3U << 24U) +#define MOD_SEL1_SSP1_0_A ((uint32_t)0U << 21U) +#define MOD_SEL1_SSP1_0_B ((uint32_t)1U << 21U) +#define MOD_SEL1_SSP1_0_C ((uint32_t)2U << 21U) +#define MOD_SEL1_SSP1_0_D ((uint32_t)3U << 21U) +#define MOD_SEL1_SSP1_0_E ((uint32_t)4U << 21U) +#define MOD_SEL1_SSI_A ((uint32_t)0U << 20U) +#define MOD_SEL1_SSI_B ((uint32_t)1U << 20U) +#define MOD_SEL1_SPEED_PULSE_IF_A ((uint32_t)0U << 19U) +#define MOD_SEL1_SPEED_PULSE_IF_B ((uint32_t)1U << 19U) +#define MOD_SEL1_SIMCARD_A ((uint32_t)0U << 17U) +#define MOD_SEL1_SIMCARD_B ((uint32_t)1U << 17U) +#define MOD_SEL1_SIMCARD_C ((uint32_t)2U << 17U) +#define MOD_SEL1_SIMCARD_D ((uint32_t)3U << 17U) +#define MOD_SEL1_SDHI2_A ((uint32_t)0U << 16U) +#define MOD_SEL1_SDHI2_B ((uint32_t)1U << 16U) +#define MOD_SEL1_SCIF4_A ((uint32_t)0U << 14U) +#define MOD_SEL1_SCIF4_B ((uint32_t)1U << 14U) +#define MOD_SEL1_SCIF4_C ((uint32_t)2U << 14U) +#define MOD_SEL1_SCIF3_A ((uint32_t)0U << 13U) +#define MOD_SEL1_SCIF3_B ((uint32_t)1U << 13U) +#define MOD_SEL1_SCIF2_A ((uint32_t)0U << 12U) +#define MOD_SEL1_SCIF2_B ((uint32_t)1U << 12U) +#define MOD_SEL1_SCIF1_A ((uint32_t)0U << 11U) +#define MOD_SEL1_SCIF1_B ((uint32_t)1U << 11U) +#define MOD_SEL1_SCIF_A ((uint32_t)0U << 10U) +#define MOD_SEL1_SCIF_B ((uint32_t)1U << 10U) +#define MOD_SEL1_REMOCON_A ((uint32_t)0U << 9U) +#define MOD_SEL1_REMOCON_B ((uint32_t)1U << 9U) +#define MOD_SEL1_RCAN0_A ((uint32_t)0U << 6U) +#define MOD_SEL1_RCAN0_B ((uint32_t)1U << 6U) +#define MOD_SEL1_PWM6_A ((uint32_t)0U << 5U) +#define MOD_SEL1_PWM6_B ((uint32_t)1U << 5U) +#define MOD_SEL1_PWM5_A ((uint32_t)0U << 4U) +#define MOD_SEL1_PWM5_B ((uint32_t)1U << 4U) +#define MOD_SEL1_PWM4_A ((uint32_t)0U << 3U) +#define MOD_SEL1_PWM4_B ((uint32_t)1U << 3U) +#define MOD_SEL1_PWM3_A ((uint32_t)0U << 2U) +#define MOD_SEL1_PWM3_B ((uint32_t)1U << 2U) +#define MOD_SEL1_PWM2_A ((uint32_t)0U << 1U) +#define MOD_SEL1_PWM2_B ((uint32_t)1U << 1U) +#define MOD_SEL1_PWM1_A ((uint32_t)0U << 0U) +#define MOD_SEL1_PWM1_B ((uint32_t)1U << 0U) +#define MOD_SEL2_I2C_5_A ((uint32_t)0U << 31U) +#define MOD_SEL2_I2C_5_B ((uint32_t)1U << 31U) +#define MOD_SEL2_I2C_3_A ((uint32_t)0U << 30U) +#define MOD_SEL2_I2C_3_B ((uint32_t)1U << 30U) +#define MOD_SEL2_I2C_0_A ((uint32_t)0U << 29U) +#define MOD_SEL2_I2C_0_B ((uint32_t)1U << 29U) +#define MOD_SEL2_FM_A ((uint32_t)0U << 27U) +#define MOD_SEL2_FM_B ((uint32_t)1U << 27U) +#define MOD_SEL2_FM_C ((uint32_t)2U << 27U) +#define MOD_SEL2_FM_D ((uint32_t)3U << 27U) +#define MOD_SEL2_SCIF5_A ((uint32_t)0U << 26U) +#define MOD_SEL2_SCIF5_B ((uint32_t)1U << 26U) +#define MOD_SEL2_I2C6_A ((uint32_t)0U << 23U) +#define MOD_SEL2_I2C6_B ((uint32_t)1U << 23U) +#define MOD_SEL2_I2C6_C ((uint32_t)2U << 23U) +#define MOD_SEL2_NDF_A ((uint32_t)0U << 22U) +#define MOD_SEL2_NDF_B ((uint32_t)1U << 22U) +#define MOD_SEL2_SSI2_A ((uint32_t)0U << 21U) +#define MOD_SEL2_SSI2_B ((uint32_t)1U << 21U) +#define MOD_SEL2_SSI9_A ((uint32_t)0U << 20U) +#define MOD_SEL2_SSI9_B ((uint32_t)1U << 20U) +#define MOD_SEL2_TIMER_TMU2_A ((uint32_t)0U << 19U) +#define MOD_SEL2_TIMER_TMU2_B ((uint32_t)1U << 19U) +#define MOD_SEL2_ADG_B_A ((uint32_t)0U << 18U) +#define MOD_SEL2_ADG_B_B ((uint32_t)1U << 18U) +#define MOD_SEL2_ADG_C_A ((uint32_t)0U << 17U) +#define MOD_SEL2_ADG_C_B ((uint32_t)1U << 17U) +#define MOD_SEL2_VIN4_A ((uint32_t)0U << 0U) +#define MOD_SEL2_VIN4_B ((uint32_t)1U << 0U) + +/* SCIF3 Registers for Dummy write */ +#define SCIF3_BASE (0xE6C50000U) +#define SCIF3_SCFCR (SCIF3_BASE + 0x0018U) +#define SCIF3_SCFDR (SCIF3_BASE + 0x001CU) +#define SCFCR_DATA (0x0000U) + +/* Realtime module stop control */ +#define CPG_BASE (0xE6150000U) +#define CPG_SCMSTPCR0 (CPG_BASE + 0x0B20U) +#define CPG_MSTPSR0 (CPG_BASE + 0x0030U) +#define SCMSTPCR0_RTDMAC (0x00200000U) + +/* RT-DMAC Registers */ +#define RTDMAC_CH (0U) /* choose 0 to 15 */ + +#define RTDMAC_BASE (0xFFC10000U) +#define RTDMAC_RDMOR (RTDMAC_BASE + 0x0060U) +#define RTDMAC_RDMCHCLR (RTDMAC_BASE + 0x0080U) +#define RTDMAC_RDMSAR(x) (RTDMAC_BASE + 0x8000U + (0x80U * (x))) +#define RTDMAC_RDMDAR(x) (RTDMAC_BASE + 0x8004U + (0x80U * (x))) +#define RTDMAC_RDMTCR(x) (RTDMAC_BASE + 0x8008U + (0x80U * (x))) +#define RTDMAC_RDMCHCR(x) (RTDMAC_BASE + 0x800CU + (0x80U * (x))) +#define RTDMAC_RDMCHCRB(x) (RTDMAC_BASE + 0x801CU + (0x80U * (x))) +#define RTDMAC_RDMDPBASE(x) (RTDMAC_BASE + 0x8050U + (0x80U * (x))) +#define RTDMAC_DESC_BASE (RTDMAC_BASE + 0xA000U) +#define RTDMAC_DESC_RDMSAR (RTDMAC_DESC_BASE + 0x0000U) +#define RTDMAC_DESC_RDMDAR (RTDMAC_DESC_BASE + 0x0004U) +#define RTDMAC_DESC_RDMTCR (RTDMAC_DESC_BASE + 0x0008U) + +#define RDMOR_DME (0x0001U) /* DMA Master Enable */ +#define RDMCHCR_DPM_INFINITE (0x30000000U) /* Infinite repeat mode */ +#define RDMCHCR_RPT_TCR (0x02000000U) /* enable to update TCR */ +#define RDMCHCR_TS_2 (0x00000008U) /* Word(2byte) units transfer */ +#define RDMCHCR_RS_AUTO (0x00000400U) /* Auto request */ +#define RDMCHCR_DE (0x00000001U) /* DMA Enable */ +#define RDMCHCRB_DRST (0x00008000U) /* Descriptor reset */ +#define RDMCHCRB_SLM_256 (0x00000080U) /* once in 256 clock cycle */ +#define RDMDPBASE_SEL_EXT (0x00000001U) /* External memory use */ + +static void start_rtdma0_descriptor(void) +{ + uint32_t reg; + + reg = mmio_read_32(RCAR_PRR); + reg &= (PRR_PRODUCT_MASK | PRR_CUT_MASK); + if (reg == (PRR_PRODUCT_M3_CUT10)) { + /* Enable clock supply to RTDMAC. */ + mstpcr_write(CPG_SCMSTPCR0, CPG_MSTPSR0, SCMSTPCR0_RTDMAC); + + /* Initialize ch0, Reset Descriptor */ + mmio_write_32(RTDMAC_RDMCHCLR, BIT(RTDMAC_CH)); + mmio_write_32(RTDMAC_RDMCHCRB(RTDMAC_CH), RDMCHCRB_DRST); + + /* Enable DMA */ + mmio_write_16(RTDMAC_RDMOR, RDMOR_DME); + + /* Set first transfer */ + mmio_write_32(RTDMAC_RDMSAR(RTDMAC_CH), RCAR_PRR); + mmio_write_32(RTDMAC_RDMDAR(RTDMAC_CH), SCIF3_SCFDR); + mmio_write_32(RTDMAC_RDMTCR(RTDMAC_CH), 0x00000001U); + + /* Set descriptor */ + mmio_write_32(RTDMAC_DESC_RDMSAR, 0x00000000U); + mmio_write_32(RTDMAC_DESC_RDMDAR, 0x00000000U); + mmio_write_32(RTDMAC_DESC_RDMTCR, 0x00200000U); + mmio_write_32(RTDMAC_RDMCHCRB(RTDMAC_CH), RDMCHCRB_SLM_256); + mmio_write_32(RTDMAC_RDMDPBASE(RTDMAC_CH), RTDMAC_DESC_BASE + | RDMDPBASE_SEL_EXT); + + /* Set transfer parameter, Start transfer */ + mmio_write_32(RTDMAC_RDMCHCR(RTDMAC_CH), RDMCHCR_DPM_INFINITE + | RDMCHCR_RPT_TCR + | RDMCHCR_TS_2 + | RDMCHCR_RS_AUTO + | RDMCHCR_DE); + } +} + +static void pfc_reg_write(uint32_t addr, uint32_t data) +{ + uint32_t prr; + + prr = mmio_read_32(RCAR_PRR); + prr &= (PRR_PRODUCT_MASK | PRR_CUT_MASK); + + mmio_write_32(PFC_PMMR, ~data); + if (prr == (PRR_PRODUCT_M3_CUT10)) { + mmio_write_16(SCIF3_SCFCR, SCFCR_DATA); /* Dummy write */ + } + mmio_write_32((uintptr_t)addr, data); + if (prr == (PRR_PRODUCT_M3_CUT10)) { + mmio_write_16(SCIF3_SCFCR, SCFCR_DATA); /* Dummy write */ + } +} + +void pfc_init_g2m(void) +{ + uint32_t reg; + + /* + * PFC write access problem seen on older SoC's. Added a workaround + * in RT-DMAC for fixing the same. + */ + start_rtdma0_descriptor(); + + /* initialize module select */ + pfc_reg_write(PFC_MOD_SEL0, MOD_SEL0_MSIOF3_A + | MOD_SEL0_MSIOF2_A + | MOD_SEL0_MSIOF1_A + | MOD_SEL0_LBSC_A + | MOD_SEL0_IEBUS_A + | MOD_SEL0_I2C2_A + | MOD_SEL0_I2C1_A + | MOD_SEL0_HSCIF4_A + | MOD_SEL0_HSCIF3_A + | MOD_SEL0_HSCIF1_A + | MOD_SEL0_FSO_A + | MOD_SEL0_HSCIF2_A + | MOD_SEL0_ETHERAVB_A + | MOD_SEL0_DRIF3_A + | MOD_SEL0_DRIF2_A + | MOD_SEL0_DRIF1_A + | MOD_SEL0_DRIF0_A + | MOD_SEL0_CANFD0_A + | MOD_SEL0_ADG_A_A); + pfc_reg_write(PFC_MOD_SEL1, MOD_SEL1_TSIF1_A + | MOD_SEL1_TSIF0_A + | MOD_SEL1_TIMER_TMU_A + | MOD_SEL1_SSP1_1_A + | MOD_SEL1_SSP1_0_A + | MOD_SEL1_SSI_A + | MOD_SEL1_SPEED_PULSE_IF_A + | MOD_SEL1_SIMCARD_A + | MOD_SEL1_SDHI2_A + | MOD_SEL1_SCIF4_A + | MOD_SEL1_SCIF3_A + | MOD_SEL1_SCIF2_A + | MOD_SEL1_SCIF1_A + | MOD_SEL1_SCIF_A + | MOD_SEL1_REMOCON_A + | MOD_SEL1_RCAN0_A + | MOD_SEL1_PWM6_A + | MOD_SEL1_PWM5_A + | MOD_SEL1_PWM4_A + | MOD_SEL1_PWM3_A + | MOD_SEL1_PWM2_A + | MOD_SEL1_PWM1_A); + pfc_reg_write(PFC_MOD_SEL2, MOD_SEL2_I2C_5_B + | MOD_SEL2_I2C_3_B + | MOD_SEL2_I2C_0_B + | MOD_SEL2_FM_A + | MOD_SEL2_SCIF5_A + | MOD_SEL2_I2C6_A + | MOD_SEL2_NDF_A + | MOD_SEL2_SSI2_A + | MOD_SEL2_SSI9_A + | MOD_SEL2_TIMER_TMU2_A + | MOD_SEL2_ADG_B_A + | MOD_SEL2_ADG_C_A + | MOD_SEL2_VIN4_A); + + /* initialize peripheral function select */ + pfc_reg_write(PFC_IPSR0, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR1, IPSR_28_FUNC(6) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(3) + | IPSR_8_FUNC(3) + | IPSR_4_FUNC(3) + | IPSR_0_FUNC(3)); + pfc_reg_write(PFC_IPSR2, IPSR_28_FUNC(0) + | IPSR_24_FUNC(6) + | IPSR_20_FUNC(6) + | IPSR_16_FUNC(6) + | IPSR_12_FUNC(6) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(6) + | IPSR_0_FUNC(6)); + pfc_reg_write(PFC_IPSR3, IPSR_28_FUNC(6) + | IPSR_24_FUNC(6) + | IPSR_20_FUNC(6) + | IPSR_16_FUNC(6) + | IPSR_12_FUNC(6) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR4, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(6) + | IPSR_0_FUNC(6)); + pfc_reg_write(PFC_IPSR5, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR6, IPSR_28_FUNC(6) + | IPSR_24_FUNC(6) + | IPSR_20_FUNC(6) + | IPSR_16_FUNC(6) + | IPSR_12_FUNC(6) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR7, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(6) + | IPSR_4_FUNC(6) + | IPSR_0_FUNC(6)); + pfc_reg_write(PFC_IPSR8, IPSR_28_FUNC(1) + | IPSR_24_FUNC(1) + | IPSR_20_FUNC(1) + | IPSR_16_FUNC(1) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR9, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR10, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR11, IPSR_28_FUNC(0) + | IPSR_24_FUNC(4) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR12, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(4) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR13, IPSR_28_FUNC(8) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(3) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR14, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(3) + | IPSR_0_FUNC(8)); + pfc_reg_write(PFC_IPSR15, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR16, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR17, IPSR_28_FUNC(0) + | IPSR_24_FUNC(0) + | IPSR_20_FUNC(0) + | IPSR_16_FUNC(0) + | IPSR_12_FUNC(0) + | IPSR_8_FUNC(0) + | IPSR_4_FUNC(1) + | IPSR_0_FUNC(0)); + pfc_reg_write(PFC_IPSR18, IPSR_4_FUNC(0) + | IPSR_0_FUNC(0)); + + /* initialize GPIO/perihperal function select */ + pfc_reg_write(PFC_GPSR0, GPSR0_D15 + | GPSR0_D14 + | GPSR0_D13 + | GPSR0_D12 + | GPSR0_D11 + | GPSR0_D10 + | GPSR0_D9 + | GPSR0_D8 + | GPSR0_D7 + | GPSR0_D6 + | GPSR0_D5 + | GPSR0_D4 + | GPSR0_D3 + | GPSR0_D2 + | GPSR0_D0); + pfc_reg_write(PFC_GPSR1, GPSR1_CLKOUT + | GPSR1_EX_WAIT0_A + | GPSR1_WE1 + | GPSR1_RD + | GPSR1_RD_WR + | GPSR1_CS0 + | GPSR1_A19 + | GPSR1_A18 + | GPSR1_A17 + | GPSR1_A16 + | GPSR1_A15 + | GPSR1_A14 + | GPSR1_A13 + | GPSR1_A12 + | GPSR1_A7 + | GPSR1_A6 + | GPSR1_A5 + | GPSR1_A4 + | GPSR1_A3 + | GPSR1_A2 + | GPSR1_A1 + | GPSR1_A0); + pfc_reg_write(PFC_GPSR2, GPSR2_AVB_AVTP_CAPTURE_A + | GPSR2_AVB_AVTP_MATCH_A + | GPSR2_AVB_LINK + | GPSR2_AVB_PHY_INT + | GPSR2_AVB_MDC + | GPSR2_PWM2_A + | GPSR2_PWM1_A + | GPSR2_IRQ4 + | GPSR2_IRQ3 + | GPSR2_IRQ2 + | GPSR2_IRQ1 + | GPSR2_IRQ0); + pfc_reg_write(PFC_GPSR3, GPSR3_SD0_CD + | GPSR3_SD1_DAT3 + | GPSR3_SD1_DAT2 + | GPSR3_SD1_DAT1 + | GPSR3_SD1_DAT0 + | GPSR3_SD0_DAT3 + | GPSR3_SD0_DAT2 + | GPSR3_SD0_DAT1 + | GPSR3_SD0_DAT0 + | GPSR3_SD0_CMD + | GPSR3_SD0_CLK); + pfc_reg_write(PFC_GPSR4, GPSR4_SD3_DS + | GPSR4_SD3_DAT7 + | GPSR4_SD3_DAT6 + | GPSR4_SD3_DAT5 + | GPSR4_SD3_DAT4 + | GPSR4_SD3_DAT3 + | GPSR4_SD3_DAT2 + | GPSR4_SD3_DAT1 + | GPSR4_SD3_DAT0 + | GPSR4_SD3_CMD + | GPSR4_SD3_CLK + | GPSR4_SD2_DAT3 + | GPSR4_SD2_DAT2 + | GPSR4_SD2_DAT1 + | GPSR4_SD2_DAT0 + | GPSR4_SD2_CMD + | GPSR4_SD2_CLK); + pfc_reg_write(PFC_GPSR5, GPSR5_MSIOF0_RXD + | GPSR5_MSIOF0_TXD + | GPSR5_MSIOF0_SYNC + | GPSR5_MSIOF0_SCK + | GPSR5_RX2_A + | GPSR5_TX2_A + | GPSR5_RTS1 + | GPSR5_CTS1 + | GPSR5_TX1_A + | GPSR5_RX1_A + | GPSR5_RTS0 + | GPSR5_SCK0); + pfc_reg_write(PFC_GPSR6, GPSR6_AUDIO_CLKB_B + | GPSR6_AUDIO_CLKA_A + | GPSR6_SSI_WS6 + | GPSR6_SSI_SCK6 + | GPSR6_SSI_SDATA4 + | GPSR6_SSI_WS4 + | GPSR6_SSI_SCK4 + | GPSR6_SSI_SDATA1_A + | GPSR6_SSI_SDATA0 + | GPSR6_SSI_WS0129 + | GPSR6_SSI_SCK0129); + pfc_reg_write(PFC_GPSR7, GPSR7_AVS2 + | GPSR7_AVS1); + + /* initialize POC control register */ + pfc_reg_write(PFC_POCCTRL0, POC_SD0_DAT3_33V + | POC_SD0_DAT2_33V + | POC_SD0_DAT1_33V + | POC_SD0_DAT0_33V + | POC_SD0_CMD_33V + | POC_SD0_CLK_33V); + + /* initialize DRV control register */ + reg = mmio_read_32(PFC_DRVCTRL0); + reg = ((reg & DRVCTRL0_MASK) | DRVCTRL0_QSPI0_SPCLK(3) + | DRVCTRL0_QSPI0_MOSI_IO0(3) + | DRVCTRL0_QSPI0_MISO_IO1(3) + | DRVCTRL0_QSPI0_IO2(3) + | DRVCTRL0_QSPI0_IO3(3) + | DRVCTRL0_QSPI0_SSL(3) + | DRVCTRL0_QSPI1_SPCLK(3) + | DRVCTRL0_QSPI1_MOSI_IO0(3)); + pfc_reg_write(PFC_DRVCTRL0, reg); + reg = mmio_read_32(PFC_DRVCTRL1); + reg = ((reg & DRVCTRL1_MASK) | DRVCTRL1_QSPI1_MISO_IO1(3) + | DRVCTRL1_QSPI1_IO2(3) + | DRVCTRL1_QSPI1_IO3(3) + | DRVCTRL1_QSPI1_SS(3) + | DRVCTRL1_RPC_INT(3) + | DRVCTRL1_RPC_WP(3) + | DRVCTRL1_RPC_RESET(3) + | DRVCTRL1_AVB_RX_CTL(7)); + pfc_reg_write(PFC_DRVCTRL1, reg); + reg = mmio_read_32(PFC_DRVCTRL2); + reg = ((reg & DRVCTRL2_MASK) | DRVCTRL2_AVB_RXC(7) + | DRVCTRL2_AVB_RD0(7) + | DRVCTRL2_AVB_RD1(7) + | DRVCTRL2_AVB_RD2(7) + | DRVCTRL2_AVB_RD3(7) + | DRVCTRL2_AVB_TX_CTL(3) + | DRVCTRL2_AVB_TXC(3) + | DRVCTRL2_AVB_TD0(3)); + pfc_reg_write(PFC_DRVCTRL2, reg); + reg = mmio_read_32(PFC_DRVCTRL3); + reg = ((reg & DRVCTRL3_MASK) | DRVCTRL3_AVB_TD1(3) + | DRVCTRL3_AVB_TD2(3) + | DRVCTRL3_AVB_TD3(3) + | DRVCTRL3_AVB_TXCREFCLK(7) + | DRVCTRL3_AVB_MDIO(7) + | DRVCTRL3_AVB_MDC(7) + | DRVCTRL3_AVB_MAGIC(7) + | DRVCTRL3_AVB_PHY_INT(7)); + pfc_reg_write(PFC_DRVCTRL3, reg); + reg = mmio_read_32(PFC_DRVCTRL4); + reg = ((reg & DRVCTRL4_MASK) | DRVCTRL4_AVB_LINK(7) + | DRVCTRL4_AVB_AVTP_MATCH(7) + | DRVCTRL4_AVB_AVTP_CAPTURE(7) + | DRVCTRL4_IRQ0(7) + | DRVCTRL4_IRQ1(7) + | DRVCTRL4_IRQ2(7) + | DRVCTRL4_IRQ3(7) + | DRVCTRL4_IRQ4(7)); + pfc_reg_write(PFC_DRVCTRL4, reg); + reg = mmio_read_32(PFC_DRVCTRL5); + reg = ((reg & DRVCTRL5_MASK) | DRVCTRL5_IRQ5(7) + | DRVCTRL5_PWM0(7) + | DRVCTRL5_PWM1(7) + | DRVCTRL5_PWM2(7) + | DRVCTRL5_A0(3) + | DRVCTRL5_A1(3) + | DRVCTRL5_A2(3) + | DRVCTRL5_A3(3)); + pfc_reg_write(PFC_DRVCTRL5, reg); + reg = mmio_read_32(PFC_DRVCTRL6); + reg = ((reg & DRVCTRL6_MASK) | DRVCTRL6_A4(3) + | DRVCTRL6_A5(3) + | DRVCTRL6_A6(3) + | DRVCTRL6_A7(3) + | DRVCTRL6_A8(7) + | DRVCTRL6_A9(7) + | DRVCTRL6_A10(7) + | DRVCTRL6_A11(7)); + pfc_reg_write(PFC_DRVCTRL6, reg); + reg = mmio_read_32(PFC_DRVCTRL7); + reg = ((reg & DRVCTRL7_MASK) | DRVCTRL7_A12(3) + | DRVCTRL7_A13(3) + | DRVCTRL7_A14(3) + | DRVCTRL7_A15(3) + | DRVCTRL7_A16(3) + | DRVCTRL7_A17(3) + | DRVCTRL7_A18(3) + | DRVCTRL7_A19(3)); + pfc_reg_write(PFC_DRVCTRL7, reg); + reg = mmio_read_32(PFC_DRVCTRL8); + reg = ((reg & DRVCTRL8_MASK) | DRVCTRL8_CLKOUT(7) + | DRVCTRL8_CS0(7) + | DRVCTRL8_CS1_A2(7) + | DRVCTRL8_BS(7) + | DRVCTRL8_RD(7) + | DRVCTRL8_RD_W(7) + | DRVCTRL8_WE0(7) + | DRVCTRL8_WE1(7)); + pfc_reg_write(PFC_DRVCTRL8, reg); + reg = mmio_read_32(PFC_DRVCTRL9); + reg = ((reg & DRVCTRL9_MASK) | DRVCTRL9_EX_WAIT0(7) + | DRVCTRL9_PRESETOU(7) + | DRVCTRL9_D0(7) + | DRVCTRL9_D1(7) + | DRVCTRL9_D2(7) + | DRVCTRL9_D3(7) + | DRVCTRL9_D4(7) + | DRVCTRL9_D5(7)); + pfc_reg_write(PFC_DRVCTRL9, reg); + reg = mmio_read_32(PFC_DRVCTRL10); + reg = ((reg & DRVCTRL10_MASK) | DRVCTRL10_D6(7) + | DRVCTRL10_D7(7) + | DRVCTRL10_D8(3) + | DRVCTRL10_D9(3) + | DRVCTRL10_D10(3) + | DRVCTRL10_D11(3) + | DRVCTRL10_D12(3) + | DRVCTRL10_D13(3)); + pfc_reg_write(PFC_DRVCTRL10, reg); + reg = mmio_read_32(PFC_DRVCTRL11); + reg = ((reg & DRVCTRL11_MASK) | DRVCTRL11_D14(3) + | DRVCTRL11_D15(3) + | DRVCTRL11_AVS1(7) + | DRVCTRL11_AVS2(7) + | DRVCTRL11_GP7_02(7) + | DRVCTRL11_GP7_03(7) + | DRVCTRL11_DU_DOTCLKIN0(3) + | DRVCTRL11_DU_DOTCLKIN1(3)); + pfc_reg_write(PFC_DRVCTRL11, reg); + reg = mmio_read_32(PFC_DRVCTRL12); + reg = ((reg & DRVCTRL12_MASK) | DRVCTRL12_DU_DOTCLKIN2(3) + | DRVCTRL12_DU_DOTCLKIN3(3) + | DRVCTRL12_DU_FSCLKST(3) + | DRVCTRL12_DU_TMS(3)); + pfc_reg_write(PFC_DRVCTRL12, reg); + reg = mmio_read_32(PFC_DRVCTRL13); + reg = ((reg & DRVCTRL13_MASK) | DRVCTRL13_TDO(3) + | DRVCTRL13_ASEBRK(3) + | DRVCTRL13_SD0_CLK(7) + | DRVCTRL13_SD0_CMD(7) + | DRVCTRL13_SD0_DAT0(7) + | DRVCTRL13_SD0_DAT1(7) + | DRVCTRL13_SD0_DAT2(7) + | DRVCTRL13_SD0_DAT3(7)); + pfc_reg_write(PFC_DRVCTRL13, reg); + reg = mmio_read_32(PFC_DRVCTRL14); + reg = ((reg & DRVCTRL14_MASK) | DRVCTRL14_SD1_CLK(7) + | DRVCTRL14_SD1_CMD(7) + | DRVCTRL14_SD1_DAT0(5) + | DRVCTRL14_SD1_DAT1(5) + | DRVCTRL14_SD1_DAT2(5) + | DRVCTRL14_SD1_DAT3(5) + | DRVCTRL14_SD2_CLK(5) + | DRVCTRL14_SD2_CMD(5)); + pfc_reg_write(PFC_DRVCTRL14, reg); + reg = mmio_read_32(PFC_DRVCTRL15); + reg = ((reg & DRVCTRL15_MASK) | DRVCTRL15_SD2_DAT0(5) + | DRVCTRL15_SD2_DAT1(5) + | DRVCTRL15_SD2_DAT2(5) + | DRVCTRL15_SD2_DAT3(5) + | DRVCTRL15_SD2_DS(5) + | DRVCTRL15_SD3_CLK(7) + | DRVCTRL15_SD3_CMD(7) + | DRVCTRL15_SD3_DAT0(7)); + pfc_reg_write(PFC_DRVCTRL15, reg); + reg = mmio_read_32(PFC_DRVCTRL16); + reg = ((reg & DRVCTRL16_MASK) | DRVCTRL16_SD3_DAT1(7) + | DRVCTRL16_SD3_DAT2(7) + | DRVCTRL16_SD3_DAT3(7) + | DRVCTRL16_SD3_DAT4(7) + | DRVCTRL16_SD3_DAT5(7) + | DRVCTRL16_SD3_DAT6(7) + | DRVCTRL16_SD3_DAT7(7) + | DRVCTRL16_SD3_DS(7)); + pfc_reg_write(PFC_DRVCTRL16, reg); + reg = mmio_read_32(PFC_DRVCTRL17); + reg = ((reg & DRVCTRL17_MASK) | DRVCTRL17_SD0_CD(7) + | DRVCTRL17_SD0_WP(7) + | DRVCTRL17_SD1_CD(7) + | DRVCTRL17_SD1_WP(7) + | DRVCTRL17_SCK0(7) + | DRVCTRL17_RX0(7) + | DRVCTRL17_TX0(7) + | DRVCTRL17_CTS0(7)); + pfc_reg_write(PFC_DRVCTRL17, reg); + reg = mmio_read_32(PFC_DRVCTRL18); + reg = ((reg & DRVCTRL18_MASK) | DRVCTRL18_RTS0_TANS(7) + | DRVCTRL18_RX1(7) + | DRVCTRL18_TX1(7) + | DRVCTRL18_CTS1(7) + | DRVCTRL18_RTS1_TANS(7) + | DRVCTRL18_SCK2(7) + | DRVCTRL18_TX2(7) + | DRVCTRL18_RX2(7)); + pfc_reg_write(PFC_DRVCTRL18, reg); + reg = mmio_read_32(PFC_DRVCTRL19); + reg = ((reg & DRVCTRL19_MASK) | DRVCTRL19_HSCK0(7) + | DRVCTRL19_HRX0(7) + | DRVCTRL19_HTX0(7) + | DRVCTRL19_HCTS0(7) + | DRVCTRL19_HRTS0(7) + | DRVCTRL19_MSIOF0_SCK(7) + | DRVCTRL19_MSIOF0_SYNC(7) + | DRVCTRL19_MSIOF0_SS1(7)); + pfc_reg_write(PFC_DRVCTRL19, reg); + reg = mmio_read_32(PFC_DRVCTRL20); + reg = ((reg & DRVCTRL20_MASK) | DRVCTRL20_MSIOF0_TXD(7) + | DRVCTRL20_MSIOF0_SS2(7) + | DRVCTRL20_MSIOF0_RXD(7) + | DRVCTRL20_MLB_CLK(7) + | DRVCTRL20_MLB_SIG(7) + | DRVCTRL20_MLB_DAT(7) + | DRVCTRL20_MLB_REF(7) + | DRVCTRL20_SSI_SCK0129(7)); + pfc_reg_write(PFC_DRVCTRL20, reg); + reg = mmio_read_32(PFC_DRVCTRL21); + reg = ((reg & DRVCTRL21_MASK) | DRVCTRL21_SSI_WS0129(7) + | DRVCTRL21_SSI_SDATA0(7) + | DRVCTRL21_SSI_SDATA1(7) + | DRVCTRL21_SSI_SDATA2(7) + | DRVCTRL21_SSI_SCK34(7) + | DRVCTRL21_SSI_WS34(7) + | DRVCTRL21_SSI_SDATA3(7) + | DRVCTRL21_SSI_SCK4(7)); + pfc_reg_write(PFC_DRVCTRL21, reg); + reg = mmio_read_32(PFC_DRVCTRL22); + reg = ((reg & DRVCTRL22_MASK) | DRVCTRL22_SSI_WS4(7) + | DRVCTRL22_SSI_SDATA4(7) + | DRVCTRL22_SSI_SCK5(7) + | DRVCTRL22_SSI_WS5(7) + | DRVCTRL22_SSI_SDATA5(7) + | DRVCTRL22_SSI_SCK6(7) + | DRVCTRL22_SSI_WS6(7) + | DRVCTRL22_SSI_SDATA6(7)); + pfc_reg_write(PFC_DRVCTRL22, reg); + reg = mmio_read_32(PFC_DRVCTRL23); + reg = ((reg & DRVCTRL23_MASK) | DRVCTRL23_SSI_SCK78(7) + | DRVCTRL23_SSI_WS78(7) + | DRVCTRL23_SSI_SDATA7(7) + | DRVCTRL23_SSI_SDATA8(7) + | DRVCTRL23_SSI_SDATA9(7) + | DRVCTRL23_AUDIO_CLKA(7) + | DRVCTRL23_AUDIO_CLKB(7) + | DRVCTRL23_USB0_PWEN(7)); + pfc_reg_write(PFC_DRVCTRL23, reg); + reg = mmio_read_32(PFC_DRVCTRL24); + reg = ((reg & DRVCTRL24_MASK) | DRVCTRL24_USB0_OVC(7) + | DRVCTRL24_USB1_PWEN(7) + | DRVCTRL24_USB1_OVC(7) + | DRVCTRL24_USB30_PWEN(7) + | DRVCTRL24_USB30_OVC(7) + | DRVCTRL24_USB31_PWEN(7) + | DRVCTRL24_USB31_OVC(7)); + pfc_reg_write(PFC_DRVCTRL24, reg); + + /* initialize LSI pin pull-up/down control */ + pfc_reg_write(PFC_PUD0, 0x00005FBFU); + pfc_reg_write(PFC_PUD1, 0x00300EFEU); + pfc_reg_write(PFC_PUD2, 0x330001E6U); + pfc_reg_write(PFC_PUD3, 0x000002E0U); + pfc_reg_write(PFC_PUD4, 0xFFFFFF00U); + pfc_reg_write(PFC_PUD5, 0x7F5FFF87U); + pfc_reg_write(PFC_PUD6, 0x00000055U); + + /* initialize LSI pin pull-enable register */ + pfc_reg_write(PFC_PUEN0, 0x00000FFFU); + pfc_reg_write(PFC_PUEN1, 0x00100234U); + pfc_reg_write(PFC_PUEN2, 0x000004C4U); + pfc_reg_write(PFC_PUEN3, 0x00000200U); + pfc_reg_write(PFC_PUEN4, 0x3E000000U); + pfc_reg_write(PFC_PUEN5, 0x1F000805U); + pfc_reg_write(PFC_PUEN6, 0x00000006U); + + /* initialize positive/negative logic select */ + mmio_write_32(GPIO_POSNEG0, 0x00000000U); + mmio_write_32(GPIO_POSNEG1, 0x00000000U); + mmio_write_32(GPIO_POSNEG2, 0x00000000U); + mmio_write_32(GPIO_POSNEG3, 0x00000000U); + mmio_write_32(GPIO_POSNEG4, 0x00000000U); + mmio_write_32(GPIO_POSNEG5, 0x00000000U); + mmio_write_32(GPIO_POSNEG6, 0x00000000U); + mmio_write_32(GPIO_POSNEG7, 0x00000000U); + + /* initialize general IO/interrupt switching */ + mmio_write_32(GPIO_IOINTSEL0, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL1, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL2, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL3, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL4, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL5, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL6, 0x00000000U); + mmio_write_32(GPIO_IOINTSEL7, 0x00000000U); + + /* initialize general output register */ + mmio_write_32(GPIO_OUTDT0, 0x00000001U); + mmio_write_32(GPIO_OUTDT1, 0x00000000U); + mmio_write_32(GPIO_OUTDT2, 0x00000400U); + mmio_write_32(GPIO_OUTDT3, 0x00000000U); + mmio_write_32(GPIO_OUTDT4, 0x00000000U); + mmio_write_32(GPIO_OUTDT5, 0x00000000U); + mmio_write_32(GPIO_OUTDT6, 0x00003800U); + mmio_write_32(GPIO_OUTDT7, 0x00000003U); + + /* initialize general input/output switching */ + mmio_write_32(GPIO_INOUTSEL0, 0x00000001U); + mmio_write_32(GPIO_INOUTSEL1, 0x00100B00U); + mmio_write_32(GPIO_INOUTSEL2, 0x00000418U); + mmio_write_32(GPIO_INOUTSEL3, 0x00002000U); + mmio_write_32(GPIO_INOUTSEL4, 0x00000040U); + mmio_write_32(GPIO_INOUTSEL5, 0x00000208U); + mmio_write_32(GPIO_INOUTSEL6, 0x00013F00U); + mmio_write_32(GPIO_INOUTSEL7, 0x00000003U); + +} diff --git a/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h new file mode 100644 index 000000000..3315cd6b9 --- /dev/null +++ b/drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PFC_INIT_G2M_H +#define PFC_INIT_G2M_H + +void pfc_init_g2m(void); + +#endif /* PFC_INIT_G2M_H */ diff --git a/drivers/renesas/rzg/pfc/pfc.mk b/drivers/renesas/rzg/pfc/pfc.mk new file mode 100644 index 000000000..5cae658b3 --- /dev/null +++ b/drivers/renesas/rzg/pfc/pfc.mk @@ -0,0 +1,20 @@ +# +# Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ifeq (${RCAR_LSI},${RCAR_AUTO}) + BL2_SOURCES += drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c + +else ifdef RCAR_LSI_CUT_COMPAT + ifeq (${RCAR_LSI},${RZ_G2M}) + BL2_SOURCES += drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c + endif +else + ifeq (${RCAR_LSI},${RZ_G2M}) + BL2_SOURCES += drivers/renesas/rzg/pfc/G2M/pfc_init_g2m.c + endif +endif + +BL2_SOURCES += drivers/renesas/rzg/pfc/pfc_init.c diff --git a/drivers/renesas/rzg/pfc/pfc_init.c b/drivers/renesas/rzg/pfc/pfc_init.c new file mode 100644 index 000000000..f51992d2e --- /dev/null +++ b/drivers/renesas/rzg/pfc/pfc_init.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <stdint.h> + +#include <common/debug.h> +#include <lib/mmio.h> + +#if RCAR_LSI == RCAR_AUTO +#include "G2M/pfc_init_g2m.h" +#endif /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) +#include "G2M/pfc_init_g2m.h" +#endif /* RCAR_LSI == RZ_G2M */ +#include "rcar_def.h" + +#define PRR_PRODUCT_ERR(reg) \ + do { \ + ERROR("LSI Product ID(PRR=0x%x) PFC init not supported.\n", \ + reg); \ + panic(); \ + } while (0) + +#define PRR_CUT_ERR(reg) \ + do { \ + ERROR("LSI Cut ID(PRR=0x%x) PFC init not supported.\n", \ + reg); \ + panic();\ + } while (0) + +void rzg_pfc_init(void) +{ + uint32_t reg; + + reg = mmio_read_32(RCAR_PRR); +#if RCAR_LSI == RCAR_AUTO + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_M3: + pfc_init_g2m(); + break; + default: + PRR_PRODUCT_ERR(reg); + break; + } + +#elif RCAR_LSI_CUT_COMPAT /* RCAR_LSI == RCAR_AUTO */ + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_M3: +#if RCAR_LSI != RZ_G2M + PRR_PRODUCT_ERR(reg); +#else /* RCAR_LSI != RZ_G2M */ + pfc_init_g2m(); +#endif /* RCAR_LSI != RZ_G2M */ + break; + default: + PRR_PRODUCT_ERR(reg); + break; + } + +#else /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) + if ((reg & PRR_PRODUCT_MASK) != PRR_PRODUCT_M3) { + PRR_PRODUCT_ERR(reg); + } + pfc_init_m3(); +#else /* RCAR_LSI == RZ_G2M */ +#error "Don't have PFC initialize routine(unknown)." +#endif /* RCAR_LSI == RZ_G2M */ +#endif /* RCAR_LSI == RCAR_AUTO */ +} diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c new file mode 100644 index 000000000..ceaad25f5 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <common/debug.h> +#include <lib/mmio.h> + +#include "../qos_common.h" +#include "qos_init_g2m_v10.h" +#include "qos_init_g2m_v10_mstat.h" +#include "qos_reg.h" + +#define RCAR_QOS_VERSION "rev.0.19" + +static const struct rcar_gen3_dbsc_qos_settings g2m_v10_qos[] = { + /* BUFCAM settings */ + /* DBSC_DBCAM0CNF0 not set */ + { DBSC_DBCAM0CNF1, 0x00043218U }, + { DBSC_DBCAM0CNF2, 0x000000F4U }, + { DBSC_DBCAM0CNF3, 0x00000000U }, + { DBSC_DBSCHCNT0, 0x080F0037U }, + /* DBSC_DBSCHCNT1 not set */ + { DBSC_DBSCHSZ0, 0x00000001U }, + { DBSC_DBSCHRW0, 0x22421111U }, + + /* DDR3 */ + { DBSC_SCFCTST2, 0x012F1123U }, + + /* QoS Settings */ + { DBSC_DBSCHQOS00, 0x00000F00U }, + { DBSC_DBSCHQOS01, 0x00000B00U }, + { DBSC_DBSCHQOS02, 0x00000000U }, + { DBSC_DBSCHQOS03, 0x00000000U }, + { DBSC_DBSCHQOS40, 0x00000300U }, + { DBSC_DBSCHQOS41, 0x000002F0U }, + { DBSC_DBSCHQOS42, 0x00000200U }, + { DBSC_DBSCHQOS43, 0x00000100U }, + { DBSC_DBSCHQOS90, 0x00000300U }, + { DBSC_DBSCHQOS91, 0x000002F0U }, + { DBSC_DBSCHQOS92, 0x00000200U }, + { DBSC_DBSCHQOS93, 0x00000100U }, + { DBSC_DBSCHQOS130, 0x00000100U }, + { DBSC_DBSCHQOS131, 0x000000F0U }, + { DBSC_DBSCHQOS132, 0x000000A0U }, + { DBSC_DBSCHQOS133, 0x00000040U }, + { DBSC_DBSCHQOS140, 0x000000C0U }, + { DBSC_DBSCHQOS141, 0x000000B0U }, + { DBSC_DBSCHQOS142, 0x00000080U }, + { DBSC_DBSCHQOS143, 0x00000040U }, + { DBSC_DBSCHQOS150, 0x00000040U }, + { DBSC_DBSCHQOS151, 0x00000030U }, + { DBSC_DBSCHQOS152, 0x00000020U }, + { DBSC_DBSCHQOS153, 0x00000010U }, +}; + +void qos_init_g2m_v10(void) +{ + rzg_qos_dbsc_setting(g2m_v10_qos, ARRAY_SIZE(g2m_v10_qos), false); + + /* DRAM split address mapping */ +#if RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH +#if RCAR_LSI == RZ_G2M +#error "Don't set DRAM Split 4ch(G2M)" +#else /* RCAR_LSI == RZ_G2M */ + ERROR("DRAM Split 4ch not supported.(G2M)"); + panic(); +#endif /* RCAR_LSI == RZ_G2M */ +#elif (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_2CH) || \ + (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_AUTO) + NOTICE("BL2: DRAM Split is 2ch\n"); + mmio_write_32(AXI_ADSPLCR0, 0x00000000U); + mmio_write_32(AXI_ADSPLCR1, ADSPLCR0_ADRMODE_DEFAULT | + ADSPLCR0_SPLITSEL(0xFFU) | ADSPLCR0_AREA(0x1CU) | + ADSPLCR0_SWP); + mmio_write_32(AXI_ADSPLCR2, 0x089A0000U); + mmio_write_32(AXI_ADSPLCR3, 0x00000000U); +#else /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + NOTICE("BL2: DRAM Split is OFF\n"); +#endif /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + +#if !(RCAR_QOS_TYPE == RCAR_QOS_NONE) +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT + NOTICE("BL2: QoS is default setting(%s)\n", RCAR_QOS_VERSION); +#endif + + /* Resource Alloc setting */ + mmio_write_32(QOSCTRL_RAS, 0x00000028U); + mmio_write_32(QOSCTRL_FIXTH, 0x000F0005U); + mmio_write_32(QOSCTRL_REGGD, 0x00000000U); + mmio_write_64(QOSCTRL_DANN, 0x0101010102020201UL); + mmio_write_32(QOSCTRL_DANT, 0x00100804U); + mmio_write_32(QOSCTRL_EC, 0x00000000U); + mmio_write_64(QOSCTRL_EMS, 0x0000000000000000UL); + mmio_write_32(QOSCTRL_FSS, 0x000003e8U); + mmio_write_32(QOSCTRL_INSFC, 0xC7840001U); + mmio_write_32(QOSCTRL_BERR, 0x00000000U); + mmio_write_32(QOSCTRL_RACNT0, 0x00000000U); + + /* QOSBW setting */ + mmio_write_32(QOSCTRL_SL_INIT, SL_INIT_REFFSSLOT | SL_INIT_SLOTSSLOT | + SL_INIT_SSLOTCLK); + mmio_write_32(QOSCTRL_REF_ARS, 0x00330000U); + + /* QOSBW SRAM setting */ + uint32_t i; + + for (i = 0U; i < ARRAY_SIZE(mstat_fix); i++) { + mmio_write_64(QOSBW_FIX_QOS_BANK0 + i * 8U, mstat_fix[i]); + mmio_write_64(QOSBW_FIX_QOS_BANK1 + i * 8U, mstat_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(mstat_be); i++) { + mmio_write_64(QOSBW_BE_QOS_BANK0 + i * 8U, mstat_be[i]); + mmio_write_64(QOSBW_BE_QOS_BANK1 + i * 8U, mstat_be[i]); + } + + /* 3DG bus Leaf setting */ + mmio_write_32(0xFD820808U, 0x00001234U); + mmio_write_32(0xFD820800U, 0x00000006U); + mmio_write_32(0xFD821800U, 0x00000006U); + mmio_write_32(0xFD822800U, 0x00000006U); + mmio_write_32(0xFD823800U, 0x00000006U); + mmio_write_32(0xFD824800U, 0x00000006U); + mmio_write_32(0xFD825800U, 0x00000006U); + mmio_write_32(0xFD826800U, 0x00000006U); + mmio_write_32(0xFD827800U, 0x00000006U); + + /* RT bus Leaf setting */ + mmio_write_32(0xFFC50800U, 0x00000000U); + mmio_write_32(0xFFC51800U, 0x00000000U); + + /* Resource Alloc start */ + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); + + /* QOSBW start */ + mmio_write_32(QOSCTRL_STATQC, 0x00000001U); +#else /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ + NOTICE("BL2: QoS is None\n"); + + /* Resource Alloc setting */ + mmio_write_32(QOSCTRL_EC, 0x00000000U); + /* Resource Alloc start */ + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ +} diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h new file mode 100644 index 000000000..627974ab2 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V10_H +#define QOS_INIT_G2M_V10_H + +void qos_init_g2m_v10(void); + +#endif /* QOS_INIT_G2M_V10_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h new file mode 100644 index 000000000..c37915c49 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10_mstat.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V10_MSTAT_H +#define QOS_INIT_G2M_V10_MSTAT_H + +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT +static const uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004030000FFFFUL, + /* 0x0038, */ 0x001004030000FFFFUL, + /* 0x0040, */ 0x001414090000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001410010000FFFFUL, + /* 0x0058, */ 0x00140C090000FFFFUL, + /* 0x0060, */ 0x00140C090000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001410010000FFFFUL, + /* 0x0078, */ 0x001004020000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFFFUL, + /* 0x0090, */ 0x001408060000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00A0, */ 0x000C08020000FFFFUL, + /* 0x00A8, */ 0x000C04010000FFFFUL, + /* 0x00B0, */ 0x000C04010000FFFFUL, + /* 0x00B8, */ 0x0000000000000000UL, + /* 0x00C0, */ 0x000C08020000FFFFUL, + /* 0x00C8, */ 0x000C04010000FFFFUL, + /* 0x00D0, */ 0x000C04010000FFFFUL, + /* 0x00D8, */ 0x000C04030000FFFFUL, + /* 0x00E0, */ 0x000C100F0000FFFFUL, + /* 0x00E8, */ 0x0000000000000000UL, + /* 0x00F0, */ 0x001010080000FFFFUL, + /* 0x00F8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x001010080000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x00100C0A0000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x00100C0A0000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x00100C0A0000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x001008050000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x001028280000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01A0, */ 0x00100C0A0000FFFFUL, + /* 0x01A8, */ 0x0000000000000000UL, + /* 0x01B0, */ 0x0000000000000000UL, + /* 0x01B8, */ 0x0000000000000000UL, + /* 0x01C0, */ 0x0000000000000000UL, + /* 0x01C8, */ 0x0000000000000000UL, + /* 0x01D0, */ 0x0000000000000000UL, + /* 0x01D8, */ 0x0000000000000000UL, + /* 0x01E0, */ 0x0000000000000000UL, + /* 0x01E8, */ 0x0000000000000000UL, + /* 0x01F0, */ 0x0000000000000000UL, + /* 0x01F8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x001408010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02A0, */ 0x000C04010000FFFFUL, + /* 0x02A8, */ 0x000C04010000FFFFUL, + /* 0x02B0, */ 0x001404010000FFFFUL, + /* 0x02B8, */ 0x0000000000000000UL, + /* 0x02C0, */ 0x0000000000000000UL, + /* 0x02C8, */ 0x0000000000000000UL, + /* 0x02D0, */ 0x000C04010000FFFFUL, + /* 0x02D8, */ 0x000C04010000FFFFUL, + /* 0x02E0, */ 0x001404010000FFFFUL, + /* 0x02E8, */ 0x0000000000000000UL, + /* 0x02F0, */ 0x0000000000000000UL, + /* 0x02F8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static const uint64_t mstat_be[] = { + /* 0x0000, */ 0x001200100C89C401UL, + /* 0x0008, */ 0x001200100C89C401UL, + /* 0x0010, */ 0x001200100C89C401UL, + /* 0x0018, */ 0x001200100C89C401UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x001100100C803401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00A0, */ 0x0000000000000000UL, + /* 0x00A8, */ 0x0000000000000000UL, + /* 0x00B0, */ 0x0000000000000000UL, + /* 0x00B8, */ 0x0000000000000000UL, + /* 0x00C0, */ 0x0000000000000000UL, + /* 0x00C8, */ 0x0000000000000000UL, + /* 0x00D0, */ 0x0000000000000000UL, + /* 0x00D8, */ 0x0000000000000000UL, + /* 0x00E0, */ 0x0000000000000000UL, + /* 0x00E8, */ 0x0000000000000000UL, + /* 0x00F0, */ 0x0000000000000000UL, + /* 0x00F8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01A0, */ 0x0000000000000000UL, + /* 0x01A8, */ 0x0000000000000000UL, + /* 0x01B0, */ 0x0000000000000000UL, + /* 0x01B8, */ 0x0000000000000000UL, + /* 0x01C0, */ 0x001100500C8FFC01UL, + /* 0x01C8, */ 0x001100500C8FFC01UL, + /* 0x01D0, */ 0x001100500C8FFC01UL, + /* 0x01D8, */ 0x001100500C8FFC01UL, + /* 0x01E0, */ 0x0000000000000000UL, + /* 0x01E8, */ 0x001200100C803401UL, + /* 0x01F0, */ 0x001100100C80FC01UL, + /* 0x01F8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x001200100C80FC01UL, + /* 0x0210, */ 0x001100100C80FC01UL, + /* 0x0218, */ 0x001100100C825801UL, + /* 0x0220, */ 0x001100100C825801UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x001100100C825801UL, + /* 0x0238, */ 0x001100100C825801UL, + /* 0x0240, */ 0x001200100C8BB801UL, + /* 0x0248, */ 0x001100100C8EA401UL, + /* 0x0250, */ 0x001200100C8BB801UL, + /* 0x0258, */ 0x001100100C8EA401UL, + /* 0x0260, */ 0x001100100C84E401UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x001100100C81F401UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02A0, */ 0x0000000000000000UL, + /* 0x02A8, */ 0x0000000000000000UL, + /* 0x02B0, */ 0x0000000000000000UL, + /* 0x02B8, */ 0x001100100C803401UL, + /* 0x02C0, */ 0x0000000000000000UL, + /* 0x02C8, */ 0x0000000000000000UL, + /* 0x02D0, */ 0x0000000000000000UL, + /* 0x02D8, */ 0x0000000000000000UL, + /* 0x02E0, */ 0x0000000000000000UL, + /* 0x02E8, */ 0x001100100C803401UL, + /* 0x02F0, */ 0x001100300C8FFC01UL, + /* 0x02F8, */ 0x001100500C8FFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x001100300C8FFC01UL, + /* 0x0310, */ 0x001100500C8FFC01UL, + /* 0x0318, */ 0x001200100C803401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ + +#endif /* QOS_INIT_G2M_V10_MSTAT_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c new file mode 100644 index 000000000..db61858ff --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <common/debug.h> +#include <lib/mmio.h> + +#include "../qos_common.h" +#include "qos_init_g2m_v11.h" +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v11_mstat195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v11_mstat390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v11_qoswt195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v11_qoswt390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ +#include "qos_reg.h" + +#define RCAR_QOS_VERSION "rev.0.19" + +#define QOSWT_TIME_BANK0 20000000U /* unit:ns */ + +#define QOSWT_WTEN_ENABLE 0x1U + +#define QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_11 (SL_INIT_SSLOTCLK_G2M_11 - 0x5U) + +#define OSWT_WTREF_SLOT0_EN_REQ1_SLOT 3U +#define OSWT_WTREF_SLOT0_EN_REQ2_SLOT 9U +#define QOSWT_WTREF_SLOT0_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) +#define QOSWT_WTREF_SLOT1_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) + +#define QOSWT_WTSET0_REQ_SSLOT0 5U +#define WT_BASE_SUB_SLOT_NUM0 12U +#define QOSWT_WTSET0_PERIOD0_G2M_11 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_11) - 1U) +#define QOSWT_WTSET0_SSLOT0 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET0_SLOTSLOT0 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +#define QOSWT_WTSET1_PERIOD1_G2M_11 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_11) - 1U) +#define QOSWT_WTSET1_SSLOT1 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET1_SLOTSLOT1 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +static const struct rcar_gen3_dbsc_qos_settings g2m_v11_qos[] = { + /* BUFCAM settings */ + { DBSC_DBCAM0CNF1, 0x00043218U }, + { DBSC_DBCAM0CNF2, 0x000000F4U }, + { DBSC_DBCAM0CNF3, 0x00000000U }, + { DBSC_DBSCHCNT0, 0x000F0037U }, + { DBSC_DBSCHSZ0, 0x00000001U }, + { DBSC_DBSCHRW0, 0x22421111U }, + + /* DDR3 */ + { DBSC_SCFCTST2, 0x012F1123U }, + + /* QoS settings */ + { DBSC_DBSCHQOS00, 0x00000F00U }, + { DBSC_DBSCHQOS01, 0x00000B00U }, + { DBSC_DBSCHQOS02, 0x00000000U }, + { DBSC_DBSCHQOS03, 0x00000000U }, + { DBSC_DBSCHQOS40, 0x00000300U }, + { DBSC_DBSCHQOS41, 0x000002F0U }, + { DBSC_DBSCHQOS42, 0x00000200U }, + { DBSC_DBSCHQOS43, 0x00000100U }, + { DBSC_DBSCHQOS90, 0x00000100U }, + { DBSC_DBSCHQOS91, 0x000000F0U }, + { DBSC_DBSCHQOS92, 0x000000A0U }, + { DBSC_DBSCHQOS93, 0x00000040U }, + { DBSC_DBSCHQOS120, 0x00000040U }, + { DBSC_DBSCHQOS121, 0x00000030U }, + { DBSC_DBSCHQOS122, 0x00000020U }, + { DBSC_DBSCHQOS123, 0x00000010U }, + { DBSC_DBSCHQOS130, 0x00000100U }, + { DBSC_DBSCHQOS131, 0x000000F0U }, + { DBSC_DBSCHQOS132, 0x000000A0U }, + { DBSC_DBSCHQOS133, 0x00000040U }, + { DBSC_DBSCHQOS140, 0x000000C0U }, + { DBSC_DBSCHQOS141, 0x000000B0U }, + { DBSC_DBSCHQOS142, 0x00000080U }, + { DBSC_DBSCHQOS143, 0x00000040U }, + { DBSC_DBSCHQOS150, 0x00000040U }, + { DBSC_DBSCHQOS151, 0x00000030U }, + { DBSC_DBSCHQOS152, 0x00000020U }, + { DBSC_DBSCHQOS153, 0x00000010U }, +}; + +void qos_init_g2m_v11(void) +{ + uint32_t i; + + rzg_qos_dbsc_setting(g2m_v11_qos, ARRAY_SIZE(g2m_v11_qos), false); + + /* DRAM Split Address mapping */ +#if RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH +#if RCAR_LSI == RZ_G2M +#error "Don't set DRAM Split 4ch(G2M)" +#else /* RCAR_LSI == RZ_G2M */ + ERROR("DRAM Split 4ch not supported.(G2M)"); + panic(); +#endif /* RCAR_LSI == RZ_G2M */ +#elif (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_2CH) || \ + (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_AUTO) + NOTICE("BL2: DRAM Split is 2ch\n"); + mmio_write_32(AXI_ADSPLCR0, 0x00000000U); + mmio_write_32(AXI_ADSPLCR1, ADSPLCR0_ADRMODE_DEFAULT | + ADSPLCR0_SPLITSEL(0xFFU) | ADSPLCR0_AREA(0x1CU) | + ADSPLCR0_SWP); + mmio_write_32(AXI_ADSPLCR2, 0x00001004U); + mmio_write_32(AXI_ADSPLCR3, 0x00000000U); +#else /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + NOTICE("BL2: DRAM Split is OFF\n"); +#endif /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + +#if !(RCAR_QOS_TYPE == RCAR_QOS_NONE) +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT + NOTICE("BL2: QoS is default setting(%s)\n", RCAR_QOS_VERSION); +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ + +#if RCAR_REF_INT == RCAR_REF_DEFAULT + NOTICE("BL2: DRAM refresh interval 1.95 usec\n"); +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + NOTICE("BL2: DRAM refresh interval 3.9 usec\n"); +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + NOTICE("BL2: Periodic Write DQ Training\n"); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_RAS, 0x00000044U); + mmio_write_64(QOSCTRL_DANN, 0x0404020002020201UL); + mmio_write_32(QOSCTRL_DANT, 0x0020100AU); + mmio_write_32(QOSCTRL_INSFC, 0x06330001U); + mmio_write_32(QOSCTRL_RACNT0, 0x02010003U); /* GPU Boost Mode ON */ + + mmio_write_32(QOSCTRL_SL_INIT, + SL_INIT_REFFSSLOT | SL_INIT_SLOTSSLOT | + SL_INIT_SSLOTCLK_G2M_11); +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + mmio_write_32(QOSCTRL_REF_ARS, + QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_11 << 16); +#else /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + mmio_write_32(QOSCTRL_REF_ARS, 0x00330000U); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + for (i = 0U; i < ARRAY_SIZE(mstat_fix); i++) { + mmio_write_64(QOSBW_FIX_QOS_BANK0 + i * 8U, mstat_fix[i]); + mmio_write_64(QOSBW_FIX_QOS_BANK1 + i * 8U, mstat_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(mstat_be); i++) { + mmio_write_64(QOSBW_BE_QOS_BANK0 + i * 8U, mstat_be[i]); + mmio_write_64(QOSBW_BE_QOS_BANK1 + i * 8U, mstat_be[i]); + } +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + for (i = 0U; i < ARRAY_SIZE(qoswt_fix); i++) { + mmio_write_64(QOSWT_FIX_WTQOS_BANK0 + i * 8U, qoswt_fix[i]); + mmio_write_64(QOSWT_FIX_WTQOS_BANK1 + i * 8U, qoswt_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(qoswt_be); i++) { + mmio_write_64(QOSWT_BE_WTQOS_BANK0 + i * 8U, qoswt_be[i]); + mmio_write_64(QOSWT_BE_WTQOS_BANK1 + i * 8U, qoswt_be[i]); + } +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + /* 3DG bus Leaf setting */ + mmio_write_32(GPU_ACT_GRD, 0x00001234U); + mmio_write_32(GPU_ACT0, 0x00000000U); + mmio_write_32(GPU_ACT1, 0x00000000U); + mmio_write_32(GPU_ACT2, 0x00000000U); + mmio_write_32(GPU_ACT3, 0x00000000U); + + /* RT bus Leaf setting */ + mmio_write_32(RT_ACT0, 0x00000000U); + mmio_write_32(RT_ACT1, 0x00000000U); + + /* CCI bus Leaf setting */ + mmio_write_32(CPU_ACT0, 0x00000003U); + mmio_write_32(CPU_ACT1, 0x00000003U); + mmio_write_32(CPU_ACT2, 0x00000003U); + mmio_write_32(CPU_ACT3, 0x00000003U); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + /* re-write training setting */ + mmio_write_32(QOSWT_WTREF, + (QOSWT_WTREF_SLOT1_EN << 16) | QOSWT_WTREF_SLOT0_EN); + mmio_write_32(QOSWT_WTSET0, + (QOSWT_WTSET0_PERIOD0_G2M_11 << 16) | + (QOSWT_WTSET0_SSLOT0 << 8) | QOSWT_WTSET0_SLOTSLOT0); + mmio_write_32(QOSWT_WTSET1, + (QOSWT_WTSET1_PERIOD1_G2M_11 << 16) | + (QOSWT_WTSET1_SSLOT1 << 8) | QOSWT_WTSET1_SLOTSLOT1); + + mmio_write_32(QOSWT_WTEN, QOSWT_WTEN_ENABLE); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_STATQC, 0x00000001U); +#else /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ + NOTICE("BL2: QoS is None\n"); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ +} diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h new file mode 100644 index 000000000..d0424930b --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_H +#define QOS_INIT_G2M_V11_H + +void qos_init_g2m_v11(void); + +#endif /* QOS_INIT_G2M_V11_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat195.h new file mode 100644 index 000000000..950abd6fb --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_MSTAT195_H +#define QOS_INIT_G2M_V11_MSTAT195_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000FFFFUL, + /* 0x0038, */ 0x001004040000FFFFUL, + /* 0x0040, */ 0x001414090000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x00140C0A0000FFFFUL, + /* 0x0060, */ 0x00140C0A0000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001004030000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFFFUL, + /* 0x0090, */ 0x001408070000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C04020000FFFFUL, + /* 0x00a8, */ 0x000C04010000FFFFUL, + /* 0x00b0, */ 0x000C04010000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C04020000FFFFUL, + /* 0x00c8, */ 0x000C04010000FFFFUL, + /* 0x00d0, */ 0x000C04010000FFFFUL, + /* 0x00d8, */ 0x000C08050000FFFFUL, + /* 0x00e0, */ 0x000C14120000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x00100C0B0000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0010100D0000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x00100C0B0000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x001008060000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x00102C2C0000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x00100C0B0000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x001408010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x001200100BD03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100600BDFFC01UL, + /* 0x01c8, */ 0x002100600BDFFC01UL, + /* 0x01d0, */ 0x002100600BDFFC01UL, + /* 0x01d8, */ 0x002100600BDFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x001100200BDFFC01UL, + /* 0x0220, */ 0x001100200BDFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x001100200BDFFC01UL, + /* 0x0238, */ 0x001100200BDFFC01UL, + /* 0x0240, */ 0x001200200BDFFC01UL, + /* 0x0248, */ 0x001100200BDFFC01UL, + /* 0x0250, */ 0x001200200BDFFC01UL, + /* 0x0258, */ 0x001100200BDFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x001100400BDFFC01UL, + /* 0x02f8, */ 0x001100600BDFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x001100400BDFFC01UL, + /* 0x0310, */ 0x001100600BDFFC01UL, + /* 0x0318, */ 0x001200100BD03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_MSTAT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat390.h new file mode 100644 index 000000000..5c6fd2492 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_mstat390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_MSTAT390_H +#define QOS_INIT_G2M_V11_MSTAT390_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000FFFFUL, + /* 0x0038, */ 0x001008070000FFFFUL, + /* 0x0040, */ 0x001424120000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x001414130000FFFFUL, + /* 0x0060, */ 0x001414130000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001008050000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFFFUL, + /* 0x0090, */ 0x0014100D0000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C08040000FFFFUL, + /* 0x00a8, */ 0x000C04020000FFFFUL, + /* 0x00b0, */ 0x000C04020000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C08040000FFFFUL, + /* 0x00c8, */ 0x000C04020000FFFFUL, + /* 0x00d0, */ 0x000C04020000FFFFUL, + /* 0x00d8, */ 0x000C0C0A0000FFFFUL, + /* 0x00e0, */ 0x000C24230000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x001044110000FFFFUL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x001014110000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x001018150000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x00101C190000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x001018150000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x00100C0B0000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x001058570000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x001018150000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x000C04010000FFFFUL, + /* 0x01f0, */ 0x000C04010000FFFFUL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x000C04010000FFFFUL, + /* 0x0210, */ 0x000C04010000FFFFUL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFFFUL, + /* 0x0268, */ 0x001410010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x000C08020000FFFFUL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x00140C010000FFFFUL, + /* 0x02b8, */ 0x000C04010000FFFFUL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x00140C010000FFFFUL, + /* 0x02e8, */ 0x000C04010000FFFFUL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x0012003005EFFC01UL, + /* 0x0008, */ 0x0012003005EFFC01UL, + /* 0x0010, */ 0x0012003005EFFC01UL, + /* 0x0018, */ 0x0012003005EFFC01UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0012001005E03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100B005EFFC01UL, + /* 0x01c8, */ 0x002100B005EFFC01UL, + /* 0x01d0, */ 0x002100B005EFFC01UL, + /* 0x01d8, */ 0x002100B005EFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0021003005EFFC01UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0021003005EFFC01UL, + /* 0x0218, */ 0x0011003005EFFC01UL, + /* 0x0220, */ 0x0011003005EFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0011003005EFFC01UL, + /* 0x0238, */ 0x0011003005EFFC01UL, + /* 0x0240, */ 0x0012003005EFFC01UL, + /* 0x0248, */ 0x0011003005EFFC01UL, + /* 0x0250, */ 0x0012003005EFFC01UL, + /* 0x0258, */ 0x0011003005EFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0011007005EFFC01UL, + /* 0x02f8, */ 0x001100B005EFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0011007005EFFC01UL, + /* 0x0310, */ 0x001100B005EFFC01UL, + /* 0x0318, */ 0x0012001005E03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_MSTAT390_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h new file mode 100644 index 000000000..f526a82e7 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_QOSWT195_H +#define QOS_INIT_G2M_V11_QOSWT195_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000C010UL, + /* 0x0038, */ 0x001004040000C010UL, + /* 0x0040, */ 0x001414090000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x00140C0A0000C010UL, + /* 0x0060, */ 0x00140C0A0000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001004030000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFF0UL, + /* 0x0090, */ 0x001408070000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C08020000FFF0UL, + /* 0x0268, */ 0x001408010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C04010000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_QOSWT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h new file mode 100644 index 000000000..bfb80e393 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11_qoswt390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V11_QOSWT390_H +#define QOS_INIT_G2M_V11_QOSWT390_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000C010UL, + /* 0x0038, */ 0x001008070000C010UL, + /* 0x0040, */ 0x001424120000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x001414130000C010UL, + /* 0x0060, */ 0x001414130000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001008050000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFF0UL, + /* 0x0090, */ 0x0014100D0000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFF0UL, + /* 0x0268, */ 0x001410010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C08020000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V11_QOSWT390_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c new file mode 100644 index 000000000..321cd2bf8 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <common/debug.h> +#include <lib/mmio.h> + +#include "../qos_common.h" +#include "qos_init_g2m_v30.h" +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v30_mstat195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v30_mstat390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE +#if RCAR_REF_INT == RCAR_REF_DEFAULT +#include "qos_init_g2m_v30_qoswt195.h" +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#include "qos_init_g2m_v30_qoswt390.h" +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ +#endif /* RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT */ +#include "qos_reg.h" + +#define RCAR_QOS_VERSION "rev.0.04" + +#define QOSWT_TIME_BANK0 20000000U /* unit:ns */ + +#define QOSWT_WTEN_ENABLE 0x1U + +#define QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_30 (SL_INIT_SSLOTCLK_G2M_30 - 0x5U) + +#define OSWT_WTREF_SLOT0_EN_REQ1_SLOT 3U +#define OSWT_WTREF_SLOT0_EN_REQ2_SLOT 9U +#define QOSWT_WTREF_SLOT0_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) +#define QOSWT_WTREF_SLOT1_EN \ + ((0x1U << OSWT_WTREF_SLOT0_EN_REQ1_SLOT) | \ + (0x1U << OSWT_WTREF_SLOT0_EN_REQ2_SLOT)) + +#define QOSWT_WTSET0_REQ_SSLOT0 5U +#define WT_BASE_SUB_SLOT_NUM0 12U +#define QOSWT_WTSET0_PERIOD0_G2M_30 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_30) - 1U) +#define QOSWT_WTSET0_SSLOT0 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET0_SLOTSLOT0 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +#define QOSWT_WTSET1_PERIOD1_G2M_30 \ + ((QOSWT_TIME_BANK0 / QOSWT_WTSET0_CYCLE_G2M_30) - 1U) +#define QOSWT_WTSET1_SSLOT1 (QOSWT_WTSET0_REQ_SSLOT0 - 1U) +#define QOSWT_WTSET1_SLOTSLOT1 (WT_BASE_SUB_SLOT_NUM0 - 1U) + +static const struct rcar_gen3_dbsc_qos_settings g2m_v30_qos[] = { + /* BUFCAM settings */ + { DBSC_DBCAM0CNF1, 0x00043218U }, + { DBSC_DBCAM0CNF2, 0x000000F4U }, + { DBSC_DBCAM0CNF3, 0x00000000U }, + { DBSC_DBSCHCNT0, 0x000F0037U }, + { DBSC_DBSCHSZ0, 0x00000001U }, + { DBSC_DBSCHRW0, 0x22421111U }, + + /* DDR3 */ + { DBSC_SCFCTST2, 0x012F1123U }, + + /* QoS settings */ + { DBSC_DBSCHQOS00, 0x00000F00U }, + { DBSC_DBSCHQOS01, 0x00000B00U }, + { DBSC_DBSCHQOS02, 0x00000000U }, + { DBSC_DBSCHQOS03, 0x00000000U }, + { DBSC_DBSCHQOS40, 0x00000300U }, + { DBSC_DBSCHQOS41, 0x000002F0U }, + { DBSC_DBSCHQOS42, 0x00000200U }, + { DBSC_DBSCHQOS43, 0x00000100U }, + { DBSC_DBSCHQOS90, 0x00000100U }, + { DBSC_DBSCHQOS91, 0x000000F0U }, + { DBSC_DBSCHQOS92, 0x000000A0U }, + { DBSC_DBSCHQOS93, 0x00000040U }, + { DBSC_DBSCHQOS120, 0x00000040U }, + { DBSC_DBSCHQOS121, 0x00000030U }, + { DBSC_DBSCHQOS122, 0x00000020U }, + { DBSC_DBSCHQOS123, 0x00000010U }, + { DBSC_DBSCHQOS130, 0x00000100U }, + { DBSC_DBSCHQOS131, 0x000000F0U }, + { DBSC_DBSCHQOS132, 0x000000A0U }, + { DBSC_DBSCHQOS133, 0x00000040U }, + { DBSC_DBSCHQOS140, 0x000000C0U }, + { DBSC_DBSCHQOS141, 0x000000B0U }, + { DBSC_DBSCHQOS142, 0x00000080U }, + { DBSC_DBSCHQOS143, 0x00000040U }, + { DBSC_DBSCHQOS150, 0x00000040U }, + { DBSC_DBSCHQOS151, 0x00000030U }, + { DBSC_DBSCHQOS152, 0x00000020U }, + { DBSC_DBSCHQOS153, 0x00000010U }, +}; + +void qos_init_g2m_v30(void) +{ + uint32_t i; + + rzg_qos_dbsc_setting(g2m_v30_qos, ARRAY_SIZE(g2m_v30_qos), true); + + /* DRAM Split Address mapping */ +#if RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH +#if RCAR_LSI == RZ_G2M + #error "Don't set DRAM Split 4ch(G2M)" +#else /* RCAR_LSI == RZ_G2M */ + ERROR("DRAM Split 4ch not supported.(G2M)"); + panic(); +#endif /* RCAR_LSI == RZ_G2M */ +#elif (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_2CH) || \ + (RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_AUTO) + NOTICE("BL2: DRAM Split is 2ch\n"); + mmio_write_32(AXI_ADSPLCR0, 0x00000000U); + mmio_write_32(AXI_ADSPLCR1, ADSPLCR0_ADRMODE_DEFAULT | + ADSPLCR0_SPLITSEL(0xFFU) | ADSPLCR0_AREA(0x1DU) | + ADSPLCR0_SWP); + mmio_write_32(AXI_ADSPLCR2, 0x00001004U); + mmio_write_32(AXI_ADSPLCR3, 0x00000000U); +#else /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + NOTICE("BL2: DRAM Split is OFF\n"); +#endif /* RCAR_DRAM_SPLIT == RCAR_DRAM_SPLIT_4CH */ + +#if !(RCAR_QOS_TYPE == RCAR_QOS_NONE) +#if RCAR_QOS_TYPE == RCAR_QOS_TYPE_DEFAULT + NOTICE("BL2: QoS is default setting(%s)\n", RCAR_QOS_VERSION); +#endif + +#if RCAR_REF_INT == RCAR_REF_DEFAULT + NOTICE("BL2: DRAM refresh interval 1.95 usec\n"); +#else /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + NOTICE("BL2: DRAM refresh interval 3.9 usec\n"); +#endif /* RCAR_REF_INT == RCAR_REF_DEFAULT */ + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + NOTICE("BL2: Periodic Write DQ Training\n"); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_RAS, 0x00000044U); + mmio_write_64(QOSCTRL_DANN, 0x0404020002020201UL); + mmio_write_32(QOSCTRL_DANT, 0x0020100AU); + mmio_write_32(QOSCTRL_FSS, 0x0000000AU); + mmio_write_32(QOSCTRL_INSFC, 0x06330001U); + mmio_write_32(QOSCTRL_EARLYR, 0x00000001U); + mmio_write_32(QOSCTRL_RACNT0, 0x02010003U); /* GPU Boost Mode ON */ + + /* GPU Boost Mode */ + mmio_write_32(QOSCTRL_STATGEN0, 0x00000001U); + + mmio_write_32(QOSCTRL_SL_INIT, + SL_INIT_REFFSSLOT | SL_INIT_SLOTSSLOT | + SL_INIT_SSLOTCLK_G2M_30); + mmio_write_32(QOSCTRL_REF_ARS, + QOSCTRL_REF_ARS_ARBSTOPCYCLE_G2M_30 << 16); + + for (i = 0U; i < ARRAY_SIZE(mstat_fix); i++) { + mmio_write_64(QOSBW_FIX_QOS_BANK0 + i * 8U, mstat_fix[i]); + mmio_write_64(QOSBW_FIX_QOS_BANK1 + i * 8U, mstat_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(mstat_be); i++) { + mmio_write_64(QOSBW_BE_QOS_BANK0 + i * 8U, mstat_be[i]); + mmio_write_64(QOSBW_BE_QOS_BANK1 + i * 8U, mstat_be[i]); + } +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + for (i = 0U; i < ARRAY_SIZE(qoswt_fix); i++) { + mmio_write_64(QOSWT_FIX_WTQOS_BANK0 + i * 8U, qoswt_fix[i]); + mmio_write_64(QOSWT_FIX_WTQOS_BANK1 + i * 8U, qoswt_fix[i]); + } + for (i = 0U; i < ARRAY_SIZE(qoswt_be); i++) { + mmio_write_64(QOSWT_BE_WTQOS_BANK0 + i * 8U, qoswt_be[i]); + mmio_write_64(QOSWT_BE_WTQOS_BANK1 + i * 8U, qoswt_be[i]); + } +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + /* RT bus Leaf setting */ + mmio_write_32(RT_ACT0, 0x00000000U); + mmio_write_32(RT_ACT1, 0x00000000U); + + /* CCI bus Leaf setting */ + mmio_write_32(CPU_ACT0, 0x00000003U); + mmio_write_32(CPU_ACT1, 0x00000003U); + mmio_write_32(CPU_ACT2, 0x00000003U); + mmio_write_32(CPU_ACT3, 0x00000003U); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); + +#if RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE + /* re-write training setting */ + mmio_write_32(QOSWT_WTREF, + (QOSWT_WTREF_SLOT1_EN << 16) | QOSWT_WTREF_SLOT0_EN); + mmio_write_32(QOSWT_WTSET0, (QOSWT_WTSET0_PERIOD0_G2M_30 << 16) | + (QOSWT_WTSET0_SSLOT0 << 8) | QOSWT_WTSET0_SLOTSLOT0); + mmio_write_32(QOSWT_WTSET1, (QOSWT_WTSET1_PERIOD1_G2M_30 << 16) | + (QOSWT_WTSET1_SSLOT1 << 8) | QOSWT_WTSET1_SLOTSLOT1); + + mmio_write_32(QOSWT_WTEN, QOSWT_WTEN_ENABLE); +#endif /* RCAR_REWT_TRAINING != RCAR_REWT_TRAINING_DISABLE */ + + mmio_write_32(QOSCTRL_STATQC, 0x00000001U); +#else /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ + NOTICE("BL2: QoS is None\n"); + + mmio_write_32(QOSCTRL_RAEN, 0x00000001U); +#endif /* !(RCAR_QOS_TYPE == RCAR_QOS_NONE) */ +} diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h new file mode 100644 index 000000000..f89eabf83 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_H +#define QOS_INIT_G2M_V30_H + +void qos_init_g2m_v30(void); + +#endif /* QOS_INIT_G2M_V30_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat195.h new file mode 100644 index 000000000..fd15788c5 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_MSTAT195_H +#define QOS_INIT_G2M_V30_MSTAT195_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000FFFFUL, + /* 0x0038, */ 0x001004040000FFFFUL, + /* 0x0040, */ 0x001414090000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x00140C0A0000FFFFUL, + /* 0x0060, */ 0x00140C0A0000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001004030000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFFFUL, + /* 0x0090, */ 0x001408070000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C04020000FFFFUL, + /* 0x00a8, */ 0x000C04010000FFFFUL, + /* 0x00b0, */ 0x000C04010000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C04020000FFFFUL, + /* 0x00c8, */ 0x000C04010000FFFFUL, + /* 0x00d0, */ 0x000C04010000FFFFUL, + /* 0x00d8, */ 0x000C08050000FFFFUL, + /* 0x00e0, */ 0x000C10100000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x001024090000FFFFUL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x00100C090000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x000C10100000FFFFUL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x00100C0B0000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0010100D0000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x00100C0B0000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x001008060000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x00102C2C0000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x00100C0B0000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x000C04010000FFFFUL, + /* 0x01f0, */ 0x000C04010000FFFFUL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x000C04010000FFFFUL, + /* 0x0210, */ 0x000C04010000FFFFUL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C08020000FFFFUL, + /* 0x0268, */ 0x001408010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x000C04010000FFFFUL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x001408010000FFFFUL, + /* 0x02b8, */ 0x000C04010000FFFFUL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x001408010000FFFFUL, + /* 0x02e8, */ 0x000C04010000FFFFUL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x001200200BDFFC01UL, + /* 0x0008, */ 0x001200200BDFFC01UL, + /* 0x0010, */ 0x001200200BDFFC01UL, + /* 0x0018, */ 0x001200200BDFFC01UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x001200100BD03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100600BDFFC01UL, + /* 0x01c8, */ 0x002100600BDFFC01UL, + /* 0x01d0, */ 0x002100600BDFFC01UL, + /* 0x01d8, */ 0x002100600BDFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x002100200BDFFC01UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x002100200BDFFC01UL, + /* 0x0218, */ 0x001100200BDFFC01UL, + /* 0x0220, */ 0x001100200BDFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x001100200BDFFC01UL, + /* 0x0238, */ 0x001100200BDFFC01UL, + /* 0x0240, */ 0x001200200BDFFC01UL, + /* 0x0248, */ 0x001100200BDFFC01UL, + /* 0x0250, */ 0x001200200BDFFC01UL, + /* 0x0258, */ 0x001100200BDFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x001100400BDFFC01UL, + /* 0x02f8, */ 0x001100600BDFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x001100400BDFFC01UL, + /* 0x0310, */ 0x001100600BDFFC01UL, + /* 0x0318, */ 0x001200100BD03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_MSTAT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat390.h new file mode 100644 index 000000000..aa2036d1e --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_mstat390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_MSTAT390_H +#define QOS_INIT_G2M_V30_MSTAT390_H + +static uint64_t mstat_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000FFFFUL, + /* 0x0038, */ 0x001008070000FFFFUL, + /* 0x0040, */ 0x001424120000FFFFUL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x001404010000FFFFUL, + /* 0x0058, */ 0x001414130000FFFFUL, + /* 0x0060, */ 0x001414130000FFFFUL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x001404010000FFFFUL, + /* 0x0078, */ 0x001008050000FFFFUL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFFFUL, + /* 0x0090, */ 0x0014100D0000FFFFUL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x000C08040000FFFFUL, + /* 0x00a8, */ 0x000C04020000FFFFUL, + /* 0x00b0, */ 0x000C04020000FFFFUL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x000C08040000FFFFUL, + /* 0x00c8, */ 0x000C04020000FFFFUL, + /* 0x00d0, */ 0x000C04020000FFFFUL, + /* 0x00d8, */ 0x000C0C0A0000FFFFUL, + /* 0x00e0, */ 0x000C201F0000FFFFUL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x001044110000FFFFUL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x001014110000FFFFUL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x000C201F0000FFFFUL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x001018150000FFFFUL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x00101C190000FFFFUL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x001018150000FFFFUL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x00100C0B0000FFFFUL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x001058570000FFFFUL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x001018150000FFFFUL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x000C04010000FFFFUL, + /* 0x01c8, */ 0x000C04010000FFFFUL, + /* 0x01d0, */ 0x000C04010000FFFFUL, + /* 0x01d8, */ 0x000C04010000FFFFUL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x000C04010000FFFFUL, + /* 0x01f0, */ 0x000C04010000FFFFUL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x000C04010000FFFFUL, + /* 0x0210, */ 0x000C04010000FFFFUL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFFFUL, + /* 0x0268, */ 0x001410010000FFFFUL, + /* 0x0270, */ 0x001404010000FFFFUL, + /* 0x0278, */ 0x000C08020000FFFFUL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFFFUL, + /* 0x0298, */ 0x001404010000FFFFUL, + /* 0x02a0, */ 0x000C04010000FFFFUL, + /* 0x02a8, */ 0x000C04010000FFFFUL, + /* 0x02b0, */ 0x00140C010000FFFFUL, + /* 0x02b8, */ 0x000C04010000FFFFUL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x000C04010000FFFFUL, + /* 0x02d8, */ 0x000C04010000FFFFUL, + /* 0x02e0, */ 0x00140C010000FFFFUL, + /* 0x02e8, */ 0x000C04010000FFFFUL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t mstat_be[] = { + /* 0x0000, */ 0x0012003005EFFC01UL, + /* 0x0008, */ 0x0012003005EFFC01UL, + /* 0x0010, */ 0x0012003005EFFC01UL, + /* 0x0018, */ 0x0012003005EFFC01UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0012001005E03401UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x002100B005EFFC01UL, + /* 0x01c8, */ 0x002100B005EFFC01UL, + /* 0x01d0, */ 0x002100B005EFFC01UL, + /* 0x01d8, */ 0x002100B005EFFC01UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0021003005EFFC01UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0021003005EFFC01UL, + /* 0x0218, */ 0x0011003005EFFC01UL, + /* 0x0220, */ 0x0011003005EFFC01UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0011003005EFFC01UL, + /* 0x0238, */ 0x0011003005EFFC01UL, + /* 0x0240, */ 0x0012003005EFFC01UL, + /* 0x0248, */ 0x0011003005EFFC01UL, + /* 0x0250, */ 0x0012003005EFFC01UL, + /* 0x0258, */ 0x0011003005EFFC01UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0011007005EFFC01UL, + /* 0x02f8, */ 0x001100B005EFFC01UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0011007005EFFC01UL, + /* 0x0310, */ 0x001100B005EFFC01UL, + /* 0x0318, */ 0x0012001005E03401UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_MSTAT390_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h new file mode 100644 index 000000000..27c9c51e1 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt195.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_QOSWT195_H +#define QOS_INIT_G2M_V30_QOSWT195_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001004040000C010UL, + /* 0x0038, */ 0x001004040000C010UL, + /* 0x0040, */ 0x001414090000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x00140C0A0000C010UL, + /* 0x0060, */ 0x00140C0A0000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001004030000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001414090000FFF0UL, + /* 0x0090, */ 0x001408070000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C08020000FFF0UL, + /* 0x0268, */ 0x001408010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C04010000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001408010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_QOSWT195_H */ diff --git a/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h new file mode 100644 index 000000000..5d18212b4 --- /dev/null +++ b/drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30_qoswt390.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_INIT_G2M_V30_QOSWT390_H +#define QOS_INIT_G2M_V30_QOSWT390_H + +static uint64_t qoswt_fix[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x001008070000C010UL, + /* 0x0038, */ 0x001008070000C010UL, + /* 0x0040, */ 0x001424120000FFF0UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x001414130000C010UL, + /* 0x0060, */ 0x001414130000C010UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x001008050000C010UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x001424120000FFF0UL, + /* 0x0090, */ 0x0014100D0000C010UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x000C0C030000FFF0UL, + /* 0x0268, */ 0x001410010000FFF0UL, + /* 0x0270, */ 0x001404010000FFF0UL, + /* 0x0278, */ 0x000C08020000FFF0UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x001410010000FFF0UL, + /* 0x0298, */ 0x001404010000FFF0UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +static uint64_t qoswt_be[] = { + /* 0x0000, */ 0x0000000000000000UL, + /* 0x0008, */ 0x0000000000000000UL, + /* 0x0010, */ 0x0000000000000000UL, + /* 0x0018, */ 0x0000000000000000UL, + /* 0x0020, */ 0x0000000000000000UL, + /* 0x0028, */ 0x0000000000000000UL, + /* 0x0030, */ 0x0000000000000000UL, + /* 0x0038, */ 0x0000000000000000UL, + /* 0x0040, */ 0x0000000000000000UL, + /* 0x0048, */ 0x0000000000000000UL, + /* 0x0050, */ 0x0000000000000000UL, + /* 0x0058, */ 0x0000000000000000UL, + /* 0x0060, */ 0x0000000000000000UL, + /* 0x0068, */ 0x0000000000000000UL, + /* 0x0070, */ 0x0000000000000000UL, + /* 0x0078, */ 0x0000000000000000UL, + /* 0x0080, */ 0x0000000000000000UL, + /* 0x0088, */ 0x0000000000000000UL, + /* 0x0090, */ 0x0000000000000000UL, + /* 0x0098, */ 0x0000000000000000UL, + /* 0x00a0, */ 0x0000000000000000UL, + /* 0x00a8, */ 0x0000000000000000UL, + /* 0x00b0, */ 0x0000000000000000UL, + /* 0x00b8, */ 0x0000000000000000UL, + /* 0x00c0, */ 0x0000000000000000UL, + /* 0x00c8, */ 0x0000000000000000UL, + /* 0x00d0, */ 0x0000000000000000UL, + /* 0x00d8, */ 0x0000000000000000UL, + /* 0x00e0, */ 0x0000000000000000UL, + /* 0x00e8, */ 0x0000000000000000UL, + /* 0x00f0, */ 0x0000000000000000UL, + /* 0x00f8, */ 0x0000000000000000UL, + /* 0x0100, */ 0x0000000000000000UL, + /* 0x0108, */ 0x0000000000000000UL, + /* 0x0110, */ 0x0000000000000000UL, + /* 0x0118, */ 0x0000000000000000UL, + /* 0x0120, */ 0x0000000000000000UL, + /* 0x0128, */ 0x0000000000000000UL, + /* 0x0130, */ 0x0000000000000000UL, + /* 0x0138, */ 0x0000000000000000UL, + /* 0x0140, */ 0x0000000000000000UL, + /* 0x0148, */ 0x0000000000000000UL, + /* 0x0150, */ 0x0000000000000000UL, + /* 0x0158, */ 0x0000000000000000UL, + /* 0x0160, */ 0x0000000000000000UL, + /* 0x0168, */ 0x0000000000000000UL, + /* 0x0170, */ 0x0000000000000000UL, + /* 0x0178, */ 0x0000000000000000UL, + /* 0x0180, */ 0x0000000000000000UL, + /* 0x0188, */ 0x0000000000000000UL, + /* 0x0190, */ 0x0000000000000000UL, + /* 0x0198, */ 0x0000000000000000UL, + /* 0x01a0, */ 0x0000000000000000UL, + /* 0x01a8, */ 0x0000000000000000UL, + /* 0x01b0, */ 0x0000000000000000UL, + /* 0x01b8, */ 0x0000000000000000UL, + /* 0x01c0, */ 0x0000000000000000UL, + /* 0x01c8, */ 0x0000000000000000UL, + /* 0x01d0, */ 0x0000000000000000UL, + /* 0x01d8, */ 0x0000000000000000UL, + /* 0x01e0, */ 0x0000000000000000UL, + /* 0x01e8, */ 0x0000000000000000UL, + /* 0x01f0, */ 0x0000000000000000UL, + /* 0x01f8, */ 0x0000000000000000UL, + /* 0x0200, */ 0x0000000000000000UL, + /* 0x0208, */ 0x0000000000000000UL, + /* 0x0210, */ 0x0000000000000000UL, + /* 0x0218, */ 0x0000000000000000UL, + /* 0x0220, */ 0x0000000000000000UL, + /* 0x0228, */ 0x0000000000000000UL, + /* 0x0230, */ 0x0000000000000000UL, + /* 0x0238, */ 0x0000000000000000UL, + /* 0x0240, */ 0x0000000000000000UL, + /* 0x0248, */ 0x0000000000000000UL, + /* 0x0250, */ 0x0000000000000000UL, + /* 0x0258, */ 0x0000000000000000UL, + /* 0x0260, */ 0x0000000000000000UL, + /* 0x0268, */ 0x0000000000000000UL, + /* 0x0270, */ 0x0000000000000000UL, + /* 0x0278, */ 0x0000000000000000UL, + /* 0x0280, */ 0x0000000000000000UL, + /* 0x0288, */ 0x0000000000000000UL, + /* 0x0290, */ 0x0000000000000000UL, + /* 0x0298, */ 0x0000000000000000UL, + /* 0x02a0, */ 0x0000000000000000UL, + /* 0x02a8, */ 0x0000000000000000UL, + /* 0x02b0, */ 0x0000000000000000UL, + /* 0x02b8, */ 0x0000000000000000UL, + /* 0x02c0, */ 0x0000000000000000UL, + /* 0x02c8, */ 0x0000000000000000UL, + /* 0x02d0, */ 0x0000000000000000UL, + /* 0x02d8, */ 0x0000000000000000UL, + /* 0x02e0, */ 0x0000000000000000UL, + /* 0x02e8, */ 0x0000000000000000UL, + /* 0x02f0, */ 0x0000000000000000UL, + /* 0x02f8, */ 0x0000000000000000UL, + /* 0x0300, */ 0x0000000000000000UL, + /* 0x0308, */ 0x0000000000000000UL, + /* 0x0310, */ 0x0000000000000000UL, + /* 0x0318, */ 0x0000000000000000UL, + /* 0x0320, */ 0x0000000000000000UL, + /* 0x0328, */ 0x0000000000000000UL, + /* 0x0330, */ 0x0000000000000000UL, + /* 0x0338, */ 0x0000000000000000UL, + /* 0x0340, */ 0x0000000000000000UL, + /* 0x0348, */ 0x0000000000000000UL, + /* 0x0350, */ 0x0000000000000000UL, +}; + +#endif /* QOS_INIT_G2M_V30_QOSWT390_H */ diff --git a/drivers/renesas/rzg/qos/qos.mk b/drivers/renesas/rzg/qos/qos.mk new file mode 100644 index 000000000..f06c685c3 --- /dev/null +++ b/drivers/renesas/rzg/qos/qos.mk @@ -0,0 +1,34 @@ +# +# Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ifeq (${RCAR_LSI},${RCAR_AUTO}) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c +else ifeq (${RCAR_LSI_CUT_COMPAT},1) + ifeq (${RCAR_LSI},${RZ_G2M}) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c + endif +else + ifeq (${RCAR_LSI},${RZ_G2M}) + ifeq (${LSI_CUT},10) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v10.c + else ifeq (${LSI_CUT},11) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + else ifeq (${LSI_CUT},13) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v11.c + else ifeq (${LSI_CUT},30) + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c + else +# LSI_CUT 30 or later + BL2_SOURCES += drivers/renesas/rzg/qos/G2M/qos_init_g2m_v30.c + endif + endif +endif + +BL2_SOURCES += drivers/renesas/rzg/qos/qos_init.c diff --git a/drivers/renesas/rzg/qos/qos_common.h b/drivers/renesas/rzg/qos/qos_common.h new file mode 100644 index 000000000..6e0cf0e85 --- /dev/null +++ b/drivers/renesas/rzg/qos/qos_common.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QOS_COMMON_H +#define QOS_COMMON_H + +#define RCAR_REF_DEFAULT 0U + +/* define used for get_refperiod. */ +/* REFPERIOD_CYCLE need smaller than QOSWT_WTSET0_CYCLEs */ +#if (RCAR_REF_INT == RCAR_REF_DEFAULT) /* REF default */ +#define REFPERIOD_CYCLE /* unit:ns */ \ + ((126U * BASE_SUB_SLOT_NUM * 1000U) / 400U) +#else /* REF option */ +#define REFPERIOD_CYCLE /* unit:ns */ \ + ((252U * BASE_SUB_SLOT_NUM * 1000U) / 400U) +#endif + +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) +/* define used for G2M */ +#if (RCAR_REF_INT == RCAR_REF_DEFAULT) /* REF 1.95usec */ +#define SUB_SLOT_CYCLE_G2M_11 0x7EU /* 126 */ +#define SUB_SLOT_CYCLE_G2M_30 0x7EU /* 126 */ +#else /* REF 3.9usec */ +#define SUB_SLOT_CYCLE_G2M_11 0xFCU /* 252 */ +#define SUB_SLOT_CYCLE_G2M_30 0xFCU /* 252 */ +#endif /* (RCAR_REF_INT == RCAR_REF_DEFAULT) */ + +#define SL_INIT_SSLOTCLK_G2M_11 (SUB_SLOT_CYCLE_G2M_11 - 1U) +#define SL_INIT_SSLOTCLK_G2M_30 (SUB_SLOT_CYCLE_G2M_30 - 1U) +#define QOSWT_WTSET0_CYCLE_G2M_11 /* unit:ns */ \ + ((SUB_SLOT_CYCLE_G2M_11 * BASE_SUB_SLOT_NUM * 1000U) / OPERATING_FREQ) +#define QOSWT_WTSET0_CYCLE_G2M_30 /* unit:ns */ \ + ((SUB_SLOT_CYCLE_G2M_30 * BASE_SUB_SLOT_NUM * 1000U) / OPERATING_FREQ) +#endif + +#define OPERATING_FREQ 400U /* MHz */ +#define BASE_SUB_SLOT_NUM 0x6U +#define SUB_SLOT_CYCLE 0x7EU /* 126 */ + +#define QOSWT_WTSET0_CYCLE /* unit:ns */ \ + ((SUB_SLOT_CYCLE * BASE_SUB_SLOT_NUM * 1000U) / OPERATING_FREQ) + +#define SL_INIT_REFFSSLOT (0x3U << 24U) +#define SL_INIT_SLOTSSLOT ((BASE_SUB_SLOT_NUM - 1U) << 16U) +#define SL_INIT_SSLOTCLK (SUB_SLOT_CYCLE - 1U) + +typedef struct { + uintptr_t addr; + uint64_t value; +} mstat_slot_t; + +struct rcar_gen3_dbsc_qos_settings { + uint32_t reg; + uint32_t val; +}; + +extern uint32_t qos_init_ddr_ch; +extern uint8_t qos_init_ddr_phyvalid; + +void rzg_qos_dbsc_setting(const struct rcar_gen3_dbsc_qos_settings *qos, + unsigned int qos_size, bool dbsc_wren); + +#endif /* QOS_COMMON_H */ diff --git a/drivers/renesas/rzg/qos/qos_init.c b/drivers/renesas/rzg/qos/qos_init.c new file mode 100644 index 000000000..2d5aecebb --- /dev/null +++ b/drivers/renesas/rzg/qos/qos_init.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <common/debug.h> +#include <lib/mmio.h> + +#if RCAR_LSI == RCAR_AUTO +#include "G2M/qos_init_g2m_v10.h" +#include "G2M/qos_init_g2m_v11.h" +#include "G2M/qos_init_g2m_v30.h" +#endif /* RCAR_LSI == RCAR_AUTO */ +#if (RCAR_LSI == RZ_G2M) +#include "G2M/qos_init_g2m_v10.h" +#include "G2M/qos_init_g2m_v11.h" +#include "G2M/qos_init_g2m_v30.h" +#endif /* RCAR_LSI == RZ_G2M */ +#include "qos_common.h" +#include "qos_init.h" +#include "qos_reg.h" +#include "rcar_def.h" + +#define DRAM_CH_CNT 0x04U +uint32_t qos_init_ddr_ch; +uint8_t qos_init_ddr_phyvalid; + +#define PRR_PRODUCT_ERR(reg) \ + { \ + ERROR("LSI Product ID(PRR=0x%x) QoS " \ + "initialize not supported.\n", reg); \ + panic(); \ + } + +#define PRR_CUT_ERR(reg) \ + { \ + ERROR("LSI Cut ID(PRR=0x%x) QoS " \ + "initialize not supported.\n", reg); \ + panic(); \ + } + +void rzg_qos_init(void) +{ + uint32_t reg; + uint32_t i; + + qos_init_ddr_ch = 0U; + qos_init_ddr_phyvalid = rzg_get_boardcnf_phyvalid(); + for (i = 0U; i < DRAM_CH_CNT; i++) { + if ((qos_init_ddr_phyvalid & (1U << i))) { + qos_init_ddr_ch++; + } + } + + reg = mmio_read_32(PRR); +#if (RCAR_LSI == RCAR_AUTO) || RCAR_LSI_CUT_COMPAT + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_M3: +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) + switch (reg & PRR_CUT_MASK) { + case PRR_PRODUCT_10: + qos_init_g2m_v10(); + break; + case PRR_PRODUCT_21: /* G2M Cut 13 */ + qos_init_g2m_v11(); + break; + case PRR_PRODUCT_30: /* G2M Cut 30 */ + default: + qos_init_g2m_v30(); + break; + } +#else /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */ + PRR_PRODUCT_ERR(reg); +#endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */ + break; + default: + PRR_PRODUCT_ERR(reg); + break; + } +#else /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */ +#if (RCAR_LSI == RZ_G2M) +#if RCAR_LSI_CUT == RCAR_CUT_10 + /* G2M Cut 10 */ + if ((PRR_PRODUCT_M3 | PRR_PRODUCT_10) + != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v10(); +#elif RCAR_LSI_CUT == RCAR_CUT_11 + /* G2M Cut 11 */ + if ((PRR_PRODUCT_M3 | PRR_PRODUCT_20) + != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v11(); +#elif RCAR_LSI_CUT == RCAR_CUT_13 + /* G2M Cut 13 */ + if ((PRR_PRODUCT_M3 | PRR_PRODUCT_21) + != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v11(); +#else + /* G2M Cut 30 or later */ + if ((PRR_PRODUCT_M3) + != (reg & (PRR_PRODUCT_MASK))) { + PRR_PRODUCT_ERR(reg); + } + qos_init_g2m_v30(); +#endif /* RCAR_LSI_CUT == RCAR_CUT_10 */ +#else /* (RCAR_LSI == RZ_G2M) */ +#error "Don't have QoS initialize routine(Unknown chip)." +#endif /* (RCAR_LSI == RZ_G2M) */ +#endif /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */ +} + +uint32_t get_refperiod(void) +{ + uint32_t refperiod = QOSWT_WTSET0_CYCLE; + +#if (RCAR_LSI == RCAR_AUTO) || RCAR_LSI_CUT_COMPAT + uint32_t reg; + + reg = mmio_read_32(PRR); + switch (reg & PRR_PRODUCT_MASK) { +#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) + case PRR_PRODUCT_M3: + switch (reg & PRR_CUT_MASK) { + case PRR_PRODUCT_10: + break; + case PRR_PRODUCT_20: /* G2M Cut 11 */ + case PRR_PRODUCT_21: /* G2M Cut 13 */ + case PRR_PRODUCT_30: /* G2M Cut 30 */ + default: + refperiod = REFPERIOD_CYCLE; + break; + } + break; +#endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */ + default: + break; + } +#elif RCAR_LSI == RZ_G2M +#if RCAR_LSI_CUT == RCAR_CUT_10 + /* G2M Cut 10 */ +#else /* RCAR_LSI_CUT == RCAR_CUT_10 */ + /* G2M Cut 11|13|30 or later */ + refperiod = REFPERIOD_CYCLE; +#endif /* RCAR_LSI_CUT == RCAR_CUT_10 */ +#endif /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */ + return refperiod; +} + +void rzg_qos_dbsc_setting(const struct rcar_gen3_dbsc_qos_settings *qos, + unsigned int qos_size, bool dbsc_wren) +{ + unsigned int i; + + /* Register write enable */ + if (dbsc_wren) { + mmio_write_32(DBSC_DBSYSCNT0, 0x00001234U); + } + + for (i = 0; i < qos_size; i++) { + mmio_write_32(qos[i].reg, qos[i].val); + } + + /* Register write protect */ + if (dbsc_wren) { + mmio_write_32(DBSC_DBSYSCNT0, 0x00000000U); + } +} diff --git a/drivers/renesas/rzg/qos/qos_init.h b/drivers/renesas/rzg/qos/qos_init.h new file mode 100644 index 000000000..10f60e7ca --- /dev/null +++ b/drivers/renesas/rzg/qos/qos_init.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RZG_QOS_INIT_H +#define RZG_QOS_INIT_H + +void rzg_qos_init(void); +uint8_t rzg_get_boardcnf_phyvalid(void); + +#endif /* RZG_QOS_INIT_H */ diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c index b39808ff7..f938f563f 100644 --- a/drivers/rpi3/gpio/rpi3_gpio.c +++ b/drivers/rpi3/gpio/rpi3_gpio.c @@ -11,7 +11,7 @@ #include <drivers/delay_timer.h> #include <drivers/rpi3/gpio/rpi3_gpio.h> -static struct rpi3_gpio_params rpi3_gpio_params; +static uintptr_t reg_base; static int rpi3_gpio_get_direction(int gpio); static void rpi3_gpio_set_direction(int gpio, int direction); @@ -43,7 +43,6 @@ static const gpio_ops_t rpi3_gpio_ops = { int rpi3_gpio_get_select(int gpio) { int ret; - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 10; int shift = 3 * (gpio % 10); uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN); @@ -69,7 +68,6 @@ int rpi3_gpio_get_select(int gpio) */ void rpi3_gpio_set_select(int gpio, int fsel) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 10; int shift = 3 * (gpio % 10); uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN); @@ -106,7 +104,6 @@ static void rpi3_gpio_set_direction(int gpio, int direction) static int rpi3_gpio_get_value(int gpio) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_lev = reg_base + RPI3_GPIO_GPLEV(regN); @@ -119,7 +116,6 @@ static int rpi3_gpio_get_value(int gpio) static void rpi3_gpio_set_value(int gpio, int value) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN); @@ -137,7 +133,6 @@ static void rpi3_gpio_set_value(int gpio, int value) static void rpi3_gpio_set_pull(int gpio, int pull) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_pud = reg_base + RPI3_GPIO_GPPUD; @@ -161,9 +156,8 @@ static void rpi3_gpio_set_pull(int gpio, int pull) mmio_write_32(reg_pud, 0x0); } -void rpi3_gpio_init(struct rpi3_gpio_params *params) +void rpi3_gpio_init(void) { - assert(params != 0); - memcpy(&rpi3_gpio_params, params, sizeof(struct rpi3_gpio_params)); + reg_base = RPI3_GPIO_BASE; gpio_init(&rpi3_gpio_ops); } diff --git a/drivers/scmi-msg/base.c b/drivers/scmi-msg/base.c new file mode 100644 index 000000000..2d7203451 --- /dev/null +++ b/drivers/scmi-msg/base.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <assert.h> +#include <string.h> + +#include <drivers/scmi-msg.h> +#include <drivers/scmi.h> +#include <lib/utils.h> +#include <lib/utils_def.h> + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_BASE, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t protocol_count = plat_scmi_protocol_count(); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* Null agent count since agent discovery is not supported */ + .attributes = SCMI_BASE_PROTOCOL_ATTRIBUTES(protocol_count, 0U), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_vendor_name(); + struct scmi_base_discover_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_sub_vendor(struct scmi_msg *msg) +{ + const char *name = plat_scmi_sub_vendor_name(); + struct scmi_base_discover_sub_vendor_p2a return_values = { + .status = SCMI_SUCCESS, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + COPY_NAME_IDENTIFIER(return_values.sub_vendor_identifier, name); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void discover_implementation_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_IMPL_VERSION, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static unsigned int count_protocols_in_list(const uint8_t *protocol_list) +{ + unsigned int count = 0U; + + if (protocol_list != NULL) { + while (protocol_list[count] != 0U) { + count++; + } + } + + return count; +} + +#define MAX_PROTOCOL_IN_LIST 8U + +static void discover_list_protocols(struct scmi_msg *msg) +{ + const struct scmi_base_discover_list_protocols_a2p *a2p = NULL; + struct scmi_base_discover_list_protocols_p2a p2a = { + .status = SCMI_SUCCESS, + }; + uint8_t outargs[sizeof(p2a) + MAX_PROTOCOL_IN_LIST] = { 0U }; + const uint8_t *list = NULL; + unsigned int count = 0U; + + if (msg->in_size != sizeof(*a2p)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + assert(msg->out_size > sizeof(outargs)); + + a2p = (void *)msg->in; + + list = plat_scmi_protocol_list(msg->agent_id); + count = count_protocols_in_list(list); + if (count > a2p->skip) { + count = MIN(count - a2p->skip, MAX_PROTOCOL_IN_LIST); + } else { + count = 0U; + } + + p2a.num_protocols = count; + + memcpy(outargs, &p2a, sizeof(p2a)); + memcpy(outargs + sizeof(p2a), list + a2p->skip, count); + + scmi_write_response(msg, outargs, sizeof(outargs)); +} + +static const scmi_msg_handler_t scmi_base_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_BASE_DISCOVER_VENDOR] = discover_vendor, + [SCMI_BASE_DISCOVER_SUB_VENDOR] = discover_sub_vendor, + [SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION] = + discover_implementation_version, + [SCMI_BASE_DISCOVER_LIST_PROTOCOLS] = discover_list_protocols, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_base_handler_table)) && + (scmi_base_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_base_handler_table)) { + VERBOSE("Base handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_base_handler_table[message_id]; +} diff --git a/drivers/scmi-msg/base.h b/drivers/scmi-msg/base.h new file mode 100644 index 000000000..c4a9c64a4 --- /dev/null +++ b/drivers/scmi-msg/base.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#ifndef SCMI_MSG_BASE_H +#define SCMI_MSG_BASE_H + +#include <stdint.h> + +#define SCMI_PROTOCOL_VERSION_BASE 0x20000U + +#define SCMI_DEFAULT_STRING_LENGTH 16U + +enum scmi_base_message_id { + SCMI_BASE_DISCOVER_VENDOR = 0x003, + SCMI_BASE_DISCOVER_SUB_VENDOR = 0x004, + SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION = 0x005, + SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x006, + SCMI_BASE_DISCOVER_AGENT = 0x007, + SCMI_BASE_NOTIFY_ERRORS = 0x008, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS 0 +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS 8 + +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK 0xFFU +#define SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK 0xFF00U + +#define SCMI_BASE_PROTOCOL_ATTRIBUTES(NUM_PROTOCOLS, NUM_AGENTS) \ + ((((NUM_PROTOCOLS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_PROTOCOLS_MASK) | \ + (((NUM_AGENTS) << SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_POS) & \ + SCMI_BASE_PROTOCOL_ATTRS_NUM_AGENTS_MASK)) + +/* + * BASE_DISCOVER_VENDOR + */ +struct scmi_base_discover_vendor_p2a { + int32_t status; + char vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_SUB_VENDOR + */ +struct scmi_base_discover_sub_vendor_p2a { + int32_t status; + char sub_vendor_identifier[SCMI_DEFAULT_STRING_LENGTH]; +}; + +/* + * BASE_DISCOVER_IMPLEMENTATION_VERSION + * No special structure right now, see protocol_version. + */ + +/* + * BASE_DISCOVER_LIST_PROTOCOLS + */ +struct scmi_base_discover_list_protocols_a2p { + uint32_t skip; +}; + +struct scmi_base_discover_list_protocols_p2a { + int32_t status; + uint32_t num_protocols; + uint32_t protocols[]; +}; + +#endif /* SCMI_MSG_BASE_H */ diff --git a/drivers/scmi-msg/clock.c b/drivers/scmi-msg/clock.c new file mode 100644 index 000000000..e96cede6e --- /dev/null +++ b/drivers/scmi-msg/clock.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <cdefs.h> +#include <string.h> + +#include <drivers/scmi-msg.h> +#include <drivers/scmi.h> +#include <lib/utils_def.h> + +#include "common.h" + +#pragma weak plat_scmi_clock_count +#pragma weak plat_scmi_clock_get_name +#pragma weak plat_scmi_clock_rates_array +#pragma weak plat_scmi_clock_rates_by_step +#pragma weak plat_scmi_clock_get_rate +#pragma weak plat_scmi_clock_set_rate +#pragma weak plat_scmi_clock_get_state +#pragma weak plat_scmi_clock_set_state + +static bool message_id_is_supported(unsigned int message_id); + +size_t plat_scmi_clock_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_clock_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *rates __unused, + size_t *nb_elts __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long *steps __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +unsigned long plat_scmi_clock_get_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return 0U; +} + +int32_t plat_scmi_clock_set_rate(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned long rate __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_get_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_clock_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool enable_not_disable __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_CLOCK, + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + size_t agent_count = plat_scmi_clock_count(msg->agent_id); + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = SCMI_CLOCK_PROTOCOL_ATTRIBUTES(1U, agent_count), + }; + + if (msg->in_size != 0) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_attributes(struct scmi_msg *msg) +{ + const struct scmi_clock_attributes_a2p *in_args = (void *)msg->in; + struct scmi_clock_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + }; + const char *name = NULL; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + + name = plat_scmi_clock_get_name(msg->agent_id, clock_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + COPY_NAME_IDENTIFIER(return_values.clock_name, name); + + return_values.attributes = plat_scmi_clock_get_state(msg->agent_id, + clock_id); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_get(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_get_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + struct scmi_clock_rate_get_p2a return_values = { + .status = SCMI_SUCCESS, + }; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = plat_scmi_clock_get_rate(msg->agent_id, clock_id); + + return_values.rate[0] = (uint32_t)rate; + return_values.rate[1] = (uint32_t)((uint64_t)rate >> 32); + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void scmi_clock_rate_set(struct scmi_msg *msg) +{ + const struct scmi_clock_rate_set_a2p *in_args = (void *)msg->in; + unsigned long rate = 0U; + int32_t status = 0; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + rate = (unsigned long)(((uint64_t)in_args->rate[1] << 32) | + in_args->rate[0]); + + status = plat_scmi_clock_set_rate(msg->agent_id, clock_id, rate); + + scmi_status_response(msg, status); +} + +static void scmi_clock_config_set(struct scmi_msg *msg) +{ + const struct scmi_clock_config_set_a2p *in_args = (void *)msg->in; + int32_t status = SCMI_GENERIC_ERROR; + bool enable = false; + unsigned int clock_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + enable = in_args->attributes & SCMI_CLOCK_CONFIG_SET_ENABLE_MASK; + + status = plat_scmi_clock_set_state(msg->agent_id, clock_id, enable); + + scmi_status_response(msg, status); +} + +#define RATES_ARRAY_SIZE_MAX (SCMI_PLAYLOAD_MAX - \ + sizeof(struct scmi_clock_describe_rates_p2a)) + +#define SCMI_RATES_BY_ARRAY(_nb_rates, _rem_rates) \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS((_nb_rates), \ + SCMI_CLOCK_RATE_FORMAT_LIST, \ + (_rem_rates)) +#define SCMI_RATES_BY_STEP \ + SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(3U, \ + SCMI_CLOCK_RATE_FORMAT_RANGE, \ + 0U) + +#define RATE_DESC_SIZE sizeof(struct scmi_clock_rate) + +static void write_rate_desc_array_in_buffer(char *dest, unsigned long *rates, + size_t nb_elt) +{ + uint32_t *out = (uint32_t *)(uintptr_t)dest; + size_t n; + + ASSERT_SYM_PTR_ALIGN(out); + + for (n = 0U; n < nb_elt; n++) { + out[2 * n] = (uint32_t)rates[n]; + out[2 * n + 1] = (uint32_t)((uint64_t)rates[n] >> 32); + } +} + +static void scmi_clock_describe_rates(struct scmi_msg *msg) +{ + const struct scmi_clock_describe_rates_a2p *in_args = (void *)msg->in; + struct scmi_clock_describe_rates_p2a p2a = { + .status = SCMI_SUCCESS, + }; + size_t nb_rates; + int32_t status; + unsigned int clock_id; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + clock_id = SPECULATION_SAFE_VALUE(in_args->clock_id); + + if (clock_id >= plat_scmi_clock_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + /* Platform may support array rate description */ + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, NULL, + &nb_rates); + if (status == SCMI_SUCCESS) { + /* Currently 12 cells mex, so it's affordable for the stack */ + unsigned long plat_rates[RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE]; + size_t max_nb = RATES_ARRAY_SIZE_MAX / RATE_DESC_SIZE; + size_t ret_nb = MIN(nb_rates - in_args->rate_index, max_nb); + size_t rem_nb = nb_rates - in_args->rate_index - ret_nb; + + status = plat_scmi_clock_rates_array(msg->agent_id, clock_id, + plat_rates, &ret_nb); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + plat_rates, ret_nb); + + p2a.num_rates_flags = SCMI_RATES_BY_ARRAY(ret_nb, + rem_nb); + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + + ret_nb * RATE_DESC_SIZE; + } + } else if (status == SCMI_NOT_SUPPORTED) { + unsigned long triplet[3] = { 0U, 0U, 0U }; + + /* Platform may support min§max/step triplet description */ + status = plat_scmi_clock_rates_by_step(msg->agent_id, clock_id, + triplet); + if (status == SCMI_SUCCESS) { + write_rate_desc_array_in_buffer(msg->out + sizeof(p2a), + triplet, 3U); + + p2a.num_rates_flags = SCMI_RATES_BY_STEP; + p2a.status = SCMI_SUCCESS; + + memcpy(msg->out, &p2a, sizeof(p2a)); + msg->out_size_out = sizeof(p2a) + (3U * RATE_DESC_SIZE); + } + } else { + /* Fallthrough generic exit sequence below with error status */ + } + + if (status != SCMI_SUCCESS) { + scmi_status_response(msg, status); + } else { + /* + * Message payload is already writen to msg->out, and + * msg->out_size_out updated. + */ + } +} + +static const scmi_msg_handler_t scmi_clock_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_CLOCK_ATTRIBUTES] = scmi_clock_attributes, + [SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates, + [SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set, + [SCMI_CLOCK_RATE_GET] = scmi_clock_rate_get, + [SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set, +}; + +static bool message_id_is_supported(size_t message_id) +{ + return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) && + (scmi_clock_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg) +{ + const size_t array_size = ARRAY_SIZE(scmi_clock_handler_table); + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= array_size) { + VERBOSE("Clock handle not found %u", msg->message_id); + return NULL; + } + + return scmi_clock_handler_table[message_id]; +} diff --git a/drivers/scmi-msg/clock.h b/drivers/scmi-msg/clock.h new file mode 100644 index 000000000..a637934ee --- /dev/null +++ b/drivers/scmi-msg/clock.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ + +#ifndef SCMI_MSG_CLOCK_H +#define SCMI_MSG_CLOCK_H + +#include <stdint.h> + +#include <lib/utils_def.h> + +#define SCMI_PROTOCOL_VERSION_CLOCK 0x20000U + +/* + * Identifiers of the SCMI Clock Management Protocol commands + */ +enum scmi_clock_command_id { + SCMI_CLOCK_ATTRIBUTES = 0x003, + SCMI_CLOCK_DESCRIBE_RATES = 0x004, + SCMI_CLOCK_RATE_SET = 0x005, + SCMI_CLOCK_RATE_GET = 0x006, + SCMI_CLOCK_CONFIG_SET = 0x007, +}; + +/* Protocol attributes */ +#define SCMI_CLOCK_CLOCK_COUNT_MASK GENMASK(15, 0) +#define SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK GENMASK(23, 16) + +#define SCMI_CLOCK_PROTOCOL_ATTRIBUTES(_max_pending, _clk_count) \ + ((((_max_pending) << 16) & SCMI_CLOCK_MAX_PENDING_TRANSITIONS_MASK) | \ + (((_clk_count) & SCMI_CLOCK_CLOCK_COUNT_MASK))) + +struct scmi_clock_attributes_a2p { + uint32_t clock_id; +}; + +#define SCMI_CLOCK_NAME_LENGTH_MAX 16U + +struct scmi_clock_attributes_p2a { + int32_t status; + uint32_t attributes; + char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX]; +}; + +/* + * Clock Rate Get + */ + +struct scmi_clock_rate_get_a2p { + uint32_t clock_id; +}; + +struct scmi_clock_rate_get_p2a { + int32_t status; + uint32_t rate[2]; +}; + +/* + * Clock Rate Set + */ + +/* If set, set the new clock rate asynchronously */ +#define SCMI_CLOCK_RATE_SET_ASYNC_POS 0 +/* If set, do not send a delayed asynchronous response */ +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS 1 +/* Round up, if set, otherwise round down */ +#define SCMI_CLOCK_RATE_SET_ROUND_UP_POS 2 +/* If set, the platform chooses the appropriate rounding mode */ +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS 3 + +#define SCMI_CLOCK_RATE_SET_ASYNC_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ASYNC_POS) +#define SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_MASK \ + BIT(SCMI_CLOCK_RATE_SET_NO_DELAYED_RESPONSE_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_UP_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_UP_POS) +#define SCMI_CLOCK_RATE_SET_ROUND_AUTO_MASK \ + BIT(SCMI_CLOCK_RATE_SET_ROUND_AUTO_POS) + +struct scmi_clock_rate_set_a2p { + uint32_t flags; + uint32_t clock_id; + uint32_t rate[2]; +}; + +struct scmi_clock_rate_set_p2a { + int32_t status; +}; + +/* + * Clock Config Set + */ + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_POS 0 + +#define SCMI_CLOCK_CONFIG_SET_ENABLE_MASK \ + BIT(SCMI_CLOCK_CONFIG_SET_ENABLE_POS) + +struct scmi_clock_config_set_a2p { + uint32_t clock_id; + uint32_t attributes; +}; + +struct scmi_clock_config_set_p2a { + int32_t status; +}; + +/* + * Clock Describe Rates + */ + +#define SCMI_CLOCK_RATE_FORMAT_RANGE 1U +#define SCMI_CLOCK_RATE_FORMAT_LIST 0U + +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK GENMASK_32(31, 16) +#define SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS 16 + +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK BIT(12) +#define SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS 12 + +#define SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK GENMASK_32(11, 0) + +#define SCMI_CLOCK_DESCRIBE_RATES_NUM_RATES_FLAGS(_count, _fmt, _rem_rates) \ + ( \ + ((_count) & SCMI_CLOCK_DESCRIBE_RATES_COUNT_MASK) | \ + (((_rem_rates) << SCMI_CLOCK_DESCRIBE_RATES_REMAINING_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_REMAINING_MASK) | \ + (((_fmt) << SCMI_CLOCK_DESCRIBE_RATES_FORMAT_POS) & \ + SCMI_CLOCK_DESCRIBE_RATES_FORMAT_MASK) \ + ) + +struct scmi_clock_rate { + uint32_t low; + uint32_t high; +}; + +struct scmi_clock_describe_rates_a2p { + uint32_t clock_id; + uint32_t rate_index; +}; + +struct scmi_clock_describe_rates_p2a { + int32_t status; + uint32_t num_rates_flags; + struct scmi_clock_rate rates[]; +}; + +#endif /* SCMI_MSG_CLOCK_H */ diff --git a/drivers/scmi-msg/common.h b/drivers/scmi-msg/common.h new file mode 100644 index 000000000..ef5953b3d --- /dev/null +++ b/drivers/scmi-msg/common.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#ifndef SCMI_MSG_COMMON_H +#define SCMI_MSG_COMMON_H + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include "base.h" +#include "clock.h" +#include "reset_domain.h" + +#define SCMI_VERSION 0x20000U +#define SCMI_IMPL_VERSION 0U + +#define SCMI_PLAYLOAD_MAX 92U + +/* + * Copy name identifier in target buffer following the SCMI specification + * that state name identifier shall be a null terminated string. + */ +#define COPY_NAME_IDENTIFIER(_dst_array, _name) \ + do { \ + assert(strlen(_name) < sizeof(_dst_array)); \ + strlcpy((_dst_array), (_name), sizeof(_dst_array)); \ + } while (0) + +/* Common command identifiers shared by all procotols */ +enum scmi_common_message_id { + SCMI_PROTOCOL_VERSION = 0x000, + SCMI_PROTOCOL_ATTRIBUTES = 0x001, + SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x002 +}; + +/* Common platform-to-agent (p2a) PROTOCOL_VERSION structure */ +struct scmi_protocol_version_p2a { + int32_t status; + uint32_t version; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_ATTRIBUTES structure */ +struct scmi_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Generic agent-to-platform (a2p) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_a2p { + uint32_t message_id; +}; + +/* Generic platform-to-agent (p2a) PROTOCOL_MESSAGE_ATTRIBUTES structure */ +struct scmi_protocol_message_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* + * struct scmi_msg - SCMI message context + * + * @agent_id: SCMI agent ID, safely set from secure world + * @protocol_id: SCMI protocol ID for the related message, set by caller agent + * @message_id: SCMI message ID for the related message, set by caller agent + * @in: Address of the incoming message payload copied in secure memory + * @in_size: Byte length of the incoming message payload, set by caller agent + * @out: Address of of the output message payload message in non-secure memory + * @out_size: Byte length of the provisionned output buffer + * @out_size_out: Byte length of the output message payload + */ +struct scmi_msg { + unsigned int agent_id; + unsigned int protocol_id; + unsigned int message_id; + char *in; + size_t in_size; + char *out; + size_t out_size; + size_t out_size_out; +}; + +/* + * Type scmi_msg_handler_t is used by procotol drivers to safely find + * the handler function for the incoming message ID. + */ +typedef void (*scmi_msg_handler_t)(struct scmi_msg *msg); + +/* + * scmi_msg_get_base_handler - Return a handler for a base message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_base_handler(struct scmi_msg *msg); + +/* + * scmi_msg_get_clock_handler - Return a handler for a clock message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg); + +/* + * scmi_msg_get_rstd_handler - Return a handler for a reset domain message + * @msg - message to process + * Return a function handler for the message or NULL + */ +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg); + +/* + * Process Read, process and write response for input SCMI message + * + * @msg: SCMI message context + */ +void scmi_process_message(struct scmi_msg *msg); + +/* + * Write SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @payload: Output message payload + * @size: Byte size of output message payload + */ +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size); + +/* + * Write status only SCMI response payload to output message shared memory + * + * @msg: SCMI message context + * @status: SCMI status value returned to caller + */ +void scmi_status_response(struct scmi_msg *msg, int32_t status); +#endif /* SCMI_MSG_COMMON_H */ diff --git a/drivers/scmi-msg/entry.c b/drivers/scmi-msg/entry.c new file mode 100644 index 000000000..ea3efa24b --- /dev/null +++ b/drivers/scmi-msg/entry.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ + +#include <assert.h> + +#include <drivers/scmi-msg.h> +#include <drivers/scmi.h> + +#include "common.h" + +void scmi_status_response(struct scmi_msg *msg, int32_t status) +{ + assert(msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, &status, sizeof(int32_t)); + msg->out_size_out = sizeof(int32_t); +} + +void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size) +{ + /* + * Output payload shall be at least the size of the status + * Output buffer shall be at least be the size of the status + * Output paylaod shall fit in output buffer + */ + assert(payload && size >= sizeof(int32_t) && size <= msg->out_size && + msg->out && msg->out_size >= sizeof(int32_t)); + + memcpy(msg->out, payload, size); + msg->out_size_out = size; +} + +void scmi_process_message(struct scmi_msg *msg) +{ + scmi_msg_handler_t handler = NULL; + + switch (msg->protocol_id) { + case SCMI_PROTOCOL_ID_BASE: + handler = scmi_msg_get_base_handler(msg); + break; + case SCMI_PROTOCOL_ID_CLOCK: + handler = scmi_msg_get_clock_handler(msg); + break; + case SCMI_PROTOCOL_ID_RESET_DOMAIN: + handler = scmi_msg_get_rstd_handler(msg); + break; + default: + break; + } + + if (handler) { + handler(msg); + return; + } + + ERROR("Agent %u Protocol 0x%x Message 0x%x: not supported", + msg->agent_id, msg->protocol_id, msg->message_id); + + scmi_status_response(msg, SCMI_NOT_SUPPORTED); +} diff --git a/drivers/scmi-msg/reset_domain.c b/drivers/scmi-msg/reset_domain.c new file mode 100644 index 000000000..76ac47ea9 --- /dev/null +++ b/drivers/scmi-msg/reset_domain.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <cdefs.h> +#include <string.h> + +#include <drivers/scmi-msg.h> +#include <drivers/scmi.h> +#include <lib/utils.h> +#include <lib/utils_def.h> + +#include "common.h" + +static bool message_id_is_supported(unsigned int message_id); + +#pragma weak plat_scmi_rstd_count +#pragma weak plat_scmi_rstd_get_name +#pragma weak plat_scmi_rstd_autonomous +#pragma weak plat_scmi_rstd_set_state + +size_t plat_scmi_rstd_count(unsigned int agent_id __unused) +{ + return 0U; +} + +const char *plat_scmi_rstd_get_name(unsigned int agent_id __unused, + unsigned int scmi_id __unused) +{ + return NULL; +} + +int32_t plat_scmi_rstd_autonomous(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + unsigned int state __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +int32_t plat_scmi_rstd_set_state(unsigned int agent_id __unused, + unsigned int scmi_id __unused, + bool assert_not_deassert __unused) +{ + return SCMI_NOT_SUPPORTED; +} + +static void report_version(struct scmi_msg *msg) +{ + struct scmi_protocol_version_p2a return_values = { + .status = SCMI_SUCCESS, + .version = SCMI_PROTOCOL_VERSION_RESET_DOMAIN, + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + .attributes = plat_scmi_rstd_count(msg->agent_id), + }; + + if (msg->in_size != 0U) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void report_message_attributes(struct scmi_msg *msg) +{ + struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in; + struct scmi_protocol_message_attributes_p2a return_values = { + .status = SCMI_SUCCESS, + /* For this protocol, attributes shall be zero */ + .attributes = 0U, + }; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + if (!message_id_is_supported(in_args->message_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_domain_attributes(struct scmi_msg *msg) +{ + struct scmi_reset_domain_attributes_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_attributes_p2a return_values; + const char *name = NULL; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_INVALID_PARAMETERS); + return; + } + + name = plat_scmi_rstd_get_name(msg->agent_id, domain_id); + if (name == NULL) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + zeromem(&return_values, sizeof(return_values)); + COPY_NAME_IDENTIFIER(return_values.name, name); + return_values.status = SCMI_SUCCESS; + return_values.flags = 0U; /* Async and Notif are not supported */ + return_values.latency = SCMI_RESET_DOMAIN_ATTR_UNK_LAT; + + scmi_write_response(msg, &return_values, sizeof(return_values)); +} + +static void reset_request(struct scmi_msg *msg) +{ + struct scmi_reset_domain_request_a2p *in_args = (void *)msg->in; + struct scmi_reset_domain_request_p2a out_args = { + .status = SCMI_SUCCESS, + }; + unsigned int domain_id = 0U; + + if (msg->in_size != sizeof(*in_args)) { + scmi_status_response(msg, SCMI_PROTOCOL_ERROR); + return; + } + + domain_id = SPECULATION_SAFE_VALUE(in_args->domain_id); + + if (domain_id >= plat_scmi_rstd_count(msg->agent_id)) { + scmi_status_response(msg, SCMI_NOT_FOUND); + return; + } + + if ((in_args->flags & SCMI_RESET_DOMAIN_AUTO) != 0U) { + out_args.status = plat_scmi_rstd_autonomous(msg->agent_id, + domain_id, + in_args->reset_state); + } else if ((in_args->flags & SCMI_RESET_DOMAIN_EXPLICIT) != 0U) { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, true); + } else { + out_args.status = plat_scmi_rstd_set_state(msg->agent_id, + domain_id, false); + } + + if (out_args.status != SCMI_SUCCESS) { + scmi_status_response(msg, out_args.status); + } else { + scmi_write_response(msg, &out_args, sizeof(out_args)); + } +} + +static const scmi_msg_handler_t scmi_rstd_handler_table[] = { + [SCMI_PROTOCOL_VERSION] = report_version, + [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes, + [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes, + [SCMI_RESET_DOMAIN_ATTRIBUTES] = reset_domain_attributes, + [SCMI_RESET_DOMAIN_REQUEST] = reset_request, +}; + +static bool message_id_is_supported(unsigned int message_id) +{ + return (message_id < ARRAY_SIZE(scmi_rstd_handler_table)) && + (scmi_rstd_handler_table[message_id] != NULL); +} + +scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg) +{ + unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id); + + if (message_id >= ARRAY_SIZE(scmi_rstd_handler_table)) { + VERBOSE("Reset domain handle not found %u\n", msg->message_id); + return NULL; + } + + return scmi_rstd_handler_table[message_id]; +} diff --git a/drivers/scmi-msg/reset_domain.h b/drivers/scmi-msg/reset_domain.h new file mode 100644 index 000000000..47bee5e39 --- /dev/null +++ b/drivers/scmi-msg/reset_domain.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Linaro Limited + */ +#ifndef SCMI_MSG_RESET_DOMAIN_H +#define SCMI_MSG_RESET_DOMAIN_H + +#include <stdbool.h> +#include <stdint.h> + +#include <lib/utils_def.h> + +#define SCMI_PROTOCOL_VERSION_RESET_DOMAIN 0x10000U + +#define SCMI_RESET_STATE_ARCH BIT(31) +#define SCMI_RESET_STATE_IMPL 0U + +/* + * Identifiers of the SCMI Reset Domain Management Protocol commands + */ +enum scmi_reset_domain_command_id { + SCMI_RESET_DOMAIN_ATTRIBUTES = 0x03, + SCMI_RESET_DOMAIN_REQUEST = 0x04, + SCMI_RESET_DOMAIN_NOTIFY = 0x05, +}; + +/* + * Identifiers of the SCMI Reset Domain Management Protocol responses + */ +enum scmi_reset_domain_response_id { + SCMI_RESET_ISSUED = 0x00, + SCMI_RESET_COMPLETE = 0x04, +}; + +/* + * PROTOCOL_ATTRIBUTES + */ + +#define SCMI_RESET_DOMAIN_COUNT_MASK GENMASK_32(15, 0) + +struct scmi_reset_domain_protocol_attributes_p2a { + int32_t status; + uint32_t attributes; +}; + +/* Value for scmi_reset_domain_attributes_p2a:flags */ +#define SCMI_RESET_DOMAIN_ATTR_ASYNC BIT(31) +#define SCMI_RESET_DOMAIN_ATTR_NOTIF BIT(30) + +/* Value for scmi_reset_domain_attributes_p2a:latency */ +#define SCMI_RESET_DOMAIN_ATTR_UNK_LAT 0x7fffffffU +#define SCMI_RESET_DOMAIN_ATTR_MAX_LAT 0x7ffffffeU + +/* Macro for scmi_reset_domain_attributes_p2a:name */ +#define SCMI_RESET_DOMAIN_ATTR_NAME_SZ 16U + +struct scmi_reset_domain_attributes_a2p { + uint32_t domain_id; +}; + +struct scmi_reset_domain_attributes_p2a { + int32_t status; + uint32_t flags; + uint32_t latency; + char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ]; +}; + +/* + * RESET + */ + +/* Values for scmi_reset_domain_request_a2p:flags */ +#define SCMI_RESET_DOMAIN_ASYNC BIT(2) +#define SCMI_RESET_DOMAIN_EXPLICIT BIT(1) +#define SCMI_RESET_DOMAIN_AUTO BIT(0) + +struct scmi_reset_domain_request_a2p { + uint32_t domain_id; + uint32_t flags; + uint32_t reset_state; +}; + +struct scmi_reset_domain_request_p2a { + int32_t status; +}; + +/* + * RESET_NOTIFY + */ + +/* Values for scmi_reset_notify_p2a:flags */ +#define SCMI_RESET_DOMAIN_DO_NOTIFY BIT(0) + +struct scmi_reset_domain_notify_a2p { + uint32_t domain_id; + uint32_t notify_enable; +}; + +struct scmi_reset_domain_notify_p2a { + int32_t status; +}; + +/* + * RESET_COMPLETE + */ + +struct scmi_reset_domain_complete_p2a { + int32_t status; + uint32_t domain_id; +}; + +/* + * RESET_ISSUED + */ + +struct scmi_reset_domain_issued_p2a { + uint32_t domain_id; + uint32_t reset_state; +}; + +#endif /* SCMI_MSG_RESET_DOMAIN_H */ diff --git a/drivers/scmi-msg/smt.c b/drivers/scmi-msg/smt.c new file mode 100644 index 000000000..b08ee0626 --- /dev/null +++ b/drivers/scmi-msg/smt.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited + */ +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include <drivers/scmi-msg.h> +#include <drivers/scmi.h> +#include <lib/cassert.h> +#include <lib/mmio.h> +#include <lib/spinlock.h> +#include <lib/utils.h> +#include <plat/common/platform.h> + +#include "common.h" + +/* Legacy SMT/SCMI messages are 128 bytes at most including SMT header */ +#define SCMI_PLAYLOAD_MAX 92U +#define SCMI_PLAYLOAD_U32_MAX (SCMI_PLAYLOAD_MAX / sizeof(uint32_t)) + +/** + * struct smt_header - SMT formatted header for SMT base shared memory transfer + * + * @status: Bit flags, see SMT_STATUS_* + * @flags: Bit flags, see SMT_FLAG_* + * @length: Byte size of message payload (variable) + ::message_header (32bit) + * payload: SCMI message payload data + */ +struct smt_header { + uint32_t reserved0; + uint32_t status; + uint64_t reserved1; + uint32_t flags; + uint32_t length; /* message_header + payload */ + uint32_t message_header; + uint32_t payload[]; +}; + +CASSERT(SCMI_PLAYLOAD_MAX + sizeof(struct smt_header) <= SMT_BUF_SLOT_SIZE, + assert_scmi_message_max_length_fits_in_smt_buffer_slot); + +/* Flag set in smt_header::status when SMT does not contain pending message */ +#define SMT_STATUS_FREE BIT(0) +/* Flag set in smt_header::status when SMT reports an error */ +#define SMT_STATUS_ERROR BIT(1) + +/* Flag set in smt_header::flags when SMT uses interrupts */ +#define SMT_FLAG_INTR_ENABLED BIT(1) + +/* Bit fields packed in smt_header::message_header */ +#define SMT_MSG_ID_MASK GENMASK_32(7, 0) +#define SMT_HDR_MSG_ID(_hdr) ((_hdr) & SMT_MSG_ID_MASK) + +#define SMT_MSG_TYPE_MASK GENMASK_32(9, 8) +#define SMT_HDR_TYPE_ID(_hdr) (((_hdr) & SMT_MSG_TYPE_MASK) >> 8) + +#define SMT_MSG_PROT_ID_MASK GENMASK_32(17, 10) +#define SMT_HDR_PROT_ID(_hdr) (((_hdr) & SMT_MSG_PROT_ID_MASK) >> 10) + +/* + * Provision input message payload buffers for fastcall SMC context entries + * and for interrupt context execution entries. + */ +static uint32_t fast_smc_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; +static uint32_t interrupt_payload[PLATFORM_CORE_COUNT][SCMI_PLAYLOAD_U32_MAX]; + +/* SMP protection on channel access */ +static struct spinlock smt_channels_lock; + +/* If channel is not busy, set busy and return true, otherwise return false */ +static bool channel_set_busy(struct scmi_msg_channel *chan) +{ + bool channel_is_busy; + + spin_lock(&smt_channels_lock); + + channel_is_busy = chan->busy; + + if (!channel_is_busy) { + chan->busy = true; + } + + spin_unlock(&smt_channels_lock); + + return !channel_is_busy; +} + +static void channel_release_busy(struct scmi_msg_channel *chan) +{ + chan->busy = false; +} + +static struct smt_header *channel_to_smt_hdr(struct scmi_msg_channel *chan) +{ + return (struct smt_header *)chan->shm_addr; +} + +/* + * Creates a SCMI message instance in secure memory and pushes it in the SCMI + * message drivers. Message structure contains SCMI protocol meta-data and + * references to input payload in secure memory and output message buffer + * in shared memory. + */ +static void scmi_proccess_smt(unsigned int agent_id, uint32_t *payload_buf) +{ + struct scmi_msg_channel *chan; + struct smt_header *smt_hdr; + size_t in_payload_size; + uint32_t smt_status; + struct scmi_msg msg; + bool error = true; + + chan = plat_scmi_get_channel(agent_id); + if (chan == NULL) { + return; + } + + smt_hdr = channel_to_smt_hdr(chan); + assert(smt_hdr); + + smt_status = __atomic_load_n(&smt_hdr->status, __ATOMIC_RELAXED); + + if (!channel_set_busy(chan)) { + VERBOSE("SCMI channel %u busy", agent_id); + goto out; + } + + in_payload_size = __atomic_load_n(&smt_hdr->length, __ATOMIC_RELAXED) - + sizeof(smt_hdr->message_header); + + if (in_payload_size > SCMI_PLAYLOAD_MAX) { + VERBOSE("SCMI payload too big %u", in_payload_size); + goto out; + } + + if ((smt_status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)) != 0U) { + VERBOSE("SCMI channel bad status 0x%x", + smt_hdr->status & (SMT_STATUS_ERROR | SMT_STATUS_FREE)); + goto out; + } + + /* Fill message */ + zeromem(&msg, sizeof(msg)); + msg.in = (char *)payload_buf; + msg.in_size = in_payload_size; + msg.out = (char *)smt_hdr->payload; + msg.out_size = chan->shm_size - sizeof(*smt_hdr); + + assert((msg.out != NULL) && (msg.out_size >= sizeof(int32_t))); + + /* Here the payload is copied in secure memory */ + memcpy(msg.in, smt_hdr->payload, in_payload_size); + + msg.protocol_id = SMT_HDR_PROT_ID(smt_hdr->message_header); + msg.message_id = SMT_HDR_MSG_ID(smt_hdr->message_header); + msg.agent_id = agent_id; + + scmi_process_message(&msg); + + /* Update message length with the length of the response message */ + smt_hdr->length = msg.out_size_out + sizeof(smt_hdr->message_header); + + channel_release_busy(chan); + error = false; + +out: + if (error) { + VERBOSE("SCMI error"); + smt_hdr->status |= SMT_STATUS_ERROR | SMT_STATUS_FREE; + } else { + smt_hdr->status |= SMT_STATUS_FREE; + } +} + +void scmi_smt_fastcall_smc_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + fast_smc_payload[plat_my_core_pos()]); +} + +void scmi_smt_interrupt_entry(unsigned int agent_id) +{ + scmi_proccess_smt(agent_id, + interrupt_payload[plat_my_core_pos()]); +} + +/* Init a SMT header for a shared memory buffer: state it a free/no-error */ +void scmi_smt_init_agent_channel(struct scmi_msg_channel *chan) +{ + if (chan != NULL) { + struct smt_header *smt_header = channel_to_smt_hdr(chan); + + if (smt_header != NULL) { + memset(smt_header, 0, sizeof(*smt_header)); + smt_header->status = SMT_STATUS_FREE; + + return; + } + } + + panic(); +} diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 0cc87cc71..564bd8798 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -16,6 +16,7 @@ #include <arch.h> #include <arch_helpers.h> #include <common/debug.h> +#include <common/fdt_wrappers.h> #include <drivers/delay_timer.h> #include <drivers/generic_delay_timer.h> #include <drivers/st/stm32mp_clkfunc.h> @@ -105,10 +106,62 @@ enum stm32mp1_parent_sel { _MCUS_SEL, _USBPHY_SEL, _USBO_SEL, + _MPU_SEL, + _PER_SEL, + _RTC_SEL, _PARENT_SEL_NB, _UNKNOWN_SEL = 0xff, }; +/* State the parent clock ID straight related to a clock */ +static const uint8_t parent_id_clock_id[_PARENT_NB] = { + [_HSE] = CK_HSE, + [_HSI] = CK_HSI, + [_CSI] = CK_CSI, + [_LSE] = CK_LSE, + [_LSI] = CK_LSI, + [_I2S_CKIN] = _UNKNOWN_ID, + [_USB_PHY_48] = _UNKNOWN_ID, + [_HSI_KER] = CK_HSI, + [_HSE_KER] = CK_HSE, + [_HSE_KER_DIV2] = CK_HSE_DIV2, + [_CSI_KER] = CK_CSI, + [_PLL1_P] = PLL1_P, + [_PLL1_Q] = PLL1_Q, + [_PLL1_R] = PLL1_R, + [_PLL2_P] = PLL2_P, + [_PLL2_Q] = PLL2_Q, + [_PLL2_R] = PLL2_R, + [_PLL3_P] = PLL3_P, + [_PLL3_Q] = PLL3_Q, + [_PLL3_R] = PLL3_R, + [_PLL4_P] = PLL4_P, + [_PLL4_Q] = PLL4_Q, + [_PLL4_R] = PLL4_R, + [_ACLK] = CK_AXI, + [_PCLK1] = CK_AXI, + [_PCLK2] = CK_AXI, + [_PCLK3] = CK_AXI, + [_PCLK4] = CK_AXI, + [_PCLK5] = CK_AXI, + [_CK_PER] = CK_PER, + [_CK_MPU] = CK_MPU, + [_CK_MCU] = CK_MCU, +}; + +static unsigned int clock_id2parent_id(unsigned long id) +{ + unsigned int n; + + for (n = 0U; n < ARRAY_SIZE(parent_id_clock_id); n++) { + if (parent_id_clock_id[n] == id) { + return n; + } + } + + return _UNKNOWN_ID; +} + enum stm32mp1_pll_id { _PLL1, _PLL2, @@ -258,7 +311,8 @@ struct stm32mp1_clk_pll { [_ ## _label ## _SEL] = { \ .offset = _rcc_selr, \ .src = _rcc_selr ## _ ## _label ## SRC_SHIFT, \ - .msk = _rcc_selr ## _ ## _label ## SRC_MASK, \ + .msk = (_rcc_selr ## _ ## _label ## SRC_MASK) >> \ + (_rcc_selr ## _ ## _label ## SRC_SHIFT), \ .parent = (_parents), \ .nb_parent = ARRAY_SIZE(_parents) \ } @@ -280,19 +334,6 @@ struct stm32mp1_clk_pll { .refclk[3] = (p4), \ } -static const uint8_t stm32mp1_clks[][2] = { - { CK_PER, _CK_PER }, - { CK_MPU, _CK_MPU }, - { CK_AXI, _ACLK }, - { CK_MCU, _CK_MCU }, - { CK_HSE, _HSE }, - { CK_CSI, _CSI }, - { CK_LSI, _LSI }, - { CK_LSE, _LSE }, - { CK_HSI, _HSI }, - { CK_HSE_DIV2, _HSE_KER_DIV2 }, -}; - #define NB_GATES ARRAY_SIZE(stm32mp1_clk_gate) static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { @@ -368,6 +409,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { _CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL), _CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL), + _CLK_SELEC(RCC_BDCR, 20, RTC, _RTC_SEL), _CLK_SELEC(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL), }; @@ -439,6 +481,18 @@ static const uint8_t usbo_parents[] = { _PLL4_R, _USB_PHY_48 }; +static const uint8_t mpu_parents[] = { + _HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */ +}; + +static const uint8_t per_parents[] = { + _HSI, _HSE, _CSI, +}; + +static const uint8_t rtc_parents[] = { + _UNKNOWN_ID, _LSE, _LSI, _HSE +}; + static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(I2C12, RCC_I2C12CKSELR, i2c12_parents), _CLK_PARENT_SEL(I2C35, RCC_I2C35CKSELR, i2c35_parents), @@ -447,6 +501,9 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(SPI6, RCC_SPI6CKSELR, spi6_parents), _CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents), _CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents), + _CLK_PARENT_SEL(MPU, RCC_MPCKSELR, mpu_parents), + _CLK_PARENT_SEL(PER, RCC_CPERCKSELR, per_parents), + _CLK_PARENT_SEL(RTC, RCC_BDCR, rtc_parents), _CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents), _CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents), _CLK_PARENT_SEL(UART35, RCC_UART35CKSELR, uart234578_parents), @@ -520,6 +577,43 @@ static const uint8_t stm32mp1_axi_div[8] = { 1, 2, 3, 4, 4, 4, 4, 4 }; +static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = { + [_HSI] = "HSI", + [_HSE] = "HSE", + [_CSI] = "CSI", + [_LSI] = "LSI", + [_LSE] = "LSE", + [_I2S_CKIN] = "I2S_CKIN", + [_HSI_KER] = "HSI_KER", + [_HSE_KER] = "HSE_KER", + [_HSE_KER_DIV2] = "HSE_KER_DIV2", + [_CSI_KER] = "CSI_KER", + [_PLL1_P] = "PLL1_P", + [_PLL1_Q] = "PLL1_Q", + [_PLL1_R] = "PLL1_R", + [_PLL2_P] = "PLL2_P", + [_PLL2_Q] = "PLL2_Q", + [_PLL2_R] = "PLL2_R", + [_PLL3_P] = "PLL3_P", + [_PLL3_Q] = "PLL3_Q", + [_PLL3_R] = "PLL3_R", + [_PLL4_P] = "PLL4_P", + [_PLL4_Q] = "PLL4_Q", + [_PLL4_R] = "PLL4_R", + [_ACLK] = "ACLK", + [_PCLK1] = "PCLK1", + [_PCLK2] = "PCLK2", + [_PCLK3] = "PCLK3", + [_PCLK4] = "PCLK4", + [_PCLK5] = "PCLK5", + [_HCLK6] = "KCLK6", + [_HCLK2] = "HCLK2", + [_CK_PER] = "CK_PER", + [_CK_MPU] = "CK_MPU", + [_CK_MCU] = "CK_MCU", + [_USB_PHY_48] = "USB_PHY_48", +}; + /* RCC clock device driver private */ static unsigned long stm32mp1_osc[NB_OSC]; static struct spinlock reg_lock; @@ -559,15 +653,17 @@ static void stm32mp1_clk_unlock(struct spinlock *lock) bool stm32mp1_rcc_is_secure(void) { uintptr_t rcc_base = stm32mp_rcc_base(); + uint32_t mask = RCC_TZCR_TZEN; - return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) != 0; + return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask; } bool stm32mp1_rcc_is_mckprot(void) { uintptr_t rcc_base = stm32mp_rcc_base(); + uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT; - return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_MCKPROT) != 0; + return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask; } void stm32mp1_clk_rcc_regs_lock(void) @@ -617,16 +713,16 @@ static enum stm32mp1_parent_id stm32mp1_clk_get_fixed_parent(int i) static int stm32mp1_clk_get_parent(unsigned long id) { const struct stm32mp1_clk_sel *sel; - uint32_t j, p_sel; + uint32_t p_sel; int i; enum stm32mp1_parent_id p; enum stm32mp1_parent_sel s; uintptr_t rcc_base = stm32mp_rcc_base(); - for (j = 0U; j < ARRAY_SIZE(stm32mp1_clks); j++) { - if (stm32mp1_clks[j][0] == id) { - return (int)stm32mp1_clks[j][1]; - } + /* Few non gateable clock have a static parent ID, find them */ + i = (int)clock_id2parent_id(id); + if (i != _UNKNOWN_ID) { + return i; } i = stm32mp1_clk_get_gated_id(id); @@ -648,7 +744,8 @@ static int stm32mp1_clk_get_parent(unsigned long id) } sel = clk_sel_ref(s); - p_sel = (mmio_read_32(rcc_base + sel->offset) & sel->msk) >> sel->src; + p_sel = (mmio_read_32(rcc_base + sel->offset) & + (sel->msk << sel->src)) >> sel->src; if (p_sel < sel->nb_parent) { return (int)sel->parent[p_sel]; } @@ -930,27 +1027,27 @@ static void __clk_enable(struct stm32mp1_clk_gate const *gate) { uintptr_t rcc_base = stm32mp_rcc_base(); + VERBOSE("Enable clock %u\n", gate->index); + if (gate->set_clr != 0U) { mmio_write_32(rcc_base + gate->offset, BIT(gate->bit)); } else { mmio_setbits_32(rcc_base + gate->offset, BIT(gate->bit)); } - - VERBOSE("Clock %d has been enabled", gate->index); } static void __clk_disable(struct stm32mp1_clk_gate const *gate) { uintptr_t rcc_base = stm32mp_rcc_base(); + VERBOSE("Disable clock %u\n", gate->index); + if (gate->set_clr != 0U) { mmio_write_32(rcc_base + gate->offset + RCC_MP_ENCLRR_OFFSET, BIT(gate->bit)); } else { mmio_clrbits_32(rcc_base + gate->offset, BIT(gate->bit)); } - - VERBOSE("Clock %d has been disabled", gate->index); } static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate) @@ -971,12 +1068,41 @@ unsigned int stm32mp1_clk_get_refcount(unsigned long id) return gate_refcounts[i]; } +/* Oscillators and PLLs are not gated at runtime */ +static bool clock_is_always_on(unsigned long id) +{ + switch (id) { + case CK_HSE: + case CK_CSI: + case CK_LSI: + case CK_LSE: + case CK_HSI: + case CK_HSE_DIV2: + case PLL1_Q: + case PLL1_R: + case PLL2_P: + case PLL2_Q: + case PLL2_R: + case PLL3_P: + case PLL3_Q: + case PLL3_R: + return true; + default: + return false; + } +} + void __stm32mp1_clk_enable(unsigned long id, bool secure) { const struct stm32mp1_clk_gate *gate; - int i = stm32mp1_clk_get_gated_id(id); + int i; unsigned int *refcnt; + if (clock_is_always_on(id)) { + return; + } + + i = stm32mp1_clk_get_gated_id(id); if (i < 0) { ERROR("Clock %d can't be enabled\n", (uint32_t)id); panic(); @@ -997,9 +1123,14 @@ void __stm32mp1_clk_enable(unsigned long id, bool secure) void __stm32mp1_clk_disable(unsigned long id, bool secure) { const struct stm32mp1_clk_gate *gate; - int i = stm32mp1_clk_get_gated_id(id); + int i; unsigned int *refcnt; + if (clock_is_always_on(id)) { + return; + } + + i = stm32mp1_clk_get_gated_id(id); if (i < 0) { ERROR("Clock %d can't be disabled\n", (uint32_t)id); panic(); @@ -1029,8 +1160,13 @@ void stm32mp_clk_disable(unsigned long id) bool stm32mp_clk_is_enabled(unsigned long id) { - int i = stm32mp1_clk_get_gated_id(id); + int i; + + if (clock_is_always_on(id)) { + return true; + } + i = stm32mp1_clk_get_gated_id(id); if (i < 0) { panic(); } @@ -1239,7 +1375,8 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id, uintptr_t clksrc_address = rcc_base + (clksrc >> 4); unsigned long refclk; uint32_t ifrge = 0U; - uint32_t src, value, fracv; + uint32_t src, value, fracv = 0; + void *fdt; /* Check PLL output */ if (mmio_read_32(pllxcr) != RCC_PLLNCR_PLLON) { @@ -1278,7 +1415,9 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id, } /* Fractional configuration */ - fracv = fdt_read_uint32_default(plloff, "frac", 0); + if (fdt_get_address(&fdt) == 1) { + fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0); + } value = fracv << RCC_PLLNFRACR_FRACV_SHIFT; value |= RCC_PLLNFRACR_FRACLE; @@ -1525,28 +1664,26 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css) static void stm32mp1_stgen_config(void) { - uintptr_t stgen; uint32_t cntfid0; unsigned long rate; unsigned long long counter; - stgen = fdt_get_stgen_base(); - cntfid0 = mmio_read_32(stgen + CNTFID_OFF); + cntfid0 = mmio_read_32(STGEN_BASE + CNTFID_OFF); rate = get_clock_rate(stm32mp1_clk_get_parent(STGEN_K)); if (cntfid0 == rate) { return; } - mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN); - counter = (unsigned long long)mmio_read_32(stgen + CNTCVL_OFF); - counter |= ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF)) << 32; + mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); + counter = (unsigned long long)mmio_read_32(STGEN_BASE + CNTCVL_OFF); + counter |= ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF)) << 32; counter = (counter * rate / cntfid0); - mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)counter); - mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(counter >> 32)); - mmio_write_32(stgen + CNTFID_OFF, rate); - mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); + mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)counter); + mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(counter >> 32)); + mmio_write_32(STGEN_BASE + CNTFID_OFF, rate); + mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); write_cntfrq((u_register_t)rate); @@ -1556,20 +1693,17 @@ static void stm32mp1_stgen_config(void) void stm32mp1_stgen_increment(unsigned long long offset_in_ms) { - uintptr_t stgen; unsigned long long cnt; - stgen = fdt_get_stgen_base(); + cnt = ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) | + mmio_read_32(STGEN_BASE + CNTCVL_OFF); - cnt = ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF) << 32) | - mmio_read_32(stgen + CNTCVL_OFF); + cnt += (offset_in_ms * mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U; - cnt += (offset_in_ms * mmio_read_32(stgen + CNTFID_OFF)) / 1000U; - - mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN); - mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)cnt); - mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(cnt >> 32)); - mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); + mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); + mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)cnt); + mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(cnt >> 32)); + mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN); } static void stm32mp1_pkcs_config(uint32_t pkcs) @@ -1600,20 +1734,25 @@ int stm32mp1_clk_init(void) bool pll4_preserve = false; bool pll4_bootrom = false; const fdt32_t *pkcs_cell; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return false; + } /* Check status field to disable security */ if (!fdt_get_rcc_secure_status()) { mmio_write_32(rcc_base + RCC_TZCR, 0); } - ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc, - (uint32_t)CLKSRC_NB); + ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB, + clksrc); if (ret < 0) { return -FDT_ERR_NOTFOUND; } - ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv, - (uint32_t)CLKDIV_NB); + ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB, + clkdiv); if (ret < 0) { return -FDT_ERR_NOTFOUND; } @@ -1628,8 +1767,8 @@ int stm32mp1_clk_init(void) continue; } - ret = fdt_read_uint32_array(plloff[i], "cfg", - pllcfg[i], (int)PLLCFG_NB); + ret = fdt_read_uint32_array(fdt, plloff[i], "cfg", + (int)PLLCFG_NB, pllcfg[i]); if (ret < 0) { return -FDT_ERR_NOTFOUND; } @@ -1794,14 +1933,14 @@ int stm32mp1_clk_init(void) continue; } - fracv = fdt_read_uint32_default(plloff[i], "frac", 0); + fracv = fdt_read_uint32_default(fdt, plloff[i], "frac", 0); ret = stm32mp1_pll_config(i, pllcfg[i], fracv); if (ret != 0) { return ret; } - ret = fdt_read_uint32_array(plloff[i], "csg", csg, - (uint32_t)PLLCSG_NB); + ret = fdt_read_uint32_array(fdt, plloff[i], "csg", + (uint32_t)PLLCSG_NB, csg); if (ret == 0) { stm32mp1_pll_csg(i, csg); } else if (ret != -FDT_ERR_NOTFOUND) { @@ -1902,8 +2041,184 @@ static void stm32mp1_osc_init(void) } } +#ifdef STM32MP_SHARED_RESOURCES +/* + * Get the parent ID of the target parent clock, for tagging as secure + * shared clock dependencies. + */ +static int get_parent_id_parent(unsigned int parent_id) +{ + enum stm32mp1_parent_sel s = _UNKNOWN_SEL; + enum stm32mp1_pll_id pll_id; + uint32_t p_sel; + uintptr_t rcc_base = stm32mp_rcc_base(); + + switch (parent_id) { + case _ACLK: + case _PCLK4: + case _PCLK5: + s = _AXIS_SEL; + break; + case _PLL1_P: + case _PLL1_Q: + case _PLL1_R: + pll_id = _PLL1; + break; + case _PLL2_P: + case _PLL2_Q: + case _PLL2_R: + pll_id = _PLL2; + break; + case _PLL3_P: + case _PLL3_Q: + case _PLL3_R: + pll_id = _PLL3; + break; + case _PLL4_P: + case _PLL4_Q: + case _PLL4_R: + pll_id = _PLL4; + break; + case _PCLK1: + case _PCLK2: + case _HCLK2: + case _HCLK6: + case _CK_PER: + case _CK_MPU: + case _CK_MCU: + case _USB_PHY_48: + /* We do not expect to access these */ + panic(); + break; + default: + /* Other parents have no parent */ + return -1; + } + + if (s != _UNKNOWN_SEL) { + const struct stm32mp1_clk_sel *sel = clk_sel_ref(s); + + p_sel = (mmio_read_32(rcc_base + sel->offset) >> sel->src) & + sel->msk; + + if (p_sel < sel->nb_parent) { + return (int)sel->parent[p_sel]; + } + } else { + const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); + + p_sel = mmio_read_32(rcc_base + pll->rckxselr) & + RCC_SELR_REFCLK_SRC_MASK; + + if (pll->refclk[p_sel] != _UNKNOWN_OSC_ID) { + return (int)pll->refclk[p_sel]; + } + } + + VERBOSE("No parent selected for %s\n", + stm32mp1_clk_parent_name[parent_id]); + + return -1; +} + +static void secure_parent_clocks(unsigned long parent_id) +{ + int grandparent_id; + + switch (parent_id) { + case _PLL3_P: + case _PLL3_Q: + case _PLL3_R: + stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3); + break; + + /* These clocks are always secure when RCC is secure */ + case _ACLK: + case _HCLK2: + case _HCLK6: + case _PCLK4: + case _PCLK5: + case _PLL1_P: + case _PLL1_Q: + case _PLL1_R: + case _PLL2_P: + case _PLL2_Q: + case _PLL2_R: + case _HSI: + case _HSI_KER: + case _LSI: + case _CSI: + case _CSI_KER: + case _HSE: + case _HSE_KER: + case _HSE_KER_DIV2: + case _LSE: + break; + + default: + VERBOSE("Cannot secure parent clock %s\n", + stm32mp1_clk_parent_name[parent_id]); + panic(); + } + + grandparent_id = get_parent_id_parent(parent_id); + if (grandparent_id >= 0) { + secure_parent_clocks(grandparent_id); + } +} + +void stm32mp1_register_clock_parents_secure(unsigned long clock_id) +{ + int parent_id; + + if (!stm32mp1_rcc_is_secure()) { + return; + } + + switch (clock_id) { + case PLL1: + case PLL2: + /* PLL1/PLL2 are always secure: nothing to do */ + break; + case PLL3: + stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3); + break; + case PLL4: + ERROR("PLL4 cannot be secured\n"); + panic(); + break; + default: + /* Others are expected gateable clock */ + parent_id = stm32mp1_clk_get_parent(clock_id); + if (parent_id < 0) { + INFO("No parent found for clock %lu\n", clock_id); + } else { + secure_parent_clocks(parent_id); + } + break; + } +} +#endif /* STM32MP_SHARED_RESOURCES */ + static void sync_earlyboot_clocks_state(void) { + unsigned int idx; + const unsigned long secure_enable[] = { + AXIDCG, + BSEC, + DDRC1, DDRC1LP, + DDRC2, DDRC2LP, + DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP, + DDRPHYC, DDRPHYCLP, + TZC1, TZC2, + TZPC, + STGEN_K, + }; + + for (idx = 0U; idx < ARRAY_SIZE(secure_enable); idx++) { + stm32mp_clk_enable(secure_enable[idx]); + } + if (!stm32mp_is_single_core()) { stm32mp1_clk_enable_secure(RTCAPB); } diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index 87c8e2b84..8333f6dfb 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,11 +10,10 @@ #include <platform_def.h> +#include <common/fdt_wrappers.h> #include <drivers/st/stm32_gpio.h> #include <drivers/st/stm32mp_clkfunc.h> -#define DT_STGEN_COMPAT "st,stm32-stgen" - /* * Get the frequency of an oscillator from its name in device tree. * @param name: oscillator name @@ -150,7 +149,8 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, continue; } - return fdt_read_uint32_default(subnode, prop_name, dflt_value); + return fdt_read_uint32_default(fdt, subnode, prop_name, + dflt_value); } return dflt_value; @@ -167,41 +167,14 @@ int fdt_get_rcc_node(void *fdt) } /* - * Get the RCC base address from the device tree - * @return: RCC address or 0 on error - */ -uint32_t fdt_rcc_read_addr(void) -{ - int node; - void *fdt; - const fdt32_t *cuint; - - if (fdt_get_address(&fdt) == 0) { - return 0; - } - - node = fdt_get_rcc_node(fdt); - if (node < 0) { - return 0; - } - - cuint = fdt_getprop(fdt, node, "reg", NULL); - if (cuint == NULL) { - return 0; - } - - return fdt32_to_cpu(*cuint); -} - -/* * Read a series of parameters in rcc-clk section in device tree * @param prop_name: Name of the RCC property to be read * @param array: the array to store the property parameters * @param count: number of parameters to be read * @return: 0 on succes or a negative value on error */ -int fdt_rcc_read_uint32_array(const char *prop_name, - uint32_t *array, uint32_t count) +int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, + uint32_t *array) { int node; void *fdt; @@ -215,7 +188,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name, return -FDT_ERR_NOTFOUND; } - return fdt_read_uint32_array(node, prop_name, array, count); + return fdt_read_uint32_array(fdt, node, prop_name, count, array); } /* @@ -297,33 +270,6 @@ bool fdt_get_rcc_secure_status(void) } /* - * Get the stgen base address. - * @return: address of stgen on success, and NULL value on failure. - */ -uintptr_t fdt_get_stgen_base(void) -{ - int node; - const fdt32_t *cuint; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return 0; - } - - node = fdt_node_offset_by_compatible(fdt, -1, DT_STGEN_COMPAT); - if (node < 0) { - return 0; - } - - cuint = fdt_getprop(fdt, node, "reg", NULL); - if (cuint == NULL) { - return 0; - } - - return fdt32_to_cpu(*cuint); -} - -/* * Get the clock ID of the given node in device tree. * @param node: node offset * @return: Clock ID on success, and a negative FDT/ERRNO error code on failure. diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c index f72787d33..317fd9eb8 100644 --- a/drivers/st/crypto/stm32_hash.c +++ b/drivers/st/crypto/stm32_hash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -51,6 +51,7 @@ #define SHA224_DIGEST_SIZE 28U #define SHA256_DIGEST_SIZE 32U +#define RESET_TIMEOUT_US_1MS 1000U #define HASH_TIMEOUT_US 10000U enum stm32_hash_data_format { @@ -251,6 +252,8 @@ int stm32_hash_final(uint8_t *digest) mmio_clrsetbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK, 8U * stm32_remain.length); zeromem(&stm32_remain, sizeof(stm32_remain)); + } else { + mmio_clrbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK); } mmio_setbits_32(hash_base() + HASH_STR, HASH_STR_DCAL); @@ -299,7 +302,9 @@ int stm32_hash_register(void) break; } #else + /* BL32 uses hash if it is assigned only to secure world */ if (hash_info.status == DT_SECURE) { + stm32mp_register_secure_periph_iomem(hash_info.base); break; } #endif @@ -319,9 +324,15 @@ int stm32_hash_register(void) stm32mp_clk_enable(stm32_hash.clock); if (hash_info.reset >= 0) { - stm32mp_reset_assert((unsigned long)hash_info.reset); + uint32_t id = (uint32_t)hash_info.reset; + + if (stm32mp_reset_assert(id, RESET_TIMEOUT_US_1MS) != 0) { + panic(); + } udelay(20); - stm32mp_reset_deassert((unsigned long)hash_info.reset); + if (stm32mp_reset_deassert(id, RESET_TIMEOUT_US_1MS) != 0) { + panic(); + } } stm32mp_clk_disable(stm32_hash.clock); diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c index 4ae55fcc7..b21c8949f 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -12,6 +12,7 @@ #include <arch_helpers.h> #include <common/debug.h> +#include <common/fdt_wrappers.h> #include <drivers/st/stm32mp1_ddr.h> #include <drivers/st/stm32mp1_ddr_helpers.h> #include <drivers/st/stm32mp1_ram.h> @@ -205,13 +206,13 @@ static int stm32mp1_ddr_setup(void) return -EINVAL; } - config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0); - if (!config.info.speed) { + ret = fdt_read_uint32(fdt, node, "st,mem-speed", &config.info.speed); + if (ret < 0) { VERBOSE("%s: no st,mem-speed\n", __func__); return -EINVAL; } - config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0); - if (!config.info.size) { + ret = fdt_read_uint32(fdt, node, "st,mem-size", &config.info.size); + if (ret < 0) { VERBOSE("%s: no st,mem-size\n", __func__); return -EINVAL; } @@ -223,10 +224,10 @@ static int stm32mp1_ddr_setup(void) INFO("RAM: %s\n", config.info.name); for (idx = 0; idx < ARRAY_SIZE(param); idx++) { - ret = fdt_read_uint32_array(node, param[idx].name, + ret = fdt_read_uint32_array(fdt, node, param[idx].name, + param[idx].size, (void *)((uintptr_t)&config + - param[idx].offset), - param[idx].size); + param[idx].offset)); VERBOSE("%s: %s[0x%x] = %d\n", __func__, param[idx].name, param[idx].size, ret); @@ -250,8 +251,9 @@ static int stm32mp1_ddr_setup(void) VERBOSE("%s : ram size(%x, %x)\n", __func__, (uint32_t)priv->info.base, (uint32_t)priv->info.size); - write_sctlr(read_sctlr() & ~SCTLR_C_BIT); - dcsw_op_all(DC_OP_CISW); + if (stm32mp_map_ddr_non_cacheable() != 0) { + panic(); + } uret = ddr_test_data_bus(); if (uret != 0U) { @@ -274,7 +276,9 @@ static int stm32mp1_ddr_setup(void) panic(); } - write_sctlr(read_sctlr() | SCTLR_C_BIT); + if (stm32mp_unmap_ddr() != 0) { + panic(); + } return 0; } diff --git a/drivers/st/etzpc/etzpc.c b/drivers/st/etzpc/etzpc.c new file mode 100644 index 000000000..ff52a22d9 --- /dev/null +++ b/drivers/st/etzpc/etzpc.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> +#include <stdint.h> + +#include <arch_helpers.h> +#include <common/debug.h> +#include <drivers/st/etzpc.h> +#include <dt-bindings/soc/st,stm32-etzpc.h> +#include <lib/mmio.h> +#include <lib/utils_def.h> +#include <libfdt.h> + +#include <platform_def.h> + +/* Device Tree related definitions */ +#define ETZPC_COMPAT "st,stm32-etzpc" +#define ETZPC_LOCK_MASK 0x1U +#define ETZPC_MODE_SHIFT 8 +#define ETZPC_MODE_MASK GENMASK(1, 0) +#define ETZPC_ID_SHIFT 16 +#define ETZPC_ID_MASK GENMASK(7, 0) + +/* ID Registers */ +#define ETZPC_TZMA0_SIZE 0x000U +#define ETZPC_DECPROT0 0x010U +#define ETZPC_DECPROT_LOCK0 0x030U +#define ETZPC_HWCFGR 0x3F0U +#define ETZPC_VERR 0x3F4U + +/* ID Registers fields */ +#define ETZPC_TZMA0_SIZE_LOCK BIT(31) +#define ETZPC_DECPROT0_MASK GENMASK(1, 0) +#define ETZPC_HWCFGR_NUM_TZMA_SHIFT 0 +#define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT 8 +#define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT 16 +#define ETZPC_HWCFGR_CHUNCKS1N4_SHIFT 24 + +#define DECPROT_SHIFT 1 +#define IDS_PER_DECPROT_REGS 16U +#define IDS_PER_DECPROT_LOCK_REGS 32U + +/* + * etzpc_instance. + * base : register base address set during init given by user + * chunk_size : supported TZMA size steps + * num_tzma: number of TZMA zone read from register at init + * num_ahb_sec : number of securable AHB master zone read from register + * num_per_sec : number of securable AHB & APB Peripherals read from register + * revision : IP revision read from register at init + */ +struct etzpc_instance { + uintptr_t base; + uint8_t chunck_size; + uint8_t num_tzma; + uint8_t num_per_sec; + uint8_t num_ahb_sec; + uint8_t revision; +}; + +/* Only 1 instance of the ETZPC is expected per platform */ +static struct etzpc_instance etzpc_dev; + +/* + * Implementation uses uint8_t to store each securable DECPROT configuration. + * When resuming from deep suspend, the DECPROT configurations are restored. + */ +#define PERIPH_LOCK_BIT BIT(7) +#define PERIPH_ATTR_MASK GENMASK(2, 0) + +#if ENABLE_ASSERTIONS +static bool valid_decprot_id(unsigned int id) +{ + return id < (unsigned int)etzpc_dev.num_per_sec; +} + +static bool valid_tzma_id(unsigned int id) +{ + return id < (unsigned int)etzpc_dev.num_tzma; +} +#endif + +/* + * etzpc_configure_decprot : Load a DECPROT configuration + * decprot_id : ID of the IP + * decprot_attr : Restriction access attribute + */ +void etzpc_configure_decprot(uint32_t decprot_id, + enum etzpc_decprot_attributes decprot_attr) +{ + uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS); + uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; + uint32_t masked_decprot = (uint32_t)decprot_attr & ETZPC_DECPROT0_MASK; + + assert(valid_decprot_id(decprot_id)); + + mmio_clrsetbits_32(etzpc_dev.base + ETZPC_DECPROT0 + offset, + (uint32_t)ETZPC_DECPROT0_MASK << shift, + masked_decprot << shift); +} + +/* + * etzpc_get_decprot : Get the DECPROT attribute + * decprot_id : ID of the IP + * return : Attribute of this DECPROT + */ +enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id) +{ + uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS); + uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; + uintptr_t base_decprot = etzpc_dev.base + offset; + uint32_t value; + + assert(valid_decprot_id(decprot_id)); + + value = (mmio_read_32(base_decprot + ETZPC_DECPROT0) >> shift) & + ETZPC_DECPROT0_MASK; + + return (enum etzpc_decprot_attributes)value; +} + +/* + * etzpc_lock_decprot : Lock access to the DECPROT attribute + * decprot_id : ID of the IP + */ +void etzpc_lock_decprot(uint32_t decprot_id) +{ + uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_LOCK_REGS); + uint32_t shift = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS); + uintptr_t base_decprot = etzpc_dev.base + offset; + + assert(valid_decprot_id(decprot_id)); + + mmio_write_32(base_decprot + ETZPC_DECPROT_LOCK0, shift); +} + +/* + * etzpc_configure_tzma : Configure the target TZMA read only size + * tzma_id : ID of the memory + * tzma_value : read-only size + */ +void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value) +{ + assert(valid_tzma_id(tzma_id)); + + mmio_write_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id), tzma_value); +} + +/* + * etzpc_get_tzma : Get the target TZMA read only size + * tzma_id : TZMA ID + * return : Size of read only size + */ +uint16_t etzpc_get_tzma(uint32_t tzma_id) +{ + assert(valid_tzma_id(tzma_id)); + + return (uint16_t)mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id)); +} + +/* + * etzpc_lock_tzma : Lock the target TZMA + * tzma_id : TZMA ID + */ +void etzpc_lock_tzma(uint32_t tzma_id) +{ + assert(valid_tzma_id(tzma_id)); + + mmio_setbits_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id), ETZPC_TZMA0_SIZE_LOCK); +} + +/* + * etzpc_get_lock_tzma : Return the lock status of the target TZMA + * tzma_id : TZMA ID + * return : True if TZMA is locked, false otherwise + */ +bool etzpc_get_lock_tzma(uint32_t tzma_id) +{ + uint32_t tzma_size; + + assert(valid_tzma_id(tzma_id)); + + tzma_size = mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE + + (sizeof(uint32_t) * tzma_id)); + + return (tzma_size & ETZPC_TZMA0_SIZE_LOCK) != 0; +} + +/* + * etzpc_get_num_per_sec : Return the DECPROT ID limit value + */ +uint8_t etzpc_get_num_per_sec(void) +{ + return etzpc_dev.num_per_sec; +} + +/* + * etzpc_get_revision : Return the ETZPC IP revision + */ +uint8_t etzpc_get_revision(void) +{ + return etzpc_dev.revision; +} + +/* + * etzpc_get_base_address : Return the ETZPC IP base address + */ +uintptr_t etzpc_get_base_address(void) +{ + return etzpc_dev.base; +} + +/* + * etzpc_init : Initialize the ETZPC driver + * Return 0 on success and a negative errno on failure + */ +int etzpc_init(void) +{ + uint32_t hwcfg; + int node; + struct dt_node_info etzpc_info; + + node = dt_get_node(&etzpc_info, -1, ETZPC_COMPAT); + if (node < 0) { + return -EIO; + } + + /* Check ETZPC is secure only */ + if (etzpc_info.status != DT_SECURE) { + return -EACCES; + } + + etzpc_dev.base = etzpc_info.base; + + hwcfg = mmio_read_32(etzpc_dev.base + ETZPC_HWCFGR); + + etzpc_dev.num_tzma = (uint8_t)(hwcfg >> ETZPC_HWCFGR_NUM_TZMA_SHIFT); + etzpc_dev.num_per_sec = (uint8_t)(hwcfg >> + ETZPC_HWCFGR_NUM_PER_SEC_SHIFT); + etzpc_dev.num_ahb_sec = (uint8_t)(hwcfg >> + ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT); + etzpc_dev.chunck_size = (uint8_t)(hwcfg >> + ETZPC_HWCFGR_CHUNCKS1N4_SHIFT); + + etzpc_dev.revision = mmio_read_8(etzpc_dev.base + ETZPC_VERR); + + VERBOSE("ETZPC version 0x%x", etzpc_dev.revision); + + return 0; +} diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c index b694fff6b..a58a243ad 100644 --- a/drivers/st/fmc/stm32_fmc2_nand.c +++ b/drivers/st/fmc/stm32_fmc2_nand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -22,9 +22,14 @@ #include <lib/mmio.h> #include <lib/utils_def.h> +/* Timeout for device interface reset */ +#define TIMEOUT_US_1_MS 1000U + /* FMC2 Compatibility */ -#define DT_FMC2_COMPAT "st,stm32mp15-fmc2" +#define DT_FMC2_EBI_COMPAT "st,stm32mp1-fmc2-ebi" +#define DT_FMC2_NFC_COMPAT "st,stm32mp1-fmc2-nfc" #define MAX_CS 2U +#define MAX_BANK 5U /* FMC2 Controller Registers */ #define FMC2_BCR1 0x00U @@ -34,6 +39,7 @@ #define FMC2_PATT 0x8CU #define FMC2_HECCR 0x94U #define FMC2_BCHISR 0x254U +#define FMC2_BCHICR 0x258U #define FMC2_BCHDSR0 0x27CU #define FMC2_BCHDSR1 0x280U #define FMC2_BCHDSR2 0x284U @@ -79,6 +85,8 @@ #define FMC2_PATT_DEFAULT 0x0A0A0A0AU /* FMC2_BCHISR register */ #define FMC2_BCHISR_DERF BIT(1) +/* FMC2_BCHICR register */ +#define FMC2_BCHICR_CLEAR_IRQ GENMASK_32(4, 0) /* FMC2_BCHDSR0 register */ #define FMC2_BCHDSR0_DUE BIT(0) #define FMC2_BCHDSR0_DEF BIT(1) @@ -365,7 +373,7 @@ static int stm32_fmc2_ham_correct(uint8_t *buffer, uint8_t *eccbuffer, xor_ecc_2b = ecc[1] ^ eccbuffer[1]; xor_ecc_3b = ecc[2] ^ eccbuffer[2]; - xor_ecc.val = 0L; + xor_ecc.val = 0U; xor_ecc.bytes[2] = xor_ecc_3b; xor_ecc.bytes[1] = xor_ecc_2b; xor_ecc.bytes[0] = xor_ecc_1b; @@ -497,6 +505,7 @@ static void stm32_fmc2_hwctl(struct nand_device *nand) if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) { mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN); + mmio_write_32(fmc2_base() + FMC2_BCHICR, FMC2_BCHICR_CLEAR_IRQ); } stm32_fmc2_set_ecc(true); @@ -786,22 +795,26 @@ static const struct nand_ctrl_ops ctrl_ops = { int stm32_fmc2_init(void) { - int fmc_node; - int fmc_subnode = 0; + int fmc_ebi_node; + int fmc_nfc_node; + int fmc_flash_node = 0; int nchips = 0; unsigned int i; void *fdt = NULL; const fdt32_t *cuint; struct dt_node_info info; + uintptr_t bank_address[MAX_BANK] = { 0, 0, 0, 0, 0 }; + uint8_t bank_assigned = 0; + uint8_t bank; + int ret; if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; } - fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT); - if (fmc_node == -FDT_ERR_NOTFOUND) { - WARN("No FMC2 node found\n"); - return fmc_node; + fmc_ebi_node = dt_get_node(&info, -1, DT_FMC2_EBI_COMPAT); + if (fmc_ebi_node < 0) { + return fmc_ebi_node; } if (info.status == DT_DISABLED) { @@ -817,27 +830,69 @@ int stm32_fmc2_init(void) stm32_fmc2.clock_id = (unsigned long)info.clock; stm32_fmc2.reset_id = (unsigned int)info.reset; - cuint = fdt_getprop(fdt, fmc_node, "reg", NULL); + cuint = fdt_getprop(fdt, fmc_ebi_node, "ranges", NULL); if (cuint == NULL) { return -FDT_ERR_BADVALUE; } - cuint += 2; - - for (i = 0U; i < MAX_CS; i++) { - stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint); - stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2)); - stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4)); - cuint += 6; + for (i = 0U; i < MAX_BANK; i++) { + bank = fdt32_to_cpu(*cuint); + if ((bank >= MAX_BANK) || ((bank_assigned & BIT(bank)) != 0U)) { + return -FDT_ERR_BADVALUE; + } + bank_assigned |= BIT(bank); + bank_address[bank] = fdt32_to_cpu(*(cuint + 2)); + cuint += 4; } /* Pinctrl initialization */ - if (dt_set_pinctrl_config(fmc_node) != 0) { + if (dt_set_pinctrl_config(fmc_ebi_node) != 0) { + return -FDT_ERR_BADVALUE; + } + + /* Parse NFC controller node */ + fmc_nfc_node = fdt_node_offset_by_compatible(fdt, fmc_ebi_node, + DT_FMC2_NFC_COMPAT); + if (fmc_nfc_node < 0) { + return fmc_nfc_node; + } + + if (fdt_get_status(fmc_nfc_node) == DT_DISABLED) { + return -FDT_ERR_NOTFOUND; + } + + cuint = fdt_getprop(fdt, fmc_nfc_node, "reg", NULL); + if (cuint == NULL) { return -FDT_ERR_BADVALUE; } + for (i = 0U; i < MAX_CS; i++) { + bank = fdt32_to_cpu(*cuint); + if (bank >= MAX_BANK) { + return -FDT_ERR_BADVALUE; + } + stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*(cuint + 1)) + + bank_address[bank]; + + bank = fdt32_to_cpu(*(cuint + 3)); + if (bank >= MAX_BANK) { + return -FDT_ERR_BADVALUE; + } + stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 4)) + + bank_address[bank]; + + bank = fdt32_to_cpu(*(cuint + 6)); + if (bank >= MAX_BANK) { + return -FDT_ERR_BADVALUE; + } + stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 7)) + + bank_address[bank]; + + cuint += 9; + } + /* Parse flash nodes */ - fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { + fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { nchips++; } @@ -846,14 +901,19 @@ int stm32_fmc2_init(void) return -FDT_ERR_BADVALUE; } - fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) { + fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) { /* Get chip select */ - cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL); + cuint = fdt_getprop(fdt, fmc_flash_node, "reg", NULL); if (cuint == NULL) { WARN("Chip select not well defined\n"); return -FDT_ERR_BADVALUE; } + stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint); + if (stm32_fmc2.cs_sel >= MAX_CS) { + return -FDT_ERR_BADVALUE; + } + VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel); } @@ -861,8 +921,14 @@ int stm32_fmc2_init(void) stm32mp_clk_enable(stm32_fmc2.clock_id); /* Reset IP */ - stm32mp_reset_assert(stm32_fmc2.reset_id); - stm32mp_reset_deassert(stm32_fmc2.reset_id); + ret = stm32mp_reset_assert(stm32_fmc2.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } + ret = stm32mp_reset_deassert(stm32_fmc2.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } /* Setup default IP registers */ stm32_fmc2_ctrl_init(); diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c index a13c341a8..7d63262d7 100644 --- a/drivers/st/gpio/stm32_gpio.c +++ b/drivers/st/gpio/stm32_gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -161,13 +161,14 @@ int dt_set_pinctrl_config(int node) const fdt32_t *cuint; int lenp = 0; uint32_t i; - uint8_t status = fdt_get_status(node); + uint8_t status; void *fdt; if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; } + status = fdt_get_status(node); if (status == DT_DISABLED) { return -FDT_ERR_NOTFOUND; } @@ -254,6 +255,15 @@ void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, mmio_read_32(base + GPIO_AFRH_OFFSET)); stm32mp_clk_disable(clock); + + if (status == DT_SECURE) { + stm32mp_register_secure_gpio(bank, pin); + set_gpio_secure_cfg(bank, pin, true); + + } else { + stm32mp_register_non_secure_gpio(bank, pin); + set_gpio_secure_cfg(bank, pin, false); + } } void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure) diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c index 44b7d1907..0ed71540c 100644 --- a/drivers/st/io/io_mmc.c +++ b/drivers/st/io/io_mmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -97,14 +97,21 @@ static int mmc_block_seek(io_entity_t *entity, int mode, static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { - *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, - buffer, length); - - if (*length_read != length) { - return -EIO; + uint8_t retries; + + for (retries = 0U; retries < 3U; retries++) { + *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE, + buffer, length); + + if (*length_read == length) { + return 0; + } + WARN("%s: length_read = %lu (!= %lu), retry %u\n", __func__, + (unsigned long)*length_read, (unsigned long)length, + retries + 1U); } - return 0; + return -EIO; } /* Close a file on the mmc device */ diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c index 413521b1e..3e377cd48 100644 --- a/drivers/st/io/io_stm32image.c +++ b/drivers/st/io/io_stm32image.c @@ -247,7 +247,7 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, size_t length, size_t *length_read) { int result; - uint8_t *local_buffer = (uint8_t *)buffer; + uint8_t *local_buffer; boot_api_image_header_t *header = (boot_api_image_header_t *)first_lba_buffer; @@ -255,6 +255,7 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, assert(buffer != 0U); assert(length_read != NULL); + local_buffer = (uint8_t *)buffer; *length_read = 0U; while (*length_read == 0U) { diff --git a/drivers/st/iwdg/stm32_iwdg.c b/drivers/st/iwdg/stm32_iwdg.c index ea6fbb2b9..c052b4dfb 100644 --- a/drivers/st/iwdg/stm32_iwdg.c +++ b/drivers/st/iwdg/stm32_iwdg.c @@ -137,6 +137,12 @@ int stm32_iwdg_init(void) ((dt_info.status & DT_NON_SECURE) != 0) ? "non-" : ""); + if ((dt_info.status & DT_NON_SECURE) != 0) { + stm32mp_register_non_secure_periph_iomem(iwdg->base); + } else { + stm32mp_register_secure_periph_iomem(iwdg->base); + } + #if defined(IMAGE_BL2) if (stm32_iwdg_shadow_update(idx, iwdg->flags) != BSEC_OK) { return -1; diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c index 24e6efe98..cff3a344f 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -113,6 +113,7 @@ SDMMC_STAR_IDMATE | \ SDMMC_STAR_IDMABTC) +#define TIMEOUT_US_1_MS 1000U #define TIMEOUT_US_10_MS 10000U #define TIMEOUT_US_1_S 1000000U @@ -257,6 +258,18 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) break; } + mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); + + /* + * Clear the SDMMC_DCTRLR if the command does not await data. + * Skip CMD55 as the next command could be data related, and + * the register could have been set in prepare function. + */ + if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && + (cmd->cmd_idx != MMC_CMD(55))) { + mmio_write_32(base + SDMMC_DCTRLR, 0U); + } + if ((cmd->resp_type & MMC_RSP_BUSY) != 0U) { mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX); } @@ -372,15 +385,15 @@ err_exit: static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) { - int8_t retry; - int err = 0; + uint8_t retry; + int err; assert(cmd != NULL); - for (retry = 0; retry <= 3; retry++) { + for (retry = 0U; retry < 3U; retry++) { err = stm32_sdmmc2_send_cmd_req(cmd); if (err == 0) { - return err; + return 0; } if ((cmd->cmd_idx == MMC_CMD(1)) || @@ -389,12 +402,12 @@ static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd) } /* Command 8 is expected to fail for eMMC */ - if (!(cmd->cmd_idx == MMC_CMD(8))) { - WARN(" CMD%d, Retry: %d, Error: %d\n", - cmd->cmd_idx, retry, err); + if (cmd->cmd_idx != MMC_CMD(8)) { + WARN(" CMD%u, Retry: %u, Error: %d\n", + cmd->cmd_idx, retry + 1U, err); } - udelay(10); + udelay(10U); } return err; @@ -711,6 +724,8 @@ unsigned long long stm32_sdmmc2_mmc_get_device_size(void) int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) { + int rc; + assert((params != NULL) && ((params->reg_base & MMC_BLOCK_MASK) == 0U) && ((params->bus_width == MMC_BUS_WIDTH_1) || @@ -726,9 +741,15 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params) stm32mp_clk_enable(sdmmc2_params.clock_id); - stm32mp_reset_assert(sdmmc2_params.reset_id); + rc = stm32mp_reset_assert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS); + if (rc != 0) { + panic(); + } udelay(2); - stm32mp_reset_deassert(sdmmc2_params.reset_id); + rc = stm32mp_reset_deassert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS); + if (rc != 0) { + panic(); + } mdelay(1); sdmmc2_params.clk_rate = stm32mp_clk_get_rate(sdmmc2_params.clock_id); diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c index 9e9dddc4d..b2bb482f9 100644 --- a/drivers/st/pmic/stm32mp_pmic.c +++ b/drivers/st/pmic/stm32mp_pmic.c @@ -54,6 +54,15 @@ int dt_pmic_status(void) return fdt_get_status(node); } +static bool dt_pmic_is_secure(void) +{ + int status = dt_pmic_status(); + + return (status >= 0) && + (status == DT_SECURE) && + (i2c_handle.dt_status == DT_SECURE); +} + /* * Get PMIC and its I2C bus configuration from the device tree. * Return 0 on success, negative on error, 1 if no PMIC node is found. @@ -223,6 +232,19 @@ bool initialize_pmic_i2c(void) return true; } +static void register_pmic_shared_peripherals(void) +{ + uintptr_t i2c_base = i2c_handle.i2c_base_addr; + + if (dt_pmic_is_secure()) { + stm32mp_register_secure_periph_iomem(i2c_base); + } else { + if (i2c_base != 0U) { + stm32mp_register_non_secure_periph_iomem(i2c_base); + } + } +} + void initialize_pmic(void) { unsigned long pmic_version; @@ -232,6 +254,8 @@ void initialize_pmic(void) return; } + register_pmic_shared_peripherals(); + if (stpmic1_get_version(&pmic_version) != 0) { ERROR("Failed to access PMIC\n"); panic(); diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c index fd3f93e01..98c8dcf71 100644 --- a/drivers/st/reset/stm32mp1_reset.c +++ b/drivers/st/reset/stm32mp1_reset.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <errno.h> #include <limits.h> #include <platform_def.h> @@ -15,8 +16,6 @@ #include <lib/mmio.h> #include <lib/utils_def.h> -#define RESET_TIMEOUT_US_1MS U(1000) - static uint32_t id2reg_offset(unsigned int reset_id) { return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t); @@ -27,36 +26,44 @@ static uint8_t id2reg_bit_pos(unsigned int reset_id) return (uint8_t)(reset_id & GENMASK(4, 0)); } -void stm32mp_reset_assert(uint32_t id) +int stm32mp_reset_assert(uint32_t id, unsigned int to_us) { uint32_t offset = id2reg_offset(id); uint32_t bitmsk = BIT(id2reg_bit_pos(id)); - uint64_t timeout_ref; uintptr_t rcc_base = stm32mp_rcc_base(); mmio_write_32(rcc_base + offset, bitmsk); - timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS); - while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) { - if (timeout_elapsed(timeout_ref)) { - panic(); + if (to_us != 0U) { + uint64_t timeout_ref = timeout_init_us(to_us); + + while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) { + if (timeout_elapsed(timeout_ref)) { + return -ETIMEDOUT; + } } } + + return 0; } -void stm32mp_reset_deassert(uint32_t id) +int stm32mp_reset_deassert(uint32_t id, unsigned int to_us) { uint32_t offset = id2reg_offset(id) + RCC_RSTCLRR_OFFSET; uint32_t bitmsk = BIT(id2reg_bit_pos(id)); - uint64_t timeout_ref; uintptr_t rcc_base = stm32mp_rcc_base(); mmio_write_32(rcc_base + offset, bitmsk); - timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS); - while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) { - if (timeout_elapsed(timeout_ref)) { - panic(); + if (to_us != 0U) { + uint64_t timeout_ref = timeout_init_us(to_us); + + while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) { + if (timeout_elapsed(timeout_ref)) { + return -ETIMEDOUT; + } } } + + return 0; } diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c index 188d2ff80..d67f8313f 100644 --- a/drivers/st/spi/stm32_qspi.c +++ b/drivers/st/spi/stm32_qspi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -9,13 +9,18 @@ #include <platform_def.h> #include <common/debug.h> +#include <common/fdt_wrappers.h> #include <drivers/delay_timer.h> #include <drivers/spi_mem.h> #include <drivers/st/stm32_gpio.h> +#include <drivers/st/stm32_qspi.h> #include <drivers/st/stm32mp_reset.h> #include <lib/mmio.h> #include <lib/utils_def.h> +/* Timeout for device interface reset */ +#define TIMEOUT_US_1_MS 1000U + /* QUADSPI registers */ #define QSPI_CR 0x00U #define QSPI_DCR 0x04U @@ -172,9 +177,8 @@ static void stm32_qspi_write_fifo(uint8_t *val, uintptr_t addr) static int stm32_qspi_poll(const struct spi_mem_op *op) { void (*fifo)(uint8_t *val, uintptr_t addr); - uint32_t len = op->data.nbytes; + uint32_t len; uint8_t *buf; - uint64_t timeout; if (op->data.dir == SPI_MEM_DATA_IN) { fifo = stm32_qspi_read_fifo; @@ -185,7 +189,8 @@ static int stm32_qspi_poll(const struct spi_mem_op *op) buf = (uint8_t *)op->data.buf; for (len = op->data.nbytes; len != 0U; len--) { - timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US); + uint64_t timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US); + while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_FTF) == 0U) { if (timeout_elapsed(timeout)) { @@ -464,13 +469,13 @@ int stm32_qspi_init(void) return -FDT_ERR_NOTFOUND; } - ret = fdt_get_reg_props_by_name(qspi_node, "qspi", + ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi", &stm32_qspi.reg_base, &size); if (ret != 0) { return ret; } - ret = fdt_get_reg_props_by_name(qspi_node, "qspi_mm", + ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi_mm", &stm32_qspi.mm_base, &stm32_qspi.mm_size); if (ret != 0) { @@ -490,8 +495,14 @@ int stm32_qspi_init(void) stm32mp_clk_enable(stm32_qspi.clock_id); - stm32mp_reset_assert(stm32_qspi.reset_id); - stm32mp_reset_deassert(stm32_qspi.reset_id); + ret = stm32mp_reset_assert(stm32_qspi.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } + ret = stm32mp_reset_deassert(stm32_qspi.reset_id, TIMEOUT_US_1_MS); + if (ret != 0) { + panic(); + } mmio_write_32(qspi_base() + QSPI_CR, QSPI_CR_SSHIFT); mmio_write_32(qspi_base() + QSPI_DCR, QSPI_DCR_FSIZE_MASK); diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S index ca3c1f618..686b18b96 100644 --- a/drivers/st/uart/aarch32/stm32_console.S +++ b/drivers/st/uart/aarch32/stm32_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -91,14 +91,14 @@ endfunc console_stm32_core_init /* ------------------------------------------------------- * int console_stm32_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * struct console_stm32 *console); + * console_t *console); * Function to initialize and register a new STM32 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). * In: r0 - UART register base address * r1 - UART clock in Hz * r2 - Baud rate - * r3 - pointer to empty console_stm32 struct + * r3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : r0, r1, r2 * ------------------------------------------------------- @@ -108,7 +108,7 @@ func console_stm32_register mov r4, r3 cmp r4, #0 beq register_fail - str r0, [r4, #CONSOLE_T_STM32_BASE] + str r0, [r4, #CONSOLE_T_BASE] bl console_stm32_core_init cmp r0, #0 @@ -157,7 +157,7 @@ putc_error: endfunc console_stm32_core_putc /* ------------------------------------------------------------ - * int console_stm32_putc(int c, struct console_stm32 *console) + * int console_stm32_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: r0 - character to be printed @@ -171,7 +171,7 @@ func console_stm32_putc cmp r1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r1, [r1, #CONSOLE_T_STM32_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] b console_stm32_core_putc endfunc console_stm32_putc @@ -193,37 +193,35 @@ func console_stm32_core_getc endfunc console_stm32_core_getc /* --------------------------------------------------------------- - * int console_core_flush(uintptr_t base_addr) + * void console_core_flush(uintptr_t base_addr) * * Function to force a write of all buffered data that hasn't been * output. * * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0, r1 * --------------------------------------------------------------- */ func console_stm32_core_flush +#if ENABLE_ASSERTIONS cmp r0, #0 - beq flush_error + ASM_ASSERT(ne) +#endif /* ENABLE_ASSERTIONS */ /* Check Transmit Data Register Empty */ txe_loop_3: ldr r1, [r0, #USART_ISR] tst r1, #USART_ISR_TXE beq txe_loop_3 - mov r0, #0 - bx lr -flush_error: - mov r0, #-1 bx lr endfunc console_stm32_core_flush /* ------------------------------------------------------ - * int console_stm32_flush(struct console_stm32 *console) + * void console_stm32_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list: r0, r1 * ------------------------------------------------------ */ @@ -232,6 +230,6 @@ func console_stm32_flush cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_STM32_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_stm32_core_flush endfunc console_stm32_flush diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S index 5cd9b30cd..0429f8702 100644 --- a/drivers/ti/uart/aarch32/16550_console.S +++ b/drivers/ti/uart/aarch32/16550_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -91,7 +91,7 @@ endfunc console_16550_core_init /* ------------------------------------------------------- * int console_16550_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_16550_t *console); + * console_t *console); * Function to initialize and register a new 16550 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). @@ -101,7 +101,7 @@ endfunc console_16550_core_init * In: r0 - UART register base address * r1 - UART clock in Hz * r2 - Baud rate (ignored if r1 is 0) - * r3 - pointer to empty console_16550_t struct + * r3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : r0, r1, r2 * ------------------------------------------------------- @@ -111,7 +111,7 @@ func console_16550_register mov r4, r3 cmp r4, #0 beq register_fail - str r0, [r4, #CONSOLE_T_16550_BASE] + str r0, [r4, #CONSOLE_T_BASE] /* A clock rate of zero means to skip the initialisation. */ cmp r1, #0 @@ -167,7 +167,7 @@ func console_16550_core_putc endfunc console_16550_core_putc /* -------------------------------------------------------- - * int console_16550_putc(int c, console_16550_t *console) + * int console_16550_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 : r0 - character to be printed @@ -181,7 +181,7 @@ func console_16550_putc cmp r1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r1, [r1, #CONSOLE_T_16550_BASE] + ldr r1, [r1, #CONSOLE_T_BASE] b console_16550_core_putc endfunc console_16550_putc @@ -213,7 +213,7 @@ no_char: endfunc console_16550_core_getc /* --------------------------------------------- - * int console_16550_getc(console_16550_t *console) + * int console_16550_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on if no character is available. @@ -227,16 +227,16 @@ func console_16550_getc cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_16550_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_16550_core_getc endfunc console_16550_getc /* --------------------------------------------- - * int console_16550_core_flush(uintptr_t base_addr) + * void console_16550_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0, r1 * --------------------------------------------- */ @@ -252,16 +252,15 @@ func console_16550_core_flush cmp r1, #(UARTLSR_TEMT | UARTLSR_THRE) bne 1b - mov r0, #0 bx lr endfunc console_16550_core_flush /* --------------------------------------------- - * int console_16550_flush(console_pl011_t *console) + * void console_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : r0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void * Clobber list : r0, r1 * --------------------------------------------- */ @@ -270,6 +269,6 @@ func console_16550_flush cmp r0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr r0, [r0, #CONSOLE_T_16550_BASE] + ldr r0, [r0, #CONSOLE_T_BASE] b console_16550_core_flush endfunc console_16550_flush diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S index 80c1b8646..cb2151253 100644 --- a/drivers/ti/uart/aarch64/16550_console.S +++ b/drivers/ti/uart/aarch64/16550_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -88,7 +88,7 @@ endfunc console_16550_core_init /* ----------------------------------------------- * int console_16550_register(uintptr_t baseaddr, * uint32_t clock, uint32_t baud, - * console_16550_t *console); + * console_t *console); * Function to initialize and register a new 16550 * console. Storage passed in for the console struct * *must* be persistent (i.e. not from the stack). @@ -98,7 +98,7 @@ endfunc console_16550_core_init * In: x0 - UART register base address * w1 - UART clock in Hz * w2 - Baud rate (ignored if w1 is 0) - * x3 - pointer to empty console_16550_t struct + * x3 - pointer to empty console_t struct * Out: return 1 on success, 0 on error * Clobber list : x0, x1, x2, x6, x7, x14 * ----------------------------------------------- @@ -107,7 +107,7 @@ func console_16550_register mov x7, x30 mov x6, x3 cbz x6, register_fail - str x0, [x6, #CONSOLE_T_16550_BASE] + str x0, [x6, #CONSOLE_T_BASE] /* A clock rate of zero means to skip the initialisation. */ cbz w1, register_16550 @@ -161,7 +161,7 @@ func console_16550_core_putc endfunc console_16550_core_putc /* -------------------------------------------------------- - * int console_16550_putc(int c, console_16550_t *console) + * int console_16550_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 @@ -175,7 +175,7 @@ func console_16550_putc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x1, [x1, #CONSOLE_T_16550_BASE] + ldr x1, [x1, #CONSOLE_T_BASE] b console_16550_core_putc endfunc console_16550_putc @@ -206,7 +206,7 @@ no_char: endfunc console_16550_core_getc /* --------------------------------------------- - * int console_16550_getc(console_16550_t *console) + * int console_16550_getc(console_t *console) * Function to get a character from the console. * It returns the character grabbed on success * or -1 on if no character is available. @@ -220,16 +220,16 @@ func console_16550_getc cmp x1, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_16550_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_16550_core_getc endfunc console_16550_getc /* --------------------------------------------- - * int console_16550_core_flush(uintptr_t base_addr) + * void console_16550_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -245,16 +245,15 @@ func console_16550_core_flush cmp w1, #(UARTLSR_TEMT | UARTLSR_THRE) b.ne 1b - mov w0, #0 ret endfunc console_16550_core_flush /* --------------------------------------------- - * int console_16550_flush(console_pl011_t *console) + * void console_16550_flush(console_t *console) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - pointer to console_t structure - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : x0, x1 * --------------------------------------------- */ @@ -263,6 +262,6 @@ func console_16550_flush cmp x0, #0 ASM_ASSERT(ne) #endif /* ENABLE_ASSERTIONS */ - ldr x0, [x0, #CONSOLE_T_16550_BASE] + ldr x0, [x0, #CONSOLE_T_BASE] b console_16550_core_flush endfunc console_16550_flush |