This is similar to what the BSP does and needed to e.g. determine necessary quirks for MIPI DSI.
Signed-off-by: Guido Günther <a...@sigxcpu.org> --- >From the list discussion and changelog it's not clear to me why a different method was chosen for the B1 silicon so I left that in place as is and only trigger on the B0 silicon I have here. --- drivers/soc/imx/soc-imx8.c | 49 ++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/soc/imx/soc-imx8.c b/drivers/soc/imx/soc-imx8.c index fc6429f9170a..363acd1151ee 100644 --- a/drivers/soc/imx/soc-imx8.c +++ b/drivers/soc/imx/soc-imx8.c @@ -3,6 +3,7 @@ * Copyright 2019 NXP. */ +#include <linux/arm-smccc.h> #include <linux/init.h> #include <linux/io.h> #include <linux/of_address.h> @@ -11,16 +12,37 @@ #include <linux/platform_device.h> #include <linux/of.h> +#define REV_B0 0x20 #define REV_B1 0x21 +#define IMX8MQ_ATF_GET_SOC_INFO 0xc2000006 #define IMX8MQ_SW_INFO_B1 0x40 #define IMX8MQ_SW_MAGIC_B1 0xff0055aa + struct imx8_soc_data { char *name; u32 (*soc_revision)(void); }; + +static u32 __init imx8mq_soc_revision_from_atf(void) +{ + struct arm_smccc_res res; + u32 digprog; + + arm_smccc_smc(IMX8MQ_ATF_GET_SOC_INFO, 0, 0, 0, 0, 0, 0, 0, &res); + digprog = res.a0; + /* + * Bit [23:16] is the silicon ID + * Bit[7:4] is the base layer revision, + * Bit[3:0] is the metal layer revision + * e.g. 0x10 stands for Tapeout 1.0 + */ + return digprog & 0xff; +} + + static u32 __init imx8mq_soc_revision(void) { struct device_node *np; @@ -29,20 +51,23 @@ static u32 __init imx8mq_soc_revision(void) u32 rev = 0; np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp"); - if (!np) - goto out; - - ocotp_base = of_iomap(np, 0); - WARN_ON(!ocotp_base); - - magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1); - if (magic == IMX8MQ_SW_MAGIC_B1) - rev = REV_B1; - - iounmap(ocotp_base); + if (np) { + ocotp_base = of_iomap(np, 0); + WARN_ON(!ocotp_base); + + magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1); + iounmap(ocotp_base); + of_node_put(np); + if (magic == IMX8MQ_SW_MAGIC_B1) + rev = REV_B1; + } + if (!rev) { + magic = imx8mq_soc_revision_from_atf(); + if (magic == REV_B0) + rev = REV_B0; + } out: - of_node_put(np); return rev; } -- 2.20.1