[PATCH] soc: imx: Get iMX8MQ revision for B0 from ATF
From: Guido GÃnther
Date: Fri May 03 2019 - 09:53:47 EST
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 <agx@xxxxxxxxxxx>
---
>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