[PATCH] soc: renesas: Consolidate product register handling
Prabhakar Mahadev Lad
prabhakar.mahadev-lad.rj at bp.renesas.com
Thu Nov 11 02:53:13 PST 2021
Hi Geert,
Thank you for the patch.
> -----Original Message-----
> From: Geert Uytterhoeven <geert+renesas at glider.be>
> Sent: 10 November 2021 19:01
> To: Magnus Damm <magnus.damm at gmail.com>; Chris Brandt <Chris.Brandt at renesas.com>; Prabhakar Mahadev
> Lad <prabhakar.mahadev-lad.rj at bp.renesas.com>
> Cc: linux-renesas-soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Geert Uytterhoeven
> <geert+renesas at glider.be>
> Subject: [PATCH] soc: renesas: Consolidate product register handling
>
> Currently renesas_soc_init() scans the whole device tree up to three times, to find a device node
> describing a product register.
> Furthermore, the product register handling for the different variants is very similar, with the major
> difference being the location of the product bitfield inside the product register.
>
> Reduce scanning to a single pass using of_find_matching_node_and_match() instead. Switch to a common
> handling of product registers, by storing the intrinsics of each product register type in the data
> field of the corresponding match entry.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> Unfortunately the simplication of the source code is not reflected in the actual object code size, due
> to the sheer size of struct of_device_id (196 or 200 bytes on 32 vs. 64-bit).
>
> "[PATCH/RFC] of: Shrink struct of_device_id"
> https://jpn01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fall%2Fef59d6fd3b22
> 01b912d5eaa7f7a037d8f9adb744.1636561068.git.geert%2Brenesas%40glider.be&data=04%7C01%7Cprabhakar.m
> ahadev-
> lad.rj%40bp.renesas.com%7C97f0415c949a4bd5f67e08d9a47c6e5c%7C53d82571da1947e49cb4625a166a4a2a%7C0%7C0%
> 7C637721676621408059%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXV
> CI6Mn0%3D%7C1000&sdata=2Yp%2Fz9uQmdg4rrZ3uHIB7QAWKlJcNAo5xyszYqDRWcM%3D&reserved=0
> ---
> drivers/soc/renesas/renesas-soc.c | 115 +++++++++++++++---------------
> 1 file changed, 56 insertions(+), 59 deletions(-)
>
Tested this patch with RFC patch applied on SMARC EVK.
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Cheers,
Prabhakar
> diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
> index 7961b0be1850922d..7da0ea3587c4eab8 100644
> --- a/drivers/soc/renesas/renesas-soc.c
> +++ b/drivers/soc/renesas/renesas-soc.c
> @@ -328,16 +328,49 @@ static const struct of_device_id renesas_socs[] __initconst = {
> { /* sentinel */ }
> };
>
> +struct renesas_id {
> + unsigned int offset;
> + u32 mask;
> +};
> +
> +static const struct renesas_id id_bsid __initconst = {
> + .offset = 0,
> + .mask = 0xff0000,
> + /*
> + * 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
> + */
> +};
> +
> +static const struct renesas_id id_rzg2l __initconst = {
> + .offset = 0xa04,
> + .mask = 0xfffffff,
> +};
> +
> +static const struct renesas_id id_prr __initconst = {
> + .offset = 0,
> + .mask = 0xff00,
> +};
> +
> +static const struct of_device_id renesas_ids[] __initconst = {
> + { .compatible = "renesas,bsid", .data = &id_bsid },
> + { .compatible = "renesas,r9a07g044-sysc", .data = &id_rzg2l },
> + { .compatible = "renesas,prr", .data = &id_prr },
> + { /* sentinel */ }
> +};
> +
> static int __init renesas_soc_init(void) {
> struct soc_device_attribute *soc_dev_attr;
> + unsigned int product, eshi = 0, eslo;
> const struct renesas_family *family;
> const struct of_device_id *match;
> const struct renesas_soc *soc;
> + const struct renesas_id *id;
> void __iomem *chipid = NULL;
> struct soc_device *soc_dev;
> struct device_node *np;
> - unsigned int product, eshi = 0, eslo;
> + const char *soc_id;
>
> match = of_match_node(renesas_socs, of_root);
> if (!match)
> @@ -345,77 +378,42 @@ static int __init renesas_soc_init(void)
>
> soc = match->data;
> family = soc->family;
> + soc_id = strchr(match->compatible, ',') + 1;
>
> - np = of_find_compatible_node(NULL, NULL, "renesas,bsid");
> + np = of_find_matching_node_and_match(NULL, renesas_ids, &match);
> if (np) {
> + id = match->data;
> 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;
> + } else if (soc->id && family->reg) {
> + /* Try hardcoded CCCR/PRR fallback */
> + id = &id_prr;
> + chipid = ioremap(family->reg, 4);
> }
>
> - np = of_find_compatible_node(NULL, NULL, "renesas,r9a07g044-sysc");
> - if (np) {
> - chipid = of_iomap(np, 0);
> - of_node_put(np);
> + if (chipid) {
> + product = readl(chipid + id->offset);
> + iounmap(chipid);
>
> - if (chipid) {
> - product = readl(chipid + 0x0a04);
> - iounmap(chipid);
> + if (id == &id_prr) {
> + /* R-Car M3-W ES1.1 incorrectly identifies as ES2.0 */
> + if ((product & 0x7fff) == 0x5210)
> + product ^= 0x11;
> + /* R-Car M3-W ES1.3 incorrectly identifies as ES2.1 */
> + if ((product & 0x7fff) == 0x5211)
> + product ^= 0x12;
>
> - if (soc->id && (product & 0xfffffff) != soc->id) {
> - pr_warn("SoC mismatch (product = 0x%x)\n",
> - product);
> - return -ENODEV;
> - }
> + eshi = ((product >> 4) & 0x0f) + 1;
> + eslo = product & 0xf;
> }
>
> - goto done;
> - }
> -
> - /* Try PRR first, then hardcoded fallback */
> - np = of_find_compatible_node(NULL, NULL, "renesas,prr");
> - if (np) {
> - chipid = of_iomap(np, 0);
> - of_node_put(np);
> - } else if (soc->id && family->reg) {
> - chipid = ioremap(family->reg, 4);
> - }
> - if (chipid) {
> - product = readl(chipid);
> - iounmap(chipid);
> - /* R-Car M3-W ES1.1 incorrectly identifies as ES2.0 */
> - if ((product & 0x7fff) == 0x5210)
> - product ^= 0x11;
> - /* R-Car M3-W ES1.3 incorrectly identifies as ES2.1 */
> - if ((product & 0x7fff) == 0x5211)
> - product ^= 0x12;
> - if (soc->id && ((product >> 8) & 0xff) != soc->id) {
> + if (soc->id &&
> + ((product & id->mask) >> __ffs(id->mask)) != soc->id) {
> 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;
> @@ -425,8 +423,7 @@ static int __init renesas_soc_init(void)
> of_node_put(np);
>
> soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL);
> - soc_dev_attr->soc_id = kstrdup_const(strchr(match->compatible, ',') + 1,
> - GFP_KERNEL);
> + soc_dev_attr->soc_id = kstrdup_const(soc_id, GFP_KERNEL);
> if (eshi)
> soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", eshi,
> eslo);
> --
> 2.25.1
More information about the linux-arm-kernel
mailing list