summaryrefslogtreecommitdiff
path: root/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
diff options
context:
space:
mode:
authorLeonard Crestez <leonard.crestez@nxp.com>2019-05-10 13:07:41 +0300
committerLeonard Crestez <leonard.crestez@nxp.com>2019-05-20 11:24:54 +0300
commit72196cbb669bf3fe9b28091889e8fc7fbf2a2556 (patch)
treee6f3105e9618281f3e5be1ebda19c0a987a0bc1e /plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
parentd8b11091b6f9032c16fdc54218ceda10d21e3355 (diff)
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 <leonard.crestez@nxp.com>
Diffstat (limited to 'plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c')
-rw-r--r--plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index eadf8811..ea60466f 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();
}