summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/cpu/armv8/Makefile1
-rw-r--r--arch/arm/cpu/armv8/crypto/Kconfig6
-rw-r--r--arch/arm/cpu/armv8/crypto/Makefile4
-rw-r--r--arch/arm/cpu/armv8/crypto/sha2-ce-core.S157
-rw-r--r--arch/arm/cpu/armv8/crypto/sha2-ce-glue.c66
-rw-r--r--arch/arm/dts/Makefile4
-rw-r--r--arch/arm/dts/fsl-imx8dxl-ddr3l-evk.dts2
-rw-r--r--arch/arm/dts/imx8mp-evk.dts2
-rw-r--r--arch/arm/dts/imx8mp.dtsi2
-rw-r--r--arch/arm/dts/imx93-11x11-evk.dts14
-rw-r--r--arch/arm/dts/imx93-9x9-qsb-ontat-wvga-panel.dts65
-rw-r--r--arch/arm/dts/imx93-9x9-qsb-u-boot.dtsi178
-rw-r--r--arch/arm/dts/imx93-9x9-qsb.dts657
-rw-r--r--arch/arm/dts/imx93.dtsi89
-rw-r--r--arch/arm/include/asm/arch-imx/cpu.h7
-rw-r--r--arch/arm/include/asm/arch-imx8ulp/imx8ulp-pins.h2
-rw-r--r--arch/arm/include/asm/arch-imx9/clock.h1
-rw-r--r--arch/arm/include/asm/arch-imx9/ddr.h4
-rw-r--r--arch/arm/include/asm/mach-imx/s400_api.h4
-rw-r--r--arch/arm/include/asm/mach-imx/sys_proto.h11
-rw-r--r--arch/arm/include/asm/macro.h40
-rw-r--r--arch/arm/mach-imx/Kconfig7
-rw-r--r--arch/arm/mach-imx/cmd_dek.c84
-rw-r--r--arch/arm/mach-imx/cmd_qspihdr.c14
-rw-r--r--arch/arm/mach-imx/ele_ahab.c39
-rw-r--r--arch/arm/mach-imx/imx8/Kconfig1
-rw-r--r--arch/arm/mach-imx/imx8/ahab.c22
-rw-r--r--arch/arm/mach-imx/imx8m/clock_imx8mm.c1
-rw-r--r--arch/arm/mach-imx/imx8ulp/cgc.c69
-rw-r--r--arch/arm/mach-imx/imx8ulp/clock.c50
-rw-r--r--arch/arm/mach-imx/imx8ulp/upower/upower_hal.c122
-rw-r--r--arch/arm/mach-imx/imx9/Kconfig11
-rw-r--r--arch/arm/mach-imx/imx9/clock.c79
-rw-r--r--arch/arm/mach-imx/imx9/soc.c584
-rw-r--r--arch/arm/mach-imx/mx6/module_fuse.c49
36 files changed, 2287 insertions, 163 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c65cad54a6..09da1b375b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2208,6 +2208,8 @@ source "arch/arm/cpu/armv7/Kconfig"
source "arch/arm/cpu/armv8/Kconfig"
+source "arch/arm/cpu/armv8/crypto/Kconfig"
+
source "arch/arm/mach-imx/Kconfig"
source "arch/arm/mach-nexell/Kconfig"
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index 85fe0475c8..6e1498b470 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_TARGET_HIKEY) += hisilicon/
obj-$(CONFIG_ARMV8_PSCI) += psci.o
obj-$(CONFIG_TARGET_BCMNS3) += bcmns3/
obj-$(CONFIG_XEN) += xen/
+obj-$(CONFIG_CRYPTO_SHA2_ARM64_CE) += crypto/
diff --git a/arch/arm/cpu/armv8/crypto/Kconfig b/arch/arm/cpu/armv8/crypto/Kconfig
new file mode 100644
index 0000000000..379c673343
--- /dev/null
+++ b/arch/arm/cpu/armv8/crypto/Kconfig
@@ -0,0 +1,6 @@
+if ARM64
+
+config CRYPTO_SHA2_ARM64_CE
+ tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)"
+
+endif
diff --git a/arch/arm/cpu/armv8/crypto/Makefile b/arch/arm/cpu/armv8/crypto/Makefile
new file mode 100644
index 0000000000..8b23b166ed
--- /dev/null
+++ b/arch/arm/cpu/armv8/crypto/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_CRYPTO_SHA2_ARM64_CE) += sha2-ce.o
+sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
diff --git a/arch/arm/cpu/armv8/crypto/sha2-ce-core.S b/arch/arm/cpu/armv8/crypto/sha2-ce-core.S
new file mode 100644
index 0000000000..ad76362dff
--- /dev/null
+++ b/arch/arm/cpu/armv8/crypto/sha2-ce-core.S
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * sha2-ce-core.S - core SHA-224/SHA-256 transform using v8 Crypto Extensions
+ *
+ * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
+ * Copyright 2022 NXP
+ */
+
+#include <linux/linkage.h>
+#include <asm/macro.h>
+
+ .text
+ .arch armv8-a+crypto
+
+ dga .req q20
+ dgav .req v20
+ dgb .req q21
+ dgbv .req v21
+
+ t0 .req v22
+ t1 .req v23
+
+ dg0q .req q24
+ dg0v .req v24
+ dg1q .req q25
+ dg1v .req v25
+ dg2q .req q26
+ dg2v .req v26
+
+ .macro add_only, ev, rc, s0
+ mov dg2v.16b, dg0v.16b
+ .ifeq \ev
+ add t1.4s, v\s0\().4s, \rc\().4s
+ sha256h dg0q, dg1q, t0.4s
+ sha256h2 dg1q, dg2q, t0.4s
+ .else
+ .ifnb \s0
+ add t0.4s, v\s0\().4s, \rc\().4s
+ .endif
+ sha256h dg0q, dg1q, t1.4s
+ sha256h2 dg1q, dg2q, t1.4s
+ .endif
+ .endm
+
+ .macro add_update, ev, rc, s0, s1, s2, s3
+ sha256su0 v\s0\().4s, v\s1\().4s
+ add_only \ev, \rc, \s1
+ sha256su1 v\s0\().4s, v\s2\().4s, v\s3\().4s
+ .endm
+
+ /*
+ * The SHA-256 round constants
+ */
+ .section ".rodata", "a"
+ .align 4
+.Lsha2_rcon:
+ .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+ .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+ .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+ .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+ .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+ .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+ .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+ .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+ .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+ .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+ .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+ .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+ .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+ .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+ .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+ .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+
+ /*
+ * void sha2_ce_transform(struct sha256_ce_state *sst, u8 const *src,
+ * int blocks)
+ */
+ .text
+ENTRY(sha2_ce_transform)
+ /* load round constants */
+ adr_l x8, .Lsha2_rcon
+ ld1 { v0.4s- v3.4s}, [x8], #64
+ ld1 { v4.4s- v7.4s}, [x8], #64
+ ld1 { v8.4s-v11.4s}, [x8], #64
+ ld1 {v12.4s-v15.4s}, [x8]
+
+ /* load state */
+ ld1 {dgav.4s, dgbv.4s}, [x0]
+
+ /* load sha256_ce_state::finalize */
+ ldr_l w4, sha256_ce_offsetof_finalize, x4
+ ldr w4, [x0, x4]
+
+ /* load input */
+0: ld1 {v16.4s-v19.4s}, [x1], #64
+ sub w2, w2, #1
+
+CPU_LE( rev32 v16.16b, v16.16b )
+CPU_LE( rev32 v17.16b, v17.16b )
+CPU_LE( rev32 v18.16b, v18.16b )
+CPU_LE( rev32 v19.16b, v19.16b )
+
+1: add t0.4s, v16.4s, v0.4s
+ mov dg0v.16b, dgav.16b
+ mov dg1v.16b, dgbv.16b
+
+ add_update 0, v1, 16, 17, 18, 19
+ add_update 1, v2, 17, 18, 19, 16
+ add_update 0, v3, 18, 19, 16, 17
+ add_update 1, v4, 19, 16, 17, 18
+
+ add_update 0, v5, 16, 17, 18, 19
+ add_update 1, v6, 17, 18, 19, 16
+ add_update 0, v7, 18, 19, 16, 17
+ add_update 1, v8, 19, 16, 17, 18
+
+ add_update 0, v9, 16, 17, 18, 19
+ add_update 1, v10, 17, 18, 19, 16
+ add_update 0, v11, 18, 19, 16, 17
+ add_update 1, v12, 19, 16, 17, 18
+
+ add_only 0, v13, 17
+ add_only 1, v14, 18
+ add_only 0, v15, 19
+ add_only 1
+
+ /* update state */
+ add dgav.4s, dgav.4s, dg0v.4s
+ add dgbv.4s, dgbv.4s, dg1v.4s
+
+ /* handled all input blocks? */
+ cbz w2, 2f
+ b 0b
+
+ /*
+ * Final block: add padding and total bit count.
+ * Skip if the input size was not a round multiple of the block size,
+ * the padding is handled by the C code in that case.
+ */
+2: cbz x4, 3f
+ ldr_l w4, sha256_ce_offsetof_count, x4
+ ldr x4, [x0, x4]
+ movi v17.2d, #0
+ mov x8, #0x80000000
+ movi v18.2d, #0
+ ror x7, x4, #29 // ror(lsl(x4, 3), 32)
+ fmov d16, x8
+ mov x4, #0
+ mov v19.d[0], xzr
+ mov v19.d[1], x7
+ b 1b
+
+ /* store new state */
+3: st1 {dgav.4s, dgbv.4s}, [x0]
+ mov w0, w2
+ ret
+ENDPROC(sha2_ce_transform)
diff --git a/arch/arm/cpu/armv8/crypto/sha2-ce-glue.c b/arch/arm/cpu/armv8/crypto/sha2-ce-glue.c
new file mode 100644
index 0000000000..31e436ef1d
--- /dev/null
+++ b/arch/arm/cpu/armv8/crypto/sha2-ce-glue.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * sha2-ce-glue.c - SHA-256 using ARMv8 Crypto Extensions
+ *
+ * Copyright (C) 2014 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
+ * Copyright 2022 NXP
+ */
+
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <crypto/sha256_base.h>
+
+struct sha256_ce_state {
+ struct sha256_state sst;
+ u32 finalize;
+};
+
+extern const u32 sha256_ce_offsetof_count;
+extern const u32 sha256_ce_offsetof_finalize;
+
+asmlinkage int sha2_ce_transform(struct sha256_ce_state *sst, u8 const *src,
+ int blocks);
+
+static void __sha2_ce_transform(struct sha256_state *sst, u8 const *src,
+ int blocks)
+{
+ while (blocks) {
+ int rem;
+
+ rem = sha2_ce_transform(container_of(sst, struct sha256_ce_state,
+ sst), src, blocks);
+ src += (blocks - rem) * SHA256_BLOCK_SIZE;
+ blocks = rem;
+ }
+}
+
+const u32 sha256_ce_offsetof_count = offsetof(struct sha256_ce_state,
+ sst.count);
+const u32 sha256_ce_offsetof_finalize = offsetof(struct sha256_ce_state,
+ finalize);
+
+static void sha256_ce_update(struct sha256_ce_state *sctx, const u8 *data,
+ unsigned int len)
+{
+ sctx->finalize = 0;
+ sha256_base_do_update(&sctx->sst, data, len, __sha2_ce_transform);
+}
+
+static void sha256_ce_final(struct sha256_ce_state *sctx, u8 *out)
+{
+ sctx->finalize = 0;
+ sha256_base_do_finalize(&sctx->sst, __sha2_ce_transform);
+ sha256_base_finish(&sctx->sst, out);
+}
+
+/*
+ * Output = SHA-256( input buffer ).
+ */
+void sha256_ce(const unsigned char *input, unsigned int ilen, unsigned char *output)
+{
+ struct sha256_ce_state sctx;
+
+ sha256_init(&sctx.sst);
+ sha256_ce_update(&sctx, input, ilen);
+ sha256_ce_final(&sctx, output);
+}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f27ff45770..45a79f0201 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1005,7 +1005,9 @@ dtb-$(CONFIG_ARCH_IMX8M) += \
imx8mq-kontron-pitx-imx8m.dtb
dtb-$(CONFIG_ARCH_IMX9) += \
- imx93-11x11-evk.dtb
+ imx93-11x11-evk.dtb \
+ imx93-9x9-qsb.dtb \
+ imx93-9x9-qsb-ontat-wvga-panel.dts
dtb-$(CONFIG_ARCH_IMXRT) += imxrt1050-evk.dtb \
imxrt1020-evk.dtb
diff --git a/arch/arm/dts/fsl-imx8dxl-ddr3l-evk.dts b/arch/arm/dts/fsl-imx8dxl-ddr3l-evk.dts
index 040e52912e..3fe19b9848 100644
--- a/arch/arm/dts/fsl-imx8dxl-ddr3l-evk.dts
+++ b/arch/arm/dts/fsl-imx8dxl-ddr3l-evk.dts
@@ -100,8 +100,8 @@
SC_P_EMMC0_CLK_CONN_NAND_READY_B 0x0e00004c
SC_P_EMMC0_STROBE_CONN_NAND_CLE 0x0e00004c
SC_P_EMMC0_RESET_B_CONN_NAND_WP_B 0x0e00004c
- SC_P_EMMC0_CMD_CONN_NAND_DQS 0x0e00004c
+ SC_P_USDHC1_CD_B_CONN_NAND_DQS 0x0e00004c
SC_P_USDHC1_RESET_B_CONN_NAND_WE_B 0x0e00004c
SC_P_USDHC1_WP_CONN_NAND_ALE 0x0e00004c
SC_P_USDHC1_VSELECT_CONN_NAND_RE_B 0x0e00004c
diff --git a/arch/arm/dts/imx8mp-evk.dts b/arch/arm/dts/imx8mp-evk.dts
index 0df546dfd0..61e8a70196 100644
--- a/arch/arm/dts/imx8mp-evk.dts
+++ b/arch/arm/dts/imx8mp-evk.dts
@@ -13,7 +13,7 @@
compatible = "fsl,imx8mp-evk", "fsl,imx8mp";
chosen {
- bootargs = "console=ttymxc1,115200";
+ bootargs = "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200";
stdout-path = &uart2;
};
diff --git a/arch/arm/dts/imx8mp.dtsi b/arch/arm/dts/imx8mp.dtsi
index 2876b94b2a..4662d53183 100644
--- a/arch/arm/dts/imx8mp.dtsi
+++ b/arch/arm/dts/imx8mp.dtsi
@@ -979,7 +979,7 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx8mp-fspi-nand";
- reg = <0 0x30bb0000 0 0x10000>, <0 0x08000000 0 0x10000000>;
+ reg = <0x30bb0000 0x10000>, <0x08000000 0x10000000>;
reg-names = "FlexSPI", "FlexSPI-memory";
status = "disabled";
};
diff --git a/arch/arm/dts/imx93-11x11-evk.dts b/arch/arm/dts/imx93-11x11-evk.dts
index 38bf2aeb99..c82e5a9c67 100644
--- a/arch/arm/dts/imx93-11x11-evk.dts
+++ b/arch/arm/dts/imx93-11x11-evk.dts
@@ -458,16 +458,16 @@
&flexspi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexspi>;
- status = "disabled";
+ status = "okay";
- flash0: flash@0 {
+ flash0: mt25qu512a@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
spi-max-frequency = <80000000>;
- spi-tx-bus-width = <1>;
- spi-rx-bus-width = <1>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
};
};
@@ -485,17 +485,11 @@
pinctrl_flexspi: flexspigrp {
fsl,pins = <
MX93_PAD_SD3_CMD__FLEXSPI1_A_SS0_B 0x42
- MX93_PAD_SD1_DATA3__FLEXSPI1_A_SS1_B 0x42
MX93_PAD_SD3_CLK__FLEXSPI1_A_SCLK 0x42
- MX93_PAD_SD1_STROBE__FLEXSPI1_A_DQS 0x42
MX93_PAD_SD3_DATA0__FLEXSPI1_A_DATA00 0x42
MX93_PAD_SD3_DATA1__FLEXSPI1_A_DATA01 0x42
MX93_PAD_SD3_DATA2__FLEXSPI1_A_DATA02 0x42
MX93_PAD_SD3_DATA3__FLEXSPI1_A_DATA03 0x42
- MX93_PAD_SD1_DATA4__FLEXSPI1_A_DATA04 0x42
- MX93_PAD_SD1_DATA5__FLEXSPI1_A_DATA05 0x42
- MX93_PAD_SD1_DATA6__FLEXSPI1_A_DATA06 0x42
- MX93_PAD_SD1_DATA7__FLEXSPI1_A_DATA07 0x42
>;
};
diff --git a/arch/arm/dts/imx93-9x9-qsb-ontat-wvga-panel.dts b/arch/arm/dts/imx93-9x9-qsb-ontat-wvga-panel.dts
new file mode 100644
index 0000000000..6eb09ec9e3
--- /dev/null
+++ b/arch/arm/dts/imx93-9x9-qsb-ontat-wvga-panel.dts
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 NXP
+ */
+
+#include "imx93-9x9-qsb.dts"
+#include "imx93-9x9-qsb-u-boot.dtsi"
+
+/ {
+ panel {
+ compatible = "ontat,kd50g21-40nt-a1", "simple-panel";
+ enable-gpios = <&pcal6524 22 GPIO_ACTIVE_HIGH>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&display_out>;
+ };
+ };
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <30000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <40>;
+ hback-porch = <40>;
+ hsync-len = <48>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ vsync-len = <3>;
+
+ vsync-active = <0>;
+ hsync-active = <0>;
+ };
+ };
+ };
+};
+
+&lcdif {
+ status = "okay";
+ /*assigned-clock-rates = <150000000>, <30000000>, <400000000>, <133333333>;*/
+};
+
+&parallel_disp_fmt {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif>;
+ fsl,interface-pix-fmt = "rgb666";
+ status = "okay";
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ display_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+};
+
+/* pin conflicts */
+&sai3 {
+ status = "disabled";
+};
diff --git a/arch/arm/dts/imx93-9x9-qsb-u-boot.dtsi b/arch/arm/dts/imx93-9x9-qsb-u-boot.dtsi
new file mode 100644
index 0000000000..06935ce1e4
--- /dev/null
+++ b/arch/arm/dts/imx93-9x9-qsb-u-boot.dtsi
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022 NXP
+ */
+
+/ {
+ wdt-reboot {
+ compatible = "wdt-reboot";
+ wdt = <&wdog3>;
+ u-boot,dm-spl;
+ };
+
+ aliases {
+ usbgadget0 = &usbg1;
+ };
+
+ usbg1: usbg1 {
+ compatible = "fsl,imx27-usb-gadget";
+ dr_mode = "peripheral";
+ chipidea,usb = <&usbotg1>;
+ status = "okay";
+ };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
+};
+
+&{/soc@0} {
+ u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
+};
+
+&aips1 {
+ u-boot,dm-spl;
+ u-boot,dm-pre-reloc;
+};
+
+&aips2 {
+ u-boot,dm-spl;
+};
+
+&aips3 {
+ u-boot,dm-spl;
+};
+
+&iomuxc {
+ u-boot,dm-spl;
+};
+
+&reg_usdhc2_vmmc {
+ u-boot,off-on-delay-us = <20000>;
+ u-boot,dm-spl;
+};
+
+&pinctrl_reg_usdhc2_vmmc {
+ u-boot,dm-spl;
+};
+
+&pinctrl_uart1 {
+ u-boot,dm-spl;
+};
+
+&pinctrl_usdhc2_gpio {
+ u-boot,dm-spl;
+};
+
+&pinctrl_usdhc2 {
+ u-boot,dm-spl;
+};
+
+&gpio1 {
+ u-boot,dm-spl;
+};
+
+&gpio2 {
+ u-boot,dm-spl;
+};
+
+&gpio3 {
+ u-boot,dm-spl;
+};
+
+&gpio4 {
+ u-boot,dm-spl;
+};
+
+&lpuart1 {
+ u-boot,dm-spl;
+};
+
+&usdhc1 {
+ u-boot,dm-spl;
+};
+
+&usdhc2 {
+ u-boot,dm-spl;
+ fsl,signal-voltage-switch-extra-delay-ms = <8>;
+};
+
+&lpi2c1 {
+ u-boot,dm-spl;
+};
+
+&lpi2c2 {
+ u-boot,dm-spl;
+};
+
+&lpi2c3 {
+ u-boot,dm-spl;
+};
+
+&{/soc@0/bus@44000000/i2c@44350000/pmic@25} {
+ u-boot,dm-spl;
+};
+
+&{/soc@0/bus@44000000/i2c@44350000/pmic@25/regulators} {
+ u-boot,dm-spl;
+};
+
+&pinctrl_lpi2c1 {
+ u-boot,dm-spl;
+};
+
+&pinctrl_lpi2c2 {
+ u-boot,dm-spl;
+};
+
+&eqos {
+ compatible = "fsl,imx-eqos";
+};
+
+&ethphy1 {
+ reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <15000>;
+ reset-deassert-us = <100000>;
+};
+
+&usbotg1 {
+ status = "okay";
+ extcon = <&ptn5110>;
+};
+
+&s4muap {
+ u-boot,dm-spl;
+ status = "okay";
+};
+
+&clk {
+ u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
+ /delete-property/ assigned-clocks;
+ /delete-property/ assigned-clock-rates;
+};
+
+&osc_32k {
+ u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
+};
+
+&osc_24m {
+ u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
+};
+
+&clk_ext1 {
+ u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
+};
+
+&lcdif {
+ assigned-clocks = <&clk IMX93_CLK_MEDIA_AXI>, <&clk IMX93_CLK_MEDIA_APB>;
+ assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>, <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+ assigned-clock-rates = <400000000>, <133333334>;
+};
diff --git a/arch/arm/dts/imx93-9x9-qsb.dts b/arch/arm/dts/imx93-9x9-qsb.dts
new file mode 100644
index 0000000000..accb295c03
--- /dev/null
+++ b/arch/arm/dts/imx93-9x9-qsb.dts
@@ -0,0 +1,657 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 NXP
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/usb/pd.h>
+#include "imx93.dtsi"
+
+/ {
+ model = "NXP i.MX93 9x9 Quick Start Board";
+ compatible = "fsl,imx93-9x9-qsb", "fsl,imx93";
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ vdev0vring0: vdev0vring0@a4000000 {
+ reg = <0 0xa4000000 0 0x8000>;
+ no-map;
+ };
+
+ vdev0vring1: vdev0vring1@a4008000 {
+ reg = <0 0xa4008000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring0: vdev1vring0@a4000000 {
+ reg = <0 0xa4010000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring1: vdev1vring1@a4018000 {
+ reg = <0 0xa4018000 0 0x8000>;
+ no-map;
+ };
+
+ rsc_table: rsc_table@2021f000 {
+ reg = <0 0x2021f000 0 0x1000>;
+ no-map;
+ };
+
+ vdevbuffer: vdevbuffer@a4020000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0xa4020000 0 0x100000>;
+ no-map;
+ };
+ };
+
+ cm33: imx93-cm33 {
+ compatible = "fsl,imx93-cm33";
+ mbox-names = "tx", "rx", "rxdb";
+ mboxes = <&mu1 0 1
+ &mu1 1 1
+ &mu1 3 1>;
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
+ <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
+ fsl,startup-delay-ms = <500>;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_vref_1v8: regulator-adc-vref {
+ compatible = "regulator-fixed";
+ regulator-name = "vref_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ usdhc3_pwrseq: usdhc3_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&pcal6524 20 GPIO_ACTIVE_LOW>;
+ };
+
+ reg_audio_pwr: regulator-audio-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "audio-pwr";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pcal6524 17 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ sound-wm8962 {
+ compatible = "fsl,imx-audio-wm8962";
+ model = "wm8962-audio";
+ audio-cpu = <&sai3>;
+ audio-codec = <&codec>;
+ hp-det-gpio = <&pcal6524 4 GPIO_ACTIVE_HIGH>;
+ audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "Ext Spk", "SPKOUTL",
+ "Ext Spk", "SPKOUTR",
+ "AMIC", "MICBIAS",
+ "IN3R", "AMIC",
+ "IN1R", "AMIC";
+ };
+
+ sound-micfil {
+ compatible = "fsl,imx-audio-card";
+ model = "imx-audio-micfil";
+ pri-dai-link {
+ link-name = "micfil hifi";
+ format = "i2s";
+ cpu {
+ sound-dai = <&micfil>;
+ };
+ };
+ };
+
+ bt_sco_codec: bt_sco_codec {
+ #sound-dai-cells = <1>;
+ compatible = "linux,bt-sco";
+ };
+
+ sound-bt-sco {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "bt-sco-audio";
+ simple-audio-card,format = "dsp_a";
+ simple-audio-card,bitclock-inversion;
+ simple-audio-card,frame-master = <&btcpu>;
+ simple-audio-card,bitclock-master = <&btcpu>;
+
+ btcpu: simple-audio-card,cpu {
+ sound-dai = <&sai1>;
+ dai-tdm-slot-num = <2>;
+ dai-tdm-slot-width = <16>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&bt_sco_codec 1>;
+ };
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&eqos {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy1>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <5000000>;
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ eee-broken-1000t;
+ rtl821x,aldps-disable;
+ rtl821x,clkout-disable;
+ };
+ };
+};
+
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi>;
+ status = "okay";
+
+ flash0: mt25qu512a@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <80000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+};
+
+&lpi2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ pinctrl-1 = <&pinctrl_lpi2c1>;
+ status = "okay";
+
+ codec: wm8962@1a {
+ compatible = "wlf,wm8962";
+ reg = <0x1a>;
+ clocks = <&clk IMX93_CLK_SAI3_GATE>;
+ DCVDD-supply = <&reg_audio_pwr>;
+ DBVDD-supply = <&reg_audio_pwr>;
+ AVDD-supply = <&reg_audio_pwr>;
+ CPVDD-supply = <&reg_audio_pwr>;
+ MICVDD-supply = <&reg_audio_pwr>;
+ PLLVDD-supply = <&reg_audio_pwr>;
+ SPKVDD1-supply = <&reg_audio_pwr>;
+ SPKVDD2-supply = <&reg_audio_pwr>;
+ gpio-cfg = <
+ 0x0000 /* 0:Default */
+ 0x0000 /* 1:Default */
+ 0x0000 /* 2:FN_DMICCLK */
+ 0x0000 /* 3:Default */
+ 0x0000 /* 4:FN_DMICCDAT */
+ 0x0000 /* 5:Default */
+ >;
+ };
+
+ ptn5110: tcpc@50 {
+ compatible = "nxp,ptn5110";
+ reg = <0x50>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+ status = "okay";
+
+ port {
+ typec1_dr_sw: endpoint {
+ remote-endpoint = <&usb1_drd_sw>;
+ };
+ };
+
+ typec1_con: connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ power-role = "dual";
+ data-role = "dual";
+ try-power-role = "sink";
+ source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+ PDO_VAR(5000, 20000, 3000)>;
+ op-sink-microwatt = <15000000>;
+ self-powered;
+ };
+ };
+};
+
+&lpi2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ pinctrl-1 = <&pinctrl_lpi2c2>;
+ status = "okay";
+
+ pmic@25 {
+ compatible = "nxp,pca9451a";
+ reg = <0x25>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+
+ regulators {
+ buck1: BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck4: BUCK4{
+ regulator-name = "BUCK4";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5: BUCK5{
+ regulator-name = "BUCK5";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6: BUCK6 {
+ regulator-name = "BUCK6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3: LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4: LDO4 {
+ regulator-name = "LDO4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5: LDO5 {
+ regulator-name = "LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+
+ pcal6524: gpio@22 {
+ compatible = "nxp,pcal6524";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcal6524>;
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&lpuart1 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+ clocks = <&clk IMX93_CLK_LPUART1_GATE>, <&clk IMX93_CLK_LPUART1_GATE>;
+ clock-names = "ipg", "per";
+};
+
+&lpuart5 {
+ /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ status = "disabled";
+};
+
+&micfil {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX93_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>;
+ assigned-clock-rates = <196608000>;
+ status = "okay";
+};
+
+&mu1 {
+ status = "okay";
+};
+
+&mu2 {
+ status = "okay";
+};
+
+&sai1 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ assigned-clocks = <&clk IMX93_CLK_SAI1>;
+ assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>;
+ assigned-clock-rates = <12288000>;
+ status = "okay";
+};
+
+&sai3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&clk IMX93_CLK_SAI3>;
+ assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>;
+ assigned-clock-rates = <12288000>;
+ fsl,sai-mclk-direction-output;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ port {
+ usb1_drd_sw: endpoint {
+ remote-endpoint = <&typec1_dr_sw>;
+ };
+ };
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1>;
+ pinctrl-2 = <&pinctrl_usdhc1>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ bus-width = <4>;
+ status = "okay";
+ no-sdio;
+ no-mmc;
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3>;
+ pinctrl-2 = <&pinctrl_usdhc3>;
+ mmc-pwrseq = <&usdhc3_pwrseq>;
+ pinctrl-assert-gpios = <&pcal6524 13 GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ keep-power-in-suspend;
+ non-removable;
+ wakeup-source;
+ fsl,sdio-async-interrupt-enabled;
+ status = "okay";
+
+ wifi_wake_host {
+ compatible = "nxp,wifi-wake-host";
+ interrupt-parent = <&pcal6524>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "host-wake";
+ };
+};
+
+&iomuxc {
+ pinctrl_eqos: eqosgrp {
+ fsl,pins = <
+ MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e
+ MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x57e
+ MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e
+ MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e
+ MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x57e
+ MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x57e
+ MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x5fe
+ MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e
+ MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e
+ MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e
+ MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x57e
+ MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x57e
+ MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x5fe
+ MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e
+ >;
+ };
+
+ pinctrl_flexspi: flexspigrp {
+ fsl,pins = <
+ MX93_PAD_SD3_CMD__FLEXSPI1_A_SS0_B 0x42
+ MX93_PAD_SD3_CLK__FLEXSPI1_A_SCLK 0x42
+ MX93_PAD_SD3_DATA0__FLEXSPI1_A_DATA00 0x42
+ MX93_PAD_SD3_DATA1__FLEXSPI1_A_DATA01 0x42
+ MX93_PAD_SD3_DATA2__FLEXSPI1_A_DATA02 0x42
+ MX93_PAD_SD3_DATA3__FLEXSPI1_A_DATA03 0x42
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e
+ MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <
+ MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e
+ MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_pcal6524: pcal6524grp {
+ fsl,pins = <
+ MX93_PAD_CCM_CLKO1__GPIO3_IO26 0x31e
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX93_PAD_UART1_RXD__LPUART1_RX 0x31e
+ MX93_PAD_UART1_TXD__LPUART1_TX 0x31e
+ >;
+ };
+
+ pinctrl_uart5: uart5grp {
+ fsl,pins = <
+ MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e
+ MX93_PAD_DAP_TDI__LPUART5_RX 0x31e
+ MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e
+ MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x17fe
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x13fe
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x13fe
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x13fe
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x13fe
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x17fe
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x17fe
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x13fe
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x13fe
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x13fe
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x13fe
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x13fe
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX93_PAD_SD3_CLK__USDHC3_CLK 0x17fe
+ MX93_PAD_SD3_CMD__USDHC3_CMD 0x13fe
+ MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x13fe
+ MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x13fe
+ MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x13fe
+ MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x13fe
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX93_PAD_SAI1_TXC__SAI1_TX_BCLK 0x31e
+ MX93_PAD_SAI1_TXFS__SAI1_TX_SYNC 0x31e
+ MX93_PAD_SAI1_TXD0__SAI1_TX_DATA00 0x31e
+ MX93_PAD_SAI1_RXD0__SAI1_RX_DATA00 0x31e
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO26__SAI3_TX_SYNC 0x31e
+ MX93_PAD_GPIO_IO16__SAI3_TX_BCLK 0x31e
+ MX93_PAD_GPIO_IO17__SAI3_MCLK 0x31e
+ MX93_PAD_GPIO_IO19__SAI3_TX_DATA00 0x31e
+ MX93_PAD_GPIO_IO20__SAI3_RX_DATA00 0x31e
+ >;
+ };
+
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX93_PAD_PDM_CLK__PDM_CLK 0x31e
+ MX93_PAD_PDM_BIT_STREAM0__PDM_BIT_STREAM00 0x31e
+ MX93_PAD_PDM_BIT_STREAM1__PDM_BIT_STREAM01 0x31e
+ >;
+ };
+
+ pinctrl_lcdif: lcdifgrp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO00__MEDIAMIX_DISP_CLK 0x31e
+ MX93_PAD_GPIO_IO01__MEDIAMIX_DISP_DE 0x31e
+ MX93_PAD_GPIO_IO02__MEDIAMIX_DISP_VSYNC 0x31e
+ MX93_PAD_GPIO_IO03__MEDIAMIX_DISP_HSYNC 0x31e
+ MX93_PAD_GPIO_IO04__MEDIAMIX_DISP_DATA00 0x31e
+ MX93_PAD_GPIO_IO05__MEDIAMIX_DISP_DATA01 0x31e
+ MX93_PAD_GPIO_IO06__MEDIAMIX_DISP_DATA02 0x31e
+ MX93_PAD_GPIO_IO07__MEDIAMIX_DISP_DATA03 0x31e
+ MX93_PAD_GPIO_IO08__MEDIAMIX_DISP_DATA04 0x31e
+ MX93_PAD_GPIO_IO09__MEDIAMIX_DISP_DATA05 0x31e
+ MX93_PAD_GPIO_IO10__MEDIAMIX_DISP_DATA06 0x31e
+ MX93_PAD_GPIO_IO11__MEDIAMIX_DISP_DATA07 0x31e
+ MX93_PAD_GPIO_IO12__MEDIAMIX_DISP_DATA08 0x31e
+ MX93_PAD_GPIO_IO13__MEDIAMIX_DISP_DATA09 0x31e
+ MX93_PAD_GPIO_IO14__MEDIAMIX_DISP_DATA10 0x31e
+ MX93_PAD_GPIO_IO15__MEDIAMIX_DISP_DATA11 0x31e
+ MX93_PAD_GPIO_IO16__MEDIAMIX_DISP_DATA12 0x31e
+ MX93_PAD_GPIO_IO17__MEDIAMIX_DISP_DATA13 0x31e
+ MX93_PAD_GPIO_IO18__MEDIAMIX_DISP_DATA14 0x31e
+ MX93_PAD_GPIO_IO19__MEDIAMIX_DISP_DATA15 0x31e
+ MX93_PAD_GPIO_IO20__MEDIAMIX_DISP_DATA16 0x31e
+ MX93_PAD_GPIO_IO21__MEDIAMIX_DISP_DATA17 0x31e
+ >;
+ };
+};
diff --git a/arch/arm/dts/imx93.dtsi b/arch/arm/dts/imx93.dtsi
index 59a09b5ec5..be4626d5e7 100644
--- a/arch/arm/dts/imx93.dtsi
+++ b/arch/arm/dts/imx93.dtsi
@@ -36,6 +36,7 @@
serial5 = &lpuart6;
serial6 = &lpuart7;
serial7 = &lpuart8;
+ spi0 = &flexspi;
isi0 = &isi_0;
i2c0 = &lpi2c1;
i2c1 = &lpi2c2;
@@ -447,58 +448,20 @@
};
tmu: tmu@44482000 {
- compatible = "fsl,imx93-tmu", "fsl,imx8mq-tmu";
- little-endian;
+ compatible = "fsl,imx93-tmu";
reg = <0x44482000 0x1000>;
clocks = <&clk IMX93_CLK_TMC_GATE>;
- fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>;
- fsl,tmu-calibration = <0x00000000 0x00000023
- 0x00000001 0x00000029
- 0x00000002 0x0000002f
- 0x00000003 0x00000035
- 0x00000004 0x0000003d
- 0x00000005 0x00000043
- 0x00000006 0x0000004b
- 0x00000007 0x00000051
- 0x00000008 0x00000057
- 0x00000009 0x0000005f
- 0x0000000a 0x00000067
- 0x0000000b 0x0000006f
-
- 0x00010000 0x0000001b
- 0x00010001 0x00000023
- 0x00010002 0x0000002b
- 0x00010003 0x00000033
- 0x00010004 0x0000003b
- 0x00010005 0x00000043
- 0x00010006 0x0000004b
- 0x00010007 0x00000055
- 0x00010008 0x0000005d
- 0x00010009 0x00000067
- 0x0001000a 0x00000070
-
- 0x00020000 0x00000017
- 0x00020001 0x00000023
- 0x00020002 0x0000002d
- 0x00020003 0x00000037
- 0x00020004 0x00000041
- 0x00020005 0x0000004b
- 0x00020006 0x00000057
- 0x00020007 0x00000063
- 0x00020008 0x0000006f
-
- 0x00030000 0x00000015
- 0x00030001 0x00000021
- 0x00030002 0x0000002d
- 0x00030003 0x00000039
- 0x00030004 0x00000045
- 0x00030005 0x00000053
- 0x00030006 0x0000005f
- 0x00030007 0x00000071>;
+ little-endian;
+ fsl,tmu-calibration = <0x0000000e 0x800000da
+ 0x00000029 0x800000e9
+ 0x00000056 0x80000102
+ 0x000000a2 0x8000012a
+ 0x00000116 0x80000166
+ 0x00000195 0x800001a7
+ 0x000001b2 0x800001b6>;
#thermal-sensor-cells = <0>;
- status = "disabled";
};
-
+
micfil: micfil@44520000 {
compatible = "fsl,imx93-micfil";
reg = <0x44520000 0x10000>;
@@ -848,9 +811,11 @@
reg = <0x425e0000 0x10000>, <0x28000000 0x10000000>;
reg-names = "fspi_base", "fspi_mmap";
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX93_CLK_DUMMY>,
- <&clk IMX93_CLK_DUMMY>;
+ clocks = <&clk IMX93_CLK_FLEXSPI1_GATE>,
+ <&clk IMX93_CLK_FLEXSPI1_GATE>;
clock-names = "fspi", "fspi_en";
+ assigned-clock-rates = <80000000>;
+ assigned-clocks = <&clk IMX93_CLK_FLEXSPI1>;
status = "disabled";
};
@@ -1332,6 +1297,25 @@
power-domains = <&media_blk_ctrl IMX93_MEDIABLK_PD_MIPI_DSI>;
status = "disabled";
};
+
+ parallel_disp_fmt: dpi {
+ compatible = "fsl,imx93-parallel-display-format";
+ /* power-domains = <&mediamix>; [Not enable for U-Boot], otherwise driver probe fail */
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dpi_to_lcdif: endpoint {
+ remote-endpoint = <&lcdif_to_dpi>;
+ };
+ };
+ };
+ };
};
ldb: ldb@4ac10020 {
@@ -1447,6 +1431,11 @@
reg = <1>;
remote-endpoint = <&ldb_ch0>;
};
+
+ lcdif_to_dpi: endpoint@2 {
+ reg = <2>;
+ remote-endpoint = <&dpi_to_lcdif>;
+ };
};
};
diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h
index f326c90312..36f51e0792 100644
--- a/arch/arm/include/asm/arch-imx/cpu.h
+++ b/arch/arm/include/asm/arch-imx/cpu.h
@@ -62,6 +62,13 @@
#define MXC_CPU_MX7ULP 0xE1 /* Temporally hard code */
#define MXC_CPU_VF610 0xF6 /* dummy ID */
#define MXC_CPU_IMX93 0xC1 /* dummy ID */
+#define MXC_CPU_IMX9351 0xC2 /* dummy ID */
+#define MXC_CPU_IMX9332 0xC3 /* dummy ID */
+#define MXC_CPU_IMX9331 0xC4 /* dummy ID */
+#define MXC_CPU_IMX9322 0xC5 /* dummy ID */
+#define MXC_CPU_IMX9321 0xC6 /* dummy ID */
+#define MXC_CPU_IMX9312 0xC7 /* dummy ID */
+#define MXC_CPU_IMX9311 0xC8 /* dummy ID */
#define MXC_SOC_MX6 0x60
#define MXC_SOC_MX7 0x70
diff --git a/arch/arm/include/asm/arch-imx8ulp/imx8ulp-pins.h b/arch/arm/include/asm/arch-imx8ulp/imx8ulp-pins.h
index 3638f0db53..cdea5d6f3c 100644
--- a/arch/arm/include/asm/arch-imx8ulp/imx8ulp-pins.h
+++ b/arch/arm/include/asm/arch-imx8ulp/imx8ulp-pins.h
@@ -73,6 +73,6 @@ enum {
IMX8ULP_PAD_PTF5__SDHC1_D2 = IOMUX_PAD(0x0114, 0x0114, 0x8, 0x0A6C, 0x2, 0),
IMX8ULP_PAD_PTF0__SDHC1_D1 = IOMUX_PAD(0x0100, 0x0100, 0x8, 0x0A68, 0x2, 0),
IMX8ULP_PAD_PTF1__SDHC1_D0 = IOMUX_PAD(0x0104, 0x0104, 0x8, 0x0A64, 0x2, 0),
-
+ IMX8ULP_PAD_PTF7__PTF7 = IOMUX_PAD(0x011C, 0x011C, 0x1, 0x0000, 0x0, 0),
};
#endif /* __ASM_ARCH_IMX8ULP_PINS_H__ */
diff --git a/arch/arm/include/asm/arch-imx9/clock.h b/arch/arm/include/asm/arch-imx9/clock.h
index 5cb762d429..758ee26ff2 100644
--- a/arch/arm/include/asm/arch-imx9/clock.h
+++ b/arch/arm/include/asm/arch-imx9/clock.h
@@ -217,6 +217,7 @@ u32 mxc_get_clock(enum mxc_clock clk);
void dram_pll_init(ulong pll_val);
void dram_enable_bypass(ulong clk_val);
void dram_disable_bypass(void);
+void set_arm_core_max_clk(void);
int configure_intpll(enum ccm_clk_src pll, u32 freq);
diff --git a/arch/arm/include/asm/arch-imx9/ddr.h b/arch/arm/include/asm/arch-imx9/ddr.h
index 83983ed391..af5e6b5764 100644
--- a/arch/arm/include/asm/arch-imx9/ddr.h
+++ b/arch/arm/include/asm/arch-imx9/ddr.h
@@ -13,11 +13,15 @@
#define DDR_PHY_BASE 0x4E100000
#define DDRMIX_BLK_CTRL_BASE 0x4E010000
+#define REG_DDR_CS0_BNDS (DDR_CTL_BASE + 0x0)
+#define REG_DDR_CS1_BNDS (DDR_CTL_BASE + 0x8)
#define REG_DDRDSR_2 (DDR_CTL_BASE + 0xB24)
#define REG_DDR_TIMING_CFG_0 (DDR_CTL_BASE + 0x104)
#define REG_DDR_SDRAM_CFG (DDR_CTL_BASE + 0x110)
+#define REG_DDR_SDRAM_CFG2 (DDR_CTL_BASE + 0x114)
#define REG_DDR_TIMING_CFG_4 (DDR_CTL_BASE + 0x160)
#define REG_DDR_DEBUG_19 (DDR_CTL_BASE + 0xF48)
+#define REG_DDR_ERR_EN (DDR_CTL_BASE + 0x1000)
#define SRC_BASE_ADDR (0x44460000)
#define SRC_DPHY_BASE_ADDR (SRC_BASE_ADDR + 0x1400)
diff --git a/arch/arm/include/asm/mach-imx/s400_api.h b/arch/arm/include/asm/mach-imx/s400_api.h
index 9e3c8136df..3862c5a39b 100644
--- a/arch/arm/include/asm/mach-imx/s400_api.h
+++ b/arch/arm/include/asm/mach-imx/s400_api.h
@@ -25,6 +25,7 @@
#define ELE_RET_LIFECYCLE_UP_REQ (0xA0)
#define ELE_GET_EVENTS_REQ (0xA2)
#define ELE_START_RNG (0xA3)
+#define ELE_GENERATE_DEK_BLOB (0xAF)
#define ELE_ENABLE_PATCH_REQ (0xC3)
#define ELE_RELEASE_RDC_REQ (0xC4)
#define ELE_GET_FW_STATUS_REQ (0xC5)
@@ -144,5 +145,8 @@ int ahab_get_fw_status(u32 *status, u32 *response);
int ahab_release_m33_trout(void);
int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response);
int ahab_start_rng(void);
+int ahab_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr,
+ u32 max_output_size);
+int ahab_write_secure_fuse(ulong signed_msg_blk, u32 *response);
#endif
diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h
index 57557db715..04505d948c 100644
--- a/arch/arm/include/asm/mach-imx/sys_proto.h
+++ b/arch/arm/include/asm/mach-imx/sys_proto.h
@@ -84,7 +84,16 @@ struct bd_info;
#define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP))
#define is_imx8dxl() (is_cpu_type(MXC_CPU_IMX8DXL))
-#define is_imx93() (is_cpu_type(MXC_CPU_IMX93))
+#define is_imx93() (is_cpu_type(MXC_CPU_IMX93) || is_cpu_type(MXC_CPU_IMX9331) || \
+ is_cpu_type(MXC_CPU_IMX9332) || is_cpu_type(MXC_CPU_IMX9351) || is_cpu_type(MXC_CPU_IMX9322) || \
+ is_cpu_type(MXC_CPU_IMX9321) || is_cpu_type(MXC_CPU_IMX9312) || is_cpu_type(MXC_CPU_IMX9311))
+#define is_imx9351() (is_cpu_type(MXC_CPU_IMX9351))
+#define is_imx9332() (is_cpu_type(MXC_CPU_IMX9332))
+#define is_imx9331() (is_cpu_type(MXC_CPU_IMX9331))
+#define is_imx9322() (is_cpu_type(MXC_CPU_IMX9322))
+#define is_imx9321() (is_cpu_type(MXC_CPU_IMX9321))
+#define is_imx9312() (is_cpu_type(MXC_CPU_IMX9312))
+#define is_imx9311() (is_cpu_type(MXC_CPU_IMX9311))
#define is_imxrt1020() (is_cpu_type(MXC_CPU_IMXRT1020))
#define is_imxrt1050() (is_cpu_type(MXC_CPU_IMXRT1050))
diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h
index ec0171e0e6..4e982892f8 100644
--- a/arch/arm/include/asm/macro.h
+++ b/arch/arm/include/asm/macro.h
@@ -3,6 +3,7 @@
* include/asm-arm/macro.h
*
* Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ * Copyright 2022 NXP
*/
#ifndef __ASM_ARM_MACRO_H__
@@ -356,6 +357,45 @@ lr .req x30
.endm
#endif
+/*
+ * Select code when configured for LE.
+ */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define CPU_LE(code...)
+#else
+#define CPU_LE(code...) code
+#endif
+
+/*
+ * Pseudo-ops for PC-relative adr/ldr <reg>, <symbol> where
+ * <symbol> is within the range +/- 4 GB of the PC.
+ */
+ /*
+ * @dst: destination register (64 bit wide)
+ * @sym: name of the symbol
+ */
+ .macro adr_l, dst, sym
+ adrp \dst, \sym
+ add \dst, \dst, :lo12:\sym
+ .endm
+
+ /*
+ * @dst: destination register (32 or 64 bit wide)
+ * @sym: name of the symbol
+ * @tmp: optional 64-bit scratch register to be used if <dst> is a
+ * 32-bit wide register, in which case it cannot be used to hold
+ * the address
+ */
+ .macro ldr_l, dst, sym, tmp=
+ .ifb \tmp
+ adrp \dst, \sym
+ ldr \dst, [\dst, :lo12:\sym]
+ .else
+ adrp \tmp, \sym
+ ldr \dst, [\tmp, :lo12:\sym]
+ .endif
+ .endm
+
#endif /* CONFIG_ARM64 */
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index b51a0464bf..3fe77a5e49 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -117,6 +117,7 @@ config CMD_DEKBLOB
select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M
select IMX_SECO_DEK_ENCAP if ARCH_IMX8
+ select IMX_ELE_DEK_ENCAP if ARCH_IMX8ULP || ARCH_IMX9
help
This enables the 'dek_blob' command which is used with the
Freescale secure boot mechanism. This command encapsulates and
@@ -145,6 +146,12 @@ config IMX_SECO_DEK_ENCAP
This enabled the DEK blob encapsulation with the SECO API. This option
is only available on imx8.
+config IMX_ELE_DEK_ENCAP
+ bool "Support the DEK blob encapsulation with ELE"
+ help
+ This enabled the DEK blob encapsulation with the ELE API. This option
+ is only available on imx8ulp and imx9.
+
config CMD_PRIBLOB
bool "Support the set_priblob_bitfield command"
depends on HAS_CAAM && IMX_HAB
diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c
index 701bf516df..9e69f2c505 100644
--- a/arch/arm/mach-imx/cmd_dek.c
+++ b/arch/arm/mach-imx/cmd_dek.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2008-2015 Freescale Semiconductor, Inc.
+ * Copyright 2022 NXP
*
* Command for encapsulating DEK blob
*/
@@ -20,6 +21,11 @@
#include <asm/arch/sci/sci.h>
#include <asm/mach-imx/image.h>
#endif
+#ifdef CONFIG_IMX_ELE_DEK_ENCAP
+#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/image.h>
+#endif
+
#include <cpu_func.h>
/**
@@ -284,6 +290,84 @@ error:
}
#endif /* CONFIG_IMX_SECO_DEK_ENCAP */
+#ifdef CONFIG_IMX_ELE_DEK_ENCAP
+
+#define DEK_BLOB_HDR_SIZE 8
+#define AHAB_PRIVATE_KEY 0x81
+#define AHAB_DEK_BLOB 0x01
+#define AHAB_ALG_AES 0x03
+#define AHAB_128_AES_KEY 0x10
+#define AHAB_192_AES_KEY 0x18
+#define AHAB_256_AES_KEY 0x20
+
+static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
+{
+ u8 in_size, out_size;
+ u8 *src_ptr, *dst_ptr;
+ struct generate_key_blob_hdr hdr;
+
+ /* Set sizes */
+ in_size = sizeof(struct generate_key_blob_hdr) + len / 8;
+ out_size = BLOB_SIZE(len / 8) + DEK_BLOB_HDR_SIZE;
+
+ /* Get src and dst virtual addresses */
+ src_ptr = map_sysmem(src_addr, in_size);
+ dst_ptr = map_sysmem(dst_addr, out_size);
+
+ /* Check addr input */
+ if (!(src_ptr && dst_ptr)) {
+ debug("src_addr or dst_addr invalid\n");
+ return -1;
+ }
+
+ /* Build key header */
+ hdr.version = 0x0;
+ hdr.length_lsb = in_size;
+ hdr.length_msb = 0x00;
+ hdr.tag = AHAB_PRIVATE_KEY;
+ hdr.flags = AHAB_DEK_BLOB;
+ hdr.algorithm = AHAB_ALG_AES;
+ hdr.mode = 0x0; /* Not used by the ELE */
+
+ switch (len) {
+ case 128:
+ hdr.size = AHAB_128_AES_KEY;
+ break;
+ case 192:
+ hdr.size = AHAB_192_AES_KEY;
+ break;
+ case 256:
+ hdr.size = AHAB_256_AES_KEY;
+ break;
+ default:
+ /* Not supported */
+ debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n");
+ return -1;
+ }
+
+ /* Move input key and append blob header */
+ memmove((void *)(src_ptr + sizeof(struct generate_key_blob_hdr)),
+ (void *)src_ptr, len / 8);
+ memcpy((void *)src_ptr, (void *)&hdr,
+ sizeof(struct generate_key_blob_hdr));
+
+ /* Flush the cache */
+ flush_dcache_range(src_addr, src_addr + in_size);
+ flush_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
+ roundup(out_size, ARCH_DMA_MINALIGN)));
+
+ /* Call ELE */
+ if (ahab_generate_dek_blob(0x00, src_addr, dst_addr, out_size))
+ return -1;
+
+ /* Invalidate output buffer */
+ invalidate_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
+ roundup(out_size, ARCH_DMA_MINALIGN)));
+
+ return 0;
+}
+#endif /* CONFIG_IMX_ELE_DEK_ENCAP */
+
/**
* do_dek_blob() - Handle the "dek_blob" command-line command
* @cmdtp: Command data struct pointer
diff --git a/arch/arm/mach-imx/cmd_qspihdr.c b/arch/arm/mach-imx/cmd_qspihdr.c
index 6e2758664f..ef4a3cf113 100644
--- a/arch/arm/mach-imx/cmd_qspihdr.c
+++ b/arch/arm/mach-imx/cmd_qspihdr.c
@@ -235,6 +235,7 @@ static int do_qspihdr_check(int argc, char * const argv[], int flag)
unsigned long addr;
char *endp;
void *tmp;
+ int ret;
#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
int off = QSPI_HDR_OFF + QSPI_HDR_TAG_OFF;
@@ -266,7 +267,11 @@ static int do_qspihdr_check(int argc, char * const argv[], int flag)
return 1;
}
} else {
- spi_flash_read(flash, off, 4, &buf);
+ ret = spi_flash_read(flash, off, 4, &buf);
+ if (ret) {
+ printf("flash read failed, ret: %d\n", ret);
+ return -1;
+ }
if (buf == tag) {
if (flag & FLAG_VERBOSE)
@@ -398,6 +403,7 @@ static int do_qspihdr_dump(int argc, char * const argv[])
char *endp;
void *tmp;
void *buf;
+ int ret;
#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
int off = QSPI_HDR_OFF;
@@ -431,7 +437,11 @@ static int do_qspihdr_dump(int argc, char * const argv[])
return 0;
}
- spi_flash_read(flash, off, HDR_LEN, buf);
+ ret = spi_flash_read(flash, off, HDR_LEN, buf);
+ if (ret) {
+ printf("flash read failed, ret: %d\n", ret);
+ return -1;
+ }
hdr_dump(buf);
free(buf);
diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c
index 6daa7a96a0..192f90e6b1 100644
--- a/arch/arm/mach-imx/ele_ahab.c
+++ b/arch/arm/mach-imx/ele_ahab.c
@@ -568,6 +568,39 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc,
return 0;
}
+static int do_sec_fuse_prog(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ ulong addr;
+ u32 header, response;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ addr = simple_strtoul(argv[1], NULL, 16);
+ header = *(u32 *)addr;
+
+ if ((header & 0xff0000ff) != 0x89000000) {
+ printf("Wrong Signed message block format, header 0x%x\n", header);
+ return CMD_RET_FAILURE;
+ }
+
+ header = (header & 0xffff00) >> 8;
+
+ printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header);
+ flush_dcache_range(addr, addr + header - 1);
+
+ if (ahab_write_secure_fuse(addr, &response)) {
+ printf("Program secure fuse failed, response 0x%x\n", response);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Program secure fuse completed, response 0x%x\n", response);
+
+ return CMD_RET_SUCCESS;
+}
+
+
U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate,
"autenticate OS container via AHAB",
"addr\n"
@@ -588,3 +621,9 @@ U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status,
"display AHAB lifecycle only",
""
);
+
+U_BOOT_CMD(ahab_sec_fuse_prog, CONFIG_SYS_MAXARGS, 1, do_sec_fuse_prog,
+ "Program secure fuse via signed message block",
+ "addr\n"
+ "addr - Signed message block for secure fuse\n"
+);
diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig
index b2b8ade0bd..7abcfeca86 100644
--- a/arch/arm/mach-imx/imx8/Kconfig
+++ b/arch/arm/mach-imx/imx8/Kconfig
@@ -176,6 +176,7 @@ config TARGET_IMX8DXL_EVK
bool "Support i.MX8DXL EVK board"
select BOARD_LATE_INIT
select IMX8DXL
+ select CRYPTO_SHA2_ARM64_CE
select FSL_CAAM
select FSL_BLOB
select ARCH_MISC_INIT
diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c
index 3c3c4cdc4f..deb18a3bb2 100644
--- a/arch/arm/mach-imx/imx8/ahab.c
+++ b/arch/arm/mach-imx/imx8/ahab.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2018-2019 NXP
+ * Copyright 2018-2019, 2022 NXP
*/
#include <common.h>
@@ -16,6 +16,7 @@
#include <asm/mach-imx/image.h>
#include <console.h>
#include <cpu_func.h>
+#include <crypto/sha2.h>
#include <asm/mach-imx/ahab.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -25,6 +26,8 @@ DECLARE_GLOBAL_DATA_PTR;
#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE (0x60000000UL)
#define SECO_PT 2U
+#define AHAB_HASH_TYPE_MASK 0x00000700
+#define AHAB_HASH_TYPE_SHA256 0
int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length)
{
@@ -130,6 +133,9 @@ int authenticate_os_container(ulong addr)
u16 length;
struct boot_img_t *img;
unsigned long s, e;
+#ifdef CONFIG_CRYPTO_SHA2_ARM64_CE
+ u8 hash_value[SHA256_DIGEST_SIZE];
+#endif
if (addr % 4) {
puts("Error: Image's address is not 4 byte aligned\n");
@@ -179,9 +185,23 @@ int authenticate_os_container(ulong addr)
flush_dcache_range(s, e);
+#ifdef CONFIG_CRYPTO_SHA2_ARM64_CE
+ if (((img->hab_flags & AHAB_HASH_TYPE_MASK) >> 8) == AHAB_HASH_TYPE_SHA256) {
+ sha256_ce((void *)img->dst, img->size, hash_value);
+ err = memcmp(&img->hash, &hash_value, SHA256_DIGEST_SIZE);
+ if (err) {
+ printf("img %d hash comparison failed, error %d\n", i, err);
+ ret = -EIO;
+ goto exit;
+ }
+ } else {
+#endif
ret = ahab_verify_cntr_image(img, i);
if (ret)
goto exit;
+#ifdef CONFIG_CRYPTO_SHA2_ARM64_CE
+ }
+#endif
}
exit:
diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
index d6be307e6e..203c52d1d3 100644
--- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c
+++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
@@ -83,7 +83,6 @@ static int fracpll_configure(enum pll_clocks pll, u32 freq)
case ANATOP_DRAM_PLL:
setbits_le32(GPC_BASE_ADDR + 0xEC, 1 << 7);
setbits_le32(GPC_BASE_ADDR + 0xF8, 1 << 5);
- writel(SRC_DDR1_ENABLE_MASK, SRC_BASE_ADDR + 0x1004);
pll_base = &ana_pll->dram_pll_gnrl_ctl;
break;
diff --git a/arch/arm/mach-imx/imx8ulp/cgc.c b/arch/arm/mach-imx/imx8ulp/cgc.c
index d3c0e64cd6..b19268c822 100644
--- a/arch/arm/mach-imx/imx8ulp/cgc.c
+++ b/arch/arm/mach-imx/imx8ulp/cgc.c
@@ -136,42 +136,34 @@ void cgc1_pll3_init(ulong freq)
clrbits_le32(&cgc1_regs->pll3div_vco, BIT(7));
clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F);
-
- if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) {
- setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 0);
- clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 3 << 21); /* 195M */
- } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) {
- setbits_le32(&cgc1_regs->pll3pfdcfg, 21 << 0);
- clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 1 << 21); /* 231M */
- } else {
- setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 0); /* 324M */
- }
-
+ setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 0); /* PFD0 324M */
clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(7));
while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(6)))
;
clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 8);
- setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 8);
+ setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 8); /* PFD1 389M */
clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(15));
while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(14)))
;
clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 16);
- setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 16);
+ setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 16); /* PFD2 324M */
clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(23));
while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(22)))
;
clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 24);
- setbits_le32(&cgc1_regs->pll3pfdcfg, 29 << 24);
+ setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 24); /* PFD3 389M */
clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(31));
while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(30)))
;
clrbits_le32(&cgc1_regs->pll3div_pfd0, 0x3f3f3f3f);
- clrbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f);
-
+ if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE))
+ clrsetbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f, 0x03010000); /* Set PFD3 DIV1 to 194M, PFD3 DIV2 to 97M */
+ else
+ clrsetbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f, 0x01000000); /* Set PFD3 DIV1 to 389M, PFD3 DIV2 to 194M */
clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(7));
clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(15));
clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(23));
@@ -182,6 +174,17 @@ void cgc1_pll3_init(ulong freq)
clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(23));
clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(31));
+ /* NIC_AP:
+ * OD source PLL3 PFD0, 324M
+ * ND source FRO192, 192M
+ * LD source FRO192, 96M
+ */
+ if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) {
+ clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 1 << 21);
+ } else {
+ clrbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21));
+ }
+
if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) {
clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(29, 28), BIT(28)); /* nicclk select pll3 pfd0 */
while (!(readl(&cgc1_regs->nicclk) & BIT(27)))
@@ -221,18 +224,9 @@ void cgc2_pll4_init(bool pll4_reset)
/* Enable all 4 PFDs */
setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 0); /* 528 */
- if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) {
- setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8);
- clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 3 << 21); /* 99Mhz for NIC_LPAV */
- } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) {
- setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8);
- clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 1 << 21); /* 198Mhz for NIC_LPAV */
- } else {
- setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */
- clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21));
- }
- setbits_le32(&cgc2_regs->pll4pfdcfg, 12 << 16); /* 792 */
- setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); /* 396 */
+ setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */
+ setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 16); /* 316.8Mhz */
+ setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); /* 396Mhz */
clrbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) | BIT(15) | BIT(23) | BIT(31));
@@ -244,9 +238,22 @@ void cgc2_pll4_init(bool pll4_reset)
clrbits_le32(&cgc2_regs->pll4div_pfd0, BIT(7) | BIT(15) | BIT(23) | BIT(31));
clrbits_le32(&cgc2_regs->pll4div_pfd1, BIT(7) | BIT(15) | BIT(23) | BIT(31));
- clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28), BIT(28));
- while (!(readl(&cgc2_regs->niclpavclk) & BIT(27)))
- ;
+ /* NIC_LPAV:
+ * OD source PLL4 PFD1, 316.8M
+ * ND source FRO192, 192M
+ * LD source FRO192, 96M
+ */
+ if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) {
+ clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 1 << 21);
+ } else {
+ clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21));
+ }
+
+ if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) {
+ clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28), BIT(28));
+ while (!(readl(&cgc2_regs->niclpavclk) & BIT(27)))
+ ;
+ }
}
void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd)
diff --git a/arch/arm/mach-imx/imx8ulp/clock.c b/arch/arm/mach-imx/imx8ulp/clock.c
index 2898c8b96c..17dff404fb 100644
--- a/arch/arm/mach-imx/imx8ulp/clock.c
+++ b/arch/arm/mach-imx/imx8ulp/clock.c
@@ -183,37 +183,20 @@ void clock_init_late(void)
*/
cgc1_pll3_init(540672000);
- if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) {
- pcc_clock_enable(4, SDHC0_PCC4_SLOT, false);
- pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD2_DIV2);
- pcc_clock_enable(4, SDHC0_PCC4_SLOT, true);
- pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false);
-
- pcc_clock_enable(4, SDHC1_PCC4_SLOT, false);
- pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV2);
- pcc_clock_enable(4, SDHC1_PCC4_SLOT, true);
- pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false);
-
- pcc_clock_enable(4, SDHC2_PCC4_SLOT, false);
- pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV2);
- pcc_clock_enable(4, SDHC2_PCC4_SLOT, true);
- pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false);
- } else {
- pcc_clock_enable(4, SDHC0_PCC4_SLOT, false);
- pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD1_DIV2);
- pcc_clock_enable(4, SDHC0_PCC4_SLOT, true);
- pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false);
-
- pcc_clock_enable(4, SDHC1_PCC4_SLOT, false);
- pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV1);
- pcc_clock_enable(4, SDHC1_PCC4_SLOT, true);
- pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false);
-
- pcc_clock_enable(4, SDHC2_PCC4_SLOT, false);
- pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV1);
- pcc_clock_enable(4, SDHC2_PCC4_SLOT, true);
- pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false);
- }
+ pcc_clock_enable(4, SDHC0_PCC4_SLOT, false);
+ pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD3_DIV1); /* 389M for OD, 194M for LD/ND*/
+ pcc_clock_enable(4, SDHC0_PCC4_SLOT, true);
+ pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false);
+
+ pcc_clock_enable(4, SDHC1_PCC4_SLOT, false);
+ pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND */
+ pcc_clock_enable(4, SDHC1_PCC4_SLOT, true);
+ pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false);
+
+ pcc_clock_enable(4, SDHC2_PCC4_SLOT, false);
+ pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND*/
+ pcc_clock_enable(4, SDHC2_PCC4_SLOT, true);
+ pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false);
/* enable MU0_MUB clock before access the register of MU0_MUB */
pcc_clock_enable(3, MU0_B_PCC3_SLOT, true);
@@ -432,6 +415,8 @@ void reset_lcdclk(void)
pcc_reset_peripheral(5, DCNANO_PCC5_SLOT, true);
}
+/* PLL4 PFD0 max frequency */
+#define PLL4_PFD0_MAX_RATE 600000 /*khz*/
void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz)
{
u8 pcd, best_pcd = 0;
@@ -450,6 +435,9 @@ void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz)
for (div = 1; div <= 64; div++) {
parent_rate = pll4_rate;
parent_rate = parent_rate * 18 / pfd;
+ if (parent_rate > PLL4_PFD0_MAX_RATE)
+ continue;
+
parent_rate = parent_rate / div;
for (pcd = 0; pcd < 8; pcd++) {
diff --git a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c
index 87152ca818..ee215a4c76 100644
--- a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c
+++ b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c
@@ -14,6 +14,24 @@
#define UPOWER_AP_MU1_ADDR 0x29280000
+#define PS_RTD BIT(0)
+#define PS_DSP BIT(1)
+#define PS_A35_0 BIT(2)
+#define PS_A35_1 BIT(3)
+#define PS_L2 BIT(4)
+#define PS_FAST_NIC BIT(5)
+#define PS_APD_PERIPH BIT(6)
+#define PS_GPU3D BIT(7)
+#define PS_HIFI4 BIT(8)
+#define PS_DDR GENMASK(12, 9)
+#define PS_PXP_EPDC BIT(13)
+#define PS_MIPI_DSI BIT(14)
+#define PS_MIPI_CSI BIT(15)
+#define PS_NIC_LPAV BIT(16)
+#define PS_FUSION_AO BIT(17)
+#define PS_FUSE BIT(18)
+#define PS_UPOWER BIT(19)
+
static struct MU_tag *muptr = (struct MU_tag *)UPOWER_AP_MU1_ADDR;
extern void upwr_txrx_isr(void);
@@ -124,6 +142,7 @@ int upower_init(void)
u32 fw_major, fw_minor, fw_vfixes;
u32 soc_id;
int status;
+ upwr_resp_t err_code;
uint32_t swton;
uint64_t memon;
@@ -156,27 +175,92 @@ int upower_init(void)
}
} while(0);
- swton = 0xfff80;
+ swton = PS_UPOWER | PS_FUSE | PS_FUSION_AO | PS_NIC_LPAV | PS_PXP_EPDC | PS_DDR |
+ PS_HIFI4 | PS_GPU3D | PS_MIPI_DSI;
ret = upwr_pwm_power_on(&swton, NULL /* no memories */, NULL /* no callback */);
if (ret)
printf("Turn on switches fail %d\n", ret);
else
- printf("Turn on switches ok\n");
- upower_wait_resp();
- ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
+ printf("Turning on switches...\n");
+
+ upower_wait_resp();
+ ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, &err_code, &ret_val, 1000);
if (ret != UPWR_REQ_OK)
- printk("Faliure %d\n", ret);
+ printf("Turn on switches faliure %d, err_code %d, ret_val 0x%x\n", ret, err_code, ret_val);
+ else
+ printf("Turn on switches ok\n");
- memon = 0x3FFFFFFFFFFFFCUL;
+ /*
+ * Ascending Order -> bit [0:54)
+ * CA35 Core 0 L1 cache
+ * CA35 Core 1 L1 cache
+ * L2 Cache 0
+ * L2 Cache 1
+ * L2 Cache victim/tag
+ * CAAM Secure RAM
+ * DMA1 RAM
+ * FlexSPI2 FIFO, Buffer
+ * SRAM0
+ * AD ROM
+ * USB0 TX/RX RAM
+ * uSDHC0 FIFO RAM
+ * uSDHC1 FIFO RAM
+ * uSDHC2 FIFO and USB1 TX/RX RAM
+ * GIC RAM
+ * ENET TX FIXO
+ * Reserved(Brainshift)
+ * DCNano Tile2Linear and RGB Correction
+ * DCNano Cursor and FIFO
+ * EPDC LUT
+ * EPDC FIFO
+ * DMA2 RAM
+ * GPU2D RAM Group 1
+ * GPU2D RAM Group 2
+ * GPU3D RAM Group 1
+ * GPU3D RAM Group 2
+ * HIFI4 Caches, IRAM, DRAM
+ * ISI Buffers
+ * MIPI-CSI FIFO
+ * MIPI-DSI FIFO
+ * PXP Caches, Buffers
+ * SRAM1
+ * Casper RAM
+ * DMA0 RAM
+ * FlexCAN RAM
+ * FlexSPI0 FIFO, Buffer
+ * FlexSPI1 FIFO, Buffer
+ * CM33 Cache
+ * PowerQuad RAM
+ * ETF RAM
+ * Sentinel PKC, Data RAM1, Inst RAM0/1
+ * Sentinel ROM
+ * uPower IRAM/DRAM
+ * uPower ROM
+ * CM33 ROM
+ * SSRAM Partition 0
+ * SSRAM Partition 1
+ * SSRAM Partition 2,3,4
+ * SSRAM Partition 5
+ * SSRAM Partition 6
+ * SSRAM Partition 7_a(128KB)
+ * SSRAM Partition 7_b(64KB)
+ * SSRAM Partition 7_c(64KB)
+ * Sentinel Data RAM0, Inst RAM2
+ */
+ /* MIPI-CSI FIFO BIT28 not set */
+ memon = 0x3FFFFFEFFFFFFCUL;
ret = upwr_pwm_power_on(NULL, (const uint32_t *)&memon /* no memories */, NULL /* no callback */);
if (ret)
printf("Turn on memories fail %d\n", ret);
else
- printf("Turn on memories ok\n");
- upower_wait_resp();
- ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
+ printf("Turning on memories...\n");
+
+ upower_wait_resp();
+ ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, &err_code, &ret_val, 1000);
if (ret != UPWR_REQ_OK)
- printk("Faliure %d\n", ret);
+ printf("Turn on memories faliure %d, err_code %d, ret_val 0x%x\n", ret, err_code, ret_val);
+ else
+ printf("Turn on memories ok\n");
mdelay(1);
@@ -184,13 +268,14 @@ int upower_init(void)
if (ret)
printf("Clear DDR retention fail %d\n", ret);
else
- printf("Clear DDR retention ok\n");
+ printf("Clearing DDR retention...\n");
upower_wait_resp();
-
- ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, NULL, &ret_val, 1000);
+ ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000);
if (ret != UPWR_REQ_OK)
- printk("Faliure %d\n", ret);
+ printf("Clear DDR retention fail %d, err_code %d, ret_val 0x%x\n", ret, err_code, ret_val);
+ else
+ printf("Clear DDR retention ok\n");
if (is_soc_rev(CHIP_REV_1_0)) {
/* Enable AFBB for AP domain */
@@ -201,12 +286,15 @@ int upower_init(void)
if (ret)
printf("Enable AFBB for APD bias fail %d\n", ret);
else
- printf("Enable AFBB for APD bias ok\n");
+ printf("Enabling AFBB for APD bias...\n");
upower_wait_resp();
- ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
+ ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, &err_code, &ret_val, 1000);
if (ret != UPWR_REQ_OK)
- printk("Faliure %d\n", ret);
+ printf("Enable AFBB fail %d, err_code %d, ret_val 0x%x\n", ret, err_code, ret_val);
+ else
+ printf("Enable AFBB for APD bias ok\n");
+
}
return 0;
diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig
index c709448411..f4fc1ac5ce 100644
--- a/arch/arm/mach-imx/imx9/Kconfig
+++ b/arch/arm/mach-imx/imx9/Kconfig
@@ -5,6 +5,11 @@ config AHAB_BOOT
help
This option enables the support for AHAB secure boot.
+config IMX9_LOW_DRIVE_MODE
+ bool "Configure to i.MX9 low drive mode"
+ help
+ This option enables the settings for iMX9 low drive mode.
+
config IMX9
bool
select ARCH_EARLY_INIT_R
@@ -27,9 +32,15 @@ config TARGET_IMX93_11X11_EVK
bool "imx93_11x11_evk"
select IMX93
+config TARGET_IMX93_9X9_QSB
+ bool "imx93_9x9_qsb"
+ select IMX93
+ select IMX9_LPDDR4X
+
endchoice
source "board/freescale/imx93_evk/Kconfig"
+source "board/freescale/imx93_qsb/Kconfig"
endif
diff --git a/arch/arm/mach-imx/imx9/clock.c b/arch/arm/mach-imx/imx9/clock.c
index 7dc33941a9..909a770e1c 100644
--- a/arch/arm/mach-imx/imx9/clock.c
+++ b/arch/arm/mach-imx/imx9/clock.c
@@ -26,6 +26,7 @@ static struct anatop_reg *ana_regs = (struct anatop_reg *)ANATOP_BASE_ADDR;
static struct imx_intpll_rate_table imx9_intpll_tbl[] = {
INT_PLL_RATE(1800000000U, 1, 150, 2), /* 1.8Ghz */
INT_PLL_RATE(1700000000U, 1, 141, 2), /* 1.7Ghz */
+ INT_PLL_RATE(1500000000U, 1, 125, 2), /* 1.5Ghz */
INT_PLL_RATE(1400000000U, 1, 175, 3), /* 1.4Ghz */
INT_PLL_RATE(1000000000U, 1, 166, 4), /* 1000Mhz */
INT_PLL_RATE(900000000U, 1, 150, 4), /* 900Mhz */
@@ -39,6 +40,7 @@ static struct imx_fracpll_rate_table imx9_fracpll_tbl[] = {
FRAC_PLL_RATE(445333333U, 1, 167, 9, 0, 1),
FRAC_PLL_RATE(466000000U, 1, 155, 8, 1, 3), /* 466Mhz */
FRAC_PLL_RATE(400000000U, 1, 200, 12, 0, 1), /* 400Mhz */
+ FRAC_PLL_RATE(300000000U, 1, 150, 12, 0, 1),
};
/* return in khz */
@@ -539,6 +541,25 @@ u32 get_arm_core_clk(void)
return ccm_clk_root_get_rate(ARM_A55_CLK_ROOT);
}
+void set_arm_core_max_clk(void)
+{
+ u32 speed;
+
+ /* Increase ARM clock to max rate according to speed grade */
+ speed = get_cpu_speed_grade_hz();
+
+ ccm_shared_gpr_set(SHARED_GPR_A55_CLK, SHARED_GPR_A55_CLK_SEL_CCM);
+ configure_intpll(ARM_PLL_CLK, speed);
+ ccm_shared_gpr_set(SHARED_GPR_A55_CLK, SHARED_GPR_A55_CLK_SEL_PLL);
+}
+
+void set_arm_core_low_drive_clk(void)
+{
+ ccm_shared_gpr_set(SHARED_GPR_A55_CLK, SHARED_GPR_A55_CLK_SEL_CCM);
+ configure_intpll(ARM_PLL_CLK, 900000000);
+ ccm_shared_gpr_set(SHARED_GPR_A55_CLK, SHARED_GPR_A55_CLK_SEL_PLL);
+}
+
unsigned int mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
@@ -611,21 +632,26 @@ void init_uart_clk(u32 index)
void init_clk_usdhc(u32 index)
{
- /* 400 Mhz */
+ u32 div;
+ if (IS_ENABLED(CONFIG_IMX9_LOW_DRIVE_MODE))
+ div = 3; /* 266.67 Mhz */
+ else
+ div = 2; /* 400 Mhz */
+
switch (index) {
case 0:
ccm_lpcg_on(CCGR_USDHC1, 0);
- ccm_clk_root_cfg(USDHC1_CLK_ROOT, SYS_PLL_PFD1, 2);
+ ccm_clk_root_cfg(USDHC1_CLK_ROOT, SYS_PLL_PFD1, div);
ccm_lpcg_on(CCGR_USDHC1, 1);
break;
case 1:
ccm_lpcg_on(CCGR_USDHC2, 0);
- ccm_clk_root_cfg(USDHC2_CLK_ROOT, SYS_PLL_PFD1, 2);
+ ccm_clk_root_cfg(USDHC2_CLK_ROOT, SYS_PLL_PFD1, div);
ccm_lpcg_on(CCGR_USDHC2, 1);
break;
case 2:
ccm_lpcg_on(CCGR_USDHC3, 0);
- ccm_clk_root_cfg(USDHC3_CLK_ROOT, SYS_PLL_PFD1, 2);
+ ccm_clk_root_cfg(USDHC3_CLK_ROOT, SYS_PLL_PFD1, div);
ccm_lpcg_on(CCGR_USDHC3, 1);
break;
default:
@@ -684,7 +710,36 @@ void dram_disable_bypass(void)
}
#endif
-int clock_init(void)
+void bus_clock_init_low_drive(void)
+{
+ /* Set A55 clk to 500M */
+ ccm_clk_root_cfg(ARM_A55_CLK_ROOT, SYS_PLL_PFD0, 2);
+ /* Set A55 periphal to 200M */
+ ccm_clk_root_cfg(ARM_A55_PERIPH_CLK_ROOT, SYS_PLL_PFD1, 4);
+ /* Set A55 mtr bus to 133M */
+ ccm_clk_root_cfg(ARM_A55_MTR_BUS_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+
+ /* Sentinel to 133M */
+ ccm_clk_root_cfg(SENTINEL_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+ /* Bus_wakeup to 133M */
+ ccm_clk_root_cfg(BUS_WAKEUP_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+ /* Bus_AON to 133M */
+ ccm_clk_root_cfg(BUS_AON_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+ /* M33 to 133M */
+ ccm_clk_root_cfg(M33_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+ /* WAKEUP_AXI to 200M */
+ ccm_clk_root_cfg(WAKEUP_AXI_CLK_ROOT, SYS_PLL_PFD1, 4);
+ /* SWO TRACE to 133M */
+ ccm_clk_root_cfg(SWO_TRACE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+ /* M33 systetick to 24M */
+ ccm_clk_root_cfg(M33_SYSTICK_CLK_ROOT, OSC_24M_CLK, 1);
+ /* NIC to 250M */
+ ccm_clk_root_cfg(NIC_CLK_ROOT, SYS_PLL_PFD0, 4);
+ /* NIC_APB to 133M */
+ ccm_clk_root_cfg(NIC_APB_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+}
+
+void bus_clock_init(void)
{
/* Set A55 periphal to 333M */
ccm_clk_root_cfg(ARM_A55_PERIPH_CLK_ROOT, SYS_PLL_PFD0, 3);
@@ -703,12 +758,22 @@ int clock_init(void)
ccm_clk_root_cfg(WAKEUP_AXI_CLK_ROOT, SYS_PLL_PFD2, 2);
/* SWO TRACE to 133M */
ccm_clk_root_cfg(SWO_TRACE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
- /* M33 systetick to 133M */
- ccm_clk_root_cfg(M33_SYSTICK_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+ /* M33 systetick to 24M */
+ ccm_clk_root_cfg(M33_SYSTICK_CLK_ROOT, OSC_24M_CLK, 1);
/* NIC to 400M */
ccm_clk_root_cfg(NIC_CLK_ROOT, SYS_PLL_PFD1, 2);
/* NIC_APB to 133M */
ccm_clk_root_cfg(NIC_APB_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3);
+}
+
+int clock_init(void)
+{
+ if (IS_ENABLED(CONFIG_IMX9_LOW_DRIVE_MODE)){
+ bus_clock_init_low_drive();
+ set_arm_core_low_drive_clk();
+ } else {
+ bus_clock_init();
+ }
/* allow for non-secure access */
int i;
diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c
index 66200dbe3c..02edced9aa 100644
--- a/arch/arm/mach-imx/imx9/soc.c
+++ b/arch/arm/mach-imx/imx9/soc.c
@@ -32,6 +32,10 @@
#include <asm/mach-imx/optee.h>
#include <linux/delay.h>
#include <fuse.h>
+#include <imx_thermal.h>
+#include <thermal.h>
+#include <imx_sip.h>
+#include <linux/arm-smccc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -153,6 +157,56 @@ int board_usb_gadget_port_auto(void)
}
#endif
+u32 get_cpu_speed_grade_hz(void)
+{
+ u32 speed, max_speed;
+ u32 grade;
+ u32 val = readl((ulong)FSB_BASE_ADDR + 0x8000 + (19 << 2));
+ val >>= 6;
+ val &= 0xf;
+
+ speed = 2300000000 - val * 100000000;
+
+ if (is_imx93()) {
+ grade = get_cpu_temp_grade(NULL, NULL);
+ if (grade == TEMP_INDUSTRIAL)
+ max_speed = 1500000000;
+ else
+ max_speed = 1700000000;
+
+ /* In case the fuse of speed grade not programmed */
+ if (speed > max_speed)
+ speed = max_speed;
+ }
+
+ return speed;
+}
+
+u32 get_cpu_temp_grade(int *minc, int *maxc)
+{
+ u32 val = readl((ulong)FSB_BASE_ADDR + 0x8000 + (19 << 2));
+
+ val >>= 4;
+ val &= 0x3;
+
+ if (minc && maxc) {
+ if (val == TEMP_AUTOMOTIVE) {
+ *minc = -40;
+ *maxc = 125;
+ } else if (val == TEMP_INDUSTRIAL) {
+ *minc = -40;
+ *maxc = 105;
+ } else if (val == TEMP_EXTCOMMERCIAL) {
+ *minc = -20;
+ *maxc = 105;
+ } else {
+ *minc = 0;
+ *maxc = 95;
+ }
+ }
+ return val;
+}
+
static void set_cpu_info(struct sentinel_get_info_data *info)
{
gd->arch.soc_rev = info->soc;
@@ -160,10 +214,33 @@ static void set_cpu_info(struct sentinel_get_info_data *info)
memcpy((void *)&gd->arch.uid, &info->uid, 4 * sizeof(u32));
}
+static u32 get_cpu_variant_type(u32 type)
+{
+ /* word 19 */
+ u32 val = readl((ulong)FSB_BASE_ADDR + 0x8000 + (19 << 2));
+ u32 val2 = readl((ulong)FSB_BASE_ADDR + 0x8000 + (20 << 2));
+ bool npu_disable = !!(val & BIT(13));
+ bool core1_disable = !!(val & BIT(15));
+ u32 pack_9x9_fused = BIT(4) | BIT(17) | BIT(19) | BIT(24);
+
+ if ((val2 & pack_9x9_fused) == pack_9x9_fused)
+ type = MXC_CPU_IMX9322;
+
+ if (npu_disable && core1_disable)
+ return type + 3;
+ else if (npu_disable)
+ return type + 2;
+ else if (core1_disable)
+ return type + 1;
+
+ return type;
+}
+
u32 get_cpu_rev(void)
{
u32 rev = (gd->arch.soc_rev >> 24) - 0xa0;
- return (MXC_CPU_IMX93 << 12) | (CHIP_REV_1_0 + rev);
+ return (get_cpu_variant_type(MXC_CPU_IMX93) << 12) |
+ (CHIP_REV_1_0 + rev);
}
#define UNLOCK_WORD 0xD928C520 /* unlock word */
@@ -262,13 +339,161 @@ static struct mm_region imx93_mem_map[] = {
struct mm_region *mem_map = imx93_mem_map;
+static unsigned int imx9_find_dram_entry_in_mem_map(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(imx93_mem_map); i++)
+ if (imx93_mem_map[i].phys == CONFIG_SYS_SDRAM_BASE)
+ return i;
+
+ hang(); /* Entry not found, this must never happen. */
+}
+
+void enable_caches(void)
+{
+ /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch
+ * If OPTEE does not run, still update the MMU table according to dram banks structure
+ * to set correct dram size from board_phys_sdram_size
+ */
+ int i = 0;
+ /*
+ * please make sure that entry initial value matches
+ * imx93_mem_map for DRAM1
+ */
+ int entry = imx9_find_dram_entry_in_mem_map();
+ u64 attrs = imx93_mem_map[entry].attrs;
+
+ while (i < CONFIG_NR_DRAM_BANKS &&
+ entry < ARRAY_SIZE(imx93_mem_map)) {
+ if (gd->bd->bi_dram[i].start == 0)
+ break;
+ imx93_mem_map[entry].phys = gd->bd->bi_dram[i].start;
+ imx93_mem_map[entry].virt = gd->bd->bi_dram[i].start;
+ imx93_mem_map[entry].size = gd->bd->bi_dram[i].size;
+ imx93_mem_map[entry].attrs = attrs;
+ debug("Added memory mapping (%d): %llx %llx\n", entry,
+ imx93_mem_map[entry].phys, imx93_mem_map[entry].size);
+ i++; entry++;
+ }
+
+ icache_enable();
+ dcache_enable();
+}
+
+__weak int board_phys_sdram_size(phys_size_t *size)
+{
+ if (!size)
+ return -EINVAL;
+
+ *size = PHYS_SDRAM_SIZE;
+
+#ifdef PHYS_SDRAM_2_SIZE
+ *size += PHYS_SDRAM_2_SIZE;
+#endif
+ return 0;
+}
+
int dram_init(void)
{
- gd->ram_size = PHYS_SDRAM_SIZE;
+ phys_size_t sdram_size;
+ int ret;
+
+ ret = board_phys_sdram_size(&sdram_size);
+ if (ret)
+ return ret;
+
+ /* rom_pointer[1] contains the size of TEE occupies */
+ if (rom_pointer[1])
+ gd->ram_size = sdram_size - rom_pointer[1];
+ else
+ gd->ram_size = sdram_size;
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ int bank = 0;
+ int ret;
+ phys_size_t sdram_size;
+ phys_size_t sdram_b1_size, sdram_b2_size;
+
+ ret = board_phys_sdram_size(&sdram_size);
+ if (ret)
+ return ret;
+
+ /* Bank 1 can't cross over 4GB space */
+ if (sdram_size > 0x80000000) {
+ sdram_b1_size = 0x80000000;
+ sdram_b2_size = sdram_size - 0x80000000;
+ } else {
+ sdram_b1_size = sdram_size;
+ sdram_b2_size = 0;
+ }
+
+ gd->bd->bi_dram[bank].start = PHYS_SDRAM;
+ if (rom_pointer[1]) {
+ phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
+ phys_size_t optee_size = (size_t)rom_pointer[1];
+
+ gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
+ if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) {
+ if (++bank >= CONFIG_NR_DRAM_BANKS) {
+ puts("CONFIG_NR_DRAM_BANKS is not enough\n");
+ return -1;
+ }
+
+ gd->bd->bi_dram[bank].start = optee_start + optee_size;
+ gd->bd->bi_dram[bank].size = PHYS_SDRAM +
+ sdram_b1_size - gd->bd->bi_dram[bank].start;
+ }
+ } else {
+ gd->bd->bi_dram[bank].size = sdram_b1_size;
+ }
+
+ if (sdram_b2_size) {
+ if (++bank >= CONFIG_NR_DRAM_BANKS) {
+ puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
+ return -1;
+ }
+ gd->bd->bi_dram[bank].start = 0x100000000UL;
+ gd->bd->bi_dram[bank].size = sdram_b2_size;
+ }
return 0;
}
+phys_size_t get_effective_memsize(void)
+{
+ int ret;
+ phys_size_t sdram_size;
+ phys_size_t sdram_b1_size;
+ ret = board_phys_sdram_size(&sdram_size);
+ if (!ret) {
+ /* Bank 1 can't cross over 4GB space */
+ if (sdram_size > 0x80000000) {
+ sdram_b1_size = 0x80000000;
+ } else {
+ sdram_b1_size = sdram_size;
+ }
+
+ if (rom_pointer[1]) {
+ /* We will relocate u-boot to Top of dram1. Tee position has two cases:
+ * 1. At the top of dram1, Then return the size removed optee size.
+ * 2. In the middle of dram1, return the size of dram1.
+ */
+ if ((rom_pointer[0] + rom_pointer[1]) == (PHYS_SDRAM + sdram_b1_size))
+ return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
+ }
+
+ return sdram_b1_size;
+ } else {
+ return PHYS_SDRAM_SIZE;
+ }
+}
+
+
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
{
u32 val[2] = {};
@@ -315,26 +540,370 @@ err:
printf("%s: fuse read err: %d\n", __func__, ret);
}
+const char *get_imx_type(u32 imxtype)
+{
+ switch (imxtype) {
+ case MXC_CPU_IMX93:
+ return "93(52)";/* iMX93 Dual core with NPU */
+ case MXC_CPU_IMX9351:
+ return "93(51)";/* iMX93 Single core with NPU */
+ case MXC_CPU_IMX9332:
+ return "93(32)";/* iMX93 Dual core without NPU */
+ case MXC_CPU_IMX9331:
+ return "93(31)";/* iMX93 Single core without NPU */
+ case MXC_CPU_IMX9322:
+ return "93(22)";/* iMX93 9x9 Dual core */
+ case MXC_CPU_IMX9321:
+ return "93(21)";/* iMX93 9x9 Single core */
+ case MXC_CPU_IMX9312:
+ return "93(12)";/* iMX93 9x9 Dual core without NPU */
+ case MXC_CPU_IMX9311:
+ return "93(11)";/* iMX93 9x9 Single core without NPU */
+ default:
+ return "??";
+ }
+}
+
+#define SRC_SRSR_RESET_CAUSE_NUM 16
+const char *reset_cause[SRC_SRSR_RESET_CAUSE_NUM] = {
+ "POR ",
+ "JTAG ",
+ "IPP USER ",
+ "WDOG1 ",
+ "WDOG2 ",
+ "WDOG3 ",
+ "WDOG4 ",
+ "WDOG5 ",
+ "TEMPSENSE ",
+ "CSU ",
+ "JTAG_SW ",
+ "M33_REQ ",
+ "M33_LOCKUP "
+ "UNK ",
+ "UNK ",
+ "UNK ",
+};
+
+static void save_reset_cause(void)
+{
+ struct src_general_regs *src = (struct src_general_regs *)SRC_GLOBAL_RBASE;
+ u32 srsr = readl(&src->srsr);
+ writel(srsr, &src->srsr); /* clear srsr in sec mode */
+
+ /* Save value to GPR1 to pass to nonsecure */
+ writel(srsr, &src->gpr[0]);
+}
+
+static const char *get_reset_cause(u32 *srsr_ret)
+{
+ struct src_general_regs *src = (struct src_general_regs *)SRC_GLOBAL_RBASE;
+ u32 srsr;
+ u32 i;
+
+ srsr = readl(&src->gpr[0]);
+ if (srsr_ret)
+ *srsr_ret = srsr;
+
+ for (i = SRC_SRSR_RESET_CAUSE_NUM; i > 0; i--) {
+ if (srsr & (1 << (i - 1)))
+ return reset_cause[i - 1];
+ }
+
+ return "unknown reset";
+}
+
int print_cpuinfo(void)
{
- u32 cpurev;
+ u32 cpurev, max_freq;
+ int minc, maxc;
+ u32 ssrs_ret;
cpurev = get_cpu_rev();
- printf("CPU: i.MX93 rev%d.%d at %d MHz\n",
- (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0,
- mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("CPU: i.MX%s rev%d.%d",
+ get_imx_type((cpurev & 0x1FF000) >> 12),
+ (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0);
+
+ max_freq = get_cpu_speed_grade_hz();
+ if (!max_freq || max_freq == mxc_get_clock(MXC_ARM_CLK)) {
+ printf(" at %dMHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ } else {
+ printf(" %d MHz (running at %d MHz)\n", max_freq / 1000000,
+ mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ }
+
+ puts("CPU: ");
+ switch (get_cpu_temp_grade(&minc, &maxc)) {
+ case TEMP_AUTOMOTIVE:
+ puts("Automotive temperature grade ");
+ break;
+ case TEMP_INDUSTRIAL:
+ puts("Industrial temperature grade ");
+ break;
+ case TEMP_EXTCOMMERCIAL:
+ puts("Extended Consumer temperature grade ");
+ break;
+ default:
+ puts("Consumer temperature grade ");
+ break;
+ }
+ printf("(%dC to %dC)", minc, maxc);
+
+#if defined(CONFIG_IMX_TMU)
+ struct udevice *udev;
+ int ret, temp;
+
+ ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal", &udev);
+ if (!ret) {
+ ret = thermal_get_temp(udev, &temp);
+
+ if (!ret)
+ printf(" at %dC", temp);
+ else
+ debug(" - invalid sensor data\n");
+ } else {
+ debug(" - invalid sensor device\n");
+ }
+#endif
+ puts("\n");
+
+ printf("Reset cause: %s", get_reset_cause(&ssrs_ret));
+ printf("(0x%x)\n", ssrs_ret);
return 0;
}
+void build_info(void)
+{
+ u32 fw_version, sha1, res, status;
+ int ret;
+
+ printf("\nBuildInfo:\n");
+
+ ret = ahab_get_fw_status(&status, &res);
+ if (ret) {
+ printf(" - ELE firmware status failed %d, 0x%x\n", ret, res);
+ } else if ((status & 0xff) == 1) {
+ ret = ahab_get_fw_version(&fw_version, &sha1, &res);
+ if (ret) {
+ printf(" - ELE firmware version failed %d, 0x%x\n", ret, res);
+ } else {
+ printf(" - ELE firmware version %u.%u.%u-%x",
+ (fw_version & (0x00ff0000)) >> 16,
+ (fw_version & (0x0000ff00)) >> 8,
+ (fw_version & (0x000000ff)), sha1);
+ ((fw_version & (0x80000000)) >> 31) == 1 ? puts("-dirty\n") : puts("\n");
+ }
+ } else {
+ printf(" - ELE firmware not included\n");
+ }
+ puts("\n");
+}
+
int arch_misc_init(void)
{
+ build_info();
+ return 0;
+}
+
+static int delete_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
+{
+ int i = 0;
+ int rc;
+ int nodeoff;
+
+ for (i = 0; i < size_array; i++) {
+ nodeoff = fdt_path_offset(blob, nodes_path[i]);
+ if (nodeoff < 0)
+ continue; /* Not found, skip it */
+
+ debug("Found %s node\n", nodes_path[i]);
+
+ rc = fdt_del_node(blob, nodeoff);
+ if (rc < 0) {
+ printf("Unable to delete node %s, err=%s\n",
+ nodes_path[i], fdt_strerror(rc));
+ } else {
+ printf("Delete node %s\n", nodes_path[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int disable_npu_nodes(void *blob)
+{
+ static const char * const nodes_path_npu[] = {
+ "/ethosu",
+ "/reserved-memory/ethosu_region@C0000000"
+ };
+
+ return delete_fdt_nodes(blob, nodes_path_npu, ARRAY_SIZE(nodes_path_npu));
+}
+
+static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores)
+{
+ static const char * const thermal_path[] = {
+ "/thermal-zones/cpu-thermal/cooling-maps/map0"
+ };
+
+ int nodeoff, cnt, i, ret, j;
+ u32 cooling_dev[6];
+
+ for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
+ nodeoff = fdt_path_offset(blob, thermal_path[i]);
+ if (nodeoff < 0)
+ continue; /* Not found, skip it */
+
+ cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 6);
+ if (cnt < 0)
+ continue;
+
+ if (cnt != 6)
+ printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt);
+
+ for (j = 0; j < cnt; j++)
+ cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
+
+ ret = fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev,
+ sizeof(u32) * (6 - disabled_cores * 3));
+ if (ret < 0) {
+ printf("Warning: %s, cooling-device setprop failed %d\n",
+ thermal_path[i], ret);
+ continue;
+ }
+
+ printf("Update node %s, cooling-device prop\n", thermal_path[i]);
+ }
+}
+
+static int disable_cpu_nodes(void *blob, u32 disabled_cores)
+{
+ u32 i = 0;
+ int rc;
+ int nodeoff;
+ char nodes_path[32];
+
+ for (i = 1; i <= disabled_cores; i++) {
+
+ sprintf(nodes_path, "/cpus/cpu@%u00", i);
+
+ nodeoff = fdt_path_offset(blob, nodes_path);
+ if (nodeoff < 0)
+ continue; /* Not found, skip it */
+
+ debug("Found %s node\n", nodes_path);
+
+ rc = fdt_del_node(blob, nodeoff);
+ if (rc < 0) {
+ printf("Unable to delete node %s, err=%s\n",
+ nodes_path, fdt_strerror(rc));
+ } else {
+ printf("Delete node %s\n", nodes_path);
+ }
+ }
+
+ disable_thermal_cpu_nodes(blob, disabled_cores);
+
return 0;
}
+struct low_drive_freq_entry {
+ const char *node_path;
+ u32 clk;
+ u32 new_rate;
+};
+
+static int low_drive_fdt_fix_clock(void *fdt, int node_off, u32 clk_index, u32 new_rate)
+{
+#define MAX_ASSIGNED_CLKS 8
+ int cnt, j;
+ u32 assignedclks[MAX_ASSIGNED_CLKS]; /* max 8 clocks*/
+
+ cnt = fdtdec_get_int_array_count(fdt, node_off, "assigned-clock-rates",
+ assignedclks, MAX_ASSIGNED_CLKS);
+ if (cnt > 0) {
+ if (cnt <= clk_index)
+ return -ENOENT;
+
+ if (assignedclks[clk_index] <= new_rate)
+ return 0;
+
+ assignedclks[clk_index] = new_rate;
+ for (j = 0; j < cnt; j++)
+ assignedclks[j] = cpu_to_fdt32(assignedclks[j]);
+
+ return fdt_setprop(fdt, node_off, "assigned-clock-rates", &assignedclks, cnt * sizeof(u32));
+ }
+
+ return -ENOENT;
+}
+
+static int low_drive_freq_update(void *blob)
+{
+ int nodeoff, ret;
+ int i;
+
+ /* Update kernel dtb clocks for low drive mode */
+ struct low_drive_freq_entry table[] = {
+ {"/soc@0/lcd-controller@4ae30000", 2, 200000000},
+ {"/soc@0/bus@42800000/camera/isi@4ae40000", 0, 200000000},
+ {"/soc@0/bus@42800000/mmc@42850000", 0, 266666667},
+ {"/soc@0/bus@42800000/mmc@42860000", 0, 266666667},
+ {"/soc@0/bus@42800000/mmc@428b0000", 0, 266666667},
+ };
+
+ for (i = 0; i < ARRAY_SIZE(table); i++) {
+ nodeoff = fdt_path_offset(blob, table[i].node_path);
+ if (nodeoff >= 0) {
+ ret = low_drive_fdt_fix_clock(blob, nodeoff, table[i].clk, table[i].new_rate);
+ if (!ret)
+ printf("%s freq updated\n", table[i].node_path);
+ }
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_OF_BOARD_FIXUP
+#ifndef CONFIG_SPL_BUILD
+int board_fix_fdt(void *fdt)
+{
+ /* Update u-boot dtb clocks for low drive mode */
+ if (IS_ENABLED(CONFIG_IMX9_LOW_DRIVE_MODE)){
+ int nodeoff;
+ int i;
+
+ struct low_drive_freq_entry table[] = {
+ {"/soc@0/lcd-controller@4ae30000", 0, 200000000},
+ {"/soc@0/bus@42800000/mmc@42850000", 0, 266666667},
+ {"/soc@0/bus@42800000/mmc@42860000", 0, 266666667},
+ {"/soc@0/bus@42800000/mmc@428b0000", 0, 266666667},
+ };
+
+ for (i = 0; i < ARRAY_SIZE(table); i++) {
+ nodeoff = fdt_path_offset(fdt, table[i].node_path);
+ if (nodeoff >= 0)
+ low_drive_fdt_fix_clock(fdt, nodeoff, table[i].clk, table[i].new_rate);
+ }
+ }
+
+ return 0;
+}
+#endif
+#endif
+
int ft_system_setup(void *blob, struct bd_info *bd)
{
+ if (is_imx9351() || is_imx9331() || is_imx9321() || is_imx9311())
+ disable_cpu_nodes(blob, 1);
+
+ if (is_imx9332() || is_imx9331() || is_imx9312() || is_imx9311())
+ disable_npu_nodes(blob);
+
+ if (IS_ENABLED(CONFIG_IMX9_LOW_DRIVE_MODE))
+ low_drive_freq_update(blob);
+
return ft_add_optee_node(blob, bd);
}
@@ -358,6 +927,9 @@ int arch_cpu_init(void)
clock_init();
trdc_early_init();
+
+ /* Save SRC SRSR to GPR1 and clear it */
+ save_reset_cause();
}
return 0;
diff --git a/arch/arm/mach-imx/mx6/module_fuse.c b/arch/arm/mach-imx/mx6/module_fuse.c
index c24d8279ed..a171e7b54d 100644
--- a/arch/arm/mach-imx/mx6/module_fuse.c
+++ b/arch/arm/mach-imx/mx6/module_fuse.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2019 NXP
+ * Copyright 2019, 2022 NXP
*/
#include <common.h>
@@ -10,6 +10,11 @@
#include <asm/arch/imx-regs.h>
#include <asm/mach-imx/module_fuse.h>
#include <linux/errno.h>
+#include <command.h>
+#include <hexdump.h>
+#include <dm.h>
+#include <malloc.h>
+#include <rng.h>
static struct fuse_entry_desc mx6_fuse_descs[] = {
#if defined(CONFIG_MX6ULL)
@@ -300,6 +305,48 @@ add_status:
}
}
+ if (IS_ENABLED(CONFIG_FSL_DCP_RNG)) {
+ /*Random number generation through RNG driver*/
+ struct udevice *dev;
+ void *buf;
+ char keys[2][16] = {"otp_crypto_key", "otp_unique_key"};
+ int ret = 0;
+ int nodeoff = fdt_node_offset_by_compatible(blob, -1, "fsl,imx28-dcp");
+
+ if (nodeoff < 0) {
+ printf("node to update the SoC serial number is not found.\n");
+ return nodeoff;
+ }
+ rc = uclass_get_device(UCLASS_RNG, 0, &dev);
+ if (rc || !dev) {
+ printf("No RNG device\n");
+ return rc;
+ }
+
+ buf = malloc(16);
+ if (!buf) {
+ printf("Out of memory\n");
+ return -ENOMEM;
+ }
+
+ for (int i = 0; i < 2; i++) {
+ ret = dm_rng_read(dev, buf, 16);
+ if (ret) {
+ printf("Reading RNG failed\n");
+ goto err;
+ }
+
+ ret = fdt_setprop(blob, nodeoff, keys[i], buf, 16);
+ if (ret < 0) {
+ printf("WARNING: could not set %s key handle %s.\n", keys[i], fdt_strerror(ret));
+ goto err;
+ }
+ }
+err:
+ free(buf);
+ return ret;
+ }
+
return 0;
}
#endif