Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/nxp introduce imx6sx_platform_bootstrap(), whic...



details:   https://anonhg.NetBSD.org/src/rev/4dada318155c
branches:  trunk
changeset: 375983:4dada318155c
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Wed May 24 16:43:40 2023 +0000

description:
introduce imx6sx_platform_bootstrap(), which calls imx_platform_bootstrap()
and then checks for an "arm,cortex-a9-twd-timer" compatible entry in the
fdt. If not present, create one so that a9ptmr will attach.
We need this entry as this is the only timer we support for this platform,
but the upstream imx6sx.dtsi is missing the entry for it (and all A9 CPUs
have it anyway).

Thanks to Jared McNeill for advices and review.

diffstat:

 sys/arch/arm/nxp/imx6_platform.c |  76 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 73 insertions(+), 3 deletions(-)

diffs (104 lines):

diff -r d546f5e049ab -r 4dada318155c sys/arch/arm/nxp/imx6_platform.c
--- a/sys/arch/arm/nxp/imx6_platform.c  Wed May 24 14:34:16 2023 +0000
+++ b/sys/arch/arm/nxp/imx6_platform.c  Wed May 24 16:43:40 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: imx6_platform.c,v 1.8 2023/05/04 13:28:04 bouyer Exp $ */
+/*     $NetBSD: imx6_platform.c,v 1.9 2023/05/24 16:43:40 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2019 Genetec Corporation.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.8 2023/05/04 13:28:04 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.9 2023/05/24 16:43:40 bouyer Exp $");
 
 #include "arml2cc.h"
 #include "opt_console.h"
@@ -175,6 +175,76 @@ imx_platform_bootstrap(void)
        arm_fdt_cpu_bootstrap();
 }
 
+static void
+imx6sx_platform_bootstrap(void)
+{
+       void *fdt_data;
+       int ofw_root;
+       int soc_node, timer_node, intc_node, clks_node;
+       int ret;
+       fdt32_t intval[3];
+       fdt32_t clkval[2];
+       u_int val32;
+
+       imx_platform_bootstrap();
+
+       /*
+        * if there's no entry for the TWD timer in the provided DTB, fake one.
+        * we can't boot witthout it.
+        * The upstream imx6sx.dtsi is missing the entry
+        */
+
+       fdt_data = __UNCONST(fdtbus_get_data());
+       KASSERT(fdt_data != NULL);
+       ofw_root = OF_peer(0);
+       if (of_find_bycompat(ofw_root, "arm,cortex-a9-twd-timer") > 0) {
+               /* already there */
+               VPRINTF("timer already present\n");
+               return;
+       }
+       VPRINTF("creating timer fdt@%p", fdt_data);
+       soc_node = fdt_path_offset(fdt_data, "/soc");
+       VPRINTF(" soc_node %d", soc_node);
+       KASSERT(soc_node >= 0);
+
+       timer_node = fdt_add_subnode(fdt_data, soc_node, "timer@a00600");
+       VPRINTF(" timer_node %d\n", timer_node);
+       KASSERT(timer_node >= 0);
+
+       ret = fdt_setprop_string(fdt_data, timer_node, "compatible",
+           "arm,cortex-a9-twd-timer");
+       KASSERTMSG(ret == 0, "fdt_setprop(compatible) returns %d", ret);
+
+       ret = fdt_appendprop_addrrange(fdt_data, soc_node, timer_node,
+           "reg", 0x00a00600, 0x20);
+       KASSERTMSG(ret == 0, "fdt_appendprop_addrrange returns %d", ret);
+
+       intval[0] = cpu_to_fdt32(1);
+       intval[1] = cpu_to_fdt32(13);
+       intval[2] = cpu_to_fdt32(0xf01);
+       ret = fdt_setprop(fdt_data, timer_node, "interrupts",
+           intval, sizeof(intval));
+       KASSERTMSG(ret == 0, "fdt_setprop(interrupts) returns %d", ret);
+
+       intc_node = of_find_bycompat(ofw_root, "arm,cortex-a9-gic");
+       KASSERT(intc_node >= 0);
+       val32 = 0;
+       of_getprop_uint32(intc_node, "phandle", &val32);
+       ret = fdt_setprop_u32(fdt_data, timer_node, "interrupt-parent",
+           val32);
+       KASSERTMSG(ret == 0, "fdt_setprop(interrupt-parent) returns %d", ret);
+
+       val32 = 0;
+       clks_node = of_find_bycompat(ofw_root, "fsl,imx6sx-ccm");
+       KASSERT(clks_node >= 0);
+       of_getprop_uint32(clks_node, "phandle", &val32);
+       clkval[0] = cpu_to_fdt32(val32);
+       clkval[1] = cpu_to_fdt32(30); /* IMX6SXCLK_TWD */
+       ret = fdt_setprop(fdt_data, timer_node, "clocks",
+           clkval, sizeof(clkval));
+       KASSERTMSG(ret == 0, "fdt_setprop(clocks) returns %d", ret);
+}
+
 static int
 imx_platform_mpstart(void)
 {
@@ -256,7 +326,7 @@ static const struct fdt_platform imx6_pl
 
 static const struct fdt_platform imx6sx_platform = {
        .fp_devmap = imx6sx_platform_devmap,
-       .fp_bootstrap = imx_platform_bootstrap,
+       .fp_bootstrap = imx6sx_platform_bootstrap,
        .fp_init_attach_args = imx_platform_init_attach_args,
        .fp_device_register = imx_platform_device_register,
        .fp_reset = imx6_platform_reset,



Home | Main Index | Thread Index | Old Index