soc: renesas: identify RZ/A2
authorChris Brandt <chris.brandt@renesas.com>
Fri, 27 Jul 2018 16:53:32 +0000 (11:53 -0500)
committerSimon Horman <horms+renesas@verge.net.au>
Mon, 27 Aug 2018 13:06:42 +0000 (15:06 +0200)
Add support for identifying the RZ/A2M (R7S9210) SoC.
Also add support for reading the BSID register which is a different format
than the PRR.

Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
drivers/soc/renesas/renesas-soc.c

index 56916183739bf53e1c4f00be0f868277cacc5892..ce19b27324339f31131c0ffd403abcd7b945ae65 100644 (file)
@@ -46,8 +46,12 @@ static const struct renesas_family fam_rmobile __initconst __maybe_unused = {
        .reg    = 0xe600101c,           /* CCCR (Common Chip Code Register) */
 };
 
-static const struct renesas_family fam_rza __initconst __maybe_unused = {
-       .name   = "RZ/A",
+static const struct renesas_family fam_rza1 __initconst __maybe_unused = {
+       .name   = "RZ/A1",
+};
+
+static const struct renesas_family fam_rza2 __initconst __maybe_unused = {
+       .name   = "RZ/A2",
 };
 
 static const struct renesas_family fam_rzg1 __initconst __maybe_unused = {
@@ -72,7 +76,12 @@ struct renesas_soc {
 };
 
 static const struct renesas_soc soc_rz_a1h __initconst __maybe_unused = {
-       .family = &fam_rza,
+       .family = &fam_rza1,
+};
+
+static const struct renesas_soc soc_rz_a2m __initconst __maybe_unused = {
+       .family = &fam_rza2,
+       .id     = 0x3b,
 };
 
 static const struct renesas_soc soc_rmobile_ape6 __initconst __maybe_unused = {
@@ -194,6 +203,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #ifdef CONFIG_ARCH_R7S72100
        { .compatible = "renesas,r7s72100",     .data = &soc_rz_a1h },
 #endif
+#ifdef CONFIG_ARCH_R7S9210
+       { .compatible = "renesas,r7s9210",      .data = &soc_rz_a2m },
+#endif
 #ifdef CONFIG_ARCH_R8A73A4
        { .compatible = "renesas,r8a73a4",      .data = &soc_rmobile_ape6 },
 #endif
@@ -275,7 +287,7 @@ static int __init renesas_soc_init(void)
        void __iomem *chipid = NULL;
        struct soc_device *soc_dev;
        struct device_node *np;
-       unsigned int product;
+       unsigned int product, eshi = 0, eslo;
 
        match = of_match_node(renesas_socs, of_root);
        if (!match)
@@ -284,6 +296,31 @@ static int __init renesas_soc_init(void)
        soc = match->data;
        family = soc->family;
 
+       np = of_find_compatible_node(NULL, NULL, "renesas,bsid");
+       if (np) {
+               chipid = of_iomap(np, 0);
+               of_node_put(np);
+
+               if (chipid) {
+                       product = readl(chipid);
+                       iounmap(chipid);
+
+                       if (soc->id && ((product >> 16) & 0xff) != soc->id) {
+                               pr_warn("SoC mismatch (product = 0x%x)\n",
+                                       product);
+                               return -ENODEV;
+                       }
+               }
+
+               /*
+                * TODO: Upper 4 bits of BSID are for chip version, but the
+                * format is not known at this time so we don't know how to
+                * specify eshi and eslo
+                */
+
+               goto done;
+       }
+
        /* Try PRR first, then hardcoded fallback */
        np = of_find_compatible_node(NULL, NULL, "renesas,prr");
        if (np) {
@@ -302,8 +339,11 @@ static int __init renesas_soc_init(void)
                        pr_warn("SoC mismatch (product = 0x%x)\n", product);
                        return -ENODEV;
                }
+               eshi = ((product >> 4) & 0x0f) + 1;
+               eslo = product & 0xf;
        }
 
+done:
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
        if (!soc_dev_attr)
                return -ENOMEM;
@@ -315,10 +355,9 @@ static int __init renesas_soc_init(void)
        soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL);
        soc_dev_attr->soc_id = kstrdup_const(strchr(match->compatible, ',') + 1,
                                             GFP_KERNEL);
-       if (chipid)
-               soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u",
-                                                  ((product >> 4) & 0x0f) + 1,
-                                                  product & 0xf);
+       if (eshi)
+               soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", eshi,
+                                                  eslo);
 
        pr_info("Detected Renesas %s %s %s\n", soc_dev_attr->family,
                soc_dev_attr->soc_id, soc_dev_attr->revision ?: "");