From 72196cbb669bf3fe9b28091889e8fc7fbf2a2556 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Fri, 10 May 2019 13:07:41 +0300 Subject: [PATCH 1/2] plat: imx8mq: Implement IMX_SIP_GET_SOC_INFO The manual documents that 0x3036006c should contains the soc revision for imx8mq but this always reports A0. Work around this by parsing the ROM header and checking if OCOTP register 0x40 is stuck at 0xff0055aa. Determining this inside TF-A makes life easier for OS, see for example this linux discussion: https://lkml.org/lkml/2019/5/3/465 The soc revision can also be useful inside TF-A itself, for example for the non-upstream DDR DVFS "busfreq" feature is affected by 8mq erratas. The clock for OCOTP block can be disabled by OS so only initialize soc revision once at boot time. Change-Id: I9ca3f27840229ce8a28b53870e44da29f63c73aa Signed-off-by: Leonard Crestez --- plat/imx/common/imx_sip_svc.c | 5 +++ plat/imx/common/include/imx_sip_svc.h | 7 ++++ plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c | 43 ++++++++++++++++++++ plat/imx/imx8m/imx8mq/include/platform_def.h | 3 ++ 4 files changed, 58 insertions(+) diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c index c27fbf2e3..45d18eff0 100644 --- a/plat/imx/common/imx_sip_svc.c +++ b/plat/imx/common/imx_sip_svc.c @@ -26,6 +26,11 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid, u_register_t flags) { switch (smc_fid) { +#if defined(PLAT_imx8mq) + case IMX_SIP_GET_SOC_INFO: + SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3)); + break; +#endif #if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX)) case IMX_SIP_SRTC: return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4); diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h index afe62d4a9..f532840d7 100644 --- a/plat/imx/common/include/imx_sip_svc.h +++ b/plat/imx/common/include/imx_sip_svc.h @@ -17,6 +17,8 @@ #define IMX_SIP_BUILDINFO 0xC2000003 #define IMX_SIP_BUILDINFO_GET_COMMITHASH 0x00 +#define IMX_SIP_GET_SOC_INFO 0xC2000006 + #define IMX_SIP_WAKEUP_SRC 0xC2000009 #define IMX_SIP_WAKEUP_SRC_SCU 0x1 #define IMX_SIP_WAKEUP_SRC_IRQSTEER 0x2 @@ -26,6 +28,11 @@ #define IMX_SIP_MISC_SET_TEMP 0xC200000C +#if defined(PLAT_imx8mq) +int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1, + u_register_t x2, u_register_t x3); +#endif + #if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX)) int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3); diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c index eadf8811f..ea60466f7 100644 --- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c +++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c @@ -27,6 +27,7 @@ static const mmap_region_t imx_mmap[] = { MAP_REGION_FLAT(GPV_BASE, GPV_SIZE, MT_DEVICE | MT_RW), /* GPV map */ + MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO), /* ROM map */ MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */ MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW), /* GIC map */ {0}, @@ -35,6 +36,45 @@ static const mmap_region_t imx_mmap[] = { static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; +static uint32_t imx_soc_revision; + +int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, + u_register_t x3) +{ + return imx_soc_revision; +} + +#define ANAMIX_DIGPROG 0x6c +#define ROM_SOC_INFO_A0 0x800 +#define ROM_SOC_INFO_B0 0x83C +#define OCOTP_SOC_INFO_B1 0x40 + +static void imx8mq_soc_info_init(void) +{ + uint32_t rom_version; + uint32_t ocotp_val; + + imx_soc_revision = mmio_read_32(IMX_ANAMIX_BASE + ANAMIX_DIGPROG); + rom_version = mmio_read_8(IMX_ROM_BASE + ROM_SOC_INFO_A0); + if (rom_version == 0x10) + return; + + rom_version = mmio_read_8(IMX_ROM_BASE + ROM_SOC_INFO_B0); + if (rom_version == 0x20) { + imx_soc_revision &= ~0xff; + imx_soc_revision |= rom_version; + return; + } + + /* 0xff0055aa is magic number for B1 */ + ocotp_val = mmio_read_32(IMX_OCOTP_BASE + OCOTP_SOC_INFO_B1); + if (ocotp_val == 0xff0055aa) { + imx_soc_revision &= ~0xff; + imx_soc_revision |= 0x21; + return; + } +} + /* get SPSR for BL33 entry */ static uint32_t get_spsr_for_bl33_entry(void) { @@ -128,6 +168,9 @@ void bl31_platform_setup(void) plat_gic_driver_init(); plat_gic_init(); + /* determine SOC revision for erratas */ + imx8mq_soc_info_init(); + /* gpc init */ imx_gpc_init(); } diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h index b54201edc..0e678ca84 100644 --- a/plat/imx/imx8m/imx8mq/include/platform_def.h +++ b/plat/imx/imx8m/imx8mq/include/platform_def.h @@ -59,6 +59,7 @@ #define IMX_AIPS_SIZE U(0xC00000) #define IMX_AIPS1_BASE U(0x30200000) #define IMX_AIPS3_ARB_BASE U(0x30800000) +#define IMX_OCOTP_BASE U(0x30350000) #define IMX_ANAMIX_BASE U(0x30360000) #define IMX_CCM_BASE U(0x30380000) #define IMX_SRC_BASE U(0x30390000) @@ -73,7 +74,9 @@ #define IMX_DDRC_BASE U(0x3d400000) #define IMX_DDRPHY_BASE U(0x3c000000) #define IMX_DDR_IPS_BASE U(0x3d000000) + #define IMX_ROM_BASE U(0x00000000) +#define IMX_ROM_SIZE U(0x20000) #define AIPSTZ1_BASE U(0x301f0000) #define AIPSTZ2_BASE U(0x305f0000) From f56afc1f59a66cf0d19f53d5ff848628d21676ca Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Mon, 20 May 2019 11:28:50 +0300 Subject: [PATCH 2/2] imx8: Replace PLAT_IMX8* with automatic PLAT_imx8* Platform defines are already provided by the build system so let's not duplicate them. Change-Id: Icf1ea76c3c3213e27b447c95e2b22b961fa7693e Signed-off-by: Leonard Crestez --- plat/imx/common/imx_sip_handler.c | 10 +++++----- plat/imx/common/imx_sip_svc.c | 2 +- plat/imx/common/include/imx_sip_svc.h | 2 +- plat/imx/imx8m/imx8mq/include/platform_def.h | 1 - plat/imx/imx8qm/include/platform_def.h | 1 - plat/imx/imx8qx/include/platform_def.h | 1 - 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c index 89771cd6f..62048b696 100644 --- a/plat/imx/common/imx_sip_handler.c +++ b/plat/imx/common/imx_sip_handler.c @@ -14,9 +14,9 @@ #include #include -#if defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX) +#if defined(PLAT_imx8qm) || defined(PLAT_imx8qx) -#ifdef PLAT_IMX8QM +#ifdef PLAT_imx8qm const static int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = { SC_R_A53, SC_R_A72, }; @@ -56,10 +56,10 @@ static void imx_cpufreq_set_target(uint32_t cluster_id, unsigned long freq) { sc_pm_clock_rate_t rate = (sc_pm_clock_rate_t)freq; -#ifdef PLAT_IMX8QM +#ifdef PLAT_imx8qm sc_pm_set_clock_rate(ipc_handle, ap_cluster_index[cluster_id], SC_PM_CLK_CPU, &rate); #endif -#ifdef PLAT_IMX8QX +#ifdef PLAT_imx8qx sc_pm_set_clock_rate(ipc_handle, SC_R_A35, SC_PM_CLK_CPU, &rate); #endif } @@ -141,7 +141,7 @@ int imx_misc_set_temp_handler(uint32_t smc_fid, return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4); } -#endif /* defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX) */ +#endif /* defined(PLAT_imx8qm) || defined(PLAT_imx8qx) */ static uint64_t imx_get_commit_hash(u_register_t x2, u_register_t x3, diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c index 45d18eff0..4893b9fa5 100644 --- a/plat/imx/common/imx_sip_svc.c +++ b/plat/imx/common/imx_sip_svc.c @@ -31,7 +31,7 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid, SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3)); break; #endif -#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX)) +#if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx)) case IMX_SIP_SRTC: return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4); case IMX_SIP_CPUFREQ: diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h index f532840d7..5898f7a81 100644 --- a/plat/imx/common/include/imx_sip_svc.h +++ b/plat/imx/common/include/imx_sip_svc.h @@ -33,7 +33,7 @@ int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3); #endif -#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX)) +#if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx)) int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3); int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1, diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h index 0e678ca84..959b820c5 100644 --- a/plat/imx/imx8m/imx8mq/include/platform_def.h +++ b/plat/imx/imx8m/imx8mq/include/platform_def.h @@ -122,7 +122,6 @@ #define DEBUG_CONSOLE 0 #define IMX_WDOG_B_RESET -#define PLAT_IMX8M 1 #define CAAM_JR0MID U(0x30900010) #define CAAM_JR1MID U(0x30900018) diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h index 946be7659..138a4e1d3 100644 --- a/plat/imx/imx8qm/include/platform_def.h +++ b/plat/imx/imx8qm/include/platform_def.h @@ -66,6 +66,5 @@ #define DEBUG_CONSOLE 0 #define DEBUG_CONSOLE_A53 0 -#define PLAT_IMX8QM 1 #endif /* PLATFORM_DEF_H */ diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h index 3a3fac86f..108627f66 100644 --- a/plat/imx/imx8qx/include/platform_def.h +++ b/plat/imx/imx8qx/include/platform_def.h @@ -58,6 +58,5 @@ #define DEBUG_CONSOLE 0 #define DEBUG_CONSOLE_A35 0 -#define PLAT_IMX8QX 1 #endif /* PLATFORM_DEF_H */