Commit 204ced24 authored by Guido Gunther's avatar Guido Gunther
Browse files

soc: imx: Try harder to get imx8mq SoC revisions



The mainline ATF doesn't currently support the FSL_SIP_GET_SOC_INFO call
nor does it have the code to identify different imx8mq SOC revisions so
mimic what NXPs ATF does here.

As a fallback use ATF so we can identify new revisions once it gains
support or when using NXPs ATF.
Signed-off-by: Guido Gunther's avatarGuido Günther <agx@sigxcpu.org>
parent d4381199
Pipeline #40063 failed with stage
in 33 minutes and 17 seconds
......@@ -289,6 +289,18 @@ soc@0 {
ranges = <0x0 0x0 0x0 0x3e000000>;
dma-ranges = <0x40000000 0x0 0x40000000 0xc0000000>;
bus@00000000 { /* ROM */
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x00000000 0x00000000 0x20000>;
rom@00000000 {
compatible = "fsl,imx8mq-bootrom";
reg = <0x00000000 0x1e800>;
};
};
bus@30000000 { /* AIPS1 */
compatible = "fsl,imx8mq-aips-bus", "simple-bus";
#address-cells = <1>;
......
......@@ -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,8 +12,12 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#define REV_A0 0x10
#define REV_B0 0x20
#define REV_B1 0x21
#define IMX8MQ_SW_INFO_A0 0x800
#define IMX8MQ_SW_INFO_B0 0x83C
#define IMX8MQ_SW_INFO_B1 0x40
#define IMX8MQ_SW_MAGIC_B1 0xff0055aa
......@@ -21,6 +26,7 @@
/* Same as ANADIG_DIGPROG_IMX7D */
#define ANADIG_DIGPROG_IMX8MM 0x800
#define FSL_SIP_GET_SOC_INFO 0xc2000006
struct imx8_soc_data {
char *name;
......@@ -37,6 +43,39 @@ static ssize_t soc_uid_show(struct device *dev,
static DEVICE_ATTR_RO(soc_uid);
static u32 __init imx8mq_soc_revision_atf(void)
{
struct arm_smccc_res res = { 0 };
arm_smccc_smc(FSL_SIP_GET_SOC_INFO, 0, 0, 0, 0, 0, 0, 0, &res);
/*
* 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 res.a0 & 0xff;
}
static u32 __init imx8mq_soc_magic_node(const char *node, u32 offset)
{
struct device_node *np;
void __iomem *base;
u32 magic;
np = of_find_compatible_node(NULL, NULL, node);
if (!np)
return 0;
base = of_iomap(np, 0);
WARN_ON(!base);
magic = readl_relaxed(base + offset);
iounmap(base);
of_node_put(np);
return magic;
}
static u32 __init imx8mq_soc_revision(void)
{
struct device_node *np;
......@@ -51,9 +90,6 @@ static u32 __init imx8mq_soc_revision(void)
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;
soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
soc_uid <<= 32;
......@@ -61,6 +97,26 @@ static u32 __init imx8mq_soc_revision(void)
iounmap(ocotp_base);
/* B1 revision identified by ocotop */
magic = imx8mq_soc_magic_node("fsl,imx8mq-ocotp", IMX8MQ_SW_INFO_B1);
if (magic == IMX8MQ_SW_MAGIC_B1)
return REV_B1;
/* B0 identified by bootrom */
magic = imx8mq_soc_magic_node("fsl,imx8mq-bootrom", IMX8MQ_SW_INFO_B0);
if ((magic & 0xff) == REV_B0)
return REV_B0;
/* A0 identified by anatop */
magic = imx8mq_soc_magic_node("fsl,imx8mq-anatop", IMX8MQ_SW_INFO_A0);
if ((magic & 0xff) == REV_A0)
return REV_A0;
/* Read revision from ATF as fallback */
magic = imx8mq_soc_revision_atf();
if (magic != 0xff)
return magic;
out:
of_node_put(np);
return rev;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment