summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/cpu/armv8/fel_utils.S5
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/Kconfig6
-rw-r--r--arch/arm/dts/Makefile2
-rw-r--r--arch/arm/dts/ast2600.dtsi2
-rw-r--r--arch/arm/dts/at91-sama7d65_curiosity-u-boot.dtsi80
-rw-r--r--arch/arm/dts/imx6dl-sielaff.dts533
-rw-r--r--arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi186
-rw-r--r--arch/arm/dts/imx93-11x11-frdm.dts603
-rw-r--r--arch/arm/dts/imx95-u-boot.dtsi8
-rw-r--r--arch/arm/dts/k3-am625-phycore-som-binman.dtsi6
-rw-r--r--arch/arm/dts/k3-am625-sk-binman.dtsi6
-rw-r--r--arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi6
-rw-r--r--arch/arm/dts/k3-am62a-phycore-som-binman.dtsi6
-rw-r--r--arch/arm/dts/k3-am62a-sk-binman.dtsi6
-rw-r--r--arch/arm/dts/k3-am62p-sk-binman.dtsi4
-rw-r--r--arch/arm/dts/k3-am62p5-verdin-wifi-dev-binman.dtsi4
-rw-r--r--arch/arm/dts/k3-am65-iot2050-boot-image.dtsi4
-rw-r--r--arch/arm/dts/k3-am67a-beagley-ai-u-boot.dtsi4
-rw-r--r--arch/arm/dts/k3-j7200-binman.dtsi10
-rw-r--r--arch/arm/dts/k3-j721s2-binman.dtsi6
-rw-r--r--arch/arm/dts/k3-j722s-binman.dtsi4
-rw-r--r--arch/arm/dts/k3-j784s4-binman.dtsi6
-rw-r--r--arch/arm/dts/ls1021a-pg-wcom-expu1.dts20
-rw-r--r--arch/arm/dts/ls1021a-pg-wcom-seli8.dts20
-rw-r--r--arch/arm/dts/zynqmp-binman-som.dts2
-rw-r--r--arch/arm/include/asm/arch-imx9/ddr.h1
-rw-r--r--arch/arm/include/asm/arch-mx27/imx-regs.h5
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h49
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h20
-rw-r--r--arch/arm/include/asm/arch-sunxi/dram.h2
-rw-r--r--arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h153
-rw-r--r--arch/arm/include/asm/arch-sunxi/watchdog.h2
-rw-r--r--arch/arm/include/asm/mach-imx/ele_api.h2
-rw-r--r--arch/arm/mach-at91/Kconfig13
-rw-r--r--arch/arm/mach-at91/armv7/Makefile1
-rw-r--r--arch/arm/mach-at91/armv7/sama7d65_devices.c31
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-at91/include/mach/sama7d65.h107
-rw-r--r--arch/arm/mach-imx/image-container.c2
-rw-r--r--arch/arm/mach-imx/imx8ulp/soc.c2
-rw-r--r--arch/arm/mach-imx/imx9/Kconfig10
-rw-r--r--arch/arm/mach-imx/imx9/scmi/container.cfg1
-rw-r--r--arch/arm/mach-imx/imx9/scmi/imximage.cfg5
-rw-r--r--arch/arm/mach-k3/r5/common.c2
-rw-r--r--arch/arm/mach-snapdragon/board.c2
-rw-r--r--arch/arm/mach-snapdragon/capsule_update.c2
-rw-r--r--arch/arm/mach-snapdragon/of_fixup.c2
-rw-r--r--arch/arm/mach-sunxi/Kconfig54
-rw-r--r--arch/arm/mach-sunxi/Makefile2
-rw-r--r--arch/arm/mach-sunxi/board.c11
-rw-r--r--arch/arm/mach-sunxi/clock_sun50i_h6.c153
-rw-r--r--arch/arm/mach-sunxi/cpu_info.c2
-rw-r--r--arch/arm/mach-sunxi/dram_sun50i_a133.c10
-rw-r--r--arch/arm/mach-sunxi/dram_sun50i_h6.c6
-rw-r--r--arch/arm/mach-sunxi/dram_sun50i_h616.c6
-rw-r--r--arch/arm/mach-sunxi/dram_sun55i_a523.c1590
-rw-r--r--arch/arm/mach-sunxi/dram_timings/Makefile2
-rw-r--r--arch/arm/mach-sunxi/dram_timings/a523_ddr3.c113
-rw-r--r--arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c119
60 files changed, 3375 insertions, 651 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5872455a0fe..4e7593616d8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -835,6 +835,9 @@ config ARCH_K3
select FIT_SIGNATURE if ARM64
select LTO
imply TI_SECURE_DEVICE
+ imply DM_RNG if ARM64
+ imply TEE if ARM64
+ imply OPTEE if ARM64
config ARCH_OMAP2PLUS
bool "TI OMAP2+"
diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S
index 6a7ec9a7ec1..ccddfaaf04c 100644
--- a/arch/arm/cpu/armv8/fel_utils.S
+++ b/arch/arm/cpu/armv8/fel_utils.S
@@ -41,10 +41,11 @@ ENTRY(return_to_fel)
str w2, [x1]
ldr w0, =0xfa50392f // CPU hotplug magic
-#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133)
+#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) || \
+ defined(CONFIG_MACH_SUN55I_A523)
ldr w2, =(SUNXI_R_CPUCFG_BASE + 0x1c0)
str w0, [x2], #0x4
-#elif CONFIG_MACH_SUN50I_H6
+#elif defined(CONFIG_MACH_SUN50I_H6)
ldr w2, =(SUNXI_RTC_BASE + 0x1b8) // BOOT_CPU_HP_FLAG_REG
str w0, [x2], #0x4
#else
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index 787c7a7c1da..20883fe6825 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -77,11 +77,11 @@ config ARCH_LS1043A
select SYS_FSL_DDR_BE
select SYS_FSL_DDR_VER_50
select SYS_FSL_ERRATUM_A008850 if !TFABOOT
- select SYS_FSL_ERRATUM_A008997
- select SYS_FSL_ERRATUM_A009008
+ select SYS_FSL_ERRATUM_A008997 if USB
+ select SYS_FSL_ERRATUM_A009008 if USB
select SYS_FSL_ERRATUM_A009660 if !TFABOOT
select SYS_FSL_ERRATUM_A009663 if !TFABOOT
- select SYS_FSL_ERRATUM_A009798
+ select SYS_FSL_ERRATUM_A009798 if USB
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
select SYS_FSL_ERRATUM_A010315 if PCIE_LAYERSCAPE
select SYS_FSL_ERRATUM_A010539
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 17795f8f746..0dc7e190eb9 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -760,7 +760,6 @@ dtb-y += \
imx6dl-riotboard.dtb \
imx6dl-sabreauto.dtb \
imx6dl-sabresd.dtb \
- imx6dl-sielaff.dtb \
imx6dl-wandboard-revd1.dtb
endif
@@ -918,6 +917,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \
imx8mq-librem5-r4.dtb
dtb-$(CONFIG_ARCH_IMX9) += \
+ imx93-11x11-frdm.dtb \
imx93-var-som-symphony.dtb
dtb-$(CONFIG_ARCH_IMXRT) += imxrt1020-evk.dtb \
diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi
index cb8ce8b6b6f..a048951fa18 100644
--- a/arch/arm/dts/ast2600.dtsi
+++ b/arch/arm/dts/ast2600.dtsi
@@ -794,7 +794,7 @@
uart11: serial@1e790500 {
compatible = "ns16550a";
- reg = <0x1e790400 0x20>;
+ reg = <0x1e790500 0x20>;
reg-shift = <2>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&scu ASPEED_CLK_GATE_UART11CLK>;
diff --git a/arch/arm/dts/at91-sama7d65_curiosity-u-boot.dtsi b/arch/arm/dts/at91-sama7d65_curiosity-u-boot.dtsi
new file mode 100644
index 00000000000..343f10cdf9a
--- /dev/null
+++ b/arch/arm/dts/at91-sama7d65_curiosity-u-boot.dtsi
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama7d65_curiosity-u-boot.dtsi - Device Tree Include file for
+ * SAMA7D65 CURIOSITY.
+ *
+ * Copyright (c) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Ryan Wanner <ryan.wanner@microchip.com>
+ */
+
+/{
+ aliases {
+ serial0 = &uart6;
+ };
+
+ chosen {
+ bootph-all;
+ };
+
+ clocks {
+ slow_rc_osc: slow_rc_osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32000>;
+ };
+ };
+
+ cpus {
+ cpu@0 {
+ clocks = <&pmc PMC_TYPE_CORE 8>, <&pmc PMC_TYPE_CORE 26>, <&main_xtal>;
+ clock-names = "cpu", "master", "xtal";
+ };
+ };
+
+ soc {
+ bootph-all;
+ };
+};
+
+&clk32k {
+ clocks = <&slow_rc_osc>, <&slow_xtal>;
+};
+
+&main_xtal {
+ bootph-all;
+};
+
+&pioa {
+ bootph-all;
+};
+
+&pinctrl_uart6_default {
+ bootph-all;
+};
+
+&pit64b0 {
+ bootph-all;
+};
+
+&pmc {
+ bootph-all;
+};
+
+&sdmmc1 {
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE 27>; /* MCK1 div */
+ microchip,sdcal-inverted;
+ no-1-8-v;
+};
+
+&slow_rc_osc {
+ bootph-all;
+};
+
+&slow_xtal {
+ bootph-all;
+};
+
+&uart6 {
+ bootph-all;
+};
diff --git a/arch/arm/dts/imx6dl-sielaff.dts b/arch/arm/dts/imx6dl-sielaff.dts
deleted file mode 100644
index 7de8d5f2651..00000000000
--- a/arch/arm/dts/imx6dl-sielaff.dts
+++ /dev/null
@@ -1,533 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+ OR MIT
-/*
- * Copyright (C) 2022 Kontron Electronics GmbH
- */
-
-/dts-v1/;
-
-#include "imx6dl.dtsi"
-#include <dt-bindings/clock/imx6qdl-clock.h>
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-
-/ {
- model = "Sielaff i.MX6 Solo";
- compatible = "sielaff,imx6dl-board", "fsl,imx6dl";
-
- chosen {
- stdout-path = &uart2;
- };
-
- backlight: pwm-backlight {
- compatible = "pwm-backlight";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_backlight>;
- pwms = <&pwm3 0 50000 0>;
- brightness-levels = <0 0 64 88 112 136 184 232 255>;
- default-brightness-level = <4>;
- enable-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
- power-supply = <&reg_backlight>;
- };
-
- cec {
- compatible = "cec-gpio";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hdmi_cec>;
- cec-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
- hdmi-phandle = <&hdmi>;
- };
-
- enet_ref: clock-enet-ref {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <50000000>;
- clock-output-names = "enet-ref";
- };
-
- gpio-keys {
- compatible = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_keys>;
-
- key-0 {
- gpios = <&gpio2 16 0>;
- debounce-interval = <10>;
- linux,code = <1>;
- };
-
- key-1 {
- gpios = <&gpio3 27 0>;
- debounce-interval = <10>;
- linux,code = <2>;
- };
-
- key-2 {
- gpios = <&gpio5 4 0>;
- debounce-interval = <10>;
- linux,code = <3>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_leds>;
-
- led-debug {
- label = "debug-led";
- gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- linux,default-trigger = "heartbeat";
- };
- };
-
- memory@80000000 {
- reg = <0x80000000 0x20000000>;
- device_type = "memory";
- };
-
- osc_eth_phy: clock-osc-eth-phy {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <25000000>;
- clock-output-names = "osc-eth-phy";
- };
-
- panel {
- compatible = "lg,lb070wv8";
- backlight = <&backlight>;
- power-supply = <&reg_3v3>;
-
- port {
- panel_in_lvds: endpoint {
- remote-endpoint = <&lvds_out>;
- };
- };
- };
-
- reg_3v3: regulator-3v3 {
- compatible = "regulator-fixed";
- regulator-name = "3v3";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- reg_backlight: regulator-backlight {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_reg_backlight>;
- enable-active-high;
- gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- regulator-name = "backlight";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- };
-
- reg_usb_otg_vbus: regulator-usb-otg-vbus {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_reg_usbotg_vbus>;
- enable-active-high;
- gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
- regulator-name = "usb_otg_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- };
-};
-
-&ecspi2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi2>;
- cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <20000000>;
- };
-};
-
-&fec {
- /*
- * Set PTP clock to external instead of internal reference, as the
- * REF_CLK from the PHY is fed back into the i.MX6 and the GPR
- * register needs to be set accordingly (see mach-imx6q.c).
- */
- clocks = <&clks IMX6QDL_CLK_ENET>,
- <&clks IMX6QDL_CLK_ENET>,
- <&enet_ref>,
- <&clks IMX6QDL_CLK_ENET_REF>;
- clock-names = "ipg", "ahb", "ptp", "enet_out";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_enet>;
- phy-connection-type = "rmii";
- phy-handle = <&ethphy>;
- status = "okay";
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
-
- ethphy: ethernet-phy@1 {
- reg = <1>;
- clocks = <&osc_eth_phy>;
- clock-names = "rmii-ref";
- micrel,led-mode = <1>;
- reset-assert-us = <500>;
- reset-deassert-us = <100>;
- reset-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&gpio1 {
- gpio-line-names =
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "key-out", "key-in",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "";
-};
-
-&gpio2 {
- gpio-line-names =
- "", "", "", "", "", "", "", "",
- "lan9500a-rst", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "";
-};
-
-&gpmi {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpmi_nand>;
- status = "okay";
-};
-
-&hdmi {
- ddc-i2c-bus = <&i2c4>;
- status = "okay";
-};
-
-&i2c2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- clock-frequency = <100000>;
- status = "okay";
-
- rtc@51 {
- compatible = "nxp,pcf8563";
- reg = <0x51>;
- };
-};
-
-&i2c3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- clock-frequency = <100000>;
- status = "okay";
-
- touchscreen@55 {
- compatible = "sitronix,st1633";
- reg = <0x55>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_touch>;
- interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
- interrupt-parent = <&gpio5>;
- gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
- status = "disabled";
- };
-
- touchscreen@5d {
- compatible = "goodix,gt928";
- reg = <0x5d>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_touch>;
- interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
- interrupt-parent = <&gpio5>;
- irq-gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
- reset-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
- status = "disabled";
- };
-};
-
-&i2c4 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c4>;
- clock-frequency = <100000>;
- status = "okay";
-};
-
-&ldb {
- status = "okay";
-
- lvds: lvds-channel@0 {
- fsl,data-mapping = "spwg";
- fsl,data-width = <24>;
- status = "okay";
-
- port@4 {
- reg = <4>;
-
- lvds_out: endpoint {
- remote-endpoint = <&panel_in_lvds>;
- };
- };
- };
-};
-
-&pwm3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm3>;
- status = "okay";
-};
-
-&uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- status = "okay";
-};
-
-&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- status = "okay";
-};
-
-&uart3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- status = "okay";
-};
-
-&usbh1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbh1>;
- disable-over-current;
- status = "okay";
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb1@1 {
- compatible = "usb4b4,6570";
- reg = <1>;
- clocks = <&clks IMX6QDL_CLK_CKO>;
-
- assigned-clocks = <&clks IMX6QDL_CLK_CKO>,
- <&clks IMX6QDL_CLK_CKO2_SEL>;
- assigned-clock-parents = <&clks IMX6QDL_CLK_CKO2>,
- <&clks IMX6QDL_CLK_OSC>;
- assigned-clock-rates = <12000000 0>;
- };
-};
-
-&usbotg {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbotg>;
- dr_mode = "host";
- over-current-active-low;
- vbus-supply = <&reg_usb_otg_vbus>;
- status = "okay";
-};
-
-&usdhc3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc3>;
- cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
- vmmc-supply = <&reg_3v3>;
- voltage-ranges = <3300 3300>;
- no-1-8-v;
- status = "okay";
-};
-
-&wdog1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_wdog>;
- fsl,ext-reset-output;
- status = "okay";
-};
-
-&iomuxc {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hog>;
-
- pinctrl_hog: hoggrp {
- fsl,pins = <
- MX6QDL_PAD_RGMII_RD0__GPIO6_IO25 0x1b0b0 /* PMIC_IRQ */
- MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x1b0b0
- MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0
- MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x1b0b0
- MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x1b0b0
- MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
- >;
- };
-
- pinctrl_backlight: backlightgrp {
- fsl,pins = <
- MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x100b1
- >;
- };
-
- pinctrl_ecspi2: ecspi2grp {
- fsl,pins = <
- MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO 0x100b1
- MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI 0x100b1
- MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK 0x100b1
- MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29 0x100b1
- >;
- };
-
- pinctrl_enet: enetgrp {
- fsl,pins = <
- MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
- MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
- MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
- MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
- MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
- MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
- MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
- MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
- MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
- MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
- MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x100b1
- >;
- };
-
- pinctrl_gpio_keys: gpiokeysgrp {
- fsl,pins = <
- MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x1b080
- MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x1b080
- MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x1b080
- >;
- };
-
- pinctrl_gpio_leds: gpioledsgrp {
- fsl,pins = <
- MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x1b0b0
- >;
- };
-
- pinctrl_gpmi_nand: gpminandgrp {
- fsl,pins = <
- MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
- MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
- MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
- MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
- MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
- MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
- MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
- MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
- MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
- MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
- MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
- MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
- MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
- MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
- MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
- >;
- };
-
- pinctrl_hdmi_cec: hdmicecgrp {
- fsl,pins = <
- MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x1b8b1
- >;
- };
-
- pinctrl_i2c2: i2c2grp {
- fsl,pins = <
- MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
- MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
- >;
- };
-
- pinctrl_i2c3: i2c3grp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001f8b1
- MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001f8b1
- >;
- };
-
- pinctrl_i2c4: i2c4grp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_7__I2C4_SCL 0x4001b8b1
- MX6QDL_PAD_GPIO_8__I2C4_SDA 0x4001b8b1
- >;
- };
-
- pinctrl_pwm3: pwm3grp {
- fsl,pins = <
- MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
- >;
- };
-
- pinctrl_reg_backlight: regbacklightgrp {
- fsl,pins = <
- MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b1
- >;
- };
-
- pinctrl_reg_usbotg_vbus: regusbotgvbusgrp {
- fsl,pins = <
- MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b1
- >;
- };
-
- pinctrl_touch: touchgrp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
- MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x1b0b0
- >;
- };
-
- pinctrl_uart1: uart1grp {
- fsl,pins = <
- MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
- MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
- >;
- };
-
- pinctrl_uart2: uart2grp {
- fsl,pins = <
- MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
- MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
- >;
- };
-
- pinctrl_uart3: uart3grp {
- fsl,pins = <
- MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b0
- MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b0
- >;
- };
-
- pinctrl_usbh1: usbh1grp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b1
- MX6QDL_PAD_CSI0_MCLK__CCM_CLKO1 0x1b0b0
- >;
- };
-
- pinctrl_usbotg: usbotggrp {
- fsl,pins = <
- MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b1
- >;
- };
-
- pinctrl_usdhc3: usdhc3grp {
- fsl,pins = <
- MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
- MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
- MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
- MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
- MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
- MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
- MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x100b1
- >;
- };
-
- pinctrl_wdog: wdoggrp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_9__WDOG1_B 0x1b0b0
- >;
- };
-};
diff --git a/arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi b/arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi
new file mode 100644
index 00000000000..41111b1a95a
--- /dev/null
+++ b/arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ */
+
+#include "imx93-u-boot.dtsi"
+
+/ {
+ wdt-reboot {
+ compatible = "wdt-reboot";
+ wdt = <&wdog3>;
+ bootph-pre-ram;
+ bootph-some-ram;
+ };
+};
+
+&A55_0 {
+ clocks = <&clk IMX93_CLK_A55_SEL>;
+};
+
+&A55_1 {
+ clocks = <&clk IMX93_CLK_A55_SEL>;
+};
+
+&{/soc@0} {
+ bootph-all;
+ bootph-pre-ram;
+};
+
+&aips1 {
+ bootph-pre-ram;
+ bootph-all;
+};
+
+&aips2 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&aips3 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&iomuxc {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&reg_usdhc2_vmmc {
+ u-boot,off-on-delay-us = <20000>;
+ bootph-pre-ram;
+};
+
+&pinctrl_reg_usdhc2_vmmc {
+ bootph-pre-ram;
+};
+
+&pinctrl_uart1 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&pinctrl_usdhc1 {
+ bootph-pre-ram;
+};
+
+&pinctrl_usdhc2_gpio {
+ bootph-pre-ram;
+};
+
+&pinctrl_usdhc2 {
+ bootph-pre-ram;
+};
+
+&gpio1 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&gpio2 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&gpio3 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&gpio4 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&lpuart1 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&usdhc1 {
+ bootph-pre-ram;
+};
+
+&usdhc2 {
+ bootph-pre-ram;
+ fsl,signal-voltage-switch-extra-delay-ms = <8>;
+};
+
+&lpi2c1 {
+ bootph-pre-ram;
+};
+
+&lpi2c2 {
+ bootph-pre-ram;
+};
+
+&lpi2c3 {
+ bootph-pre-ram;
+};
+
+&{/soc@0/bus@44000000/i2c@44350000/pmic@25} {
+ bootph-pre-ram;
+};
+
+&{/soc@0/bus@44000000/i2c@44350000/pmic@25/regulators} {
+ bootph-pre-ram;
+};
+
+&pinctrl_lpi2c2 {
+ bootph-pre-ram;
+};
+
+&pinctrl_lpi2c3 {
+ bootph-pre-ram;
+};
+
+&fec {
+ phy-reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>;
+ phy-reset-duration = <15>;
+ phy-reset-post-delay = <100>;
+};
+
+&ethphy1 {
+ reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <15000>;
+ reset-deassert-us = <100000>;
+};
+
+&usbotg1 {
+ status = "okay";
+ extcon = <&ptn5110>;
+};
+
+&usbotg2 {
+ status = "okay";
+};
+
+&s4muap {
+ bootph-pre-ram;
+ bootph-some-ram;
+ status = "okay";
+};
+
+&clk {
+ bootph-all;
+ bootph-pre-ram;
+ /delete-property/ assigned-clocks;
+ /delete-property/ assigned-clock-rates;
+ /delete-property/ assigned-clock-parents;
+};
+
+&osc_32k {
+ bootph-all;
+ bootph-pre-ram;
+};
+
+&osc_24m {
+ bootph-all;
+ bootph-pre-ram;
+};
+
+&clk_ext1 {
+ bootph-all;
+ bootph-pre-ram;
+};
diff --git a/arch/arm/dts/imx93-11x11-frdm.dts b/arch/arm/dts/imx93-11x11-frdm.dts
new file mode 100644
index 00000000000..993567e767d
--- /dev/null
+++ b/arch/arm/dts/imx93-11x11-frdm.dts
@@ -0,0 +1,603 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/dts-v1/;
+
+#include <dt-bindings/usb/pd.h>
+#include "imx93.dtsi"
+
+/ {
+ compatible = "fsl,imx93-11x11-frdm", "fsl,imx93";
+ model = "NXP i.MX93 11X11 FRDM board";
+
+ aliases {
+ mmc0 = &usdhc1; /* EMMC */
+ mmc1 = &usdhc2; /* uSD */
+ rtc0 = &pcf2131;
+ serial0 = &lpuart1;
+ };
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ reg_vref_1v8: regulator-adc-vref {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vref_1v8";
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ off-on-delay-us = <12000>;
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+ pinctrl-names = "default";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "VSD_3V3";
+ gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usdhc3_vmmc: regulator-usdhc3 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "WLAN_EN";
+ gpio = <&pcal6524 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ /*
+ * IW612 wifi chip needs more delay than other wifi chips to complete
+ * the host interface initialization after power up, otherwise the
+ * internal state of IW612 may be unstable, resulting in the failure of
+ * the SDIO3.0 switch voltage.
+ */
+ startup-delay-us = <20000>;
+ };
+
+ reserved-memory {
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x80000000 0 0x30000000>;
+ reusable;
+ size = <0 0x10000000>;
+ linux,cma-default;
+ };
+
+ rsc_table: rsc-table@2021e000 {
+ reg = <0 0x2021e000 0 0x1000>;
+ no-map;
+ };
+
+ vdev0vring0: vdev0vring0@a4000000 {
+ reg = <0 0xa4000000 0 0x8000>;
+ no-map;
+ };
+
+ vdev0vring1: vdev0vring1@a4008000 {
+ reg = <0 0xa4008000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring0: vdev1vring0@a4010000 {
+ reg = <0 0xa4010000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring1: vdev1vring1@a4018000 {
+ reg = <0 0xa4018000 0 0x8000>;
+ no-map;
+ };
+
+ vdevbuffer: vdevbuffer@a4020000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0xa4020000 0 0x100000>;
+ no-map;
+ };
+ };
+
+ usdhc3_pwrseq: usdhc3_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&pcal6524 12 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&adc1 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&eqos {
+ phy-handle = <&ethphy1>;
+ phy-mode = "rgmii-id";
+ pinctrl-0 = <&pinctrl_eqos>;
+ pinctrl-1 = <&pinctrl_eqos_sleep>;
+ pinctrl-names = "default", "sleep";
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <5000000>;
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&fec {
+ phy-handle = <&ethphy2>;
+ phy-mode = "rgmii-id";
+ pinctrl-0 = <&pinctrl_fec>;
+ pinctrl-1 = <&pinctrl_fec_sleep>;
+ pinctrl-names = "default", "sleep";
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <5000000>;
+
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ eee-broken-1000t;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&lpi2c2 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ pcal6524: gpio@22 {
+ compatible = "nxp,pcal6524";
+ reg = <0x22>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ pinctrl-0 = <&pinctrl_pcal6524>;
+ pinctrl-names = "default";
+ };
+
+ pmic@25 {
+ compatible = "nxp,pca9451a";
+ reg = <0x25>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+
+ regulators {
+
+ buck1: BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <2237500>;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck4: BUCK4 {
+ regulator-name = "BUCK4";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ buck5: BUCK5 {
+ regulator-name = "BUCK5";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ buck6: BUCK6 {
+ regulator-name = "BUCK6";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ ldo1: LDO1 {
+ regulator-name = "LDO1";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo4: LDO4 {
+ regulator-name = "LDO4";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo5: LDO5 {
+ regulator-name = "LDO5";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ pagesize = <64>;
+ };
+};
+
+&lpi2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ pinctrl-0 = <&pinctrl_lpi2c3>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ ptn5110: tcpc@50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+ typec1_con: connector {
+ compatible = "usb-c-connector";
+ data-role = "dual";
+ label = "USB-C";
+ op-sink-microwatt = <15000000>;
+ power-role = "dual";
+ self-powered;
+ sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+ PDO_VAR(5000, 20000, 3000)>;
+ source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ try-power-role = "sink";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ typec1_dr_sw: endpoint {
+ remote-endpoint = <&usb1_drd_sw>;
+ };
+ };
+ };
+ };
+ };
+
+ pcf2131: rtc@53 {
+ compatible = "nxp,pcf2131";
+ reg = <0x53>;
+ interrupt-parent = <&pcal6524>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&lpuart1 { /* console */
+ pinctrl-0 = <&pinctrl_uart1>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&usbotg1 {
+ adp-disable;
+ disable-over-current;
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ usb-role-switch;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ status = "okay";
+
+ port {
+
+ usb1_drd_sw: endpoint {
+ remote-endpoint = <&typec1_dr_sw>;
+ };
+ };
+};
+
+&usbotg2 {
+ disable-over-current;
+ dr_mode = "host";
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ status = "okay";
+};
+
+&usdhc1 {
+ bus-width = <8>;
+ non-removable;
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ status = "okay";
+};
+
+&usdhc2 {
+ bus-width = <4>;
+ cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
+ no-mmc;
+ no-sdio;
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&wdog3 {
+ status = "okay";
+};
+
+&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 0x58e
+ 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 0x58e
+ MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e
+ >;
+ };
+
+ pinctrl_eqos_sleep: eqossleepgrp {
+ fsl,pins = <
+ MX93_PAD_ENET1_MDC__GPIO4_IO00 0x31e
+ MX93_PAD_ENET1_MDIO__GPIO4_IO01 0x31e
+ MX93_PAD_ENET1_RD0__GPIO4_IO10 0x31e
+ MX93_PAD_ENET1_RD1__GPIO4_IO11 0x31e
+ MX93_PAD_ENET1_RD2__GPIO4_IO12 0x31e
+ MX93_PAD_ENET1_RD3__GPIO4_IO13 0x31e
+ MX93_PAD_ENET1_RXC__GPIO4_IO09 0x31e
+ MX93_PAD_ENET1_RX_CTL__GPIO4_IO08 0x31e
+ MX93_PAD_ENET1_TD0__GPIO4_IO05 0x31e
+ MX93_PAD_ENET1_TD1__GPIO4_IO04 0x31e
+ MX93_PAD_ENET1_TD2__GPIO4_IO03 0x31e
+ MX93_PAD_ENET1_TD3__GPIO4_IO02 0x31e
+ MX93_PAD_ENET1_TXC__GPIO4_IO07 0x31e
+ MX93_PAD_ENET1_TX_CTL__GPIO4_IO06 0x31e
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX93_PAD_ENET2_MDC__ENET1_MDC 0x57e
+ MX93_PAD_ENET2_MDIO__ENET1_MDIO 0x57e
+ MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x57e
+ MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e
+ MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x57e
+ MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x57e
+ MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x58e
+ MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e
+ MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x57e
+ MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x57e
+ MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x57e
+ MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x57e
+ MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x58e
+ MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x57e
+ >;
+ };
+
+ pinctrl_fec_sleep: fecsleepgrp {
+ fsl,pins = <
+ MX93_PAD_ENET2_MDC__GPIO4_IO14 0x51e
+ MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x51e
+ MX93_PAD_ENET2_RD0__GPIO4_IO24 0x51e
+ MX93_PAD_ENET2_RD1__GPIO4_IO25 0x51e
+ MX93_PAD_ENET2_RD2__GPIO4_IO26 0x51e
+ MX93_PAD_ENET2_RD3__GPIO4_IO27 0x51e
+ MX93_PAD_ENET2_RXC__GPIO4_IO23 0x51e
+ MX93_PAD_ENET2_RX_CTL__GPIO4_IO22 0x51e
+ MX93_PAD_ENET2_TD0__GPIO4_IO19 0x51e
+ MX93_PAD_ENET2_TD1__GPIO4_IO18 0x51e
+ MX93_PAD_ENET2_TD2__GPIO4_IO17 0x51e
+ MX93_PAD_ENET2_TD3__GPIO4_IO16 0x51e
+ MX93_PAD_ENET2_TXC__GPIO4_IO21 0x51e
+ MX93_PAD_ENET2_TX_CTL__GPIO4_IO20 0x51e
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO25__CAN2_TX 0x139e
+ MX93_PAD_GPIO_IO27__CAN2_RX 0x139e
+ >;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <
+ MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e
+ MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_lpi2c3: lpi2c3grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e
+ MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e
+ >;
+ };
+
+ pinctrl_pcal6524: pcal6524grp {
+ fsl,pins = <
+ MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX93_PAD_UART1_RXD__LPUART1_RX 0x31e
+ MX93_PAD_UART1_TXD__LPUART1_TX 0x31e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x1582
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x40001382
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x40001382
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x40001382
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x40001382
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x40001382
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x40001382
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x40001382
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x40001382
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x40001382
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1582
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x158e
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000138e
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000138e
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000138e
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000138e
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000138e
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000138e
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000138e
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000138e
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x158e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2_gpio_sleep: usdhc2gpiosleepgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x51e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ pinctrl_usdhc2_sleep: usdhc2-sleepgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__GPIO3_IO01 0x51e
+ MX93_PAD_SD2_CMD__GPIO3_IO02 0x51e
+ MX93_PAD_SD2_DATA0__GPIO3_IO03 0x51e
+ MX93_PAD_SD2_DATA1__GPIO3_IO04 0x51e
+ MX93_PAD_SD2_DATA2__GPIO3_IO05 0x51e
+ MX93_PAD_SD2_DATA3__GPIO3_IO06 0x51e
+ MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e
+ >;
+ };
+};
diff --git a/arch/arm/dts/imx95-u-boot.dtsi b/arch/arm/dts/imx95-u-boot.dtsi
index 5ec3b1c51d6..9bf8f9834c9 100644
--- a/arch/arm/dts/imx95-u-boot.dtsi
+++ b/arch/arm/dts/imx95-u-boot.dtsi
@@ -22,12 +22,12 @@
type = "nxp-header-ddrfw";
imx-lpddr-imem {
- filename = "lpddr5_imem_v202311.bin";
+ filename = "lpddr5_imem_v202409.bin";
type = "blob-ext";
};
imx-lpddr-dmem {
- filename = "lpddr5_dmem_v202311.bin";
+ filename = "lpddr5_dmem_v202409.bin";
type = "blob-ext";
};
};
@@ -36,12 +36,12 @@
type = "nxp-header-ddrfw";
imx-lpddr-imem-qb {
- filename = "lpddr5_imem_qb_v202311.bin";
+ filename = "lpddr5_imem_qb_v202409.bin";
type = "blob-ext";
};
imx-lpddr-dmem-qb {
- filename = "lpddr5_dmem_qb_v202311.bin";
+ filename = "lpddr5_dmem_qb_v202409.bin";
type = "blob-ext";
};
};
diff --git a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
index 6deebdadf09..a9bd5a2be84 100644
--- a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
+++ b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
@@ -25,7 +25,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -69,7 +69,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -105,7 +105,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/k3-am625-sk-binman.dtsi b/arch/arm/dts/k3-am625-sk-binman.dtsi
index 6822a5dac89..f743c4353b4 100644
--- a/arch/arm/dts/k3-am625-sk-binman.dtsi
+++ b/arch/arm/dts/k3-am625-sk-binman.dtsi
@@ -23,7 +23,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -67,7 +67,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -103,7 +103,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi b/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi
index bfbba28269c..65fef6e4790 100644
--- a/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi
+++ b/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi
@@ -23,7 +23,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -67,7 +67,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -103,7 +103,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/k3-am62a-phycore-som-binman.dtsi b/arch/arm/dts/k3-am62a-phycore-som-binman.dtsi
index fd340101532..9bcdf74ffe4 100644
--- a/arch/arm/dts/k3-am62a-phycore-som-binman.dtsi
+++ b/arch/arm/dts/k3-am62a-phycore-som-binman.dtsi
@@ -30,7 +30,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -74,7 +74,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -110,7 +110,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/k3-am62a-sk-binman.dtsi b/arch/arm/dts/k3-am62a-sk-binman.dtsi
index 877a513a241..0685bdd7e0c 100644
--- a/arch/arm/dts/k3-am62a-sk-binman.dtsi
+++ b/arch/arm/dts/k3-am62a-sk-binman.dtsi
@@ -27,7 +27,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -71,7 +71,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c3a800>;
@@ -107,7 +107,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/k3-am62p-sk-binman.dtsi b/arch/arm/dts/k3-am62p-sk-binman.dtsi
index d65e5c4d4e1..feb59edcd83 100644
--- a/arch/arm/dts/k3-am62p-sk-binman.dtsi
+++ b/arch/arm/dts/k3-am62p-sk-binman.dtsi
@@ -25,7 +25,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c4a800>;
@@ -72,7 +72,7 @@
content-sysfw-data = <&combined_tifs_cfg_hs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_hs>;
content-dm-data = <&combined_dm_cfg_hs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c4a800>;
diff --git a/arch/arm/dts/k3-am62p5-verdin-wifi-dev-binman.dtsi b/arch/arm/dts/k3-am62p5-verdin-wifi-dev-binman.dtsi
index 13fac18d7aa..b1591faaf0a 100644
--- a/arch/arm/dts/k3-am62p5-verdin-wifi-dev-binman.dtsi
+++ b/arch/arm/dts/k3-am62p5-verdin-wifi-dev-binman.dtsi
@@ -25,7 +25,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c4a800>;
@@ -74,7 +74,7 @@
content-sysfw-data = <&combined_tifs_cfg_hs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_hs>;
content-dm-data = <&combined_dm_cfg_hs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c4a800>;
diff --git a/arch/arm/dts/k3-am65-iot2050-boot-image.dtsi b/arch/arm/dts/k3-am65-iot2050-boot-image.dtsi
index f49d6f262f2..b3d64485249 100644
--- a/arch/arm/dts/k3-am65-iot2050-boot-image.dtsi
+++ b/arch/arm/dts/k3-am65-iot2050-boot-image.dtsi
@@ -208,7 +208,7 @@
fit,fdt-list-val = "ti/k3-am6528-iot2050-basic", "ti/k3-am6548-iot2050-advanced";
configurations {
- default = "ti/k3-am6528-iot2050-basic";
+ default = "config-1";
@config-SEQ {
loadables =
#ifdef CONFIG_WDT_K3_RTI_FW_FILE
@@ -265,7 +265,7 @@
};
configurations {
- default = "ti/k3-am6528-iot2050-basic-pg2";
+ default = "config-1";
@config-SEQ {
loadables =
#ifdef CONFIG_WDT_K3_RTI_FW_FILE
diff --git a/arch/arm/dts/k3-am67a-beagley-ai-u-boot.dtsi b/arch/arm/dts/k3-am67a-beagley-ai-u-boot.dtsi
index 2a0023fb7c3..0e810e7f492 100644
--- a/arch/arm/dts/k3-am67a-beagley-ai-u-boot.dtsi
+++ b/arch/arm/dts/k3-am67a-beagley-ai-u-boot.dtsi
@@ -75,7 +75,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c7a800>;
@@ -125,7 +125,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c7a800>;
diff --git a/arch/arm/dts/k3-j7200-binman.dtsi b/arch/arm/dts/k3-j7200-binman.dtsi
index b74bd1657f9..b4e0ce8bfcf 100644
--- a/arch/arm/dts/k3-j7200-binman.dtsi
+++ b/arch/arm/dts/k3-j7200-binman.dtsi
@@ -24,7 +24,7 @@
content-sysfw-data = <&combined_tifs_cfg_sr1>;
content-sysfw-inner-cert = <&sysfw_inner_cert_sr1>;
content-dm-data = <&combined_dm_cfg_sr1>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x7f000>;
load-dm-data = <0x41c80000>;
@@ -67,7 +67,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x7f000>;
load-dm-data = <0x41c80000>;
@@ -112,7 +112,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs_sr1>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs_sr1>;
content-dm-data = <&combined_dm_cfg_fs_sr1>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x7f000>;
load-dm-data = <0x41c80000>;
@@ -155,7 +155,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x7f000>;
load-dm-data = <0x41c80000>;
@@ -192,7 +192,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/k3-j721s2-binman.dtsi b/arch/arm/dts/k3-j721s2-binman.dtsi
index 4f524e58ceb..f79b3e543ae 100644
--- a/arch/arm/dts/k3-j721s2-binman.dtsi
+++ b/arch/arm/dts/k3-j721s2-binman.dtsi
@@ -23,7 +23,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x41c80000>;
@@ -66,7 +66,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x41c80000>;
@@ -103,7 +103,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/k3-j722s-binman.dtsi b/arch/arm/dts/k3-j722s-binman.dtsi
index 57e966ea666..278b7bfac7f 100644
--- a/arch/arm/dts/k3-j722s-binman.dtsi
+++ b/arch/arm/dts/k3-j722s-binman.dtsi
@@ -23,7 +23,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c7a800>;
@@ -73,7 +73,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x43c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x67000>;
load-dm-data = <0x43c7a800>;
diff --git a/arch/arm/dts/k3-j784s4-binman.dtsi b/arch/arm/dts/k3-j784s4-binman.dtsi
index a7ce1ee2b03..34b2cc1e681 100644
--- a/arch/arm/dts/k3-j784s4-binman.dtsi
+++ b/arch/arm/dts/k3-j784s4-binman.dtsi
@@ -27,7 +27,7 @@
content-sysfw-data = <&combined_tifs_cfg>;
content-sysfw-inner-cert = <&sysfw_inner_cert>;
content-dm-data = <&combined_dm_cfg>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x66800>;
load-dm-data = <0x41c80000>;
@@ -74,7 +74,7 @@
content-sysfw-data = <&combined_tifs_cfg_fs>;
content-sysfw-inner-cert = <&sysfw_inner_cert_fs>;
content-dm-data = <&combined_dm_cfg_fs>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
load-sysfw = <0x40000>;
load-sysfw-data = <0x66800>;
load-dm-data = <0x41c80000>;
@@ -114,7 +114,7 @@
combined;
dm-data;
content-sbl = <&u_boot_spl_unsigned>;
- load = <0x41c00000>;
+ load = <CONFIG_SPL_TEXT_BASE>;
content-sysfw = <&ti_fs_gp>;
load-sysfw = <0x40000>;
content-sysfw-data = <&combined_tifs_cfg_gp>;
diff --git a/arch/arm/dts/ls1021a-pg-wcom-expu1.dts b/arch/arm/dts/ls1021a-pg-wcom-expu1.dts
index ec8e7dee271..1068f1a288a 100644
--- a/arch/arm/dts/ls1021a-pg-wcom-expu1.dts
+++ b/arch/arm/dts/ls1021a-pg-wcom-expu1.dts
@@ -51,6 +51,26 @@
&i2c0 {
status = "okay";
+
+ pca9547@70 {
+ compatible = "nxp,pca9547";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ivm@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ label = "MAIN_CTRL";
+ };
+ };
+ };
};
&dspi1 {
diff --git a/arch/arm/dts/ls1021a-pg-wcom-seli8.dts b/arch/arm/dts/ls1021a-pg-wcom-seli8.dts
index 03ce3ab4e47..3e8c54d83c9 100644
--- a/arch/arm/dts/ls1021a-pg-wcom-seli8.dts
+++ b/arch/arm/dts/ls1021a-pg-wcom-seli8.dts
@@ -44,6 +44,26 @@
&i2c0 {
status = "okay";
+
+ pca9547@70 {
+ compatible = "nxp,pca9547";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ivm@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ label = "MAIN_CTRL";
+ };
+ };
+ };
};
&ifc {
diff --git a/arch/arm/dts/zynqmp-binman-som.dts b/arch/arm/dts/zynqmp-binman-som.dts
index a70123feead..469b94bbde6 100644
--- a/arch/arm/dts/zynqmp-binman-som.dts
+++ b/arch/arm/dts/zynqmp-binman-som.dts
@@ -20,7 +20,6 @@
binman: binman {
multiple-images;
-#ifdef CONFIG_SPL
fit-dtb.blob {
filename = "fit-dtb.blob";
pad-byte = <0>;
@@ -109,6 +108,7 @@
};
};
+#ifdef CONFIG_SPL
/* Generation in a static way */
itb {
filename = U_BOOT_ITB_FILENAME;
diff --git a/arch/arm/include/asm/arch-imx9/ddr.h b/arch/arm/include/asm/arch-imx9/ddr.h
index 0dd2d62b9ef..a8e3f7354c7 100644
--- a/arch/arm/include/asm/arch-imx9/ddr.h
+++ b/arch/arm/include/asm/arch-imx9/ddr.h
@@ -118,6 +118,7 @@ void ddrphy_init_set_dfi_clk(unsigned int drate);
void ddrphy_init_read_msg_block(enum fw_type type);
void get_trained_CDD(unsigned int fsp);
+u32 lpddr4_mr_read(u32 mr_rank, u32 mr_addr);
ulong ddrphy_addr_remap(u32 paddr_apb_from_ctlr);
diff --git a/arch/arm/include/asm/arch-mx27/imx-regs.h b/arch/arm/include/asm/arch-mx27/imx-regs.h
index 60499189b2c..a9152814245 100644
--- a/arch/arm/include/asm/arch-mx27/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx27/imx-regs.h
@@ -21,11 +21,6 @@ extern void mx27_uart1_init_pins(void);
extern void mx27_fec_init_pins(void);
#endif /* CONFIG_FEC_MXC */
-#ifdef CONFIG_MMC_MXC
-extern void mx27_sd1_init_pins(void);
-extern void mx27_sd2_init_pins(void);
-#endif /* CONFIG_MMC_MXC */
-
/* AIPI */
struct aipi_regs {
u32 psr0;
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
index 575dff68804..45fa4ab6e57 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
@@ -13,6 +13,7 @@
#include <linux/bitops.h>
#endif
+/* Main CCU register offsets */
#define CCU_H6_PLL1_CFG 0x000
#define CCU_H6_PLL5_CFG 0x010
#define CCU_H6_PLL6_CFG 0x020
@@ -31,29 +32,39 @@
#define CCU_H6_UART_GATE_RESET 0x90c
#define CCU_H6_I2C_GATE_RESET 0x91c
-/* pll1 bit field */
-#define CCM_PLL1_CTRL_EN BIT(31)
-#define CCM_PLL1_LDO_EN BIT(30)
-#define CCM_PLL1_LOCK_EN BIT(29)
-#define CCM_PLL1_LOCK BIT(28)
-#define CCM_PLL1_OUT_EN BIT(27)
-#define CCM_PLL1_CLOCK_TIME_2 (2 << 24)
+/* A523 CPU PLL offsets */
+#define CPC_CPUA_PLL_CTRL 0x04
+#define CPC_DSU_PLL_CTRL 0x08
+#define CPC_CPUB_PLL_CTRL 0x0c
+#define CPC_CPUA_CLK_REG 0x60
+#define CPC_CPUB_CLK_REG 0x64
+#define CPC_DSU_CLK_REG 0x6c
+
+/* PLL bit fields */
+#define CCM_PLL_CTRL_EN BIT(31)
+#define CCM_PLL_LDO_EN BIT(30)
+#define CCM_PLL_LOCK_EN BIT(29)
+#define CCM_PLL_LOCK BIT(28)
+#define CCM_PLL_OUT_EN BIT(27)
+#define CCM_PLL1_UPDATE BIT(26)
#define CCM_PLL1_CTRL_P(p) ((p) << 16)
+#define CCM_PLL1_CTRL_N_MASK GENMASK(15, 8)
#define CCM_PLL1_CTRL_N(n) (((n) - 1) << 8)
+/* A523 CPU clock fields */
+#define CPU_CLK_SRC_HOSC (0 << 24)
+#define CPU_CLK_SRC_CPUPLL (3 << 24)
+#define CPU_CLK_CTRL_P(p) ((p) << 16)
+#define CPU_CLK_APB_DIV(n) (((n) - 1) << 8)
+#define CPU_CLK_PERI_DIV(m1) (((m1) - 1) << 2)
+#define CPU_CLK_AXI_DIV(m) (((m) - 1) << 0)
+
/* pll5 bit field */
-#define CCM_PLL5_CTRL_EN BIT(31)
-#define CCM_PLL5_LOCK_EN BIT(29)
-#define CCM_PLL5_LOCK BIT(28)
-#define CCM_PLL5_OUT_EN BIT(27)
#define CCM_PLL5_CTRL_N(n) (((n) - 1) << 8)
#define CCM_PLL5_CTRL_DIV1(div1) ((div1) << 0)
#define CCM_PLL5_CTRL_DIV2(div0) ((div0) << 1)
/* pll6 bit field */
-#define CCM_PLL6_CTRL_EN BIT(31)
-#define CCM_PLL6_LOCK_EN BIT(29)
-#define CCM_PLL6_LOCK BIT(28)
#define CCM_PLL6_CTRL_P0_SHIFT 16
#define CCM_PLL6_CTRL_P0_MASK (0x7 << CCM_PLL6_CTRL_P0_SHIFT)
#define CCM_PLL6_CTRL_N_SHIFT 8
@@ -97,6 +108,13 @@
#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002
#define CCM_AHB3_DEFAULT 0x03000002
#define CCM_APB1_DEFAULT 0x03000102
+
+#elif CONFIG_MACH_SUN55I_A523 /* A523 */
+
+#define CCM_PLL6_DEFAULT 0xe8216310 /* 1200 MHz */
+#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 /* 200 MHz */
+#define CCM_APB1_DEFAULT 0x03000005 /* APB0 really */
+#define CCM_APB2_DEFAULT 0x03000005 /* APB1 really */
#endif
/* apb2 bit field */
@@ -116,6 +134,7 @@
/* MBUS clock bit field */
#define MBUS_ENABLE BIT(31)
#define MBUS_RESET BIT(30)
+#define MBUS_UPDATE BIT(27)
#define MBUS_CLK_SRC_MASK GENMASK(25, 24)
#define MBUS_CLK_SRC_OSCM24 (0 << 24)
#define MBUS_CLK_SRC_PLL6X2 (1 << 24)
@@ -128,10 +147,12 @@
#define GATE_SHIFT (0)
/* DRAM clock bit field */
+#define DRAM_CLK_ENABLE BIT(31)
#define DRAM_MOD_RESET BIT(30)
#define DRAM_CLK_UPDATE BIT(27)
#define DRAM_CLK_SRC_MASK GENMASK(25, 24)
#define DRAM_CLK_SRC_PLL5 (0 << 24)
+#define DRAM_CLK_M_MASK (0x1f)
#define DRAM_CLK_M(m) (((m)-1) << 0)
/* MMC clock bit field */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
index 908a582ae0f..bcfdc0a41c5 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
@@ -21,14 +21,34 @@
#define SUNXI_SID_BASE 0x03006200
#define SUNXI_GIC400_BASE 0x03020000
+#ifdef CONFIG_MACH_SUN55I_A523
+#define SUNXI_DRAM_COM_BASE 0x03120000
+#define SUNXI_DRAM_CTL0_BASE 0x03130000
+#define SUNXI_DRAM_PHY0_BASE 0x03140000
+#endif
+
#define SUNXI_MMC0_BASE 0x04020000
#define SUNXI_MMC1_BASE 0x04021000
#define SUNXI_MMC2_BASE 0x04022000
+#ifndef CONFIG_MACH_SUN55I_A523
#define SUNXI_R_CPUCFG_BASE 0x07000400
+#endif
#define SUNXI_PRCM_BASE 0x07010000
+#define SUNXI_R_WDOG_BASE 0x07020400
+#ifdef CONFIG_MACH_SUN55I_A523
+#define SUNXI_R_CPUCFG_BASE 0x07050000
+#endif
+#define SUNXI_R_TWI_BASE 0x07081400
+#define SUNXI_RTC_BASE 0x07090000
+#ifdef CONFIG_MACH_SUN55I_A523
+#define SUNXI_CPUCFG_BASE 0x08815000
+#else
#define SUNXI_CPUCFG_BASE 0x09010000
+#endif
+
+#define SUNXI_CPU_PLL_CFG_BASE 0x08817000
#ifndef __ASSEMBLY__
void sunxi_board_init(void);
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
index 0708ae3ee3b..0eccb1e6c28 100644
--- a/arch/arm/include/asm/arch-sunxi/dram.h
+++ b/arch/arm/include/asm/arch-sunxi/dram.h
@@ -35,6 +35,8 @@
#include <asm/arch/dram_sun50i_a133.h>
#elif defined(CONFIG_MACH_SUNIV)
#include <asm/arch/dram_suniv.h>
+#elif defined(CONFIG_MACH_SUN55I_A523)
+#include <asm/arch/dram_sun55i_a523.h>
#else
#include <asm/arch/dram_sun4i.h>
#endif
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h b/arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h
new file mode 100644
index 00000000000..08bfe462856
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * t527 dram controller register and constant defines
+ *
+ * (C) Copyright 2024 Jernej Skrabec <jernej.skrabec@gmail.com>
+ */
+
+#ifndef _SUNXI_DRAM_SUN55I_A523_H
+#define _SUNXI_DRAM_SUN55I_A523_H
+
+#include <linux/bitops.h>
+
+enum sunxi_dram_type {
+ SUNXI_DRAM_TYPE_DDR3 = 3,
+ SUNXI_DRAM_TYPE_DDR4,
+ SUNXI_DRAM_TYPE_LPDDR3 = 7,
+ SUNXI_DRAM_TYPE_LPDDR4
+};
+
+#define MCTL_COM_UNK_008 0x008
+#define MCTL_COM_MAER0 0x020
+
+/*
+ * Controller registers seems to be the same or at least very similar
+ * to those in H6.
+ */
+struct sunxi_mctl_ctl_reg {
+ u32 mstr; /* 0x000 */
+ u32 statr; /* 0x004 unused */
+ u32 mstr1; /* 0x008 unused */
+ u32 clken; /* 0x00c */
+ u32 mrctrl0; /* 0x010 unused */
+ u32 mrctrl1; /* 0x014 unused */
+ u32 mrstatr; /* 0x018 unused */
+ u32 mrctrl2; /* 0x01c unused */
+ u32 derateen; /* 0x020 unused */
+ u32 derateint; /* 0x024 unused */
+ u8 reserved_0x028[8]; /* 0x028 */
+ u32 pwrctl; /* 0x030 */
+ u32 pwrtmg; /* 0x034 unused */
+ u32 hwlpctl; /* 0x038 */
+ u8 reserved_0x03c[20]; /* 0x03c */
+ u32 rfshctl0; /* 0x050 unused */
+ u32 rfshctl1; /* 0x054 unused */
+ u8 reserved_0x058[8]; /* 0x058 */
+ u32 rfshctl3; /* 0x060 */
+ u32 rfshtmg; /* 0x064 */
+ u8 reserved_0x068[104]; /* 0x068 */
+ u32 init[8]; /* 0x0d0 */
+ u32 dimmctl; /* 0x0f0 unused */
+ u32 rankctl; /* 0x0f4 */
+ u8 reserved_0x0f8[8]; /* 0x0f8 */
+ u32 dramtmg[17]; /* 0x100 */
+ u8 reserved_0x144[60]; /* 0x144 */
+ u32 zqctl[3]; /* 0x180 */
+ u32 zqstat; /* 0x18c unused */
+ u32 dfitmg0; /* 0x190 */
+ u32 dfitmg1; /* 0x194 */
+ u32 dfilpcfg[2]; /* 0x198 unused */
+ u32 dfiupd[3]; /* 0x1a0 */
+ u32 reserved_0x1ac; /* 0x1ac */
+ u32 dfimisc; /* 0x1b0 */
+ u32 dfitmg2; /* 0x1b4 unused */
+ u32 dfitmg3; /* 0x1b8 unused */
+ u32 dfistat; /* 0x1bc */
+ u32 dbictl; /* 0x1c0 */
+ u8 reserved_0x1c4[60]; /* 0x1c4 */
+ u32 addrmap[12]; /* 0x200 */
+ u8 reserved_0x230[16]; /* 0x230 */
+ u32 odtcfg; /* 0x240 */
+ u32 odtmap; /* 0x244 */
+ u8 reserved_0x248[8]; /* 0x248 */
+ u32 sched[2]; /* 0x250 */
+ u8 reserved_0x258[12]; /* 0x258 */
+ u32 unk_0x264; /* 0x264 */
+ u8 reserved_0x268[8]; /* 0x268 */
+ u32 unk_0x270; /* 0x270 */
+ u8 reserved_0x274[152]; /* 0x274 */
+ u32 dbgcmd; /* 0x30c unused */
+ u32 dbgstat; /* 0x310 unused */
+ u8 reserved_0x314[12]; /* 0x314 */
+ u32 swctl; /* 0x320 */
+ u32 swstat; /* 0x324 */
+ u8 reserved_0x328[7768];/* 0x328 */
+ u32 unk_0x2180; /* 0x2180 */
+ u8 reserved_0x2184[188];/* 0x2184 */
+ u32 unk_0x2240; /* 0x2240 */
+ u8 reserved_0x2244[3900];/* 0x2244 */
+ u32 unk_0x3180; /* 0x3180 */
+ u8 reserved_0x3184[188];/* 0x3184 */
+ u32 unk_0x3240; /* 0x3240 */
+ u8 reserved_0x3244[3900];/* 0x3244 */
+ u32 unk_0x4180; /* 0x4180 */
+ u8 reserved_0x4184[188];/* 0x4184 */
+ u32 unk_0x4240; /* 0x4240 */
+};
+check_member(sunxi_mctl_ctl_reg, swstat, 0x324);
+check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
+
+#define MSTR_DEVICETYPE_DDR3 BIT(0)
+#define MSTR_DEVICETYPE_LPDDR2 BIT(2)
+#define MSTR_DEVICETYPE_LPDDR3 BIT(3)
+#define MSTR_DEVICETYPE_DDR4 BIT(4)
+#define MSTR_DEVICETYPE_LPDDR4 BIT(5)
+#define MSTR_DEVICETYPE_MASK GENMASK(5, 0)
+#define MSTR_2TMODE BIT(10)
+#define MSTR_BUSWIDTH_FULL (0 << 12)
+#define MSTR_BUSWIDTH_HALF (1 << 12)
+#define MSTR_ACTIVE_RANKS(x) ((((x) == 2) ? 3 : 1) << 24)
+#define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16)
+
+#define TPR10_CA_BIT_DELAY 0xffff0000
+#define TPR10_DX_BIT_DELAY0 BIT(17)
+#define TPR10_DX_BIT_DELAY1 BIT(18)
+#define TPR10_WRITE_LEVELING BIT(20)
+#define TPR10_READ_CALIBRATION BIT(21)
+#define TPR10_READ_TRAINING BIT(22)
+#define TPR10_WRITE_TRAINING BIT(23)
+
+struct dram_para {
+ enum sunxi_dram_type type;
+ u32 dx_odt;
+ u32 dx_dri;
+ u32 ca_dri;
+ u32 tpr0;
+ u32 tpr1;
+ u32 tpr2;
+ u32 tpr6;
+ u32 tpr10;
+};
+
+struct dram_config {
+ u8 cols;
+ u8 rows;
+ u8 ranks;
+ u8 bus_full_width;
+ u32 clk;
+ u32 odt_en;
+ u32 tpr11;
+ u32 tpr12;
+ u32 tpr14;
+};
+
+static inline int ns_to_t(int nanoseconds, u32 clk)
+{
+ const unsigned int ctrl_freq = clk / 2;
+
+ return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
+}
+
+void mctl_set_timing_params(u32 clk);
+
+#endif /* _SUNXI_DRAM_SUN55I_T527_H */
diff --git a/arch/arm/include/asm/arch-sunxi/watchdog.h b/arch/arm/include/asm/arch-sunxi/watchdog.h
index 38e2ef2aca3..14a6e89ccfa 100644
--- a/arch/arm/include/asm/arch-sunxi/watchdog.h
+++ b/arch/arm/include/asm/arch-sunxi/watchdog.h
@@ -12,6 +12,8 @@
#define WDT_CTRL_RESTART (0x1 << 0)
#define WDT_CTRL_KEY (0x0a57 << 1)
+#define WDT_SRST_REG 0x08
+
#if defined(CONFIG_MACH_SUN4I) || \
defined(CONFIG_MACH_SUN5I) || \
defined(CONFIG_MACH_SUN7I) || \
diff --git a/arch/arm/include/asm/mach-imx/ele_api.h b/arch/arm/include/asm/mach-imx/ele_api.h
index 19d12696a1e..64b243dcaaa 100644
--- a/arch/arm/include/asm/mach-imx/ele_api.h
+++ b/arch/arm/include/asm/mach-imx/ele_api.h
@@ -134,6 +134,8 @@ struct ele_get_info_data {
u32 sha_fw[8];
u32 oem_srkh[16];
u32 state;
+ u32 oem_pqc_srkh[16];
+ u32 reserved[8];
};
int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response);
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index d21534ce883..7d00f1650b4 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -52,6 +52,11 @@ config SAMA7G5
select CPU_V7A
select AT91RESET_EXTRST
+config SAMA7D65
+ bool
+ select CPU_V7A
+ select AT91RESET_EXTRST
+
config SAMA5D2
bool
select CPU_V7A
@@ -299,6 +304,13 @@ config TARGET_SAMA7G54_CURIOSITY
4Gbit SLC nand-flash, MCP16502 PMIC, 2 x Mikrobus connectors,
1 x SD-Card connector, 1 x M.2 slot, 3 x USB
+config TARGET_SAMA7D65_CURIOSITY
+ bool "SAMA7D65 CURIOSITY board"
+ select SAMA7D65
+ select BOARD_EARLY_INIT_F
+ select BOARD_LATE_INIT
+ imply OF_UPSTREAM
+
config TARGET_TAURUS
bool "Support taurus"
select AT91SAM9G20
@@ -365,6 +377,7 @@ source "board/atmel/sam9x60_curiosity/Kconfig"
source "board/atmel/sam9x75_curiosity/Kconfig"
source "board/atmel/sama7g5ek/Kconfig"
source "board/atmel/sama7g54_curiosity/Kconfig"
+source "board/atmel/sama7d65_curiosity/Kconfig"
source "board/atmel/sama5d2_ptc_ek/Kconfig"
source "board/atmel/sama5d2_xplained/Kconfig"
source "board/atmel/sama5d27_som1_ek/Kconfig"
diff --git a/arch/arm/mach-at91/armv7/Makefile b/arch/arm/mach-at91/armv7/Makefile
index 6da1cdffef6..4303a60e0e3 100644
--- a/arch/arm/mach-at91/armv7/Makefile
+++ b/arch/arm/mach-at91/armv7/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SAMA5D2) += sama5d2_devices.o clock.o
obj-$(CONFIG_SAMA5D3) += sama5d3_devices.o clock.o
obj-$(CONFIG_SAMA5D4) += sama5d4_devices.o clock.o
obj-$(CONFIG_SAMA7G5) += sama7g5_devices.o
+obj-$(CONFIG_SAMA7D65) += sama7d65_devices.o
obj-y += cpu.o
ifneq ($(CONFIG_ATMEL_TCB_TIMER),y)
ifneq ($(CONFIG_ATMEL_PIT_TIMER),y)
diff --git a/arch/arm/mach-at91/armv7/sama7d65_devices.c b/arch/arm/mach-at91/armv7/sama7d65_devices.c
new file mode 100644
index 00000000000..6c6ae751b1a
--- /dev/null
+++ b/arch/arm/mach-at91/armv7/sama7d65_devices.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Microchip Technology, Inc.
+ */
+
+#include <asm/arch/sama7d65.h>
+
+char *get_cpu_name(void)
+{
+ unsigned int extension_id = get_extension_chip_id();
+
+ if (cpu_is_sama7d65())
+ switch (extension_id) {
+ case ARCH_EXID_SAMA7D65:
+ return "SAMA7D65";
+ case ARCH_EXID_SAMA7D65_DD2:
+ return "SAMA7D65 DDR2";
+ case ARCH_EXID_SAMA7D65_D1G:
+ return "SAMA7D65 1Gb DDR3L SiP";
+ case ARCH_EXID_SAMA7D65_D2G:
+ return "SAMA7D65 2Gb DDR3L SiP";
+ case ARCH_EXID_SAMA7D65_D4G:
+ return "SAMA7D65 4Gb DDR3L SiP";
+ case ARCH_EXID_SAMA7D65_TA:
+ return "SAMA7D65 TA1000 SiP";
+ default:
+ return "Unknown CPU type";
+ }
+ else
+ return "Unknown CPU type10";
+}
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index de89714b097..0b2ddbab3be 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -27,6 +27,8 @@
# include <asm/arch/sam9x7.h>
#elif defined(CONFIG_SAMA7G5)
# include <asm/arch/sama7g5.h>
+#elif defined(CONFIG_SAMA7D65)
+# include <asm/arch/sama7d65.h>
#elif defined(CONFIG_SAMA5D2)
# include <asm/arch/sama5d2.h>
#elif defined(CONFIG_SAMA5D3)
diff --git a/arch/arm/mach-at91/include/mach/sama7d65.h b/arch/arm/mach-at91/include/mach/sama7d65.h
new file mode 100644
index 00000000000..8adc5c9a733
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sama7d65.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Chip-specific header file for the SAMA7D65 SoC
+ *
+ * Copyright (C) 2024 Microchip Technology, Inc. and its subsidiaries
+ */
+
+#ifndef __SAMA7D65_H__
+#define __SAMA7D65_H__
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define ATMEL_ID_FLEXCOM0 34
+#define ATMEL_ID_FLEXCOM1 35
+#define ATMEL_ID_FLEXCOM2 36
+#define ATMEL_ID_FLEXCOM3 37
+#define ATMEL_ID_FLEXCOM4 38
+#define ATMEL_ID_FLEXCOM5 39
+#define ATMEL_ID_FLEXCOM6 40
+#define ATMEL_ID_FLEXCOM7 41
+#define ATMEL_ID_FLEXCOM8 42
+
+#define ATMEL_ID_SDMMC0 75
+#define ATMEL_ID_SDMMC1 76
+#define ATMEL_ID_SDMMC2 77
+
+#define ATMEL_ID_PIT64B0 66
+#define ATMEL_ID_PIT64B ATMEL_ID_PIT64B0
+
+#define ATMEL_CHIPID_CIDR 0xe0020000
+#define ATMEL_CHIPID_EXID 0xe0020004
+/*
+ * User Peripherals physical base addresses.
+ */
+#define ATMEL_BASE_PIOA 0xe0014000
+#define ATMEL_BASE_PIOB (ATMEL_BASE_PIOA + 0x40)
+#define ATMEL_BASE_PIOC (ATMEL_BASE_PIOB + 0x40)
+#define ATMEL_BASE_PIOD (ATMEL_BASE_PIOC + 0x40)
+#define ATMEL_BASE_PIOE (ATMEL_BASE_PIOD + 0x40)
+
+#define ATMEL_PIO_PORTS 5
+
+#define CPU_HAS_PCR
+
+#define ATMEL_BASE_PMC 0xe0018000
+
+#define ATMEL_BASE_WDT 0xe001c000
+#define ATMEL_BASE_RSTC 0xe001d100
+#define ATMEL_BASE_WDTS 0xe001d180
+#define ATMEL_BASE_SCKCR 0xe001d500
+
+#define ATMEL_BASE_SDMMC0 0xe1204000
+#define ATMEL_BASE_SDMMC1 0xe1208000
+
+#define ATMEL_BASE_PIT64B0 0xe1800000
+
+#define ATMEL_BASE_FLEXCOM0 0xe1820000
+#define ATMEL_BASE_FLEXCOM1 0xe1824000
+#define ATMEL_BASE_FLEXCOM2 0xe1828000
+#define ATMEL_BASE_FLEXCOM3 0xe182c000
+#define ATMEL_BASE_FLEXCOM4 0xe2018000
+#define ATMEL_BASE_FLEXCOM5 0xe201C000
+#define ATMEL_BASE_FLEXCOM6 0xe2020000
+#define ATMEL_BASE_FLEXCOM7 0xe2024000
+#define ATMEL_BASE_FLEXCOM8 0xe281C000
+
+#define ATMEL_BASE_TZC400 0xe3000000
+
+#define ATMEL_BASE_UMCTL2 0xe3800000
+#define ATMEL_BASE_UMCTL2_MP 0xe38003f8
+#define ATMEL_BASE_PUBL 0xe3804000
+
+#define ATMEL_NUM_FLEXCOM 11
+#define ATMEL_PIO_PORTS 5
+
+#define ATMEL_BASE_PIT64BC ATMEL_BASE_PIT64B0
+
+#define ARCH_ID_SAMA7D65 0x80262100
+#define ARCH_EXID_SAMA7D65 0x00000080
+#define ARCH_EXID_SAMA7D65_DD2 0x00000010
+#define ARCH_EXID_SAMA7D65_D1G 0x00000018
+#define ARCH_EXID_SAMA7D65_D2G 0x00000020
+#define ARCH_EXID_SAMA7D65_D4G 0x00000028
+#define ARCH_EXID_SAMA7D65_TA 0x00000040
+
+#define cpu_is_sama7d65() (get_chip_id() == ARCH_ID_SAMA7D65)
+#define cpu_is_sama7d65_S() (cpu_is_sama7d65() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA7D65))
+#define cpu_is_sama7d65_DD2() (cpu_is_sama7d65() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA7D65_DD2))
+#define cpu_is_sama7d65_D1G() (cpu_is_sama7d65() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA7D65_D1G))
+#define cpu_is_sama7d65_D2G() (cpu_is_sama7d65() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA7D65_D2G))
+#define cpu_is_sama7d65_D4G() (cpu_is_sama7d65() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA7D65_D4G))
+#define cpu_is_sama7d65_TA() (cpu_is_sama7d65() && \
+ (get_extension_chip_id() == ARCH_EXID_SAMA7D65_TA))
+
+#ifndef __ASSEMBLY__
+unsigned int get_chip_id(void);
+unsigned int get_extension_chip_id(void);
+char *get_cpu_name(void);
+#endif
+
+#endif /* #ifndef __SAMA7D65_H__ */
diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c
index f84e23f4b2a..3a9e6dcf225 100644
--- a/arch/arm/mach-imx/image-container.c
+++ b/arch/arm/mach-imx/image-container.c
@@ -66,7 +66,7 @@ static bool is_v2x_fw_container(ulong addr)
struct boot_img_t *img_entry;
phdr = (struct container_hdr *)addr;
- if (phdr->tag != 0x87 || phdr->version != 0x0) {
+ if ((phdr->tag != 0x87 && phdr->tag != 0x82) || phdr->version != 0x0) {
debug("Wrong container header\n");
return false;
}
diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c
index 8fe70e2424f..e85cb0dd252 100644
--- a/arch/arm/mach-imx/imx8ulp/soc.c
+++ b/arch/arm/mach-imx/imx8ulp/soc.c
@@ -279,7 +279,7 @@ int print_cpuinfo(void)
if (!ret) {
ret = thermal_get_temp(udev, &temp);
if (!ret)
- printf("CPU current temperature: %d\n", temp);
+ printf("CPU current temperature: %dC\n", temp);
else
debug(" - failed to get CPU current temperature\n");
} else {
diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig
index 6af45938edb..4e0e194690b 100644
--- a/arch/arm/mach-imx/imx9/Kconfig
+++ b/arch/arm/mach-imx/imx9/Kconfig
@@ -33,6 +33,7 @@ config IMX95
select DM_MAILBOX
select SCMI_FIRMWARE
select SPL_IMX_CONTAINER_USE_TRAMPOLINE
+ select IMX_PQC_SUPPORT
config SYS_SOC
default "imx9"
@@ -65,6 +66,14 @@ config TARGET_IMX93_11X11_EVK
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
+config TARGET_IMX93_FRDM
+ bool "imx93_frdm"
+ select OF_BOARD_FIXUP
+ select IMX93
+ select IMX9_LPDDR4X
+ imply BOOTSTD_FULL
+ imply BOOTSTD_BOOTCOMMAND
+
config TARGET_IMX93_VAR_SOM
bool "imx93_var_som"
select IMX93
@@ -89,6 +98,7 @@ endchoice
source "board/freescale/imx91_evk/Kconfig"
source "board/freescale/imx93_evk/Kconfig"
+source "board/freescale/imx93_frdm/Kconfig"
source "board/freescale/imx93_qsb/Kconfig"
source "board/phytec/phycore_imx93/Kconfig"
source "board/variscite/imx93_var_som/Kconfig"
diff --git a/arch/arm/mach-imx/imx9/scmi/container.cfg b/arch/arm/mach-imx/imx9/scmi/container.cfg
index 441d9beedd1..b25f3b726c5 100644
--- a/arch/arm/mach-imx/imx9/scmi/container.cfg
+++ b/arch/arm/mach-imx/imx9/scmi/container.cfg
@@ -3,6 +3,7 @@
* Copyright 2025 NXP
*/
+CNTR_VERSION 2
BOOT_FROM SD
SOC_TYPE IMX9
CONTAINER
diff --git a/arch/arm/mach-imx/imx9/scmi/imximage.cfg b/arch/arm/mach-imx/imx9/scmi/imximage.cfg
index 6af1c4ba628..c2c92174c1c 100644
--- a/arch/arm/mach-imx/imx9/scmi/imximage.cfg
+++ b/arch/arm/mach-imx/imx9/scmi/imximage.cfg
@@ -3,13 +3,14 @@
* Copyright 2025 NXP
*/
+CNTR_VERSION 2
BOOT_FROM SD
SOC_TYPE IMX9
-APPEND mx95a0-ahab-container.img
+APPEND mx95b0-ahab-container.img
CONTAINER
+DUMMY_DDR
IMAGE OEI m33-oei-ddrfw.bin 0x1ffc0000
HOLD 0x10000
-IMAGE OEI oei-m33-tcm.bin 0x1ffc0000
IMAGE M33 m33_image.bin 0x1ffc0000
IMAGE A55 spl/u-boot-spl.bin 0x20480000
DUMMY_V2X 0x8b000000
diff --git a/arch/arm/mach-k3/r5/common.c b/arch/arm/mach-k3/r5/common.c
index 6ac2973bd67..6269b33f66b 100644
--- a/arch/arm/mach-k3/r5/common.c
+++ b/arch/arm/mach-k3/r5/common.c
@@ -27,7 +27,7 @@ enum {
IMAGE_ID_DM_FW,
IMAGE_ID_TIFSSTUB_HS,
IMAGE_ID_TIFSSTUB_FS,
- IMAGE_ID_T,
+ IMAGE_ID_TIFSSTUB_GP,
IMAGE_AMT,
};
diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index ec51ebbbe7f..fc921a4be26 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -3,7 +3,7 @@
* Common initialisation for Qualcomm Snapdragon boards.
*
* Copyright (c) 2024 Linaro Ltd.
- * Author: Caleb Connolly <caleb.connolly@linaro.org>
+ * Author: Casey Connolly <casey.connolly@linaro.org>
*/
#define LOG_CATEGORY LOGC_BOARD
diff --git a/arch/arm/mach-snapdragon/capsule_update.c b/arch/arm/mach-snapdragon/capsule_update.c
index 4dced4961b6..3699d91852d 100644
--- a/arch/arm/mach-snapdragon/capsule_update.c
+++ b/arch/arm/mach-snapdragon/capsule_update.c
@@ -3,7 +3,7 @@
* Capsule update support for Qualcomm boards.
*
* Copyright (c) 2024 Linaro Ltd.
- * Author: Caleb Connolly <caleb.connolly@linaro.org>
+ * Author: Casey Connolly <casey.connolly@linaro.org>
*/
#define pr_fmt(fmt) "QCOM-FMP: " fmt
diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
index 328c7812f30..eec2c0c757e 100644
--- a/arch/arm/mach-snapdragon/of_fixup.c
+++ b/arch/arm/mach-snapdragon/of_fixup.c
@@ -13,7 +13,7 @@
* boot Linux with the original FDT.
*
* Copyright (c) 2024 Linaro Ltd.
- * Author: Caleb Connolly <caleb.connolly@linaro.org>
+ * Author: Casey Connolly <casey.connolly@linaro.org>
*/
#define pr_fmt(fmt) "of_fixup: " fmt
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 0a7c029b15a..6a511c4fd39 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -57,7 +57,12 @@ config DRAM_SUN50I_A133
Select this dram controller driver for some sun50i platforms,
like A133.
-if DRAM_SUN50I_H616 || DRAM_SUN50I_A133
+config DRAM_SUN55I_A523
+ bool
+ help
+ Select this DRAM controller driver for A523/T527 SoCs.
+
+if DRAM_SUN50I_H616 || DRAM_SUN50I_A133 || DRAM_SUN55I_A523
config DRAM_SUNXI_DX_ODT
hex "DRAM DX ODT parameter"
help
@@ -170,8 +175,8 @@ config DRAM_SUNXI_TPR13
config DRAM_SUNXI_TPR14
hex "DRAM TPR14 parameter"
- depends on DRAM_SUN50I_A133
- default 0x0
+ depends on DRAM_SUN50I_A133 || MACH_SUN55I_A523
+ default 0x48484848
help
TPR14 value from vendor DRAM settings.
@@ -209,6 +214,7 @@ config AXP_PMIC_BUS
config SUNXI_SRAM_ADDRESS
hex
default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
+ default 0x44000 if MACH_SUN55I_A523
default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
default 0x0
---help---
@@ -221,6 +227,7 @@ config SUNXI_RVBAR_ADDRESS
hex
depends on ARM64
default 0x08100040 if MACH_SUN50I_A133
+ default 0x08000040 if MACH_SUN55I_A523
default 0x09010040 if SUN50I_GEN_H6
default 0x017000a0
---help---
@@ -249,6 +256,7 @@ config SUNXI_BL31_BASE
default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5
default 0x40000000 if MACH_SUN50I_H616
default 0x00104000 if SUN50I_GEN_H6
+ default 0x00054000 if MACH_SUN55I_A523
default 0x0
help
Address where BL31 (TF-A) is loaded, or zero if BL31 is not used.
@@ -330,7 +338,7 @@ config MACH_SUNXI_H3_H5
# TODO: try out A80's 8GiB DRAM space
config SUNXI_DRAM_MAX_SIZE
hex
- default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133
+ default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133 || MACH_SUN55I_A523
default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6
default 0x80000000
@@ -532,6 +540,16 @@ config MACH_SUN50I_A133
select SUN50I_GEN_H6
imply OF_UPSTREAM
+config MACH_SUN55I_A523
+ bool "sun55i (Allwinner A523/A527/T527/H728)"
+ select ARM64
+ select SUNXI_GEN_NCAT2
+ select SUNXI_NEW_PINCTRL
+ select DRAM_SUN55I_A523
+ select FIT
+ select SPL_LOAD_FIT if SPL
+ imply OF_UPSTREAM
+
endchoice
# The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"
@@ -569,7 +587,7 @@ config ARM_BOOT_HOOK_RMR
This allows both the SPL and the U-Boot proper to be entered in
either mode and switch to AArch64 if needed.
-if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133
+if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133 || DRAM_SUN55I_A523
config SUNXI_DRAM_DDR3
bool
@@ -587,6 +605,7 @@ config SUNXI_DRAM_DDR4
choice
prompt "DRAM Type and Timing"
+ default SUNXI_DRAM_A523_LPDDR4 if MACH_SUN55I_A523
default SUNXI_DRAM_DDR3_1333 if !MACH_SUN8I_V3S
default SUNXI_DRAM_DDR2_V3S if MACH_SUN8I_V3S
@@ -670,6 +689,21 @@ config SUNXI_DRAM_DDR2_V3S
This option is only for the DDR2 memory chip which is co-packaged in
Allwinner V3s SoC.
+config SUNXI_DRAM_A523_DDR3
+ bool "DDR3 DRAM chips on the A523/T527 DRAM controller"
+ select SUNXI_DRAM_DDR3
+ depends on DRAM_SUN55I_A523
+ help
+ This option is the DDR3 timing used by the stock boot0 by
+ Allwinner.
+
+config SUNXI_DRAM_A523_LPDDR4
+ bool "LPDDR4 DRAM chips on the A523/T527 DRAM controller"
+ select SUNXI_DRAM_LPDDR4
+ depends on DRAM_SUN55I_A523
+ help
+ This option is the LPDDR4 timing used by the stock boot0 by
+ Allwinner.
endchoice
endif
@@ -690,6 +724,7 @@ config DRAM_CLK
default 672 if MACH_SUN50I
default 744 if MACH_SUN50I_H6
default 720 if MACH_SUN50I_H616 || MACH_SUN50I_A133
+ default 1200 if MACH_SUN55I_A523
---help---
Set the dram clock speed, valid range 240 - 480 (prior to sun9i),
must be a multiple of 24. For the sun9i (A80), the tested values
@@ -706,7 +741,9 @@ endif
config DRAM_ZQ
int "sunxi dram zq value"
- depends on !MACH_SUN50I_H616 && !MACH_SUN50I_A133
+ depends on !MACH_SUN50I_H616
+ depends on !MACH_SUN50I_A133
+ depends on !MACH_SUN55I_A523
default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \
MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T
default 127 if MACH_SUN7I
@@ -720,6 +757,7 @@ config DRAM_ZQ
config DRAM_ODT_EN
bool "sunxi dram odt enable"
depends on !MACH_SUN50I_H616
+ depends on !MACH_SUN55I_A523
default y if MACH_SUN8I_A23
default y if MACH_SUNXI_H3_H5
default y if MACH_SUN8I_R40
@@ -809,6 +847,7 @@ endif
config SYS_CLK_FREQ
default 408000000 if MACH_SUNIV
+ default 792000000 if MACH_SUN55I_A523
default 816000000 if MACH_SUN50I || MACH_SUN50I_H5
default 888000000 if MACH_SUN50I_H6
default 912000000 if MACH_SUN7I
@@ -827,6 +866,7 @@ config SYS_CONFIG_NAME
default "sun50i" if MACH_SUN50I_H6
default "sun50i" if MACH_SUN50I_H616
default "sun50i" if MACH_SUN50I_A133
+ default "sun55i" if MACH_SUN55I_A523
config SYS_BOARD
default "sunxi"
@@ -893,7 +933,7 @@ config I2C1_ENABLE
---help---
See I2C0_ENABLE help text.
-if SUNXI_GEN_SUN6I || SUN50I_GEN_H6
+if SUNXI_GEN_SUN6I || SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
config R_I2C_ENABLE
bool "Enable the PRCM I2C/TWI controller"
# This is used for the pmic on H3
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 8eff20b77bf..579530f27e3 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -47,4 +47,6 @@ obj-$(CONFIG_DRAM_SUN50I_H616) += dram_sun50i_h616.o dram_dw_helpers.o
obj-$(CONFIG_DRAM_SUN50I_H616) += dram_timings/
obj-$(CONFIG_DRAM_SUN50I_A133) += dram_sun50i_a133.o
obj-$(CONFIG_DRAM_SUN50I_A133) += dram_timings/
+obj-$(CONFIG_MACH_SUN55I_A523) += dram_sun55i_a523.o
+obj-$(CONFIG_DRAM_SUN55I_A523) += dram_timings/
endif
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 08d55b3a0e3..fb4837c2082 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -141,6 +141,10 @@ static int gpio_init(void)
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN55I_A523)
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(9), 2);
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(10), 2);
+ sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T)
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0);
@@ -197,6 +201,7 @@ static int gpio_init(void)
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
IS_ENABLED(CONFIG_SUN50I_GEN_NCAT2)) {
val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+ /* TODO: A523: keep only the lower two bits? */
writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
}
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) {
@@ -502,6 +507,12 @@ void reset_cpu(void)
/* sun5i sometimes gets stuck without this */
writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
}
+#elif defined(CONFIG_MACH_SUN55I_A523)
+ static const void *wdog = (void *)SUNXI_TIMER_BASE;
+
+ writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, wdog + WDT_SRST_REG);
+ while (1)
+ ;
#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
#if defined(CONFIG_MACH_SUN50I_H6)
/* WDOG is broken for some H6 rev. use the R_WDOG instead */
diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
index 3f375a51965..80004f13a1e 100644
--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
@@ -1,7 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
#include <asm/arch/prcm.h>
+#include <linux/delay.h>
+
+#ifndef SUNXI_CPU_PLL_CFG_BASE
+#define SUNXI_CPU_PLL_CFG_BASE 0
+#endif
#ifdef CONFIG_XPL_BUILD
void clock_init_safe(void)
@@ -9,15 +16,22 @@ void clock_init_safe(void)
void *const ccm = (void *)SUNXI_CCM_BASE;
void *const prcm = (void *)SUNXI_PRCM_BASE;
- if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) {
- /* this seems to enable PLLs on H616 */
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 0x10);
+ if (IS_ENABLED(CONFIG_MACH_SUN55I_A523))
+ setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 0x200);
+ udelay(1);
+
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
+ IS_ENABLED(CONFIG_MACH_SUN55I_A523))
setbits_le32(prcm + CCU_PRCM_RES_CAL_CTRL, 2);
- }
+ udelay(1);
if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
- IS_ENABLED(CONFIG_MACH_SUN50I_H6)) {
+ IS_ENABLED(CONFIG_MACH_SUN50I_H6) ||
+ IS_ENABLED(CONFIG_MACH_SUN55I_A523)) {
clrbits_le32(prcm + CCU_PRCM_RES_CAL_CTRL, 1);
+ udelay(1);
setbits_le32(prcm + CCU_PRCM_RES_CAL_CTRL, 1);
}
@@ -31,12 +45,13 @@ void clock_init_safe(void)
clock_set_pll1(408000000);
writel(CCM_PLL6_DEFAULT, ccm + CCU_H6_PLL6_CFG);
- while (!(readl(ccm + CCU_H6_PLL6_CFG) & CCM_PLL6_LOCK))
+ while (!(readl(ccm + CCU_H6_PLL6_CFG) & CCM_PLL_LOCK))
;
- clrsetbits_le32(ccm + CCU_H6_CPU_AXI_CFG,
- CCM_CPU_AXI_APB_MASK | CCM_CPU_AXI_AXI_MASK,
- CCM_CPU_AXI_DEFAULT_FACTORS);
+ if (!IS_ENABLED(CONFIG_MACH_SUN55I_A523))
+ clrsetbits_le32(ccm + CCU_H6_CPU_AXI_CFG,
+ CCM_CPU_AXI_APB_MASK | CCM_CPU_AXI_AXI_MASK,
+ CCM_CPU_AXI_DEFAULT_FACTORS);
writel(CCM_PSI_AHB1_AHB2_DEFAULT, ccm + CCU_H6_PSI_AHB1_AHB2_CFG);
#ifdef CCM_AHB3_DEFAULT
@@ -48,7 +63,15 @@ void clock_init_safe(void)
* The mux and factor are set, but the clock will be enabled in
* DRAM initialization code.
*/
- writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), ccm + CCU_H6_MBUS_CFG);
+ if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) {
+ writel(MBUS_RESET, ccm + CCU_H6_MBUS_CFG);
+ udelay(1);
+ writel(MBUS_UPDATE | MBUS_CLK_SRC_OSCM24 | MBUS_CLK_M(4),
+ ccm + CCU_H6_MBUS_CFG);
+ } else {
+ writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3),
+ ccm + CCU_H6_MBUS_CFG);
+ }
}
void clock_init_uart(void)
@@ -70,38 +93,118 @@ void clock_init_uart(void)
1 << (RESET_SHIFT + CONFIG_CONS_INDEX - 1));
}
-void clock_set_pll1(unsigned int clk)
+static bool has_pll_output_gate(void)
{
- void *const ccm = (void *)SUNXI_CCM_BASE;
+ return (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) ||
+ IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
+ IS_ENABLED(CONFIG_MACH_SUN50I_A133));
+}
+
+/* A shared routine to program the CPU PLLs for H6, H616, T113, A523 */
+static void clock_set_pll(u32 *reg, unsigned int n)
+{
+ u32 val = readl(reg);
+
+ /* clear the lock enable bit */
+ val &= ~CCM_PLL_LOCK_EN;
+ writel(val, reg);
+
+ /* gate the output on the newer SoCs */
+ if (has_pll_output_gate()) {
+ val &= ~CCM_PLL_OUT_EN;
+ writel(val, reg);
+ }
+
+ val &= ~(CCM_PLL1_CTRL_N_MASK | GENMASK(3, 0) | GENMASK(21, 16));
+ val |= CCM_PLL1_CTRL_N(n);
+ writel(val, reg); /* program parameter */
+
+ val |= CCM_PLL_CTRL_EN;
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
+ val |= CCM_PLL_LDO_EN;
+ writel(val, reg); /* enable PLL */
+
+ val |= CCM_PLL_LOCK_EN;
+ if (IS_ENABLED(CONFIG_MACH_SUN55I_A523))
+ val |= CCM_PLL1_UPDATE;
+ writel(val, reg); /* start locking process */
+
+ while (!(readl(reg) & CCM_PLL_LOCK)) { /* wait for lock bit */
+ }
+ udelay(20); /* wait as per manual */
+
+ /* un-gate the output on the newer SoCs */
+ if (has_pll_output_gate()) {
+ val |= CCM_PLL_OUT_EN;
+ writel(val, reg);
+ }
+}
+
+/* Program the PLLs for both clusters plus the DSU. */
+static void clock_a523_set_cpu_plls(unsigned int n_factor)
+{
+ void *const cpc = (void *)SUNXI_CPU_PLL_CFG_BASE;
u32 val;
- /* Do not support clocks < 288MHz as they need factor P */
- if (clk < 288000000) clk = 288000000;
+ val = CPU_CLK_SRC_HOSC | CPU_CLK_CTRL_P(0) |
+ CPU_CLK_APB_DIV(4) | CPU_CLK_PERI_DIV(2) |
+ CPU_CLK_AXI_DIV(2);
+
+ /* Switch CPU clock source to 24MHz HOSC while changing the PLL */
+ writel(val, cpc + CPC_CPUA_CLK_REG);
+ writel(val, cpc + CPC_CPUB_CLK_REG);
+ udelay(20);
+ writel(CPU_CLK_SRC_HOSC | CPU_CLK_CTRL_P(0),
+ cpc + CPC_DSU_CLK_REG);
+ udelay(20);
- /* Switch to 24MHz clock while changing PLL1 */
+ clock_set_pll(cpc + CPC_CPUA_PLL_CTRL, n_factor);
+ clock_set_pll(cpc + CPC_CPUB_PLL_CTRL, n_factor);
+ clock_set_pll(cpc + CPC_DSU_PLL_CTRL, n_factor);
+
+ /* Switch CPU clock source to the CPU PLL */
+ clrsetbits_le32(cpc + CPC_CPUA_CLK_REG, CPU_CLK_SRC_HOSC,
+ CPU_CLK_SRC_CPUPLL);
+ clrsetbits_le32(cpc + CPC_CPUB_CLK_REG, CPU_CLK_SRC_HOSC,
+ CPU_CLK_SRC_CPUPLL);
+ clrsetbits_le32(cpc + CPC_DSU_CLK_REG, CPU_CLK_SRC_HOSC,
+ CPU_CLK_SRC_CPUPLL);
+}
+
+static void clock_h6_set_cpu_pll(unsigned int n_factor)
+{
+ void *const ccm = (void *)SUNXI_CCM_BASE;
+ u32 val;
+
+ /* Switch CPU clock source to 24MHz HOSC while changing the PLL */
val = readl(ccm + CCU_H6_CPU_AXI_CFG);
val &= ~CCM_CPU_AXI_MUX_MASK;
val |= CCM_CPU_AXI_MUX_OSC24M;
writel(val, ccm + CCU_H6_CPU_AXI_CFG);
- /* clk = 24*n/p, p is ignored if clock is >288MHz */
- val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2;
- val |= CCM_PLL1_CTRL_N(clk / 24000000);
- if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
- IS_ENABLED(CONFIG_MACH_SUN50I_A133))
- val |= CCM_PLL1_OUT_EN;
- if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
- val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN;
- writel(val, ccm + CCU_H6_PLL1_CFG);
- while (!(readl(ccm + CCU_H6_PLL1_CFG) & CCM_PLL1_LOCK)) {}
+ clock_set_pll(ccm + CCU_H6_PLL1_CFG, n_factor);
- /* Switch CPU to PLL1 */
+ /* Switch CPU clock source to the CPU PLL */
val = readl(ccm + CCU_H6_CPU_AXI_CFG);
val &= ~CCM_CPU_AXI_MUX_MASK;
val |= CCM_CPU_AXI_MUX_PLL_CPUX;
writel(val, ccm + CCU_H6_CPU_AXI_CFG);
}
+void clock_set_pll1(unsigned int clk)
+{
+ /* Do not support clocks < 288MHz as they need factor P */
+ if (clk < 288000000)
+ clk = 288000000;
+
+ clk /= 24000000;
+
+ if (IS_ENABLED(CONFIG_MACH_SUN55I_A523))
+ clock_a523_set_cpu_plls(clk);
+ else
+ clock_h6_set_cpu_pll(clk);
+}
+
int clock_twi_onoff(int port, int state)
{
void *const ccm = (void *)SUNXI_CCM_BASE;
diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
index 3f4735d4717..c3a51d9956e 100644
--- a/arch/arm/mach-sunxi/cpu_info.c
+++ b/arch/arm/mach-sunxi/cpu_info.c
@@ -106,6 +106,8 @@ int print_cpuinfo(void)
puts("CPU: Allwinner H616 (SUN50I)\n");
#elif defined CONFIG_MACH_SUN50I_A133
puts("CPU: Allwinner A133 (SUN50I)\n");
+#elif defined CONFIG_MACH_SUN55I_A523
+ puts("CPU: Allwinner A523 (SUN55I)\n");
#else
#warning Please update cpu_info.c with correct CPU information
puts("CPU: SUNXI Family\n");
diff --git a/arch/arm/mach-sunxi/dram_sun50i_a133.c b/arch/arm/mach-sunxi/dram_sun50i_a133.c
index a0fca3738f4..3a231141168 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_a133.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_a133.c
@@ -78,19 +78,19 @@ static void mctl_clk_init(u32 clk)
clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET);
clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT));
clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT));
- clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN);
+ clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN);
clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET);
udelay(5);
/* Set up PLL5 clock, used for DRAM */
clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0xff03,
- CCM_PLL5_CTRL_N((clk * 2) / 24) | CCM_PLL5_CTRL_EN);
+ CCM_PLL5_CTRL_N((clk * 2) / 24) | CCM_PLL_CTRL_EN);
setbits_le32(ccm + CCU_H6_PLL5_CFG, BIT(24));
clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3,
- CCM_PLL5_LOCK_EN | CCM_PLL5_CTRL_EN | BIT(30));
- clrbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3 | BIT(30));
+ CCM_PLL_LOCK_EN | CCM_PLL_CTRL_EN | CCM_PLL_LDO_EN);
+ clrbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3 | CCM_PLL_LDO_EN);
mctl_await_completion(ccm + CCU_H6_PLL5_CFG,
- CCM_PLL5_LOCK, CCM_PLL5_LOCK);
+ CCM_PLL_LOCK, CCM_PLL_LOCK);
/* Enable DRAM clock and gate*/
clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, BIT(24) | BIT(25));
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h6.c b/arch/arm/mach-sunxi/dram_sun50i_h6.c
index 84fd64a2bfc..ea26e6dd327 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h6.c
@@ -167,16 +167,16 @@ static void mctl_sys_init(u32 clk_rate)
clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(0));
udelay(5);
writel(0, ccm + CCU_H6_DRAM_GATE_RESET);
- clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN);
+ clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN);
clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET);
udelay(5);
/* Set PLL5 rate to doubled DRAM clock rate */
- writel(CCM_PLL5_CTRL_EN | CCM_PLL5_LOCK_EN |
+ writel(CCM_PLL_CTRL_EN | CCM_PLL_LOCK_EN |
CCM_PLL5_CTRL_N(clk_rate * 2 / 24), ccm + CCU_H6_PLL5_CFG);
mctl_await_completion(ccm + CCU_H6_PLL5_CFG,
- CCM_PLL5_LOCK, CCM_PLL5_LOCK);
+ CCM_PLL_LOCK, CCM_PLL_LOCK);
/* Configure DRAM mod clock */
writel(DRAM_CLK_SRC_PLL5, ccm + CCU_H6_DRAM_CLK_CFG);
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c
index 5a59f82d1ef..877181016f3 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
@@ -106,16 +106,16 @@ static void mctl_sys_init(u32 clk_rate)
clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT));
udelay(5);
clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT));
- clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN);
+ clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN);
clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET);
udelay(5);
/* Set PLL5 rate to doubled DRAM clock rate */
- writel(CCM_PLL5_CTRL_EN | CCM_PLL5_LOCK_EN | CCM_PLL5_OUT_EN |
+ writel(CCM_PLL_CTRL_EN | CCM_PLL_LOCK_EN | CCM_PLL_OUT_EN |
CCM_PLL5_CTRL_N(clk_rate * 2 / 24), ccm + CCU_H6_PLL5_CFG);
mctl_await_completion(ccm + CCU_H6_PLL5_CFG,
- CCM_PLL5_LOCK, CCM_PLL5_LOCK);
+ CCM_PLL_LOCK, CCM_PLL_LOCK);
/* Configure DRAM mod clock */
writel(DRAM_CLK_SRC_PLL5, ccm + CCU_H6_DRAM_CLK_CFG);
diff --git a/arch/arm/mach-sunxi/dram_sun55i_a523.c b/arch/arm/mach-sunxi/dram_sun55i_a523.c
new file mode 100644
index 00000000000..30bbeb40d0b
--- /dev/null
+++ b/arch/arm/mach-sunxi/dram_sun55i_a523.c
@@ -0,0 +1,1590 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * sun55i A523/A527/T527/H728 platform DRAM controller driver
+ *
+ * This driver supports DDR3 and LPDDR4 memory.
+ *
+ * (C) Copyright 2024 Jernej Skrabec <jernej.skrabec@gmail.com>
+ *
+ */
+#include <init.h>
+#include <log.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/dram.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/prcm.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+
+static void mctl_sys_init(u32 clk_rate)
+{
+ void * const ccm = (void *)SUNXI_CCM_BASE;
+
+ /* Put all DRAM-related blocks to reset state */
+ clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE);
+ clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET);
+ setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_UPDATE);
+ clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT));
+ udelay(5);
+ clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT));
+ clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN);
+ clrsetbits_le32(ccm + CCU_H6_DRAM_CLK_CFG,
+ DRAM_CLK_ENABLE, DRAM_CLK_UPDATE);
+
+ udelay(5);
+
+ /* Set PLL5 rate to doubled DRAM clock rate */
+ writel(CCM_PLL_CTRL_EN | CCM_PLL_LDO_EN | CCM_PLL_LOCK_EN |
+ CCM_PLL_OUT_EN | CCM_PLL5_CTRL_N(clk_rate * 2 / 24),
+ ccm + CCU_H6_PLL5_CFG);
+ mctl_await_completion(ccm + CCU_H6_PLL5_CFG,
+ CCM_PLL_LOCK, CCM_PLL_LOCK);
+
+ /* Configure DRAM mod clock */
+ writel(DRAM_CLK_SRC_PLL5, ccm + CCU_H6_DRAM_CLK_CFG);
+ writel(BIT(RESET_SHIFT), ccm + CCU_H6_DRAM_GATE_RESET);
+ udelay(5);
+ setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT));
+
+ /* Configure MBUS and enable DRAM clock */
+ setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET | MBUS_UPDATE);
+ setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE | MBUS_UPDATE);
+
+ clrsetbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_CLK_M_MASK,
+ DRAM_CLK_ENABLE | DRAM_CLK_UPDATE | DRAM_CLK_M(4));
+ udelay(5);
+}
+
+static void mctl_set_addrmap(const struct dram_config *config)
+{
+ struct sunxi_mctl_ctl_reg * const mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+ u8 cols = config->cols;
+ u8 rows = config->rows;
+ u8 ranks = config->ranks;
+
+ if (!config->bus_full_width)
+ cols -= 1;
+
+ /* Ranks */
+ if (ranks == 2)
+ mctl_ctl->addrmap[0] = 0x1F00 | (rows + cols - 3);
+ else
+ mctl_ctl->addrmap[0] = 0x1F1F;
+
+ /* Banks, hardcoded to 8 banks now */
+ mctl_ctl->addrmap[1] = (cols - 2) | (cols - 2) << 8 | (cols - 2) << 16;
+
+ /* Columns */
+ mctl_ctl->addrmap[2] = 0;
+ switch (cols) {
+ case 7:
+ mctl_ctl->addrmap[3] = 0x1F1F1F00;
+ mctl_ctl->addrmap[4] = 0x1F1F;
+ break;
+ case 8:
+ mctl_ctl->addrmap[3] = 0x1F1F0000;
+ mctl_ctl->addrmap[4] = 0x1F1F;
+ break;
+ case 9:
+ mctl_ctl->addrmap[3] = 0x1F000000;
+ mctl_ctl->addrmap[4] = 0x1F1F;
+ break;
+ case 10:
+ mctl_ctl->addrmap[3] = 0;
+ mctl_ctl->addrmap[4] = 0x1F1F;
+ break;
+ case 11:
+ mctl_ctl->addrmap[3] = 0;
+ mctl_ctl->addrmap[4] = 0x1F00;
+ break;
+ case 12:
+ mctl_ctl->addrmap[3] = 0;
+ mctl_ctl->addrmap[4] = 0;
+ break;
+ default:
+ panic("Unsupported DRAM configuration: column number invalid\n");
+ }
+
+ /* Rows */
+ mctl_ctl->addrmap[5] = (cols - 3) | ((cols - 3) << 8) |
+ ((cols - 3) << 16) | ((cols - 3) << 24);
+ switch (rows) {
+ case 13:
+ mctl_ctl->addrmap[6] = (cols - 3) | 0x0F0F0F00;
+ mctl_ctl->addrmap[7] = 0x0F0F;
+ break;
+ case 14:
+ mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) |
+ 0x0F0F0000;
+ mctl_ctl->addrmap[7] = 0x0F0F;
+ break;
+ case 15:
+ mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) |
+ ((cols - 3) << 16) | 0x0F000000;
+ mctl_ctl->addrmap[7] = 0x0F0F;
+ break;
+ case 16:
+ mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) |
+ ((cols - 3) << 16) | ((cols - 3) << 24);
+ mctl_ctl->addrmap[7] = 0x0F0F;
+ break;
+ case 17:
+ mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) |
+ ((cols - 3) << 16) | ((cols - 3) << 24);
+ mctl_ctl->addrmap[7] = (cols - 3) | 0x0F00;
+ break;
+ case 18:
+ mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) |
+ ((cols - 3) << 16) | ((cols - 3) << 24);
+ mctl_ctl->addrmap[7] = (cols - 3) | ((cols - 3) << 8);
+ break;
+ default:
+ panic("Unsupported DRAM configuration: row number invalid\n");
+ }
+
+ /* Bank groups, DDR4 only */
+ mctl_ctl->addrmap[8] = 0x3F3F;
+}
+
+#define MASK_BYTE(reg, nr) (((reg) >> ((nr) * 8)) & 0x1f)
+static void mctl_phy_configure_odt(const struct dram_para *para)
+{
+ u32 val_lo, val_hi;
+
+ val_hi = para->dx_dri;
+ val_lo = (para->type != SUNXI_DRAM_TYPE_LPDDR4) ? para->dx_dri :
+ (para->tpr1 & 0x1f1f1f1f) ? para->tpr1 : 0x04040404;
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x304, 0x1f1f0000,
+ (MASK_BYTE(val_hi, 0) << 24) |
+ (MASK_BYTE(val_lo, 0) << 16));
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x484, 0x1f1f0000,
+ (MASK_BYTE(val_hi, 1) << 24) |
+ (MASK_BYTE(val_lo, 1) << 16));
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x604, 0x1f1f0000,
+ (MASK_BYTE(val_hi, 2) << 24) |
+ (MASK_BYTE(val_lo, 2) << 16));
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x784, 0x1f1f0000,
+ (MASK_BYTE(val_hi, 3) << 24) |
+ (MASK_BYTE(val_lo, 3) << 16));
+
+ val_lo = para->ca_dri;
+ val_hi = para->ca_dri;
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xf4, 0x1f1f1f1f,
+ (MASK_BYTE(val_hi, 0) << 24) |
+ (MASK_BYTE(val_lo, 0) << 16) |
+ (MASK_BYTE(val_hi, 1) << 8) |
+ (MASK_BYTE(val_lo, 1)));
+
+ val_hi = para->dx_odt;
+ val_lo = (para->type == SUNXI_DRAM_TYPE_LPDDR4) ? 0 : para->dx_odt;
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x304, 0x00001f1f,
+ (MASK_BYTE(val_hi, 0) << 8) | MASK_BYTE(val_lo, 0));
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x484, 0x00001f1f,
+ (MASK_BYTE(val_hi, 1) << 8) | MASK_BYTE(val_lo, 1));
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x604, 0x00001f1f,
+ (MASK_BYTE(val_hi, 2) << 8) | MASK_BYTE(val_lo, 2));
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x784, 0x00001f1f,
+ (MASK_BYTE(val_hi, 3) << 8) | MASK_BYTE(val_lo, 3));
+}
+
+static bool mctl_phy_write_leveling(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ u32 mr2, low, high, val = 0;
+ bool result = true;
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0xf00, 0xe00);
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
+ if (config->clk <= 936)
+ mr2 = 0x1b;
+ else if (config->clk <= 1200)
+ mr2 = 0x2d;
+ else
+ mr2 = 0x36;
+ writeb(mr2, SUNXI_DRAM_PHY0_BASE + 3);
+ }
+
+ low = readw(SUNXI_DRAM_PHY0_BASE + 2) | 4;
+ high = readw(SUNXI_DRAM_PHY0_BASE + 4);
+ writew(low, SUNXI_DRAM_PHY0_BASE + 2);
+ writew(high, SUNXI_DRAM_PHY0_BASE + 4);
+
+ if (config->bus_full_width)
+ val = 0xf;
+ else
+ val = 3;
+
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x62), val, val);
+
+ low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xfffb;
+ high = readw(SUNXI_DRAM_PHY0_BASE + 4);
+ writew(low, SUNXI_DRAM_PHY0_BASE + 2);
+ writew(high, SUNXI_DRAM_PHY0_BASE + 4);
+
+ val = readl(SUNXI_DRAM_PHY0_BASE + 0x96);
+ if (val == 0 || val == 0x3f)
+ result = false;
+ val = readl(SUNXI_DRAM_PHY0_BASE + 0x97); //TODO: ???
+ if (val == 0 || val == 0x3f)
+ result = false;
+ val = readl(SUNXI_DRAM_PHY0_BASE + 0xc6);
+ if (val == 0 || val == 0x3f)
+ result = false;
+ val = readl(SUNXI_DRAM_PHY0_BASE + 0xc7); //TODO: ???
+ if (val == 0 || val == 0x3f)
+ result = false;
+
+ low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xff3f;
+ high = readw(SUNXI_DRAM_PHY0_BASE + 4);
+ writew(low, SUNXI_DRAM_PHY0_BASE + 2);
+ writew(high, SUNXI_DRAM_PHY0_BASE + 4);
+
+ if (config->ranks == 2) {
+ low = (readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xff3f) | 0x40;
+ high = readw(SUNXI_DRAM_PHY0_BASE + 4);
+ writew(low, SUNXI_DRAM_PHY0_BASE + 2);
+ writew(high, SUNXI_DRAM_PHY0_BASE + 4);
+
+ low = readw(SUNXI_DRAM_PHY0_BASE + 2) | 4;
+ high = readw(SUNXI_DRAM_PHY0_BASE + 4);
+ writew(low, SUNXI_DRAM_PHY0_BASE + 2);
+ writew(high, SUNXI_DRAM_PHY0_BASE + 4);
+
+ if (config->bus_full_width)
+ val = 0xf;
+ else
+ val = 3;
+
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x62), val, val);
+
+ low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xfffb;
+ high = readw(SUNXI_DRAM_PHY0_BASE + 4);
+ writew(low, SUNXI_DRAM_PHY0_BASE + 2);
+ writew(high, SUNXI_DRAM_PHY0_BASE + 4);
+ }
+
+ low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xff3f;
+ high = readw(SUNXI_DRAM_PHY0_BASE + 4);
+ writew(low, SUNXI_DRAM_PHY0_BASE + 2);
+ writew(high, SUNXI_DRAM_PHY0_BASE + 4);
+
+ return result;
+}
+
+static bool mctl_phy_read_calibration(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ bool result = true;
+ u32 val;
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4)
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, 0x20000000);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c, 0x38);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1);
+
+ if (config->bus_full_width)
+ val = 0xf;
+ else
+ val = 3;
+
+ while ((readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & val) != val) {
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & 0x20) {
+ result = false;
+ break;
+ }
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c);
+
+ if (config->ranks == 2) {
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c, 0x34);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1);
+
+ while ((readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & val) != val) {
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & 0x20) {
+ result = false;
+ break;
+ }
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c);
+ }
+
+ return result;
+}
+
+static bool mctl_phy_read_training(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ u32 val1, val2, *ptr1, *ptr2;
+ bool result = true;
+ int i;
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
+ writel(0, SUNXI_DRAM_PHY0_BASE + 0x200);
+ writeb(0, SUNXI_DRAM_PHY0_BASE + 0x207);
+ writeb(0, SUNXI_DRAM_PHY0_BASE + 0x208);
+ writeb(0, SUNXI_DRAM_PHY0_BASE + 0x209);
+ writeb(0, SUNXI_DRAM_PHY0_BASE + 0x20a);
+ }
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 3, 2);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x804, 0x3f, 0xf);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x808, 0x3f, 0xf);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa04, 0x3f, 0xf);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa08, 0x3f, 0xf);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
+
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
+ result = false;
+
+ if (config->bus_full_width) {
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
+ result = false;
+ }
+
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x898);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x850);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8bc);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x874);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+
+ if (config->bus_full_width) {
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa98);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa50);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xabc);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa74);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 3);
+
+ if (config->ranks == 2) {
+ /* maybe last parameter should be 1? */
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 3, 2);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1);
+
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3)
+ result = false;
+
+ if (config->bus_full_width) {
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3)
+ result = false;
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 3);
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 3);
+
+ return result;
+}
+
+static bool mctl_phy_write_training(const struct dram_config *config)
+{
+ u32 val1, val2, *ptr1, *ptr2;
+ bool result = true;
+ int i;
+
+ writel(0, SUNXI_DRAM_PHY0_BASE + 0x134);
+ writel(0, SUNXI_DRAM_PHY0_BASE + 0x138);
+ writel(0, SUNXI_DRAM_PHY0_BASE + 0x19c);
+ writel(0, SUNXI_DRAM_PHY0_BASE + 0x1a0);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 0xc, 8);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
+
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
+ result = false;
+
+ if (config->bus_full_width) {
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
+ result = false;
+ }
+
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x938);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8f0);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x95c);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x914);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+
+ if (config->bus_full_width) {
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb38);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xaf0);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+ ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb5c);
+ ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb14);
+ for (i = 0; i < 9; i++) {
+ val1 = readl(&ptr1[i]);
+ val2 = readl(&ptr2[i]);
+ if (val1 - val2 <= 6)
+ result = false;
+ }
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x60);
+
+ if (config->ranks == 2) {
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 0xc, 4);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20);
+
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc)
+ result = false;
+
+ if (config->bus_full_width) {
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3);
+ if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc)
+ result = false;
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x60);
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 0xc);
+
+ return result;
+}
+
+static void mctl_phy_bit_delay_compensation(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ u8 array0[32], array1[32];
+ u32 tmp;
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ array0[i] = (config->tpr11 >> (i & 0xf8)) & 0xff;
+ array1[i] = (config->tpr12 >> (i & 0xf8)) & 0x7f;
+ }
+
+ if (para->tpr10 & TPR10_DX_BIT_DELAY1) {
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa0, 3);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x80);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, BIT(28));
+
+ writel(array0[0], SUNXI_DRAM_PHY0_BASE + 0x320);
+ writel((array0[0] << 24) | (array0[1] << 16) |
+ (array0[2] << 8) |
+ array0[3], SUNXI_DRAM_PHY0_BASE + 0x324);
+ writel((array0[4] << 24) | (array0[5] << 16) |
+ (array0[6] << 8) |
+ array0[7], SUNXI_DRAM_PHY0_BASE + 0x328);
+
+ writel(array0[0], SUNXI_DRAM_PHY0_BASE + 0x340);
+ writel((array0[0] << 24) | (array0[1] << 16) |
+ (array0[2] << 8) |
+ array0[3], SUNXI_DRAM_PHY0_BASE + 0x344);
+ writel((array0[4] << 24) | (array0[5] << 16) |
+ (array0[6] << 8) |
+ array0[7], SUNXI_DRAM_PHY0_BASE + 0x348);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x40c, 0xff00,
+ array0[0] << 8);
+ writel((array0[0] << 24) | (array0[1] << 16) |
+ (array0[2] << 8) | array0[3],
+ SUNXI_DRAM_PHY0_BASE + 0x400);
+ writel((array0[4] << 24) | (array0[5] << 16) |
+ (array0[6] << 8) | array0[7],
+ SUNXI_DRAM_PHY0_BASE + 0x404);
+
+ writel(array0[0], SUNXI_DRAM_PHY0_BASE + 0x41c);
+ writel((array0[0] << 24) | (array0[1] << 16) |
+ (array0[2] << 8) | array0[3],
+ SUNXI_DRAM_PHY0_BASE + 0x420);
+ writel((array0[4] << 24) | (array0[5] << 16) |
+ (array0[6] << 8) | array0[7],
+ SUNXI_DRAM_PHY0_BASE + 0x424);
+
+ tmp = config->odt_en & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x32c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x34c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x408);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x428);
+
+ writel(array0[8], SUNXI_DRAM_PHY0_BASE + 0x4a0);
+ writel((array0[8] << 24) | (array0[9] << 16) |
+ (array0[10] << 8) | array0[11],
+ SUNXI_DRAM_PHY0_BASE + 0x4a4);
+ writel((array0[12] << 24) | (array0[13] << 16) |
+ (array0[14] << 8) | array0[15],
+ SUNXI_DRAM_PHY0_BASE + 0x4a8);
+
+ writel(array0[8], SUNXI_DRAM_PHY0_BASE + 0x4c0);
+ writel((array0[8] << 24) | (array0[9] << 16) |
+ (array0[10] << 8) | array0[11],
+ SUNXI_DRAM_PHY0_BASE + 0x4c4);
+ writel((array0[12] << 24) | (array0[13] << 16) |
+ (array0[14] << 8) | array0[15],
+ SUNXI_DRAM_PHY0_BASE + 0x4c8);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x58c, 0xff00,
+ array0[8] << 8);
+ writel((array0[8] << 24) | (array0[9] << 16) |
+ (array0[10] << 8) | array0[11],
+ SUNXI_DRAM_PHY0_BASE + 0x580);
+ writel((array0[12] << 24) | (array0[13] << 16) |
+ (array0[14] << 8) | array0[15],
+ SUNXI_DRAM_PHY0_BASE + 0x584);
+
+ writel(array0[8], SUNXI_DRAM_PHY0_BASE + 0x59c);
+ writel((array0[8] << 24) | (array0[9] << 16) |
+ (array0[10] << 8) | array0[11],
+ SUNXI_DRAM_PHY0_BASE + 0x5a0);
+ writel((array0[12] << 24) | (array0[13] << 16) |
+ (array0[14] << 8) | array0[15],
+ SUNXI_DRAM_PHY0_BASE + 0x5a4);
+
+ tmp = (config->odt_en >> 8) & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4ac);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4cc);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x588);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x5a8);
+
+ writel(array0[16], SUNXI_DRAM_PHY0_BASE + 0x620);
+ writel((array0[16] << 24) | (array0[17] << 16) |
+ (array0[18] << 8) | array0[19],
+ SUNXI_DRAM_PHY0_BASE + 0x624);
+ writel((array0[20] << 24) | (array0[21] << 16) |
+ (array0[22] << 8) | array0[23],
+ SUNXI_DRAM_PHY0_BASE + 0x628);
+
+ writel(array0[16], SUNXI_DRAM_PHY0_BASE + 0x640);
+ writel((array0[16] << 24) | (array0[17] << 16) |
+ (array0[18] << 8) | array0[19],
+ SUNXI_DRAM_PHY0_BASE + 0x644);
+ writel((array0[20] << 24) | (array0[21] << 16) |
+ (array0[22] << 8) | array0[23],
+ SUNXI_DRAM_PHY0_BASE + 0x648);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x70c,
+ 0xff00, array0[16] << 8);
+ writel((array0[16] << 24) | (array0[17] << 16) |
+ (array0[18] << 8) | array0[19],
+ SUNXI_DRAM_PHY0_BASE + 0x700);
+ writel((array0[20] << 24) | (array0[21] << 16) |
+ (array0[22] << 8) | array0[23],
+ SUNXI_DRAM_PHY0_BASE + 0x704);
+
+ writel(array0[16], SUNXI_DRAM_PHY0_BASE + 0x71c);
+ writel((array0[16] << 24) | (array0[17] << 16) |
+ (array0[18] << 8) | array0[19],
+ SUNXI_DRAM_PHY0_BASE + 0x720);
+ writel((array0[20] << 24) | (array0[21] << 16) |
+ (array0[22] << 8) | array0[23], SUNXI_DRAM_PHY0_BASE + 0x724);
+
+ tmp = (config->odt_en >> 16) & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x62c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x64c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x708);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x728);
+
+ writel(array0[24], SUNXI_DRAM_PHY0_BASE + 0x7a0);
+ writel((array0[24] << 24) | (array0[25] << 16) |
+ (array0[26] << 8) | array0[27],
+ SUNXI_DRAM_PHY0_BASE + 0x7a4);
+ writel((array0[28] << 24) | (array0[29] << 16) |
+ (array0[30] << 8) | array0[31],
+ SUNXI_DRAM_PHY0_BASE + 0x7a8);
+
+ writel(array0[24], SUNXI_DRAM_PHY0_BASE + 0x7c0);
+ writel((array0[24] << 24) | (array0[25] << 16) |
+ (array0[26] << 8) | array0[27],
+ SUNXI_DRAM_PHY0_BASE + 0x7c4);
+ writel((array0[28] << 24) | (array0[29] << 16) |
+ (array0[30] << 8) | array0[31],
+ SUNXI_DRAM_PHY0_BASE + 0x7c8);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x88c, 0xff00,
+ array0[24] << 8);
+ writel((array0[24] << 24) | (array0[25] << 16) |
+ (array0[26] << 8) | array0[27],
+ SUNXI_DRAM_PHY0_BASE + 0x880);
+ writel((array0[28] << 24) | (array0[29] << 16) |
+ (array0[30] << 8) | array0[31],
+ SUNXI_DRAM_PHY0_BASE + 0x884);
+
+ writel(array0[24], SUNXI_DRAM_PHY0_BASE + 0x89c);
+ writel((array0[24] << 24) | (array0[25] << 16) |
+ (array0[26] << 8) | array0[27],
+ SUNXI_DRAM_PHY0_BASE + 0x8a0);
+ writel((array0[28] << 24) | (array0[29] << 16) |
+ (array0[30] << 8) | array0[31],
+ SUNXI_DRAM_PHY0_BASE + 0x8a4);
+
+ tmp = (config->odt_en >> 24) & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7ac);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7cc);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x888);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x8a8);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, BIT(28));
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, BIT(28));
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000);
+ }
+
+ if (para->tpr10 & TPR10_DX_BIT_DELAY0) {
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000);
+
+ writel(array1[0] << 8, SUNXI_DRAM_PHY0_BASE + 0x330);
+ writel((array1[0] << 24) | (array1[1] << 16) |
+ (array1[2] << 8) | array1[3],
+ SUNXI_DRAM_PHY0_BASE + 0x334);
+ writel((array1[4] << 24) | (array1[5] << 16) |
+ (array1[6] << 8) | array1[7],
+ SUNXI_DRAM_PHY0_BASE + 0x338);
+
+ writel(array1[0] << 8, SUNXI_DRAM_PHY0_BASE + 0x350);
+ writel((array1[0] << 24) | (array1[1] << 16) |
+ (array1[2] << 8) | array1[3],
+ SUNXI_DRAM_PHY0_BASE + 0x354);
+ writel((array1[4] << 24) | (array1[5] << 16) |
+ (array1[6] << 8) | array1[7],
+ SUNXI_DRAM_PHY0_BASE + 0x358);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x40c, 0xff, array1[0]);
+ writel((array1[0] << 24) | (array1[1] << 16) |
+ (array1[2] << 8) | array1[3],
+ SUNXI_DRAM_PHY0_BASE + 0x410);
+ writel((array1[4] << 24) | (array1[5] << 16) |
+ (array1[6] << 8) | array1[7],
+ SUNXI_DRAM_PHY0_BASE + 0x414);
+
+ writel(array1[0] << 8, SUNXI_DRAM_PHY0_BASE + 0x42c);
+ writel((array1[0] << 24) | (array1[1] << 16) |
+ (array1[2] << 8) | array1[3],
+ SUNXI_DRAM_PHY0_BASE + 0x430);
+ writel((array1[4] << 24) | (array1[5] << 16) |
+ (array1[6] << 8) | array1[7],
+ SUNXI_DRAM_PHY0_BASE + 0x434);
+
+ tmp = config->tpr14 & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x33c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x35c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x418);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x438);
+
+ writel(array1[8] << 8, SUNXI_DRAM_PHY0_BASE + 0x4b0);
+ writel((array1[8] << 24) | (array1[9] << 16) |
+ (array1[10] << 8) | array1[11],
+ SUNXI_DRAM_PHY0_BASE + 0x4b4);
+ writel((array1[12] << 24) | (array1[13] << 16) |
+ (array1[14] << 8) | array1[15],
+ SUNXI_DRAM_PHY0_BASE + 0x4b8);
+
+ writel(array1[8] << 8, SUNXI_DRAM_PHY0_BASE + 0x4d0);
+ writel((array1[8] << 24) | (array1[9] << 16) |
+ (array1[10] << 8) | array1[11],
+ SUNXI_DRAM_PHY0_BASE + 0x4d4);
+ writel((array1[12] << 24) | (array1[13] << 16) |
+ (array1[14] << 8) | array1[15],
+ SUNXI_DRAM_PHY0_BASE + 0x4d8);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x58c, 0xff, array1[8]);
+ writel((array1[8] << 24) | (array1[9] << 16) |
+ (array1[10] << 8) | array1[11],
+ SUNXI_DRAM_PHY0_BASE + 0x590);
+ writel((array1[12] << 24) | (array1[13] << 16) |
+ (array1[14] << 8) | array1[15],
+ SUNXI_DRAM_PHY0_BASE + 0x594);
+
+ writel(array1[8] << 8, SUNXI_DRAM_PHY0_BASE + 0x5ac);
+ writel((array1[8] << 24) | (array1[9] << 16) |
+ (array1[10] << 8) | array1[11],
+ SUNXI_DRAM_PHY0_BASE + 0x5b0);
+ writel((array1[12] << 24) | (array1[13] << 16) |
+ (array1[14] << 8) | array1[15],
+ SUNXI_DRAM_PHY0_BASE + 0x5b4);
+
+ tmp = (config->tpr14 >> 8) & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4bc);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4dc);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x598);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x5b8);
+
+ writel(array1[16] << 8, SUNXI_DRAM_PHY0_BASE + 0x630);
+ writel((array1[16] << 24) | (array1[17] << 16) |
+ (array1[18] << 8) | array1[19],
+ SUNXI_DRAM_PHY0_BASE + 0x634);
+ writel((array1[20] << 24) | (array1[21] << 16) |
+ (array1[22] << 8) | array1[23],
+ SUNXI_DRAM_PHY0_BASE + 0x638);
+
+ writel(array1[16] << 8, SUNXI_DRAM_PHY0_BASE + 0x650);
+ writel((array1[16] << 24) | (array1[17] << 16) |
+ (array1[18] << 8) | array1[19],
+ SUNXI_DRAM_PHY0_BASE + 0x654);
+ writel((array1[20] << 24) | (array1[21] << 16) |
+ (array1[22] << 8) | array1[23],
+ SUNXI_DRAM_PHY0_BASE + 0x658);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x70c, 0xff, array1[16]);
+ writel((array1[16] << 24) | (array1[17] << 16) |
+ (array1[18] << 8) | array1[19],
+ SUNXI_DRAM_PHY0_BASE + 0x710);
+ writel((array1[20] << 24) | (array1[21] << 16) |
+ (array1[22] << 8) | array1[23],
+ SUNXI_DRAM_PHY0_BASE + 0x714);
+
+ writel(array1[16] << 8, SUNXI_DRAM_PHY0_BASE + 0x72c);
+ writel((array1[16] << 24) | (array1[17] << 16) |
+ (array1[18] << 8) | array1[19],
+ SUNXI_DRAM_PHY0_BASE + 0x730);
+ writel((array1[20] << 24) | (array1[21] << 16) |
+ (array1[22] << 8) | array1[23],
+ SUNXI_DRAM_PHY0_BASE + 0x734);
+
+ tmp = (config->tpr14 >> 16) & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x63c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x65c);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x718);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x738);
+
+ writel(array1[24] << 8, SUNXI_DRAM_PHY0_BASE + 0x7b0);
+ writel((array1[24] << 24) | (array1[25] << 16) |
+ (array1[26] << 8) | array1[27],
+ SUNXI_DRAM_PHY0_BASE + 0x7b4);
+ writel((array1[28] << 24) | (array1[29] << 16) |
+ (array1[30] << 8) | array1[31],
+ SUNXI_DRAM_PHY0_BASE + 0x7b8);
+
+ writel(array1[24] << 8, SUNXI_DRAM_PHY0_BASE + 0x7d0);
+ writel((array1[24] << 24) | (array1[25] << 16) |
+ (array1[26] << 8) | array1[27],
+ SUNXI_DRAM_PHY0_BASE + 0x7d4);
+ writel((array1[28] << 24) | (array1[29] << 16) |
+ (array1[30] << 8) | array1[31],
+ SUNXI_DRAM_PHY0_BASE + 0x7d8);
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x88c, 0xff, array1[24]);
+ writel((array1[24] << 24) | (array1[25] << 16) |
+ (array1[26] << 8) | array1[27],
+ SUNXI_DRAM_PHY0_BASE + 0x890);
+ writel((array1[28] << 24) | (array1[29] << 16) |
+ (array1[30] << 8) | array1[31],
+ SUNXI_DRAM_PHY0_BASE + 0x894);
+
+ writel(array1[24] << 8, SUNXI_DRAM_PHY0_BASE + 0x8ac);
+ writel((array1[24] << 24) | (array1[25] << 16) |
+ (array1[26] << 8) | array1[27],
+ SUNXI_DRAM_PHY0_BASE + 0x8b0);
+ writel((array1[28] << 24) | (array1[29] << 16) |
+ (array1[30] << 8) | array1[31],
+ SUNXI_DRAM_PHY0_BASE + 0x8b4);
+
+ tmp = (config->tpr14 >> 24) & 0xff;
+ tmp = (tmp << 24) | (tmp << 8);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7bc);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7dc);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x898);
+ writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x8b8);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 4);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 4);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000);
+ }
+}
+
+static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ u32 val, low, high;
+
+ if (para->tpr10 & BIT(31)) {
+ val = para->tpr0;
+ } else {
+ val = ((para->tpr10 & 0xf0) << 5) | ((para->tpr10 & 0xf) << 1);
+ if (para->tpr10 >> 29)
+ val <<= 1;
+ }
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0xac, 0x1000);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x48, 0xc0000000);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ case SUNXI_DRAM_TYPE_DDR4:
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ low = val & 0xff;
+ high = (val >> 8) & 0xff;
+
+ val = (high << 24) | (high << 16) | (high << 8) | high;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x104);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x108);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x10c);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x114);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x118);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x11c);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x120);
+
+ val = (low << 24) | (low << 16) | (high << 8) | high;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x11c);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ low = val & 0xff;
+ high = (val >> 8) & 0xff;
+
+ val = (high << 24) | (high << 16) | (high << 8) | high;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x104);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x108);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x10c);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x114);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x118);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x11c);
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x120);
+
+ val = (high << 24) | (high << 16) | (low << 8) | low;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x110);
+
+ val = (low << 24) | (high << 16) | (low << 8) | high;
+ writel(val, SUNXI_DRAM_PHY0_BASE + 0x11c);
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x38, 1);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x38, 1);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000);
+}
+
+static bool mctl_phy_init(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ void * const mctl_com = (void *)SUNXI_DRAM_COM_BASE;
+ struct sunxi_mctl_ctl_reg * const mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+ void *const prcm = (void *)SUNXI_PRCM_BASE;
+ u32 val, val2, mr1, mr2;
+ int i;
+
+ clrbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 1);
+ udelay(1);
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000);
+
+ if (config->bus_full_width)
+ val = 0xf00;
+ else
+ val = 0x300;
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, 0xf00, val);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = 9;
+ val2 = 13;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ if (config->clk <= 936) {
+ val = 10;
+ val2 = 14;
+ } else if (config->clk <= 1200) {
+ val = 12;
+ val2 = 16;
+ } else {
+ val = 14;
+ val2 = 18;
+ }
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ val = 8;
+ val2 = 14;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ if (config->clk <= 936) {
+ val = 10;
+ val2 = 20;
+ } else if (config->clk <= 1200) {
+ val = 14;
+ val2 = 28;
+ } else {
+ val = 16;
+ val2 = 32;
+ }
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+
+ writel((val << 24) | (val << 16) | (val << 8) | val, SUNXI_DRAM_PHY0_BASE + 0x10);
+ writel((val2 << 24) | (val2 << 16) | (val2 << 8) | val2, SUNXI_DRAM_PHY0_BASE + 0x0c);
+ writel(0, SUNXI_DRAM_PHY0_BASE + 0x08);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ writel(0x150a0310, SUNXI_DRAM_PHY0_BASE + 0x54);
+ writel(0x13140816, SUNXI_DRAM_PHY0_BASE + 0x58);
+ writel(0x001c0d1b, SUNXI_DRAM_PHY0_BASE + 0x5c);
+ writel(0x050c1d1a, SUNXI_DRAM_PHY0_BASE + 0x60);
+ writel(0x0411060b, SUNXI_DRAM_PHY0_BASE + 0x64);
+ writel(0x09071217, SUNXI_DRAM_PHY0_BASE + 0x68);
+ writel(0x18190e01, SUNXI_DRAM_PHY0_BASE + 0x6c);
+ writel(0x020f1e00, SUNXI_DRAM_PHY0_BASE + 0x70);
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ writel(0x090c1c14, SUNXI_DRAM_PHY0_BASE + 0x54);
+ writel(0x1300060f, SUNXI_DRAM_PHY0_BASE + 0x58);
+ writel(0x12030807, SUNXI_DRAM_PHY0_BASE + 0x5c);
+ writel(0x0b100a02, SUNXI_DRAM_PHY0_BASE + 0x60);
+ writel(0x1a110e05, SUNXI_DRAM_PHY0_BASE + 0x64);
+ writel(0x0d041617, SUNXI_DRAM_PHY0_BASE + 0x68);
+ writel(0x1819011b, SUNXI_DRAM_PHY0_BASE + 0x6c);
+ writel(0x151d1e00, SUNXI_DRAM_PHY0_BASE + 0x70);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ writel(0x010a1a0f, SUNXI_DRAM_PHY0_BASE + 0x54);
+ writel(0x10081b07, SUNXI_DRAM_PHY0_BASE + 0x58);
+ writel(0x11061c12, SUNXI_DRAM_PHY0_BASE + 0x5c);
+ writel(0x00131409, SUNXI_DRAM_PHY0_BASE + 0x60);
+ writel(0x15030e16, SUNXI_DRAM_PHY0_BASE + 0x64);
+ writel(0x0b0c0d17, SUNXI_DRAM_PHY0_BASE + 0x68);
+ writel(0x18190204, SUNXI_DRAM_PHY0_BASE + 0x6c);
+ writel(0x051d1e00, SUNXI_DRAM_PHY0_BASE + 0x70);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ writel(0x00010203, SUNXI_DRAM_PHY0_BASE + 0x54);
+ writel(0x04050607, SUNXI_DRAM_PHY0_BASE + 0x58);
+ writel(0x08090a0b, SUNXI_DRAM_PHY0_BASE + 0x5c);
+ writel(0x0c0d0e0f, SUNXI_DRAM_PHY0_BASE + 0x60);
+ writel(0x10111213, SUNXI_DRAM_PHY0_BASE + 0x64);
+ writel(0x14151617, SUNXI_DRAM_PHY0_BASE + 0x68);
+ writel(0x18191a1b, SUNXI_DRAM_PHY0_BASE + 0x6c);
+ writel(0x1c1d1e00, SUNXI_DRAM_PHY0_BASE + 0x70);
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+
+ mctl_phy_configure_odt(para);
+
+ if (para->tpr10 & TPR10_CA_BIT_DELAY)
+ mctl_phy_ca_bit_delay_compensation(para, config);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = 0x2bbd4900;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ val = 0x3841b800;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ val = 0x19016300;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ val = 0x18fd6300;
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa8, 0xffffff00, val);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, 0x70);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = 0x20;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ val = 0x40;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ val = 0x30;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ val = 0x50;
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, val);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, 0x80);
+
+ // TODO: fix intervals
+ if (config->clk - 251 < 250) {
+ val = 0x18000000;
+ val2 = 0x18181818;
+ } else if (config->clk - 126 < 125) {
+ val = 0x28000000;
+ val2 = 0x28282828;
+ } else if (config->clk < 126) {
+ val = 0x38000000;
+ val2 = 0x38383838;
+ } else {
+ val = 0x18000000;
+ val2 = 0;
+ }
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xc0, 0x78000000, val);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xd0, 0x78787878, val2);
+
+ clrbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(9));
+ udelay(10);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = para->tpr6 & 0xff;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ val = para->tpr6 >> 8 & 0xff;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ val = para->tpr6 >> 16 & 0xff;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ val = para->tpr6 >> 24;
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+ val <<= 24;
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x300, 0xff800060, val | 0x40);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x600, 0xff800060, val | 0x40);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x480, 0xff800060, val | 0x40);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x780, 0xff800060, val | 0x40);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x8000000);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 0x80);
+ udelay(10);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 0x80);
+ udelay(10);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x8000000);
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x308, 0x200);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x488, 0x200);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x608, 0x200);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x788, 0x200);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x908, 0x200);
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x308, 0x200);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x488, 0x200);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x608, 0x200);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x788, 0x200);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x908, 0x200);
+ }
+
+ if (config->clk < 936)
+ val = 0x1b000000;
+ else
+ val = 0xc000000;
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14, 0x1f000000, val);
+
+ setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(8));
+
+ /* start DFI init */
+ writel(0, &mctl_ctl->swctl);
+ setbits_le32(&mctl_ctl->dfimisc, 1);
+ setbits_le32(&mctl_ctl->dfimisc, 0x20);
+ writel(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, 1, 1);
+ mctl_await_completion(&mctl_ctl->dfistat, 1, 1);
+
+ udelay(500);
+ setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 1);
+ udelay(1);
+
+ writel(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->dfimisc, 0x20);
+ writel(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, 1, 1);
+
+ writel(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->pwrctl, 0x20);
+ writel(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, 1, 1);
+ mctl_await_completion(&mctl_ctl->statr, 3, 1);
+
+ udelay(500);
+
+ writel(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->dfimisc, 1);
+ writel(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, 1, 1);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ writel(0x1f14, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(4, &mctl_ctl->mrctrl1);
+ writel(0x800010f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0x20, &mctl_ctl->mrctrl1);
+ writel(0x800020f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0, &mctl_ctl->mrctrl1);
+ writel(0x800030f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ if (config->clk <= 936) {
+ mr1 = 0x34;
+ mr2 = 0x1b;
+ } else if (config->clk <= 1200) {
+ mr1 = 0x54;
+ mr2 = 0x2d;
+ } else {
+ mr1 = 0x64;
+ mr2 = 0x36;
+ }
+
+ writel(0x0, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0x100 | mr1, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0x200 | mr2, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0x333, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0x403, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0xb04, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0xc72, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0xd00, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0xe08, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+
+ writel(0x1626, &mctl_ctl->mrctrl1);
+ writel(0x800000f0, &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+
+ writel(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->rfshctl3, 1);
+ writel(1, &mctl_ctl->swctl);
+
+ if (para->tpr10 & TPR10_WRITE_LEVELING) {
+ for (i = 0; i < 5; i++)
+ if (mctl_phy_write_leveling(para, config))
+ break;
+ if (i == 5) {
+ debug("write leveling failed!\n");
+ return false;
+ }
+ }
+
+ if (para->tpr10 & TPR10_READ_CALIBRATION) {
+ for (i = 0; i < 5; i++)
+ if (mctl_phy_read_calibration(para, config))
+ break;
+ if (i == 5) {
+ debug("read calibration failed!\n");
+ return false;
+ }
+ }
+
+ if (para->tpr10 & TPR10_READ_TRAINING) {
+ for (i = 0; i < 5; i++)
+ if (mctl_phy_read_training(para, config))
+ break;
+ if (i == 5) {
+ debug("read training failed!\n");
+ return false;
+ }
+ }
+
+ if (para->tpr10 & TPR10_WRITE_TRAINING) {
+ for (i = 0; i < 5; i++)
+ if (mctl_phy_write_training(config))
+ break;
+ if (i == 5) {
+ debug("write training failed!\n");
+ return false;
+ }
+ }
+
+ mctl_phy_bit_delay_compensation(para, config);
+
+ return true;
+}
+
+static bool mctl_ctrl_init(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ void * const mctl_com = (void *)SUNXI_DRAM_COM_BASE;
+ struct sunxi_mctl_ctl_reg * const mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+ u32 reg_val;
+
+ clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(25) | BIT(9));
+ setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(15) | BIT(9));
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
+ setbits_le32(0x02023ea8, 1); // NSI
+ setbits_le32(0x02071008, 1); // NSI_CPU
+ }
+
+ clrsetbits_le32(&mctl_ctl->sched[0], 0xff08, 0x3000);
+ clrsetbits_le32(&mctl_ctl->sched[1], 0x77000000, 0x33000000);
+ clrsetbits_le32(&mctl_ctl->unk_0x270, 0xffff, 0x808);
+ clrsetbits_le32(&mctl_ctl->unk_0x264, 0xff00ffff, 0x1f000030);
+
+ writel(0, &mctl_ctl->hwlpctl);
+
+ reg_val = MSTR_ACTIVE_RANKS(config->ranks);
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ reg_val |= MSTR_BURST_LENGTH(8) | MSTR_DEVICETYPE_DDR3 | MSTR_2TMODE;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ reg_val |= MSTR_BURST_LENGTH(16) | MSTR_DEVICETYPE_LPDDR4;
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+ if (config->bus_full_width)
+ reg_val |= MSTR_BUSWIDTH_FULL;
+ else
+ reg_val |= MSTR_BUSWIDTH_HALF;
+ writel(BIT(31) | BIT(30) | reg_val, &mctl_ctl->mstr);
+
+ if (config->ranks == 2)
+ writel(0x0303, &mctl_ctl->odtmap);
+ else
+ writel(0x0201, &mctl_ctl->odtmap);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ reg_val = 0x06000400;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ reg_val = 0x04000400;
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+ writel(reg_val, &mctl_ctl->odtcfg);
+ writel(reg_val, &mctl_ctl->unk_0x2240);
+ writel(reg_val, &mctl_ctl->unk_0x3240);
+ writel(reg_val, &mctl_ctl->unk_0x4240);
+
+ mctl_set_addrmap(config);
+
+ mctl_set_timing_params(config->clk);
+
+ writel(0, &mctl_ctl->pwrctl);
+
+ setbits_le32(&mctl_ctl->dfiupd[0], BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->zqctl[0], BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->unk_0x2180, BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->unk_0x3180, BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->unk_0x4180, BIT(31) | BIT(30));
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4)
+ setbits_le32(&mctl_ctl->dbictl, 0x1);
+
+ setbits_le32(&mctl_ctl->rfshctl3, BIT(0));
+ clrbits_le32(&mctl_ctl->dfimisc, BIT(0));
+
+ writel(0x20, &mctl_ctl->pwrctl);
+ setbits_le32(&mctl_ctl->clken, BIT(8));
+
+ clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(9));
+ udelay(1);
+ /* this write seems to enable PHY MMIO region */
+ setbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24));
+
+ if (!mctl_phy_init(para, config))
+ return false;
+
+ writel(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->rfshctl3, BIT(0));
+ writel(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, 1, 1);
+
+ return true;
+}
+
+static bool mctl_core_init(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ mctl_sys_init(config->clk);
+
+ return mctl_ctrl_init(para, config);
+}
+
+static void mctl_auto_detect_rank_width(const struct dram_para *para,
+ struct dram_config *config)
+{
+ /* this is minimum size that it's supported */
+ config->cols = 8;
+ config->rows = 13;
+
+ /*
+ * Strategy here is to test most demanding combination first and least
+ * demanding last, otherwise HW might not be fully utilized. For
+ * example, half bus width and rank = 1 combination would also work
+ * on HW with full bus width and rank = 2, but only 1/4 RAM would be
+ * visible.
+ */
+
+ debug("testing 32-bit width, rank = 2\n");
+ config->bus_full_width = 1;
+ config->ranks = 2;
+ if (mctl_core_init(para, config))
+ return;
+
+ debug("testing 32-bit width, rank = 1\n");
+ config->bus_full_width = 1;
+ config->ranks = 1;
+ if (mctl_core_init(para, config))
+ return;
+
+ debug("testing 16-bit width, rank = 2\n");
+ config->bus_full_width = 0;
+ config->ranks = 2;
+ if (mctl_core_init(para, config))
+ return;
+
+ debug("testing 16-bit width, rank = 1\n");
+ config->bus_full_width = 0;
+ config->ranks = 1;
+ if (mctl_core_init(para, config))
+ return;
+
+ panic("This DRAM setup is currently not supported.\n");
+}
+
+static void mctl_auto_detect_dram_size(const struct dram_para *para,
+ struct dram_config *config)
+{
+ /* detect row address bits */
+ config->cols = 8;
+ config->rows = 16;
+ mctl_core_init(para, config);
+
+ for (config->rows = 13; config->rows < 16; config->rows++) {
+ /* 8 banks, 8 bit per byte and 16/32 bit width */
+ if (mctl_mem_matches((1 << (config->rows + config->cols +
+ 4 + config->bus_full_width))))
+ break;
+ }
+
+ /* detect column address bits */
+ config->cols = 11;
+ mctl_core_init(para, config);
+
+ for (config->cols = 8; config->cols < 11; config->cols++) {
+ /* 8 bits per byte and 16/32 bit width */
+ if (mctl_mem_matches(1 << (config->cols + 1 +
+ config->bus_full_width)))
+ break;
+ }
+}
+
+static unsigned long long mctl_calc_size(const struct dram_config *config)
+{
+ u8 width = config->bus_full_width ? 4 : 2;
+
+ /* 8 banks */
+ return (1ULL << (config->cols + config->rows + 3)) * width * config->ranks;
+}
+
+static const struct dram_para para = {
+#ifdef CONFIG_SUNXI_DRAM_A523_DDR3
+ .type = SUNXI_DRAM_TYPE_DDR3,
+#elif defined(CONFIG_SUNXI_DRAM_A523_LPDDR4)
+ .type = SUNXI_DRAM_TYPE_LPDDR4,
+#endif
+ .dx_odt = CONFIG_DRAM_SUNXI_DX_ODT,
+ .dx_dri = CONFIG_DRAM_SUNXI_DX_DRI,
+ .ca_dri = CONFIG_DRAM_SUNXI_CA_DRI,
+ .tpr0 = CONFIG_DRAM_SUNXI_TPR0,
+ .tpr1 = CONFIG_DRAM_SUNXI_TPR1,
+ .tpr2 = CONFIG_DRAM_SUNXI_TPR2,
+ .tpr6 = CONFIG_DRAM_SUNXI_TPR6,
+ .tpr10 = CONFIG_DRAM_SUNXI_TPR10,
+};
+
+static void sunxi_nsi_init(void)
+{
+ /* IOMMU prio 3 */
+ writel(0x1, 0x02021418);
+ writel(0xf, 0x02021414);
+ /* DE prio 2 */
+ writel(0x1, 0x02021a18);
+ writel(0xa, 0x02021a14);
+ /* VE R prio 2 */
+ writel(0x1, 0x02021618);
+ writel(0xa, 0x02021614);
+ /* VE RW prio 2 */
+ writel(0x1, 0x02021818);
+ writel(0xa, 0x02021814);
+ /* ISP prio 2 */
+ writel(0x1, 0x02020c18);
+ writel(0xa, 0x02020c14);
+ /* CSI prio 2 */
+ writel(0x1, 0x02021c18);
+ writel(0xa, 0x02021c14);
+ /* NPU prio 2 */
+ writel(0x1, 0x02020a18);
+ writel(0xa, 0x02020a14);
+
+ /* close ra0 autogating */
+ writel(0x0, 0x02023c00);
+ /* close ta autogating */
+ writel(0x0, 0x02023e00);
+ /* close pcie autogating */
+ writel(0x0, 0x02020600);
+}
+
+static void init_something(void)
+
+{
+ u32 *ptr = (u32 *)0x02000804;
+
+ do {
+ *ptr++ = 0xffffffff;
+ } while (ptr != (u32 *)0x20008e4);
+
+ writel(0, 0x07002400);
+ writel(0, 0x07002404);
+ writel(0, 0x07002408);
+
+ writel(0xffffffff, 0x07002004);
+ writel(0xffffffff, 0x07002014);
+ writel(0xffffffff, 0x07002024);
+ setbits_le32(0x07010290, 7);
+
+ writel(7, 0x02001f00);
+ writel(0xffff, 0x03002020);
+ writel(3, 0x020008e0);
+ writel(7, 0x07102008);
+}
+
+unsigned long sunxi_dram_init(void)
+{
+ struct dram_config config;
+ unsigned long size;
+
+ config.clk = 360;
+ switch (para.type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ config.odt_en = 0x90909090;
+ config.tpr11 = 0x8f919190;
+ config.tpr12 = 0x22222723;
+ config.tpr14 = 0x48484848;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ config.odt_en = 0x84848484;
+ config.tpr11 = 0x9a9a9a9a;
+ config.tpr12 = 0x0e0f070a;
+ config.tpr14 = 0x48484848;
+ break;
+ default:
+ panic("This DRAM setup is currently not supported.\n");
+ };
+
+ setbits_le32(0x03000160, BIT(8));
+ clrbits_le32(0x03000168, 0x3f);
+
+ mctl_auto_detect_rank_width(&para, &config);
+ mctl_auto_detect_dram_size(&para, &config);
+
+ config.clk = CONFIG_DRAM_CLK;
+ config.odt_en = CONFIG_DRAM_SUNXI_ODT_EN;
+ config.tpr11 = CONFIG_DRAM_SUNXI_TPR11;
+ config.tpr12 = CONFIG_DRAM_SUNXI_TPR12;
+ config.tpr14 = CONFIG_DRAM_SUNXI_TPR14;
+
+ mctl_core_init(&para, &config);
+
+ size = mctl_calc_size(&config);
+
+ sunxi_nsi_init();
+ init_something();
+
+ return size;
+};
diff --git a/arch/arm/mach-sunxi/dram_timings/Makefile b/arch/arm/mach-sunxi/dram_timings/Makefile
index 4dc1f29fc08..5de9fd5aab4 100644
--- a/arch/arm/mach-sunxi/dram_timings/Makefile
+++ b/arch/arm/mach-sunxi/dram_timings/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR3) += h616_lpddr3.o
obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR4) += h616_lpddr4_2133.o
obj-$(CONFIG_SUNXI_DRAM_A133_DDR4) += a133_ddr4.o
obj-$(CONFIG_SUNXI_DRAM_A133_LPDDR4) += a133_lpddr4.o
+obj-$(CONFIG_SUNXI_DRAM_A523_DDR3) += a523_ddr3.o
+obj-$(CONFIG_SUNXI_DRAM_A523_LPDDR4) += a523_lpddr4.o
diff --git a/arch/arm/mach-sunxi/dram_timings/a523_ddr3.c b/arch/arm/mach-sunxi/dram_timings/a523_ddr3.c
new file mode 100644
index 00000000000..6e140bb1454
--- /dev/null
+++ b/arch/arm/mach-sunxi/dram_timings/a523_ddr3.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * sun55i A523 DDR3 timings, as programmed by Allwinner's boot0 on
+ * the X96QPro+ TV box. As usual very conservative timings, but probably
+ * the most compatible and reliable.
+ *
+ * (C) Copyright 2024 Mikhail Kalashnikov <iuncuim@gmail.com>
+ * Based on H616 DDR3 timings:
+ * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net>
+ */
+
+#include <asm/arch/dram.h>
+#include <asm/arch/cpu.h>
+
+void mctl_set_timing_params(u32 clk)
+{
+ struct sunxi_mctl_ctl_reg * const mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ /*
+ * formulas and constraints as of
+ * JEDEC DDR3 specification, for
+ * DDR3-1600, per JESD79-3F
+ */
+ u8 tccd = 2; /* 4nCK */
+ u8 tfaw = ns_to_t(50, clk);
+ u8 trrd = max(ns_to_t(6, clk), 4); /* max(6 ns, 4nCK) */
+ u8 twtr = max(ns_to_t(8, clk), 4); /* max(7.5 ns, 4nCK) */
+ u8 trcd = ns_to_t(15, clk); /* 13.5 ns */
+ u8 trc = ns_to_t(53, clk);
+ u8 txp = max(ns_to_t(8, clk), 2); /* max(6 ns, 3nCK) */
+ u8 trtp = max(ns_to_t(8, clk), 4); /* max(7.5 ns, 4nCK) */
+ u8 trp = ns_to_t(15, clk); /* >= 13.75 ns */
+ u8 tras = ns_to_t(38, clk);
+ u16 trefi = ns_to_t(11350, clk) / 32;
+ u16 trfc = ns_to_t(360, clk); /* 160 ns for 2Gb */
+ u16 txsr = 4;
+
+ u8 tmrw = 0;
+ u8 tmrd = 4; /* 4nCK */
+
+ u8 tmod = max(ns_to_t(15, clk), 12); /* max(15 ns, 12nCK) */
+ u8 tcke = max(ns_to_t(6, clk), 4); /* max(5.625 ns, 3nCK)*/
+ u8 tcksrx = max(ns_to_t(10, clk), 4); /* max(10 ns, 5nCK) */
+ u8 tcksre = max(ns_to_t(10, clk), 4); /* max(10 ns, 5nCK) */
+ u8 trasmax = (clk / 2) / 15; /* tREFI * 9 */
+
+ /*
+ * TODO: support multiple DDR3 speed grades, these values below match
+ * the worst case for DDR3-2133, so should be good for all frequencies,
+ * but use the most conversative timings.
+ * DDR3-1866 (DRAM_CLK=912) should also work, or tcl=6 and tcwl=4 with
+ * DRAM_CLK=792. Maybe even the combination of both, depending on the
+ * particular device.
+ */
+ u8 tcl = 7; /* CAS latency: 14 */
+ u8 tcwl = 5; /* CAS write latency: 10 */
+ u8 t_rdata_en = 9;
+ u8 tphy_wrlat = 5;
+ u8 twr = 7;
+
+ u8 tckesr = tcke + 1; /* tCKE(min) + 1nCK */
+
+ u8 twtp = twr + 2 + tcwl;
+ u8 twr2rd = twtr + 2 + tcwl; /* (WL + BL / 2 + tWTR) / 2 */
+ u8 trd2wr = tcl + 3 - tcwl;
+ u8 txs = ns_to_t(360, clk) / 32; /* max(5nCK,tRFC+10ns)*/
+ u8 txsdll = 512 / 32; /* 512 nCK */
+ u8 txsabort = 4;
+ u8 txsfast = 4;
+
+ /* set DRAM timing */
+ writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
+ &mctl_ctl->dramtmg[0]);
+ writel((txp << 16) | (trtp << 8) | trc, &mctl_ctl->dramtmg[1]);
+ writel((tcwl << 24) | (tcl << 16) | (trd2wr << 8) | twr2rd,
+ &mctl_ctl->dramtmg[2]);
+ writel((tmrw << 20) | (tmrd << 12) | tmod, &mctl_ctl->dramtmg[3]);
+ writel((trcd << 24) | (tccd << 16) | (trrd << 8) | trp,
+ &mctl_ctl->dramtmg[4]);
+ writel((tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | tcke,
+ &mctl_ctl->dramtmg[5]);
+ /* Value suggested by ZynqMP manual and used by libdram */
+ writel((txp + 2) | 0x02020000, &mctl_ctl->dramtmg[6]);
+ writel((txsfast << 24) | (txsabort << 16) | (txsdll << 8) | txs,
+ &mctl_ctl->dramtmg[8]);
+ writel(0x00020208, &mctl_ctl->dramtmg[9]);
+ writel(0xe0c05, &mctl_ctl->dramtmg[10]);
+ writel(0x440c021c, &mctl_ctl->dramtmg[11]);
+ writel(8, &mctl_ctl->dramtmg[12]);
+ writel(0xa100002, &mctl_ctl->dramtmg[13]);
+ writel(txsr, &mctl_ctl->dramtmg[14]);
+
+ clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 0x156);
+ writel(0x01f20000, &mctl_ctl->init[1]);
+ writel(0x00001700, &mctl_ctl->init[2]);
+ writel(0, &mctl_ctl->dfimisc);
+ writel(0x1f140004, &mctl_ctl->init[3]);
+ writel(0x00200000, &mctl_ctl->init[4]);
+ writel(0, &mctl_ctl->init[6]); /* ? */
+ writel(0, &mctl_ctl->init[7]); /* ? */
+
+ clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
+
+ /* Configure DFI timing */
+ writel(tphy_wrlat | 0x2000000 | (t_rdata_en << 16) | 0x808000,
+ &mctl_ctl->dfitmg0);
+ writel(0x100202, &mctl_ctl->dfitmg1);
+
+ /* set refresh timing */
+ trfc = 0; /* as written so by boot0 */
+ writel((trefi << 16) | trfc, &mctl_ctl->rfshtmg);
+}
diff --git a/arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c b/arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c
new file mode 100644
index 00000000000..940a4d04d57
--- /dev/null
+++ b/arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * sun55i A523 LPDDR4-2133 timings, as programmed by Allwinner's boot0
+ *
+ * (C) Copyright 2024 Jernej Skrabec <jernej.skrabec@gmail.com>
+ * (C) Copyright 2023 Mikhail Kalashnikov <iuncuim@gmail.com>
+ *
+ */
+
+#include <asm/arch/dram.h>
+#include <asm/arch/cpu.h>
+
+void mctl_set_timing_params(u32 clk)
+{
+ struct sunxi_mctl_ctl_reg * const mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+ u8 tcl, tcwl, t_rdata_en, trtp, twr, tphy_wrlat;
+ unsigned int mr1, mr2;
+
+ u8 tccd = 4;
+ u8 tfaw = ns_to_t(40, clk);
+ u8 trrd = max(ns_to_t(10, clk), 2);
+ u8 twtr = max(ns_to_t(10, clk), 4);
+ u8 trcd = max(ns_to_t(18, clk), 2);
+ u8 trc = ns_to_t(65, clk);
+ u8 txp = max(ns_to_t(8, clk), 2);
+ u8 trp = ns_to_t(21, clk);
+ u8 tras = ns_to_t(42, clk);
+ u16 trefi = ns_to_t(3904, clk) / 32;
+ u16 trfc = ns_to_t(280, clk);
+ u16 txsr = ns_to_t(290, clk);
+
+ u8 tmrw = max(ns_to_t(14, clk), 5);
+ u8 tmod = 12;
+ u8 tcke = max(ns_to_t(15, clk), 2);
+ u8 tcksrx = max(ns_to_t(2, clk), 2);
+ u8 tcksre = max(ns_to_t(5, clk), 2);
+ u8 trasmax = (trefi * 9) / 32;
+
+ if (clk <= 936) {
+ mr1 = 0x34;
+ mr2 = 0x1b;
+ tcl = 10;
+ tcwl = 5;
+ t_rdata_en = 17;
+ trtp = 4;
+ tphy_wrlat = 5;
+ twr = 10;
+ } else if (clk <= 1200) {
+ mr1 = 0x54;
+ mr2 = 0x2d;
+ tcl = 14;
+ tcwl = 7;
+ t_rdata_en = 25;
+ trtp = 6;
+ tphy_wrlat = 9;
+ twr = 15;
+ } else {
+ mr1 = 0x64;
+ mr2 = 0x36;
+ tcl = 16;
+ tcwl = 8;
+ t_rdata_en = 29;
+ trtp = 7;
+ tphy_wrlat = 11;
+ twr = 17;
+ }
+
+ u8 tmrd = tmrw;
+ u8 tckesr = tcke;
+ u8 twtp = twr + 9 + tcwl;
+ u8 twr2rd = twtr + 9 + tcwl;
+ u8 trd2wr = ns_to_t(4, clk) + 7 - ns_to_t(1, clk) + tcl;
+ u8 txs = 4;
+ u8 txsdll = 16;
+ u8 txsabort = 4;
+ u8 txsfast = 4;
+
+ /* set DRAM timing */
+ writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
+ &mctl_ctl->dramtmg[0]);
+ writel((txp << 16) | (trtp << 8) | trc, &mctl_ctl->dramtmg[1]);
+ writel((tcwl << 24) | (tcl << 16) | (trd2wr << 8) | twr2rd,
+ &mctl_ctl->dramtmg[2]);
+ writel((tmrw << 20) | (tmrd << 12) | tmod, &mctl_ctl->dramtmg[3]);
+ writel((trcd << 24) | (tccd << 16) | (trrd << 8) | trp,
+ &mctl_ctl->dramtmg[4]);
+ writel((tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | tcke,
+ &mctl_ctl->dramtmg[5]);
+ /* Value suggested by ZynqMP manual and used by libdram */
+ writel((txp + 2) | 0x02020000, &mctl_ctl->dramtmg[6]);
+ writel((txsfast << 24) | (txsabort << 16) | (txsdll << 8) | txs,
+ &mctl_ctl->dramtmg[8]);
+ writel(0x00020208, &mctl_ctl->dramtmg[9]);
+ writel(0xE0C05, &mctl_ctl->dramtmg[10]);
+ writel(0x440C021C, &mctl_ctl->dramtmg[11]);
+ writel(8, &mctl_ctl->dramtmg[12]);
+ writel(0xA100002, &mctl_ctl->dramtmg[13]);
+ writel(txsr, &mctl_ctl->dramtmg[14]);
+
+ clrsetbits_le32(&mctl_ctl->init[0], 0xC0000FFF, 0x558);
+ writel(0x01f20000, &mctl_ctl->init[1]);
+ writel(0x00001705, &mctl_ctl->init[2]);
+ writel(0, &mctl_ctl->dfimisc);
+ writel((mr1 << 16) | mr2, &mctl_ctl->init[3]);
+ writel(0x00330000, &mctl_ctl->init[4]);
+ writel(0x00040072, &mctl_ctl->init[6]);
+ writel(0x00260008, &mctl_ctl->init[7]);
+
+ clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
+
+ /* Configure DFI timing */
+ writel(tphy_wrlat | 0x2000000 | (t_rdata_en << 16) | 0x808000,
+ &mctl_ctl->dfitmg0);
+ writel(0x100202, &mctl_ctl->dfitmg1);
+
+ /* set refresh timing */
+ writel((trefi << 16) | trfc, &mctl_ctl->rfshtmg);
+}