diff options
Diffstat (limited to 'arch/arm')
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 = <®_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 = <®_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 = <ðphy>; - 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 = <®_usb_otg_vbus>; - status = "okay"; -}; - -&usdhc3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc3>; - cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - vmmc-supply = <®_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; +}; + +®_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>; +}; + +ðphy1 { + 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 = <®_vref_1v8>; + status = "okay"; +}; + +&eqos { + phy-handle = <ðphy1>; + 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 = <ðphy2>; + 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 = <®_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(¶, &config); + mctl_auto_detect_dram_size(¶, &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(¶, &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); +} |