summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi42
-rw-r--r--arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts72
-rw-r--r--arch/arm/dts/imx6qdl-phytec-mira.dtsi390
-rw-r--r--arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi287
-rw-r--r--arch/arm/dts/imx7s.dtsi2
-rw-r--r--arch/arm/include/asm/arch-imx/cpu.h5
-rw-r--r--arch/arm/include/asm/arch-imx8/sci/rpc.h1
-rw-r--r--arch/arm/include/asm/arch-imx8/sci/sci.h1
-rw-r--r--arch/arm/include/asm/arch-imx8m/ddr.h10
-rw-r--r--arch/arm/include/asm/arch-imx8m/imx-regs.h158
-rw-r--r--arch/arm/include/asm/mach-imx/sys_proto.h9
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/cpu.c12
-rw-r--r--arch/arm/mach-imx/imx8/misc.c7
-rw-r--r--arch/arm/mach-imx/imx8m/clock_imx8mm.c299
-rw-r--r--arch/arm/mach-imx/imx8m/lowlevel_init.S12
-rw-r--r--arch/arm/mach-imx/imx8m/soc.c612
-rw-r--r--arch/arm/mach-imx/imx_bootaux.c11
-rw-r--r--arch/arm/mach-imx/mx6/Kconfig4
-rw-r--r--arch/arm/mach-imx/mx6/soc.c10
-rw-r--r--arch/arm/mach-imx/sip.c48
23 files changed, 1929 insertions, 68 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 86238524f7..e16fe03887 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -888,7 +888,7 @@ config ARCH_MX7
config ARCH_MX6
bool "Freescale MX6"
select CPU_V7A
- select SYS_FSL_HAS_SEC if IMX_HAB
+ select SYS_FSL_HAS_SEC
select SYS_FSL_SEC_COMPAT_4
select SYS_FSL_SEC_LE
imply MXC_GPIO
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index d839cb49b3..cee10f533f 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -678,6 +678,7 @@ dtb-y += \
imx6q-nitrogen6x.dtb \
imx6q-novena.dtb \
imx6q-pico.dtb \
+ imx6q-phytec-mira-rdk-nand.dtb \
imx6q-sabreauto.dtb \
imx6q-sabrelite.dtb \
imx6q-sabresd.dtb \
diff --git a/arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi b/arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi
new file mode 100644
index 0000000000..8555be1696
--- /dev/null
+++ b/arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020
+ * Niel Fourie, DENX Software Engineering, lusus@denx.de.
+ */
+#include "imx6qdl-u-boot.dtsi"
+
+&gpio3 {
+ u-boot,dm-spl;
+};
+
+&gpio6 {
+ u-boot,dm-spl;
+};
+
+&pinctrl_uart2 {
+ u-boot,dm-spl;
+};
+
+&uart2 {
+ u-boot,dm-spl;
+};
+
+&usdhc1 {
+ u-boot,dm-spl;
+};
+
+&pinctrl_usdhc1 {
+ u-boot,dm-spl;
+};
+
+&ecspi1 {
+ u-boot,dm-spl;
+};
+
+&pinctrl_ecspi1 {
+ u-boot,dm-spl;
+};
+
+&m25p80 {
+ u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts b/arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts
new file mode 100644
index 0000000000..65d2e483c1
--- /dev/null
+++ b/arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-phytec-phycore-som.dtsi"
+#include "imx6qdl-phytec-mira.dtsi"
+
+/ {
+ model = "PHYTEC phyBOARD-Mira Quad Carrier-Board with NAND";
+ compatible = "phytec,imx6q-pbac06-nand", "phytec,imx6q-pbac06",
+ "phytec,imx6qdl-pcm058", "fsl,imx6q";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+};
+
+&can1 {
+ status = "okay";
+};
+
+&fec {
+ status = "okay";
+};
+
+&gpmi {
+ status = "okay";
+};
+
+&hdmi {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c_rtc {
+ status = "okay";
+};
+
+&m25p80 {
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ status = "okay";
+};
+
+&usdhc1 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/imx6qdl-phytec-mira.dtsi b/arch/arm/dts/imx6qdl-phytec-mira.dtsi
new file mode 100644
index 0000000000..9ebd438dce
--- /dev/null
+++ b/arch/arm/dts/imx6qdl-phytec-mira.dtsi
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+
+/ {
+ aliases {
+ rtc0 = &i2c_rtc;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_backlight>;
+ pwms = <&pwm1 0 5000000>;
+ status = "okay";
+ };
+
+ gpio_leds: leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpioleds>;
+ status = "disabled";
+
+ red {
+ label = "phyboard-mira:red";
+ gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>;
+ };
+
+ green {
+ label = "phyboard-mira:green";
+ gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ blue {
+ label = "phyboard-mira:blue";
+ gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ reg_backlight: regulator-backlight {
+ compatible = "regulator-fixed";
+ regulator-name = "backlight_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_en_switch: regulator-en-switch {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_en_switch>;
+ regulator-name = "Enable Switch";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ };
+
+ reg_flexcan1: regulator-flexcan1 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1_en>;
+ regulator-name = "flexcan1-reg";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_panel: regulator-panel {
+ compatible = "regulator-fixed";
+ regulator-name = "panel-power-supply";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ };
+
+ reg_pcie: regulator-pcie {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie_reg>;
+ regulator-name = "mPCIe_1V5";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&gpio3 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_h1_vbus: usb-h1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_vbus>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio2 18 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usbotg_vbus: usbotg-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg_vbus>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ panel {
+ compatible = "auo,g104sn02";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_panel_en>;
+ power-supply = <&reg_panel>;
+ enable-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+ backlight = <&backlight>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ xceiver-supply = <&reg_flexcan1>;
+ status = "disabled";
+};
+
+&hdmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmicec>;
+ ddc-i2c-bus = <&i2c2>;
+ status = "disabled";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clock-frequency = <400000>;
+ status = "disabled";
+
+ stmpe: touchctrl@44 {
+ compatible = "st,stmpe811";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_stmpe>;
+ reg = <0x44>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <12 IRQ_TYPE_NONE>;
+ status = "disabled";
+
+ stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ st,sample-time = <4>;
+ st,mod-12b = <1>;
+ st,ref-sel = <0>;
+ st,adc-freq = <1>;
+ st,ave-ctrl = <1>;
+ st,touch-det-delay = <2>;
+ st,settling = <2>;
+ st,fraction-z = <7>;
+ st,i-drive = <1>;
+ };
+ };
+
+ i2c_rtc: rtc@68 {
+ compatible = "microcrystal,rv4162";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rtc_int>;
+ reg = <0x68>;
+ interrupt-parent = <&gpio7>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clock-frequency = <100000>;
+ status = "disabled";
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "disabled";
+
+ port@4 {
+ reg = <4>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio2 25 GPIO_ACTIVE_LOW>;
+ vpcie-supply = <&reg_pcie>;
+ status = "disabled";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ uart-has-rtscts;
+ status = "disabled";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usb_h1_vbus>;
+ disable-over-current;
+ status = "disabled";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ vbus-supply = <&reg_usbotg_vbus>;
+ disable-over-current;
+ status = "disabled";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ cd-gpios = <&gpio6 31 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_panel_en: panelen1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0xb0b1
+ >;
+ };
+
+ pinctrl_en_switch: enswitchgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0xb0b1
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
+ MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_flexcan1_en: flexcan1engrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0xb0b1
+ >;
+ };
+
+ pinctrl_gpioleds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT6__GPIO5_IO24 0x1b0b0
+ >;
+ };
+
+ pinctrl_hdmicec: hdmicecgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_OE__GPIO2_IO25 0xb0b1
+ >;
+ };
+
+ pinctrl_pcie_reg: pciereggrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0xb0b1
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_rtc_int: rtcintgrp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x1b0b0
+ >;
+ };
+
+ pinctrl_stmpe: stmpegrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB3__UART3_CTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D23__UART3_RTS_B 0x1b0b1
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbh1_vbus: usbh1vbusgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A20__GPIO2_IO18 0xb0b1
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg_vbus: usbotgvbusgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A19__GPIO2_IO19 0xb0b1
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f9
+ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9
+ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
+ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
+ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
+ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0xb0b1 /* CD */
+ >;
+ };
+};
diff --git a/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi
new file mode 100644
index 0000000000..77d871340e
--- /dev/null
+++ b/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 PHYTEC Messtechnik GmbH
+ * Author: Christian Hemp <c.hemp@phytec.de>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/dlg,da9063-regulator.h>
+
+/ {
+ aliases {
+ rtc1 = &da9062_rtc;
+ rtc2 = &snvs_rtc;
+ };
+
+ /*
+ * Set the minimum memory size here and
+ * let the bootloader set the real size.
+ */
+ memory@10000000 {
+ device_type = "memory";
+ reg = <0x10000000 0x8000000>;
+ };
+
+ gpio_leds_som: somleds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpioleds_som>;
+
+ som-led-green {
+ label = "phycore:green";
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ m25p80: flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ status = "disabled";
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-handle = <&ethphy>;
+ phy-mode = "rgmii";
+ phy-supply = <&vdd_eth_io>;
+ phy-reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy: ethernet-phy@3 {
+ reg = <3>;
+ txc-skew-ps = <1680>;
+ rxc-skew-ps = <1860>;
+ };
+ };
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ nand-on-flash-bbt;
+ status = "disabled";
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c32";
+ reg = <0x50>;
+ };
+
+ pmic@58 {
+ compatible = "dlg,da9062";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ reg = <0x58>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+
+ da9062_rtc: rtc {
+ compatible = "dlg,da9062-rtc";
+ };
+
+ da9062_onkey: onkey {
+ compatible = "dlg,da9062-onkey";
+ };
+
+ watchdog {
+ compatible = "dlg,da9062-watchdog";
+ };
+
+ regulators {
+ vdd_arm: buck1 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1380000>;
+ regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
+ regulator-always-on;
+ };
+
+ vdd_soc: buck2 {
+ regulator-name = "vdd_soc";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1380000>;
+ regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
+ regulator-always-on;
+ };
+
+ vdd_ddr3_1p5: buck3 {
+ regulator-name = "vdd_ddr3";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
+ regulator-always-on;
+ };
+
+ vdd_eth_1p2: buck4 {
+ regulator-name = "vdd_eth";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
+ regulator-always-on;
+ };
+
+ vdd_snvs: ldo1 {
+ regulator-name = "vdd_snvs";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vdd_high: ldo2 {
+ regulator-name = "vdd_high";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ vdd_eth_io: ldo3 {
+ regulator-name = "vdd_eth_io";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ vdd_emmc_1p8: ldo4 {
+ regulator-name = "vdd_emmc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+};
+
+&reg_arm {
+ vin-supply = <&vdd_arm>;
+};
+
+&reg_pu {
+ vin-supply = <&vdd_soc>;
+};
+
+&reg_soc {
+ vin-supply = <&vdd_soc>;
+};
+
+&snvs_poweroff {
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpioleds_som: gpioledssomgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 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_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS2__NAND_CE2_B 0xb0b1
+ MX6QDL_PAD_NANDF_CS3__NAND_CE3_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
+ MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x1b0b0
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+};
diff --git a/arch/arm/dts/imx7s.dtsi b/arch/arm/dts/imx7s.dtsi
index 5c2e98be06..967023fde1 100644
--- a/arch/arm/dts/imx7s.dtsi
+++ b/arch/arm/dts/imx7s.dtsi
@@ -323,7 +323,7 @@
port {
tpiu_in_port: endpoint {
slave-mode;
- remote-endpoint = <&replicator_out_port1>;
+ remote-endpoint = <&replicator_out_port0>;
};
};
};
diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h
index e9c0078922..75ff991248 100644
--- a/arch/arm/include/asm/arch-imx/cpu.h
+++ b/arch/arm/include/asm/arch-imx/cpu.h
@@ -41,6 +41,11 @@
#define MXC_CPU_IMX8MNDL 0x8f /* dummy ID */
#define MXC_CPU_IMX8MNSL 0x181 /* dummy ID */
#define MXC_CPU_IMX8MP 0x182/* dummy ID */
+#define MXC_CPU_IMX8MP7 0x183 /* dummy ID */
+#define MXC_CPU_IMX8MP6 0x184 /* dummy ID */
+#define MXC_CPU_IMX8MP5 0x185 /* dummy ID */
+#define MXC_CPU_IMX8MPL 0x186 /* dummy ID */
+#define MXC_CPU_IMX8MPD 0x187 /* dummy ID */
#define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */
#define MXC_CPU_IMX8QM 0x91 /* dummy ID */
#define MXC_CPU_IMX8QXP 0x92 /* dummy ID */
diff --git a/arch/arm/include/asm/arch-imx8/sci/rpc.h b/arch/arm/include/asm/arch-imx8/sci/rpc.h
index c1a9c353ba..9f55904f44 100644
--- a/arch/arm/include/asm/arch-imx8/sci/rpc.h
+++ b/arch/arm/include/asm/arch-imx8/sci/rpc.h
@@ -115,6 +115,7 @@ struct sc_rpc_msg_s {
#define MISC_FUNC_GET_TEMP 13U
#define MISC_FUNC_GET_BOOT_DEV 16U
#define MISC_FUNC_GET_BUTTON_STATUS 18U
+#define MISC_FUNC_GET_BOOT_CONTAINER 36U
/* PAD RPC */
#define PAD_FUNC_UNKNOWN 0
diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h
index f91f7cc587..1c29209b39 100644
--- a/arch/arm/include/asm/arch-imx8/sci/sci.h
+++ b/arch/arm/include/asm/arch-imx8/sci/sci.h
@@ -82,6 +82,7 @@ int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
u32 *val);
void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev);
void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx);
void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit);
int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val);
int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
diff --git a/arch/arm/include/asm/arch-imx8m/ddr.h b/arch/arm/include/asm/arch-imx8m/ddr.h
index 7a2a2d8edc..0f1e832c03 100644
--- a/arch/arm/include/asm/arch-imx8m/ddr.h
+++ b/arch/arm/include/asm/arch-imx8m/ddr.h
@@ -529,6 +529,8 @@ enum msg_response {
#define DDRC_SBRWDATA0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf2c)
#define DDRC_SBRWDATA1(X) (DDRC_IPS_BASE_ADDR(X) + 0xf30)
#define DDRC_PDCH(X) (DDRC_IPS_BASE_ADDR(X) + 0xf34)
+#define DDRC_SBRSTART0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf38)
+#define DDRC_SBRRANGE0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf40)
#define DDRC_FREQ1_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x2020)
#define DDRC_FREQ1_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x2024)
@@ -708,12 +710,20 @@ int ddr_cfg_phy(struct dram_timing_info *timing_info);
void load_lpddr4_phy_pie(void);
void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num);
void dram_config_save(struct dram_timing_info *info, unsigned long base);
+void board_dram_ecc_scrub(void);
+void ddrc_inline_ecc_scrub(unsigned int start_address,
+ unsigned int range_address);
+void ddrc_inline_ecc_scrub_end(unsigned int start_address,
+ unsigned int range_address);
/* utils function for ddr phy training */
int wait_ddrphy_training_complete(void);
void ddrphy_init_set_dfi_clk(unsigned int drate);
void ddrphy_init_read_msg_block(enum fw_type type);
+void update_umctl2_rank_space_setting(unsigned int pstat_num);
+void get_trained_CDD(unsigned int fsp);
+
static inline void reg32_write(unsigned long addr, u32 val)
{
writel(val, addr);
diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h
index 3cfa169c97..f1c410ec78 100644
--- a/arch/arm/include/asm/arch-imx8m/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h
@@ -331,5 +331,163 @@ struct bootrom_sw_info {
#define ROM_SW_INFO_ADDR is_soc_rev(CHIP_REV_1_0) ? \
(struct bootrom_sw_info **)ROM_SW_INFO_ADDR_A0 : \
(struct bootrom_sw_info **)ROM_SW_INFO_ADDR_B0
+
+struct gpc_reg {
+ u32 lpcr_bsc;
+ u32 lpcr_ad;
+ u32 lpcr_cpu1;
+ u32 lpcr_cpu2;
+ u32 lpcr_cpu3;
+ u32 slpcr;
+ u32 mst_cpu_mapping;
+ u32 mmdc_cpu_mapping;
+ u32 mlpcr;
+ u32 pgc_ack_sel;
+ u32 pgc_ack_sel_m4;
+ u32 gpc_misc;
+ u32 imr1_core0;
+ u32 imr2_core0;
+ u32 imr3_core0;
+ u32 imr4_core0;
+ u32 imr1_core1;
+ u32 imr2_core1;
+ u32 imr3_core1;
+ u32 imr4_core1;
+ u32 imr1_cpu1;
+ u32 imr2_cpu1;
+ u32 imr3_cpu1;
+ u32 imr4_cpu1;
+ u32 imr1_cpu3;
+ u32 imr2_cpu3;
+ u32 imr3_cpu3;
+ u32 imr4_cpu3;
+ u32 isr1_cpu0;
+ u32 isr2_cpu0;
+ u32 isr3_cpu0;
+ u32 isr4_cpu0;
+ u32 isr1_cpu1;
+ u32 isr2_cpu1;
+ u32 isr3_cpu1;
+ u32 isr4_cpu1;
+ u32 isr1_cpu2;
+ u32 isr2_cpu2;
+ u32 isr3_cpu2;
+ u32 isr4_cpu2;
+ u32 isr1_cpu3;
+ u32 isr2_cpu3;
+ u32 isr3_cpu3;
+ u32 isr4_cpu3;
+ u32 slt0_cfg;
+ u32 slt1_cfg;
+ u32 slt2_cfg;
+ u32 slt3_cfg;
+ u32 slt4_cfg;
+ u32 slt5_cfg;
+ u32 slt6_cfg;
+ u32 slt7_cfg;
+ u32 slt8_cfg;
+ u32 slt9_cfg;
+ u32 slt10_cfg;
+ u32 slt11_cfg;
+ u32 slt12_cfg;
+ u32 slt13_cfg;
+ u32 slt14_cfg;
+ u32 pgc_cpu_0_1_mapping;
+ u32 cpu_pgc_up_trg;
+ u32 mix_pgc_up_trg;
+ u32 pu_pgc_up_trg;
+ u32 cpu_pgc_dn_trg;
+ u32 mix_pgc_dn_trg;
+ u32 pu_pgc_dn_trg;
+ u32 lpcr_bsc2;
+ u32 pgc_cpu_2_3_mapping;
+ u32 lps_cpu0;
+ u32 lps_cpu1;
+ u32 lps_cpu2;
+ u32 lps_cpu3;
+ u32 gpc_gpr;
+ u32 gtor;
+ u32 debug_addr1;
+ u32 debug_addr2;
+ u32 cpu_pgc_up_status1;
+ u32 mix_pgc_up_status0;
+ u32 mix_pgc_up_status1;
+ u32 mix_pgc_up_status2;
+ u32 m4_mix_pgc_up_status0;
+ u32 m4_mix_pgc_up_status1;
+ u32 m4_mix_pgc_up_status2;
+ u32 pu_pgc_up_status0;
+ u32 pu_pgc_up_status1;
+ u32 pu_pgc_up_status2;
+ u32 m4_pu_pgc_up_status0;
+ u32 m4_pu_pgc_up_status1;
+ u32 m4_pu_pgc_up_status2;
+ u32 a53_lp_io_0;
+ u32 a53_lp_io_1;
+ u32 a53_lp_io_2;
+ u32 cpu_pgc_dn_status1;
+ u32 mix_pgc_dn_status0;
+ u32 mix_pgc_dn_status1;
+ u32 mix_pgc_dn_status2;
+ u32 m4_mix_pgc_dn_status0;
+ u32 m4_mix_pgc_dn_status1;
+ u32 m4_mix_pgc_dn_status2;
+ u32 pu_pgc_dn_status0;
+ u32 pu_pgc_dn_status1;
+ u32 pu_pgc_dn_status2;
+ u32 m4_pu_pgc_dn_status0;
+ u32 m4_pu_pgc_dn_status1;
+ u32 m4_pu_pgc_dn_status2;
+ u32 res[3];
+ u32 mix_pdn_flg;
+ u32 pu_pdn_flg;
+ u32 m4_mix_pdn_flg;
+ u32 m4_pu_pdn_flg;
+ u32 imr1_core2;
+ u32 imr2_core2;
+ u32 imr3_core2;
+ u32 imr4_core2;
+ u32 imr1_core3;
+ u32 imr2_core3;
+ u32 imr3_core3;
+ u32 imr4_core3;
+ u32 pgc_ack_sel_pu;
+ u32 pgc_ack_sel_m4_pu;
+ u32 slt15_cfg;
+ u32 slt16_cfg;
+ u32 slt17_cfg;
+ u32 slt18_cfg;
+ u32 slt19_cfg;
+ u32 gpc_pu_pwrhsk;
+ u32 slt0_cfg_pu;
+ u32 slt1_cfg_pu;
+ u32 slt2_cfg_pu;
+ u32 slt3_cfg_pu;
+ u32 slt4_cfg_pu;
+ u32 slt5_cfg_pu;
+ u32 slt6_cfg_pu;
+ u32 slt7_cfg_pu;
+ u32 slt8_cfg_pu;
+ u32 slt9_cfg_pu;
+ u32 slt10_cfg_pu;
+ u32 slt11_cfg_pu;
+ u32 slt12_cfg_pu;
+ u32 slt13_cfg_pu;
+ u32 slt14_cfg_pu;
+ u32 slt15_cfg_pu;
+ u32 slt16_cfg_pu;
+ u32 slt17_cfg_pu;
+ u32 slt18_cfg_pu;
+ u32 slt19_cfg_pu;
+};
+
+struct pgc_reg {
+ u32 pgcr;
+ u32 pgpupscr;
+ u32 pgpdnscr;
+ u32 pgsr;
+ u32 pgauxsw;
+ u32 pgdr;
+};
#endif
#endif
diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h
index 0bc705df17..ab94024c9b 100644
--- a/arch/arm/include/asm/mach-imx/sys_proto.h
+++ b/arch/arm/include/asm/mach-imx/sys_proto.h
@@ -66,7 +66,14 @@ struct bd_info;
#define is_imx8mnl() (is_cpu_type(MXC_CPU_IMX8MNL))
#define is_imx8mndl() (is_cpu_type(MXC_CPU_IMX8MNDL))
#define is_imx8mnsl() (is_cpu_type(MXC_CPU_IMX8MNSL))
-#define is_imx8mp() (is_cpu_type(MXC_CPU_IMX8MP))
+#define is_imx8mp() (is_cpu_type(MXC_CPU_IMX8MP) || is_cpu_type(MXC_CPU_IMX8MPD) || \
+ is_cpu_type(MXC_CPU_IMX8MPL) || is_cpu_type(MXC_CPU_IMX8MP7) || \
+ is_cpu_type(MXC_CPU_IMX8MP6) || is_cpu_type(MXC_CPU_IMX8MP5))
+#define is_imx8mpd() (is_cpu_type(MXC_CPU_IMX8MPD))
+#define is_imx8mpl() (is_cpu_type(MXC_CPU_IMX8MPL))
+#define is_imx8mp7() (is_cpu_type(MXC_CPU_IMX8MP7))
+#define is_imx8mp6() (is_cpu_type(MXC_CPU_IMX8MP6))
+#define is_imx8mp5() (is_cpu_type(MXC_CPU_IMX8MP5))
#define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP))
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index a70d51b5cf..1aa26a50ad 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -218,7 +218,7 @@ endif
targets += $(addprefix ../../../,SPL spl/u-boot-spl.cfgout u-boot-dtb.cfgout u-boot.cfgout u-boot.uim spl/u-boot-nand-spl.imx)
-obj-$(CONFIG_ARM64) += lowlevel.o sip.o
+obj-$(CONFIG_ARM64) += lowlevel.o
obj-$(CONFIG_MX5) += mx5/
obj-$(CONFIG_MX6) += mx6/
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index f2070c9714..b89d27ffd2 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -96,7 +96,17 @@ const char *get_imx_type(u32 imxtype)
{
switch (imxtype) {
case MXC_CPU_IMX8MP:
- return "8MP"; /* Quad-core version of the imx8mp */
+ return "8MP[8]"; /* Quad-core version of the imx8mp */
+ case MXC_CPU_IMX8MPD:
+ return "8MP Dual[3]"; /* Dual-core version of the imx8mp */
+ case MXC_CPU_IMX8MPL:
+ return "8MP Lite[4]"; /* Quad-core Lite version of the imx8mp */
+ case MXC_CPU_IMX8MP7:
+ return "8MP[7]"; /* Quad-core version of the imx8mp, VPU fused */
+ case MXC_CPU_IMX8MP6:
+ return "8MP[6]"; /* Quad-core version of the imx8mp, NPU fused */
+ case MXC_CPU_IMX8MP5:
+ return "8MP[5]"; /* Quad-core version of the imx8mp, ISP fused */
case MXC_CPU_IMX8MN:
return "8MNano Quad"; /* Quad-core version */
case MXC_CPU_IMX8MND:
diff --git a/arch/arm/mach-imx/imx8/misc.c b/arch/arm/mach-imx/imx8/misc.c
index 2cd794d54a..de19955e2f 100644
--- a/arch/arm/mach-imx/imx8/misc.c
+++ b/arch/arm/mach-imx/imx8/misc.c
@@ -4,6 +4,7 @@
#include <asm/arch/sci/sci.h>
#include <asm/mach-imx/sys_proto.h>
#include <imx_sip.h>
+#include <linux/arm-smccc.h>
int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate)
{
@@ -30,6 +31,7 @@ int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate)
void build_info(void)
{
+ struct arm_smccc_res res;
u32 seco_build = 0, seco_commit = 0;
u32 sc_build = 0, sc_commit = 0;
ulong atf_commit = 0;
@@ -50,8 +52,9 @@ void build_info(void)
}
/* Get ARM Trusted Firmware commit id */
- atf_commit = call_imx_sip(IMX_SIP_BUILDINFO,
- IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0);
+ arm_smccc_smc(IMX_SIP_BUILDINFO, IMX_SIP_BUILDINFO_GET_COMMITHASH,
+ 0, 0, 0, 0, 0, 0, &res);
+ atf_commit = res.a0;
if (atf_commit == 0xffffffff) {
debug("ATF does not support build info\n");
atf_commit = 0x30; /* Display 0 */
diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
index aafe2ed084..3610f5b2fc 100644
--- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c
+++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
@@ -19,6 +19,7 @@ DECLARE_GLOBAL_DATA_PTR;
static struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
+static u32 get_root_clk(enum clk_root_index clock_id);
void enable_ocotp_clk(unsigned char enable)
{
clock_enable(CCGR_OCOTP, !!enable);
@@ -164,6 +165,109 @@ void dram_disable_bypass(void)
}
#endif
+int intpll_configure(enum pll_clocks pll, ulong freq)
+{
+ void __iomem *pll_gnrl_ctl, __iomem *pll_div_ctl;
+ u32 pll_div_ctl_val, pll_clke_masks;
+
+ switch (pll) {
+ case ANATOP_SYSTEM_PLL1:
+ pll_gnrl_ctl = &ana_pll->sys_pll1_gnrl_ctl;
+ pll_div_ctl = &ana_pll->sys_pll1_div_ctl;
+ pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
+ INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
+ INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
+ INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
+ INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
+ break;
+ case ANATOP_SYSTEM_PLL2:
+ pll_gnrl_ctl = &ana_pll->sys_pll2_gnrl_ctl;
+ pll_div_ctl = &ana_pll->sys_pll2_div_ctl;
+ pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
+ INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
+ INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
+ INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
+ INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
+ break;
+ case ANATOP_SYSTEM_PLL3:
+ pll_gnrl_ctl = &ana_pll->sys_pll3_gnrl_ctl;
+ pll_div_ctl = &ana_pll->sys_pll3_div_ctl;
+ pll_clke_masks = INTPLL_CLKE_MASK;
+ break;
+ case ANATOP_ARM_PLL:
+ pll_gnrl_ctl = &ana_pll->arm_pll_gnrl_ctl;
+ pll_div_ctl = &ana_pll->arm_pll_div_ctl;
+ pll_clke_masks = INTPLL_CLKE_MASK;
+ break;
+ case ANATOP_GPU_PLL:
+ pll_gnrl_ctl = &ana_pll->gpu_pll_gnrl_ctl;
+ pll_div_ctl = &ana_pll->gpu_pll_div_ctl;
+ pll_clke_masks = INTPLL_CLKE_MASK;
+ break;
+ case ANATOP_VPU_PLL:
+ pll_gnrl_ctl = &ana_pll->vpu_pll_gnrl_ctl;
+ pll_div_ctl = &ana_pll->vpu_pll_div_ctl;
+ pll_clke_masks = INTPLL_CLKE_MASK;
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ switch (freq) {
+ case MHZ(600):
+ /* 24 * 0x12c / 3 / 2 ^ 2 */
+ pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x12c) |
+ INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2);
+ break;
+ case MHZ(750):
+ /* 24 * 0xfa / 2 / 2 ^ 2 */
+ pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
+ INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(2);
+ break;
+ case MHZ(800):
+ /* 24 * 0x190 / 3 / 2 ^ 2 */
+ pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x190) |
+ INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2);
+ break;
+ case MHZ(1000):
+ /* 24 * 0xfa / 3 / 2 ^ 1 */
+ pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
+ INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(1);
+ break;
+ case MHZ(1200):
+ /* 24 * 0xc8 / 2 / 2 ^ 1 */
+ pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xc8) |
+ INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(1);
+ break;
+ case MHZ(2000):
+ /* 24 * 0xfa / 3 / 2 ^ 0 */
+ pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
+ INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(0);
+ break;
+ default:
+ return -EINVAL;
+ };
+ /* Bypass clock and set lock to pll output lock */
+ setbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK | INTPLL_LOCK_SEL_MASK);
+ /* Enable reset */
+ clrbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
+ /* Configure */
+ writel(pll_div_ctl_val, pll_div_ctl);
+
+ __udelay(100);
+
+ /* Disable reset */
+ setbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
+ /* Wait Lock */
+ while (!(readl(pll_gnrl_ctl) & INTPLL_LOCK_MASK))
+ ;
+ /* Clear bypass */
+ clrbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK);
+ setbits_le32(pll_gnrl_ctl, pll_clke_masks);
+
+ return 0;
+}
+
void init_uart_clk(u32 index)
{
/*
@@ -213,6 +317,72 @@ void init_wdog_clk(void)
clock_enable(CCGR_WDOG3, 1);
}
+void init_clk_usdhc(u32 index)
+{
+ /*
+ * set usdhc clock root
+ * sys pll1 400M
+ */
+ switch (index) {
+ case 0:
+ clock_enable(CCGR_USDHC1, 0);
+ clock_set_target_val(USDHC1_CLK_ROOT, CLK_ROOT_ON |
+ CLK_ROOT_SOURCE_SEL(1));
+ clock_enable(CCGR_USDHC1, 1);
+ return;
+ case 1:
+ clock_enable(CCGR_USDHC2, 0);
+ clock_set_target_val(USDHC2_CLK_ROOT, CLK_ROOT_ON |
+ CLK_ROOT_SOURCE_SEL(1));
+ clock_enable(CCGR_USDHC2, 1);
+ return;
+ case 2:
+ clock_enable(CCGR_USDHC3, 0);
+ clock_set_target_val(USDHC3_CLK_ROOT, CLK_ROOT_ON |
+ CLK_ROOT_SOURCE_SEL(1));
+ clock_enable(CCGR_USDHC3, 1);
+ return;
+ default:
+ printf("Invalid usdhc index\n");
+ return;
+ }
+}
+
+void init_clk_ecspi(u32 index)
+{
+ switch (index) {
+ case 0:
+ clock_enable(CCGR_ECSPI1, 0);
+ clock_set_target_val(ECSPI1_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0));
+ clock_enable(CCGR_ECSPI1, 1);
+ return;
+ case 1:
+ clock_enable(CCGR_ECSPI2, 0);
+ clock_set_target_val(ECSPI2_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0));
+ clock_enable(CCGR_ECSPI2, 1);
+ case 2:
+ clock_enable(CCGR_ECSPI3, 0);
+ clock_set_target_val(ECSPI3_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0));
+ clock_enable(CCGR_ECSPI3, 1);
+ return;
+ default:
+ printf("Invalid ecspi index\n");
+ return;
+ }
+}
+
+void init_nand_clk(void)
+{
+ /*
+ * set rawnand root
+ * sys pll1 400M
+ */
+ clock_enable(CCGR_RAWNAND, 0);
+ clock_set_target_val(NAND_CLK_ROOT, CLK_ROOT_ON |
+ CLK_ROOT_SOURCE_SEL(3) | CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4)); /* 100M */
+ clock_enable(CCGR_RAWNAND, 1);
+}
+
int clock_init(void)
{
u32 val_cfg0;
@@ -240,11 +410,33 @@ int clock_init(void)
INTPLL_DIV20_CLKE_MASK;
writel(val_cfg0, &ana_pll->sys_pll2_gnrl_ctl);
+ /* Configure ARM at 1.2GHz */
+ clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON |
+ CLK_ROOT_SOURCE_SEL(2));
+
+ intpll_configure(ANATOP_ARM_PLL, MHZ(1200));
+
+ /* Bypass CCM A53 ROOT, Switch to ARM PLL -> MUX-> CPU */
+ clock_set_target_val(CORE_SEL_CFG, CLK_ROOT_SOURCE_SEL(1));
+
+ if (is_imx8mn() || is_imx8mp())
+ intpll_configure(ANATOP_SYSTEM_PLL3, MHZ(600));
+ else
+ intpll_configure(ANATOP_SYSTEM_PLL3, MHZ(750));
+
+#ifdef CONFIG_IMX8MP
+ /* 8MP ROM already set NOC to 800Mhz, only need to configure NOC_IO clk to 600Mhz */
+ /* 8MP ROM already set GIC to 400Mhz, system_pll1_800m with div = 2 */
+ clock_set_target_val(NOC_IO_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2));
+#else
+ clock_set_target_val(NOC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2));
+
/* config GIC to sys_pll2_100m */
clock_enable(CCGR_GIC, 0);
clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(3));
clock_enable(CCGR_GIC, 1);
+#endif
clock_set_target_val(NAND_USDHC_BUS_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
@@ -519,6 +711,8 @@ static u32 get_root_src_clk(enum clk_root_src root_src)
case AUDIO_PLL2_CLK:
case VIDEO_PLL_CLK:
return decode_fracpll(root_src);
+ case ARM_A53_ALT_CLK:
+ return get_root_clk(ARM_A53_CLK_ROOT);
default:
return 0;
}
@@ -548,13 +742,26 @@ static u32 get_root_clk(enum clk_root_index clock_id)
return root_src_clk / (post_podf + 1) / (pre_podf + 1);
}
+u32 get_arm_core_clk(void)
+{
+ enum clk_root_src root_src;
+ u32 root_src_clk;
+
+ if (clock_get_src(CORE_SEL_CFG, &root_src) < 0)
+ return 0;
+
+ root_src_clk = get_root_src_clk(root_src);
+
+ return root_src_clk;
+}
+
u32 mxc_get_clock(enum mxc_clock clk)
{
u32 val;
switch (clk) {
case MXC_ARM_CLK:
- return get_root_clk(ARM_A53_CLK_ROOT);
+ return get_arm_core_clk();
case MXC_IPG_CLK:
clock_get_target_val(IPG_CLK_ROOT, &val);
val = val & 0x3;
@@ -581,6 +788,96 @@ u32 mxc_get_clock(enum mxc_clock clk)
return 0;
}
+#ifdef CONFIG_DWC_ETH_QOS
+int set_clk_eqos(enum enet_freq type)
+{
+ u32 target;
+ u32 enet1_ref;
+
+ switch (type) {
+ case ENET_125MHZ:
+ enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
+ break;
+ case ENET_50MHZ:
+ enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
+ break;
+ case ENET_25MHZ:
+ enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* disable the clock first */
+ clock_enable(CCGR_QOS_ETHENET, 0);
+ clock_enable(CCGR_SDMA2, 0);
+
+ /* set enet axi clock 266Mhz */
+ target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_SYS1_PLL_266M |
+ CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
+ CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
+ clock_set_target_val(ENET_AXI_CLK_ROOT, target);
+
+ target = CLK_ROOT_ON | enet1_ref |
+ CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
+ CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
+ clock_set_target_val(ENET_QOS_CLK_ROOT, target);
+
+ target = CLK_ROOT_ON |
+ ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK |
+ CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
+ CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
+ clock_set_target_val(ENET_QOS_TIMER_CLK_ROOT, target);
+
+ /* enable clock */
+ clock_enable(CCGR_QOS_ETHENET, 1);
+ clock_enable(CCGR_SDMA2, 1);
+
+ return 0;
+}
+
+int imx_eqos_txclk_set_rate(u32 rate)
+{
+ u32 val;
+ u32 eqos_post_div;
+
+ /* disable the clock first */
+ clock_enable(CCGR_QOS_ETHENET, 0);
+ clock_enable(CCGR_SDMA2, 0);
+
+ switch (rate) {
+ case 125000000:
+ eqos_post_div = 1;
+ break;
+ case 25000000:
+ eqos_post_div = 125000000 / 25000000;
+ break;
+ case 2500000:
+ eqos_post_div = 125000000 / 2500000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ clock_get_target_val(ENET_QOS_CLK_ROOT, &val);
+ val &= ~(CLK_ROOT_PRE_DIV_MASK | CLK_ROOT_POST_DIV_MASK);
+ val |= CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
+ CLK_ROOT_POST_DIV(eqos_post_div - 1);
+ clock_set_target_val(ENET_QOS_CLK_ROOT, val);
+
+ /* enable clock */
+ clock_enable(CCGR_QOS_ETHENET, 1);
+ clock_enable(CCGR_SDMA2, 1);
+
+ return 0;
+}
+
+u32 imx_get_eqos_csr_clk(void)
+{
+ return get_root_clk(ENET_AXI_CLK_ROOT);
+}
+#endif
+
#ifdef CONFIG_FEC_MXC
int set_clk_enet(enum enet_freq type)
{
diff --git a/arch/arm/mach-imx/imx8m/lowlevel_init.S b/arch/arm/mach-imx/imx8m/lowlevel_init.S
index a4c6466ca9..a49a9cdb35 100644
--- a/arch/arm/mach-imx/imx8m/lowlevel_init.S
+++ b/arch/arm/mach-imx/imx8m/lowlevel_init.S
@@ -60,3 +60,15 @@ restore_boot_params:
ldr x0, [x0]
mov sp, x0
ret
+
+.global armv8_el2_to_aarch32
+armv8_el2_to_aarch32:
+ cmp x0, #0
+ bne 0f
+ mov x3, x2
+ mov x2, x1
+ mov x1, x4
+ ldr x0, =0xc20000fd
+0:
+ smc #0
+ ret
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 1d2c8e6db2..b3c08271e6 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -16,12 +16,17 @@
#include <asm/mach-imx/hab.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/mach-imx/syscounter.h>
+#include <asm/ptrace.h>
#include <asm/armv8/mmu.h>
#include <dm/uclass.h>
+#include <efi_loader.h>
+#include <env.h>
+#include <env_internal.h>
#include <errno.h>
#include <fdt_support.h>
#include <fsl_wdog.h>
#include <imx_sip.h>
+#include <linux/arm-smccc.h>
#include <linux/bitops.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -138,6 +143,9 @@ static struct mm_region imx8m_mem_map[] = {
PTE_BLOCK_OUTER_SHARE
#endif
}, {
+ /* empty entrie to split table entry 5 if needed when TEEs are used */
+ 0,
+ }, {
/* List terminator */
0,
}
@@ -147,18 +155,123 @@ struct mm_region *mem_map = imx8m_mem_map;
void enable_caches(void)
{
- /*
- * If OPTEE runs, remove OPTEE memory from MMU table to
- * avoid speculative prefetch. OPTEE runs at the top of
- * the first memory bank
- */
- if (rom_pointer[1])
- imx8m_mem_map[5].size -= rom_pointer[1];
+ /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch */
+ if (rom_pointer[1]) {
+ /*
+ * TEE are loaded, So the ddr bank structures
+ * have been modified update mmu table accordingly
+ */
+ int i = 0;
+ /*
+ * please make sure that entry initial value matches
+ * imx8m_mem_map for DRAM1
+ */
+ int entry = 5;
+ u64 attrs = imx8m_mem_map[entry].attrs;
+
+ while (i < CONFIG_NR_DRAM_BANKS && entry < 8) {
+ if (gd->bd->bi_dram[i].start == 0)
+ break;
+ imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start;
+ imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start;
+ imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size;
+ imx8m_mem_map[entry].attrs = attrs;
+ debug("Added memory mapping (%d): %llx %llx\n", entry,
+ imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size);
+ i++; entry++;
+ }
+ }
icache_enable();
dcache_enable();
}
+__weak int board_phys_sdram_size(phys_size_t *size)
+{
+ if (!size)
+ return -EINVAL;
+
+ *size = PHYS_SDRAM_SIZE;
+ return 0;
+}
+
+int dram_init(void)
+{
+ phys_size_t sdram_size;
+ int ret;
+
+ ret = board_phys_sdram_size(&sdram_size);
+ if (ret)
+ return ret;
+
+ /* rom_pointer[1] contains the size of TEE occupies */
+ if (rom_pointer[1])
+ gd->ram_size = sdram_size - rom_pointer[1];
+ else
+ gd->ram_size = sdram_size;
+
+#ifdef PHYS_SDRAM_2_SIZE
+ gd->ram_size += PHYS_SDRAM_2_SIZE;
+#endif
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ int bank = 0;
+ int ret;
+ phys_size_t sdram_size;
+
+ ret = board_phys_sdram_size(&sdram_size);
+ if (ret)
+ return ret;
+
+ gd->bd->bi_dram[bank].start = PHYS_SDRAM;
+ if (rom_pointer[1]) {
+ phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
+ phys_size_t optee_size = (size_t)rom_pointer[1];
+
+ gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
+ if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_size)) {
+ if (++bank >= CONFIG_NR_DRAM_BANKS) {
+ puts("CONFIG_NR_DRAM_BANKS is not enough\n");
+ return -1;
+ }
+
+ gd->bd->bi_dram[bank].start = optee_start + optee_size;
+ gd->bd->bi_dram[bank].size = PHYS_SDRAM +
+ sdram_size - gd->bd->bi_dram[bank].start;
+ }
+ } else {
+ gd->bd->bi_dram[bank].size = sdram_size;
+ }
+
+#ifdef PHYS_SDRAM_2_SIZE
+ if (++bank >= CONFIG_NR_DRAM_BANKS) {
+ puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
+ return -1;
+ }
+ gd->bd->bi_dram[bank].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[bank].size = PHYS_SDRAM_2_SIZE;
+#endif
+
+ return 0;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+ /* return the first bank as effective memory */
+ if (rom_pointer[1])
+ return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
+
+#ifdef PHYS_SDRAM_2_SIZE
+ return gd->ram_size - PHYS_SDRAM_2_SIZE;
+#else
+ return gd->ram_size;
+#endif
+}
+
static u32 get_cpu_variant_type(u32 type)
{
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
@@ -208,6 +321,38 @@ static u32 get_cpu_variant_type(u32 type)
return MXC_CPU_IMX8MNL;
break;
}
+ } else if (type == MXC_CPU_IMX8MP) {
+ u32 value0 = readl(&fuse->tester3);
+ u32 flag = 0;
+
+ if ((value0 & 0xc0000) == 0x80000)
+ return MXC_CPU_IMX8MPD;
+
+ /* vpu disabled */
+ if ((value0 & 0x43000000) == 0x43000000)
+ flag = 1;
+
+ /* npu disabled*/
+ if ((value & 0x8) == 0x8)
+ flag |= (1 << 1);
+
+ /* isp disabled */
+ if ((value & 0x3) == 0x3)
+ flag |= (1 << 2);
+
+ switch (flag) {
+ case 7:
+ return MXC_CPU_IMX8MPL;
+ case 6:
+ return MXC_CPU_IMX8MP5;
+ case 2:
+ return MXC_CPU_IMX8MP6;
+ case 1:
+ return MXC_CPU_IMX8MP7;
+ default:
+ break;
+ }
+
}
return type;
@@ -225,7 +370,7 @@ u32 get_cpu_rev(void)
/* iMX8MP */
if (major_low == 0x43) {
- return (MXC_CPU_IMX8MP << 12) | reg;
+ type = get_cpu_variant_type(MXC_CPU_IMX8MP);
} else if (major_low == 0x42) {
/* iMX8MN */
type = get_cpu_variant_type(MXC_CPU_IMX8MN);
@@ -307,6 +452,25 @@ int arch_cpu_init(void)
if (IS_ENABLED(CONFIG_SPL_BUILD)) {
clock_init();
imx_set_wdog_powerdown(false);
+
+ if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() ||
+ is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() ||
+ is_imx8mnsl() || is_imx8mpd()) {
+ /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */
+ struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840);
+ struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880);
+ struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0);
+ struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR;
+
+ writel(0x1, &pgc_core2->pgcr);
+ writel(0x1, &pgc_core3->pgcr);
+ if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl()) {
+ writel(0x1, &pgc_core1->pgcr);
+ writel(0xE, &gpc->cpu_pgc_dn_trg);
+ } else {
+ writel(0xC, &gpc->cpu_pgc_dn_trg);
+ }
+ }
}
if (is_imx8mq()) {
@@ -372,12 +536,298 @@ bool is_usb_boot(void)
}
#ifdef CONFIG_OF_SYSTEM_SETUP
+bool check_fdt_new_path(void *blob)
+{
+ const char *soc_path = "/soc@0";
+ int nodeoff;
+
+ nodeoff = fdt_path_offset(blob, soc_path);
+ if (nodeoff < 0)
+ return false;
+
+ return true;
+}
+
+static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
+{
+ int i = 0;
+ int rc;
+ int nodeoff;
+ const char *status = "disabled";
+
+ for (i = 0; i < size_array; i++) {
+ nodeoff = fdt_path_offset(blob, nodes_path[i]);
+ if (nodeoff < 0)
+ continue; /* Not found, skip it */
+
+ printf("Found %s node\n", nodes_path[i]);
+
+add_status:
+ rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
+ if (rc) {
+ if (rc == -FDT_ERR_NOSPACE) {
+ rc = fdt_increase_size(blob, 512);
+ if (!rc)
+ goto add_status;
+ }
+ printf("Unable to update property %s:%s, err=%s\n",
+ nodes_path[i], "status", fdt_strerror(rc));
+ } else {
+ printf("Modify %s:%s disabled\n",
+ nodes_path[i], "status");
+ }
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_IMX8MQ
+bool check_dcss_fused(void)
+{
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[1];
+ struct fuse_bank1_regs *fuse =
+ (struct fuse_bank1_regs *)bank->fuse_regs;
+ u32 value = readl(&fuse->tester4);
+
+ if (value & 0x4000000)
+ return true;
+
+ return false;
+}
+
+static int disable_mipi_dsi_nodes(void *blob)
+{
+ static const char * const nodes_path[] = {
+ "/mipi_dsi@30A00000",
+ "/mipi_dsi_bridge@30A00000",
+ "/dsi_phy@30A00300",
+ "/soc@0/bus@30800000/mipi_dsi@30a00000",
+ "/soc@0/bus@30800000/dphy@30a00300"
+ };
+
+ return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
+}
+
+static int disable_dcss_nodes(void *blob)
+{
+ static const char * const nodes_path[] = {
+ "/dcss@0x32e00000",
+ "/dcss@32e00000",
+ "/hdmi@32c00000",
+ "/hdmi_cec@32c33800",
+ "/hdmi_drm@32c00000",
+ "/display-subsystem",
+ "/sound-hdmi",
+ "/sound-hdmi-arc",
+ "/soc@0/bus@32c00000/display-controller@32e00000",
+ "/soc@0/bus@32c00000/hdmi@32c00000",
+ };
+
+ return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
+}
+
+static int check_mipi_dsi_nodes(void *blob)
+{
+ static const char * const lcdif_path[] = {
+ "/lcdif@30320000",
+ "/soc@0/bus@30000000/lcdif@30320000"
+ };
+ static const char * const mipi_dsi_path[] = {
+ "/mipi_dsi@30A00000",
+ "/soc@0/bus@30800000/mipi_dsi@30a00000"
+ };
+ static const char * const lcdif_ep_path[] = {
+ "/lcdif@30320000/port@0/mipi-dsi-endpoint",
+ "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint"
+ };
+ static const char * const mipi_dsi_ep_path[] = {
+ "/mipi_dsi@30A00000/port@1/endpoint",
+ "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint"
+ };
+
+ int lookup_node;
+ int nodeoff;
+ bool new_path = check_fdt_new_path(blob);
+ int i = new_path ? 1 : 0;
+
+ nodeoff = fdt_path_offset(blob, lcdif_path[i]);
+ if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
+ /*
+ * If can't find lcdif node or lcdif node is disabled,
+ * then disable all mipi dsi, since they only can input
+ * from DCSS
+ */
+ return disable_mipi_dsi_nodes(blob);
+ }
+
+ nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
+ if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
+ return 0;
+
+ nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
+ if (nodeoff < 0) {
+ /*
+ * If can't find lcdif endpoint, then disable all mipi dsi,
+ * since they only can input from DCSS
+ */
+ return disable_mipi_dsi_nodes(blob);
+ }
+
+ lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
+ nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
+
+ if (nodeoff > 0 && nodeoff == lookup_node)
+ return 0;
+
+ return disable_mipi_dsi_nodes(blob);
+}
+#endif
+
+int disable_vpu_nodes(void *blob)
+{
+ static const char * const nodes_path_8mq[] = {
+ "/vpu@38300000",
+ "/soc@0/vpu@38300000"
+ };
+
+ static const char * const nodes_path_8mm[] = {
+ "/vpu_g1@38300000",
+ "/vpu_g2@38310000",
+ "/vpu_h1@38320000"
+ };
+
+ static const char * const nodes_path_8mp[] = {
+ "/vpu_g1@38300000",
+ "/vpu_g2@38310000",
+ "/vpu_vc8000e@38320000"
+ };
+
+ if (is_imx8mq())
+ return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
+ else if (is_imx8mm())
+ return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
+ else if (is_imx8mp())
+ return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
+ else
+ return -EPERM;
+}
+
+int disable_gpu_nodes(void *blob)
+{
+ static const char * const nodes_path_8mn[] = {
+ "/gpu@38000000"
+ };
+
+ return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
+}
+
+int disable_npu_nodes(void *blob)
+{
+ static const char * const nodes_path_8mp[] = {
+ "/vipsi@38500000"
+ };
+
+ return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
+}
+
+int disable_isp_nodes(void *blob)
+{
+ static const char * const nodes_path_8mp[] = {
+ "/soc@0/bus@32c00000/camera/isp@32e10000",
+ "/soc@0/bus@32c00000/camera/isp@32e20000"
+ };
+
+ return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
+}
+
+int disable_dsp_nodes(void *blob)
+{
+ static const char * const nodes_path_8mp[] = {
+ "/dsp@3b6e8000"
+ };
+
+ return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
+}
+
+static int disable_cpu_nodes(void *blob, u32 disabled_cores)
+{
+ static const char * const nodes_path[] = {
+ "/cpus/cpu@1",
+ "/cpus/cpu@2",
+ "/cpus/cpu@3",
+ };
+ u32 i = 0;
+ int rc;
+ int nodeoff;
+
+ if (disabled_cores > 3)
+ return -EINVAL;
+
+ i = 3 - disabled_cores;
+
+ for (; i < 3; i++) {
+ nodeoff = fdt_path_offset(blob, nodes_path[i]);
+ if (nodeoff < 0)
+ continue; /* Not found, skip it */
+
+ debug("Found %s node\n", nodes_path[i]);
+
+ rc = fdt_del_node(blob, nodeoff);
+ if (rc < 0) {
+ printf("Unable to delete node %s, err=%s\n",
+ nodes_path[i], fdt_strerror(rc));
+ } else {
+ printf("Delete node %s\n", nodes_path[i]);
+ }
+ }
+
+ return 0;
+}
+
int ft_system_setup(void *blob, bd_t *bd)
{
+#ifdef CONFIG_IMX8MQ
int i = 0;
int rc;
int nodeoff;
+ if (get_boot_device() == USB_BOOT) {
+ disable_dcss_nodes(blob);
+
+ bool new_path = check_fdt_new_path(blob);
+ int v = new_path ? 1 : 0;
+ static const char * const usb_dwc3_path[] = {
+ "/usb@38100000/dwc3",
+ "/soc@0/usb@38100000"
+ };
+
+ nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
+ if (nodeoff >= 0) {
+ const char *speed = "high-speed";
+
+ printf("Found %s node\n", usb_dwc3_path[v]);
+
+usb_modify_speed:
+
+ rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
+ if (rc) {
+ if (rc == -FDT_ERR_NOSPACE) {
+ rc = fdt_increase_size(blob, 512);
+ if (!rc)
+ goto usb_modify_speed;
+ }
+ printf("Unable to set property %s:%s, err=%s\n",
+ usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
+ } else {
+ printf("Modify %s:%s = %s\n",
+ usb_dwc3_path[v], "maximum-speed", speed);
+ }
+ } else {
+ printf("Can't found %s node\n", usb_dwc3_path[v]);
+ }
+ }
+
/* Disable the CPU idle for A0 chip since the HW does not support it */
if (is_soc_rev(CHIP_REV_1_0)) {
static const char * const nodes_path[] = {
@@ -408,6 +858,53 @@ int ft_system_setup(void *blob, bd_t *bd)
}
}
+ if (is_imx8mql()) {
+ disable_vpu_nodes(blob);
+ if (check_dcss_fused()) {
+ printf("DCSS is fused\n");
+ disable_dcss_nodes(blob);
+ check_mipi_dsi_nodes(blob);
+ }
+ }
+
+ if (is_imx8md())
+ disable_cpu_nodes(blob, 2);
+
+#elif defined(CONFIG_IMX8MM)
+ if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl())
+ disable_vpu_nodes(blob);
+
+ if (is_imx8mmd() || is_imx8mmdl())
+ disable_cpu_nodes(blob, 2);
+ else if (is_imx8mms() || is_imx8mmsl())
+ disable_cpu_nodes(blob, 3);
+
+#elif defined(CONFIG_IMX8MN)
+ if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl())
+ disable_gpu_nodes(blob);
+
+ if (is_imx8mnd() || is_imx8mndl())
+ disable_cpu_nodes(blob, 2);
+ else if (is_imx8mns() || is_imx8mnsl())
+ disable_cpu_nodes(blob, 3);
+
+#elif defined(CONFIG_IMX8MP)
+ if (is_imx8mpl() || is_imx8mp7())
+ disable_vpu_nodes(blob);
+
+ if (is_imx8mpl() || is_imx8mp6() || is_imx8mp5())
+ disable_npu_nodes(blob);
+
+ if (is_imx8mpl() || is_imx8mp5())
+ disable_isp_nodes(blob);
+
+ if (is_imx8mpl() || is_imx8mp7() || is_imx8mp6() || is_imx8mp5())
+ disable_dsp_nodes(blob);
+
+ if (is_imx8mpd())
+ disable_cpu_nodes(blob, 2);
+#endif
+
return 0;
}
#endif
@@ -432,10 +929,12 @@ void reset_cpu(ulong addr)
static void acquire_buildinfo(void)
{
u64 atf_commit = 0;
+ struct arm_smccc_res res;
/* Get ARM Trusted Firmware commit id */
- atf_commit = call_imx_sip(IMX_SIP_BUILDINFO,
- IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0);
+ arm_smccc_smc(IMX_SIP_BUILDINFO, IMX_SIP_BUILDINFO_GET_COMMITHASH,
+ 0, 0 , 0, 0, 0, 0, &res);
+ atf_commit = res.a0;
if (atf_commit == 0xffffffff) {
debug("ATF does not support build info\n");
atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */
@@ -524,3 +1023,96 @@ void imx_tmu_arch_init(void *reg_base)
writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
#endif
}
+
+#if defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
+bool serror_need_skip = true;
+
+void do_error(struct pt_regs *pt_regs, unsigned int esr)
+{
+ /*
+ * If stack is still in ROM reserved OCRAM not switch to SPL,
+ * it is the ROM SError
+ */
+ ulong sp;
+
+ asm volatile("mov %0, sp" : "=r"(sp) : );
+
+ if (serror_need_skip && sp < 0x910000 && sp >= 0x900000) {
+ /* Check for ERR050342, imx8mq HDCP enabled parts */
+ if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
+ serror_need_skip = false;
+ return; /* Do nothing skip the SError in ROM */
+ }
+
+ /* Check for ERR050350, field return mode for imx8mq, mm and mn */
+ if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
+ serror_need_skip = false;
+ return; /* Do nothing skip the SError in ROM */
+ }
+ }
+
+ efi_restore_gd();
+ printf("\"Error\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+#endif
+#endif
+
+#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+ enum boot_device dev = get_boot_device();
+ enum env_location env_loc = ENVL_UNKNOWN;
+
+ if (prio)
+ return env_loc;
+
+ switch (dev) {
+#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+ case QSPI_BOOT:
+ env_loc = ENVL_SPI_FLASH;
+ break;
+#endif
+#ifdef CONFIG_ENV_IS_IN_NAND
+ case NAND_BOOT:
+ env_loc = ENVL_NAND;
+ break;
+#endif
+#ifdef CONFIG_ENV_IS_IN_MMC
+ case SD1_BOOT:
+ case SD2_BOOT:
+ case SD3_BOOT:
+ case MMC1_BOOT:
+ case MMC2_BOOT:
+ case MMC3_BOOT:
+ env_loc = ENVL_MMC;
+ break;
+#endif
+ default:
+#if defined(CONFIG_ENV_IS_NOWHERE)
+ env_loc = ENVL_NOWHERE;
+#endif
+ break;
+ }
+
+ return env_loc;
+}
+
+#ifndef ENV_IS_EMBEDDED
+long long env_get_offset(long long defautl_offset)
+{
+ enum boot_device dev = get_boot_device();
+
+ switch (dev) {
+ case NAND_BOOT:
+ return (60 << 20); /* 60MB offset for NAND */
+ default:
+ break;
+ }
+
+ return defautl_offset;
+}
+#endif
+#endif
diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c
index 868633cf8a..e1fc4b3e19 100644
--- a/arch/arm/mach-imx/imx_bootaux.c
+++ b/arch/arm/mach-imx/imx_bootaux.c
@@ -10,6 +10,7 @@
#include <command.h>
#include <elf.h>
#include <imx_sip.h>
+#include <linux/arm-smccc.h>
#include <linux/compiler.h>
#include <cpu_func.h>
@@ -55,7 +56,8 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr)
/* Enable M4 */
#ifdef CONFIG_IMX8M
- call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0);
+ arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0,
+ 0, 0, 0, 0, NULL);
#else
clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET,
SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK);
@@ -67,7 +69,12 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr)
int arch_auxiliary_core_check_up(u32 core_id)
{
#ifdef CONFIG_IMX8M
- return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0);
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0,
+ 0, 0, 0, 0, &res);
+
+ return res.a0;
#else
unsigned int val;
diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig
index fa6e1112e6..fdee0d4f64 100644
--- a/arch/arm/mach-imx/mx6/Kconfig
+++ b/arch/arm/mach-imx/mx6/Kconfig
@@ -511,6 +511,10 @@ config TARGET_PCM058
bool "Phytec PCM058 i.MX6 Quad"
select BOARD_LATE_INIT
select SUPPORT_SPL
+ select MX6Q
+ select DM
+ select OF_CONTROL
+ imply CMD_DM
config TARGET_PFLA02
bool "Phytec PFLA02 (PhyFlex) i.MX6 Quad"
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c
index 19ca382649..e129286065 100644
--- a/arch/arm/mach-imx/mx6/soc.c
+++ b/arch/arm/mach-imx/mx6/soc.c
@@ -22,6 +22,7 @@
#include <asm/arch/mxc_hdmi.h>
#include <asm/arch/crm_regs.h>
#include <dm.h>
+#include <fsl_sec.h>
#include <imx_thermal.h>
#include <mmc.h>
@@ -691,6 +692,15 @@ void imx_setup_hdmi(void)
}
#endif
+#ifdef CONFIG_ARCH_MISC_INIT
+int arch_misc_init(void)
+{
+#ifdef CONFIG_FSL_CAAM
+ sec_init();
+#endif
+ return 0;
+}
+#endif
/*
* gpr_init() function is common for boards using MX6S, MX6DL, MX6D,
diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c
deleted file mode 100644
index 6cb8179ee8..0000000000
--- a/arch/arm/mach-imx/sip.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2017 NXP
- */
-
-#include <common.h>
-#include <asm/arch/sys_proto.h>
-#include <asm/cache.h>
-#include <asm/ptrace.h>
-
-unsigned long call_imx_sip(unsigned long id, unsigned long reg0,
- unsigned long reg1, unsigned long reg2,
- unsigned long reg3)
-{
- struct pt_regs regs;
-
- regs.regs[0] = id;
- regs.regs[1] = reg0;
- regs.regs[2] = reg1;
- regs.regs[3] = reg2;
- regs.regs[4] = reg3;
-
- smc_call(&regs);
-
- return regs.regs[0];
-}
-
-/*
- * Do an SMC call to return 2 registers by having reg1 passed in by reference
- */
-unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0,
- unsigned long *reg1, unsigned long reg2,
- unsigned long reg3)
-{
- struct pt_regs regs;
-
- regs.regs[0] = id;
- regs.regs[1] = reg0;
- regs.regs[2] = *reg1;
- regs.regs[3] = reg2;
- regs.regs[4] = reg3;
-
- smc_call(&regs);
-
- *reg1 = regs.regs[1];
-
- return regs.regs[0];
-}