diff options
73 files changed, 2697 insertions, 718 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 86238524f75..e16fe038872 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 d839cb49b33..cee10f533f5 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 00000000000..8555be16966 --- /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 00000000000..65d2e483c13 --- /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 00000000000..9ebd438dce7 --- /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 = <®_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 = <®_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 = <®_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 = <®_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 = <®_usb_h1_vbus>; + disable-over-current; + status = "disabled"; +}; + +&usbotg { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + vbus-supply = <®_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 00000000000..77d871340eb --- /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 = <ðphy>; + 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>; + }; + }; + }; +}; + +®_arm { + vin-supply = <&vdd_arm>; +}; + +®_pu { + vin-supply = <&vdd_soc>; +}; + +®_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 5c2e98be063..967023fde19 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 e9c00789226..75ff991248c 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 c1a9c353ba0..9f55904f442 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 f91f7cc5876..1c29209b399 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 7a2a2d8edce..0f1e832c038 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 3cfa169c971..f1c410ec78a 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 0bc705df172..ab94024c9b8 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 a70d51b5cf1..1aa26a50ad8 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 f2070c97143..b89d27ffd23 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 2cd794d54a3..de19955e2f7 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 aafe2ed084e..3610f5b2fca 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 a4c6466ca94..a49a9cdb35c 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 1d2c8e6db28..b3c08271e60 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 868633cf8a4..e1fc4b3e19a 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 fa6e1112e62..fdee0d4f641 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 19ca3826495..e1292860656 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 6cb8179ee8c..00000000000 --- 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(®s); - - 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(®s); - - *reg1 = regs.regs[1]; - - return regs.regs[0]; -} diff --git a/board/beacon/imx8mm/imx8mm_beacon.c b/board/beacon/imx8mm/imx8mm_beacon.c index e82e8b78d80..c61d25fbead 100644 --- a/board/beacon/imx8mm/imx8mm_beacon.c +++ b/board/beacon/imx8mm/imx8mm_beacon.c @@ -13,17 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #if IS_ENABLED(CONFIG_FEC_MXC) static int setup_fec(void) { diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c b/board/freescale/imx8mm_evk/imx8mm_evk.c index c43af9bc484..6af71006966 100644 --- a/board/freescale/imx8mm_evk/imx8mm_evk.c +++ b/board/freescale/imx8mm_evk/imx8mm_evk.c @@ -15,17 +15,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #if IS_ENABLED(CONFIG_FEC_MXC) static int setup_fec(void) { diff --git a/board/freescale/imx8mn_evk/imx8mn_evk.c b/board/freescale/imx8mn_evk/imx8mn_evk.c index ea02bb75f41..e5ca54f9ae7 100644 --- a/board/freescale/imx8mn_evk/imx8mn_evk.c +++ b/board/freescale/imx8mn_evk/imx8mn_evk.c @@ -9,13 +9,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - int board_init(void) { return 0; diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c b/board/freescale/imx8mp_evk/imx8mp_evk.c index 97ba15645a2..034a349236e 100644 --- a/board/freescale/imx8mp_evk/imx8mp_evk.c +++ b/board/freescale/imx8mp_evk/imx8mp_evk.c @@ -40,46 +40,6 @@ int board_early_init_f(void) return 0; } -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - -#if CONFIG_NR_DRAM_BANKS > 1 - gd->ram_size += PHYS_SDRAM_2_SIZE; -#endif - - return 0; -} - -int dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM; - if (rom_pointer[1]) - - gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE; - -#if CONFIG_NR_DRAM_BANKS > 1 - gd->bd->bi_dram[1].start = PHYS_SDRAM_2; - gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; -#endif - - return 0; -} - -phys_size_t get_effective_memsize(void) -{ - if (rom_pointer[1]) - return (PHYS_SDRAM_SIZE - rom_pointer[1]); - else - return PHYS_SDRAM_SIZE; -} - int board_init(void) { return 0; diff --git a/board/freescale/imx8mp_evk/lpddr4_timing.c b/board/freescale/imx8mp_evk/lpddr4_timing.c index 14542490bce..7658262b37d 100644 --- a/board/freescale/imx8mp_evk/lpddr4_timing.c +++ b/board/freescale/imx8mp_evk/lpddr4_timing.c @@ -11,7 +11,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d400304, 0x1 }, { 0x3d400030, 0x1 }, { 0x3d400000, 0xa3080020 }, - { 0x3d400020, 0x323 }, + { 0x3d400020, 0x1323 }, { 0x3d400024, 0x1e84800 }, { 0x3d400064, 0x7a0118 }, { 0x3d4000d0, 0xc00307a3 }, @@ -52,12 +52,13 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d400214, 0x7070707 }, { 0x3d400218, 0x68070707 }, { 0x3d40021c, 0xf08 }, - { 0x3d400250, 0x29001701 }, + { 0x3d400250, 0x00001705 }, { 0x3d400254, 0x2c }, { 0x3d40025c, 0x4000030 }, { 0x3d400264, 0x900093e7 }, { 0x3d40026c, 0x2005574 }, { 0x3d400400, 0x111 }, + { 0x3d400404, 0x72ff }, { 0x3d400408, 0x72ff }, { 0x3d400494, 0x2100e07 }, { 0x3d400498, 0x620096 }, diff --git a/board/freescale/imx8mp_evk/spl.c b/board/freescale/imx8mp_evk/spl.c index 3b3a854e29b..3214718e62b 100644 --- a/board/freescale/imx8mp_evk/spl.c +++ b/board/freescale/imx8mp_evk/spl.c @@ -68,7 +68,7 @@ int power_init_board(void) struct pmic *p; int ret; - ret = power_pca9450b_init(I2C_PMIC); + ret = power_pca9450_init(I2C_PMIC); if (ret) printf("power init failed"); p = pmic_get("PCA9450"); diff --git a/board/freescale/imx8mq_evk/imx8mq_evk.c b/board/freescale/imx8mq_evk/imx8mq_evk.c index ae3be5785c9..1ad670b8ccf 100644 --- a/board/freescale/imx8mq_evk/imx8mq_evk.c +++ b/board/freescale/imx8mq_evk/imx8mq_evk.c @@ -53,17 +53,6 @@ int board_early_init_f(void) return 0; } -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #ifdef CONFIG_FEC_MXC static int setup_fec(void) { diff --git a/board/google/imx8mq_phanbell/imx8mq_phanbell.c b/board/google/imx8mq_phanbell/imx8mq_phanbell.c index c0cc3e9b71d..746071b4150 100644 --- a/board/google/imx8mq_phanbell/imx8mq_phanbell.c +++ b/board/google/imx8mq_phanbell/imx8mq_phanbell.c @@ -48,17 +48,6 @@ int board_early_init_f(void) return 0; } -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #ifdef CONFIG_FEC_MXC static int setup_fec(void) { diff --git a/board/liebherr/xea/xea.c b/board/liebherr/xea/xea.c index 8159f3a2d9e..4062c6fb82b 100644 --- a/board/liebherr/xea/xea.c +++ b/board/liebherr/xea/xea.c @@ -116,6 +116,7 @@ void board_boot_order(u32 *spl_boot_list) { spl_boot_list[0] = BOOT_DEVICE_MMC1; spl_boot_list[1] = BOOT_DEVICE_SPI; + spl_boot_list[2] = BOOT_DEVICE_UART; } int spl_start_uboot(void) diff --git a/board/phytec/pcm058/MAINTAINERS b/board/phytec/pcm058/MAINTAINERS index b0ca40277f0..909dfc44af0 100644 --- a/board/phytec/pcm058/MAINTAINERS +++ b/board/phytec/pcm058/MAINTAINERS @@ -1,6 +1,7 @@ PHYTEC PHYBOARD MIRA -M: Stefano Babic <sbabic@denx.de> +M: Niel Fourie <lusus@denx.de> S: Maintained F: board/phytec/pcm058/ F: include/configs/pcm058.h F: configs/pcm058_defconfig +F: arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi diff --git a/board/phytec/pcm058/README b/board/phytec/pcm058/README index 33271356451..02be0994fcd 100644 --- a/board/phytec/pcm058/README +++ b/board/phytec/pcm058/README @@ -33,3 +33,54 @@ is present, then the RBL tries to load SPL from the SD Card, if not, RBL loads from SPI-NOR. The SPL tries then to load from the same device where SPL was loaded (SD or SPI). Booting from NAND is not supported. + +Flashing U-Boot onto an SD card +------------------------------- + +After a successful build, the generated SPL and U-boot binaries can be copied +to an SD card. Adjust the SD card device as necessary: + +$ sudo dd if=u-boot-with-spl.imx of=/dev/mmcblk0 bs=1k seek=1 + +This is equivalent to separately copying the SPL and U-boot using: + +$ sudo dd if=SPL of=/dev/mmcblk0 bs=1k seek=1 +$ sudo dd if=u-boot-dtb.img of=/dev/mmcblk0 bs=1k seek=197 + +The default bootscripts expect a kernel fit-image file named "fitImage" in the +first partition and Linux ext4 rootfs in the second partition. + +Flashing U-boot to the SPI Flash, for booting Linux from NAND +------------------------------------------------------------- + +The SD card created above can also be used to install the SPL and U-boot into +the SPI flash. Boot U-boot from the SD card as above, and stop at the autoboot. + +Then, clear the SPI flash: + +=> sf probe +=> sf erase 0x0 0x1000000 + +Load the SPL from raw MMC into memory and copy to the SPI. The SPL is maximum +392*512-byte blocks in size therefore 0x188 blocks, totaling 0x31000 bytes: + +=> mmc read ${loadaddr} 0x2 0x188 +=> sf write ${loadaddr} 0x400 0x31000 + +Load the U-boot binary into memory and copy to the SPI. U-boot should fit into +640KiB, so 0x500 512-byte blocks, totalling 0xA0000 bytes: + +=> mmc read ${loadaddr} 0x18a 0x500 +=> sf write ${loadaddr} 0x40000 0xA0000 + +The default NAND bootscripts expect a single MTD partition named "rootfs", +which in turn contains the UBI volumes "fit" (which contains the kernel fit- +image) and "root" (which contains a ubifs root filesystem). + +The "bootm_size" variable in the environment +-------------------------------------------- + +By default, U-boot relocates the device tree towards the upper end of the RAM, +which kernels using CONFIG_HIGHMEM=y may not be able to access during early +boot. With the bootm_size variable set to 0x30000000, U-boot relocates the +device tree to below this address instead. diff --git a/board/phytec/pcm058/pcm058.c b/board/phytec/pcm058/pcm058.c index 096425c5dfe..79c666588f4 100644 --- a/board/phytec/pcm058/pcm058.c +++ b/board/phytec/pcm058/pcm058.c @@ -12,60 +12,14 @@ #include <common.h> #include <init.h> #include <net.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/imx-regs.h> #include <asm/arch/crm_regs.h> #include <asm/arch/mx6-ddr.h> -#include <asm/arch/iomux.h> -#include <asm/arch/mx6-pins.h> -#include <asm/mach-imx/iomux-v3.h> #include <asm/mach-imx/boot_mode.h> -#include <asm/mach-imx/mxc_i2c.h> -#include <asm/mach-imx/spi.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <asm/gpio.h> -#include <mmc.h> -#include <i2c.h> -#include <fsl_esdhc_imx.h> -#include <nand.h> -#include <miiphy.h> -#include <netdev.h> #include <asm/arch/sys_proto.h> -#include <asm/sections.h> +#include <dm.h> DECLARE_GLOBAL_DATA_PTR; -#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ - PAD_CTL_SRE_FAST | PAD_CTL_HYS) - -#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ - PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ - PAD_CTL_SRE_FAST | PAD_CTL_HYS) - -#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) - -#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ - PAD_CTL_ODE | PAD_CTL_SRE_FAST) - -#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) - -#define ASRC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define NAND_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define ENET_PHY_RESET_GPIO IMX_GPIO_NR(1, 14) -#define USDHC1_CD_GPIO IMX_GPIO_NR(6, 31) -#define USER_LED IMX_GPIO_NR(1, 4) #define IMX6Q_DRIVE_STRENGTH 0x30 int dram_init(void) @@ -74,229 +28,16 @@ int dram_init(void) return 0; } -void board_turn_off_led(void) -{ - gpio_direction_output(USER_LED, 0); -} - -static iomux_v3_cfg_t const uart1_pads[] = { - MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), - MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), -}; - -static iomux_v3_cfg_t const enet_pads[] = { - MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_SD2_DAT1__GPIO1_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - -static iomux_v3_cfg_t const ecspi1_pads[] = { - MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), - MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), - MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), - MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - -#ifdef CONFIG_CMD_NAND -/* NAND */ -static iomux_v3_cfg_t const nfc_pads[] = { - MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS1__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS2__NAND_CE2_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS3__NAND_CE3_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NAND_PAD_CTRL), -}; -#endif - -static struct i2c_pads_info i2c_pad_info2 = { - .scl = { - .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD, - .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD, - .gp = IMX_GPIO_NR(1, 5) - }, - .sda = { - .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | I2C_PAD, - .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | I2C_PAD, - .gp = IMX_GPIO_NR(1, 6) - } -}; - -static struct fsl_esdhc_cfg usdhc_cfg[] = { - {.esdhc_base = USDHC1_BASE_ADDR, - .max_bus_width = 4}, -#ifndef CONFIG_CMD_NAND - {USDHC4_BASE_ADDR}, -#endif -}; - -static iomux_v3_cfg_t const usdhc1_pads[] = { - MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ -}; - -#if !defined(CONFIG_CMD_NAND) && !defined(CONFIG_SPL_BUILD) -static iomux_v3_cfg_t const usdhc4_pads[] = { - MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), -}; -#endif - int board_mmc_get_env_dev(int devno) { return devno - 1; } -int board_mmc_getcd(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; - int ret = 0; - - switch (cfg->esdhc_base) { - case USDHC1_BASE_ADDR: - ret = !gpio_get_value(USDHC1_CD_GPIO); - break; - case USDHC4_BASE_ADDR: - ret = 1; /* eMMC/uSDHC4 is always present */ - break; - } - - return ret; -} - -int board_mmc_init(bd_t *bis) -{ -#ifndef CONFIG_SPL_BUILD - int ret; - int i; - - for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { - switch (i) { - case 0: - imx_iomux_v3_setup_multiple_pads( - usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); - gpio_direction_input(USDHC1_CD_GPIO); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); - break; -#ifndef CONFIG_CMD_NAND - case 1: - imx_iomux_v3_setup_multiple_pads( - usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); - usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); - break; -#endif - default: - printf("Warning: you configured more USDHC controllers" - "(%d) then supported by the board (%d)\n", - i + 1, CONFIG_SYS_FSL_USDHC_NUM); - return -EINVAL; - } - - ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); - if (ret) - return ret; - } - - return 0; -#else - struct src *psrc = (struct src *)SRC_BASE_ADDR; - unsigned reg = readl(&psrc->sbmr1) >> 11; - /* - * Upon reading BOOT_CFG register the following map is done: - * Bit 11 and 12 of BOOT_CFG register can determine the current - * mmc port - * 0x1 SD1 - * 0x2 SD2 - * 0x3 SD4 - */ - - switch (reg & 0x3) { - case 0x0: - imx_iomux_v3_setup_multiple_pads( - usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); - gpio_direction_input(USDHC1_CD_GPIO); - usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR; - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); - usdhc_cfg[0].max_bus_width = 4; - gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; - break; - } - return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); -#endif -} - -static void setup_iomux_uart(void) -{ - imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); -} - -static void setup_iomux_enet(void) -{ - imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); - - gpio_direction_output(ENET_PHY_RESET_GPIO, 0); - mdelay(10); - gpio_set_value(ENET_PHY_RESET_GPIO, 1); - mdelay(30); -} - -static void setup_spi(void) -{ - gpio_request(IMX_GPIO_NR(3, 19), "spi_cs0"); - gpio_direction_output(IMX_GPIO_NR(3, 19), 1); - - imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); - - enable_spi_clk(true, 0); -} - #ifdef CONFIG_CMD_NAND static void setup_gpmi_nand(void) { struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - /* config gpmi nand iomux */ - imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); - /* gate ENFC_CLK_ROOT clock first,before clk source switch */ clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); @@ -325,48 +66,17 @@ static void setup_gpmi_nand(void) } #endif -int board_spi_cs_gpio(unsigned bus, unsigned cs) -{ - if (bus != 0 || (cs != 0)) - return -EINVAL; - - return IMX_GPIO_NR(3, 19); -} - -int board_eth_init(bd_t *bis) -{ - setup_iomux_enet(); - - return cpu_eth_init(bis); -} - -int board_early_init_f(void) -{ - setup_iomux_uart(); - - return 0; -} - int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; -#ifdef CONFIG_SYS_I2C_MXC - setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); -#endif - -#ifdef CONFIG_MXC_SPI - setup_spi(); -#endif - #ifdef CONFIG_CMD_NAND setup_gpmi_nand(); #endif return 0; } - #ifdef CONFIG_CMD_BMODE /* * BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4 @@ -535,11 +245,6 @@ void board_boot_order(u32 *spl_boot_list) void board_init_f(ulong dummy) { -#ifdef CONFIG_CMD_NAND - /* Enable NAND */ - setup_gpmi_nand(); -#endif - /* setup clock gating */ ccgr_init(); @@ -549,23 +254,33 @@ void board_init_f(ulong dummy) /* setup AXI */ gpr_init(); - board_early_init_f(); - /* setup GP timer */ timer_init(); - setup_spi(); - - /* UART clocks enabled and gd valid - init serial console */ - preloader_console_init(); - /* DDR initialization */ spl_dram_init(); /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - /* load/boot image from boot device */ - board_init_r(NULL, 0); + /* Enable device tree and early DM support*/ + spl_early_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); +} + +/* + * Manually probe the SPI bus devices, as this does not happen when the + * SPI Flash is probed, which then fails to find the bus. + */ +void spl_board_init(void) +{ + struct udevice *udev; + int ret = uclass_get_device_by_name(UCLASS_SPI, "spi@2008000", &udev); + + if (ret) { + printf("SPI bus probe failed, err = %d\n", ret); + }; } #endif diff --git a/board/technexion/pico-imx6ul/README b/board/technexion/pico-imx6ul/README index 40d43441429..e58640c55ec 100644 --- a/board/technexion/pico-imx6ul/README +++ b/board/technexion/pico-imx6ul/README @@ -22,8 +22,8 @@ If the eMMC has already a U-Boot flashed with DFU support then the user can go to step 2 below in order to update U-Boot. Put pico board in USB download mode (refer to the document -http://www.wandboard.org/images/hobbit/hobbitboard-imx6ul-reva1.pdf -page 15). +https://www.nxp.com/files-static/32bit/doc/quick_start_guide/PICO-IMX6UL-QSG.pdf +Figure 6a at page 7). Connect a USB to serial adapter between the host PC and pico. diff --git a/board/technexion/pico-imx8mq/pico-imx8mq.c b/board/technexion/pico-imx8mq/pico-imx8mq.c index 2a3e6e7e265..330de7137c3 100644 --- a/board/technexion/pico-imx8mq/pico-imx8mq.c +++ b/board/technexion/pico-imx8mq/pico-imx8mq.c @@ -51,24 +51,22 @@ int board_early_init_f(void) return 0; } -int dram_init(void) +int board_phys_sdram_size(phys_size_t *size) { int ddr_size = readl(M4_BOOTROM_BASE_ADDR); - if (ddr_size == 0x4) - gd->ram_size = 0x100000000; - else if (ddr_size == 0x3) - gd->ram_size = 0xc0000000; - else if (ddr_size == 0x2) - gd->ram_size = 0x80000000; - else if (ddr_size == 0x1) - gd->ram_size = 0x40000000; - else + if (ddr_size == 0x4) { + *size = 0x100000000; + } else if (ddr_size == 0x3) { + *size = 0xc0000000; + } else if (ddr_size == 0x2) { + *size = 0x80000000; + } else if (ddr_size == 0x1) { + *size = 0x40000000; + } else { printf("Unknown DDR type!!!\n"); - - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size -= rom_pointer[1]; + return -1; + } return 0; } diff --git a/board/toradex/verdin-imx8mm/verdin-imx8mm.c b/board/toradex/verdin-imx8mm/verdin-imx8mm.c index ff05c7d5523..fa51b776abc 100644 --- a/board/toradex/verdin-imx8mm/verdin-imx8mm.c +++ b/board/toradex/verdin-imx8mm/verdin-imx8mm.c @@ -14,17 +14,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #if IS_ENABLED(CONFIG_FEC_MXC) static int setup_fec(void) { diff --git a/configs/apalis_imx6_defconfig b/configs/apalis_imx6_defconfig index 34d939a0e91..e162f0a5e85 100644 --- a/configs/apalis_imx6_defconfig +++ b/configs/apalis_imx6_defconfig @@ -74,7 +74,6 @@ CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y diff --git a/configs/aristainetos2_defconfig b/configs/aristainetos2_defconfig index 01990bd9704..7e902127e1a 100644 --- a/configs/aristainetos2_defconfig +++ b/configs/aristainetos2_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set # CONFIG_CMD_NANDBCB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -53,7 +54,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2_4" CONFIG_OF_LIST="imx6dl-aristainetos2_4 imx6dl-aristainetos2_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -61,6 +61,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y diff --git a/configs/aristainetos2b_defconfig b/configs/aristainetos2b_defconfig index 318b81e331c..3c605c2121b 100644 --- a/configs/aristainetos2b_defconfig +++ b/configs/aristainetos2b_defconfig @@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_4" CONFIG_OF_LIST="imx6dl-aristainetos2b_4 imx6dl-aristainetos2b_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -59,6 +59,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y diff --git a/configs/aristainetos2bcsl_defconfig b/configs/aristainetos2bcsl_defconfig index 0ff67a44cbe..6cd095fb852 100644 --- a/configs/aristainetos2bcsl_defconfig +++ b/configs/aristainetos2bcsl_defconfig @@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_csl_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_csl_4" CONFIG_OF_LIST="imx6dl-aristainetos2b_csl_4 imx6dl-aristainetos2b_csl_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -59,6 +59,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y diff --git a/configs/aristainetos2c_defconfig b/configs/aristainetos2c_defconfig index ffd4360159f..4f6b9b94019 100644 --- a/configs/aristainetos2c_defconfig +++ b/configs/aristainetos2c_defconfig @@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2c_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2c_4" CONFIG_OF_LIST="imx6dl-aristainetos2c_4 imx6dl-aristainetos2c_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -62,6 +62,7 @@ CONFIG_APBH_DMA=y CONFIG_APBH_DMA_BURST=y CONFIG_APBH_DMA_BURST8=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y diff --git a/configs/colibri_imx6_defconfig b/configs/colibri_imx6_defconfig index 11cd1da26e2..ffa773b581c 100644 --- a/configs/colibri_imx6_defconfig +++ b/configs/colibri_imx6_defconfig @@ -73,7 +73,6 @@ CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ8XXX=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index d91ff77a4a6..e643ade2e6c 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -77,7 +77,6 @@ CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig index b879de5042d..38f3fa6871c 100644 --- a/configs/imx28_xea_defconfig +++ b/configs/imx28_xea_defconfig @@ -36,6 +36,7 @@ CONFIG_SPL_MMC_TINY=y CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_SPI_LOAD=y +CONFIG_SPL_YMODEM_SUPPORT=y CONFIG_HUSH_PARSER=y CONFIG_CMD_SPL=y CONFIG_CMD_ASKENV=y diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig index dcfc336634d..f49116c9c55 100644 --- a/configs/imx8mp_evk_defconfig +++ b/configs/imx8mp_evk_defconfig @@ -16,7 +16,6 @@ CONFIG_TARGET_IMX8MP_EVK=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 CONFIG_FIT=y diff --git a/configs/mx6memcal_defconfig b/configs/mx6memcal_defconfig index 57e44a14bac..01a0fff6e0f 100644 --- a/configs/mx6memcal_defconfig +++ b/configs/mx6memcal_defconfig @@ -39,6 +39,7 @@ CONFIG_SYS_MEMTEST_END=0x20000000 CONFIG_CMD_CACHE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set +CONFIG_DM=y # CONFIG_MMC is not set CONFIG_FSL_USDHC=y CONFIG_USB=y @@ -47,4 +48,5 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL" CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_CI_UDC=y -CONFIG_REGEX=y +CONFIG_OF_LIBFDT=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mx6sabreauto_defconfig b/configs/mx6sabreauto_defconfig index 56fe307e638..106c967652b 100644 --- a/configs/mx6sabreauto_defconfig +++ b/configs/mx6sabreauto_defconfig @@ -76,7 +76,6 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y CONFIG_PHY_ATHEROS=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_RGMII=y CONFIG_MII=y diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig index 24bc8630f10..f88c629fbfa 100644 --- a/configs/mx6sabresd_defconfig +++ b/configs/mx6sabresd_defconfig @@ -83,7 +83,6 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y CONFIG_PHY_ATHEROS=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_RGMII=y CONFIG_MII=y diff --git a/configs/pcm058_defconfig b/configs/pcm058_defconfig index 64947e8355d..c491cbf9a0c 100644 --- a/configs/pcm058_defconfig +++ b/configs/pcm058_defconfig @@ -7,9 +7,12 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_OFFSET=0x100000 CONFIG_ENV_SECT_SIZE=0x10000 -CONFIG_SYS_SPI_U_BOOT_OFFS=0x10000 +CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 +CONFIG_MX6_OCRAM_256KB=y CONFIG_TARGET_PCM058=y CONFIG_SPL_TEXT_BASE=0x00908000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 @@ -26,10 +29,11 @@ CONFIG_BOOTDELAY=3 # CONFIG_USE_BOOTCOMMAND is not set CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_BOUNCE_BUFFER=y -CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x18a CONFIG_SPL_DMA=y CONFIG_SPL_FS_EXT4=y -CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_SPL_YMODEM_SUPPORT=y @@ -38,33 +42,51 @@ CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_NAND_TRIMFFS=y -CONFIG_CMD_SF=y +# CONFIG_CMD_PINMUX is not set CONFIG_CMD_CACHE=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_MTDPARTS=y -CONFIG_MTDIDS_DEFAULT="nand0=nand" -CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:16m(uboot),1m(env),-(rootfs)" +CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand" +CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:-(rootfs)" CONFIG_CMD_UBI=y # CONFIG_SPL_PARTITION_UUIDS is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="imx6q-phytec-mira-rdk-nand" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y -CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MXC=y +CONFIG_DM_MMC=y CONFIG_FSL_USDHC=y CONFIG_MTD=y CONFIG_DM_MTD=y CONFIG_MTD_RAW_NAND=y CONFIG_SYS_NAND_USE_FLASH_BBT=y CONFIG_NAND_MXS=y -CONFIG_SPI_FLASH=y +CONFIG_NAND_MXS_DT=y +CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=20000000 CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y +CONFIG_DM_ETH=y +CONFIG_DM_MDIO=y +CONFIG_FEC_MXC=y CONFIG_MII=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +# CONFIG_PINCONF_RECURSIVE is not set +CONFIG_SPL_PINCTRL=y +CONFIG_SPL_PINCONF=y +# CONFIG_SPL_PINCONF_RECURSIVE is not set +CONFIG_PINCTRL_IMX6=y +CONFIG_DM_SERIAL=y +CONFIG_MXC_UART=y CONFIG_SPI=y +CONFIG_DM_SPI=y CONFIG_MXC_SPI=y -CONFIG_DM_THERMAL=y -CONFIG_OF_LIBFDT=y +# CONFIG_SPL_WDT is not set diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 66c9601b0c1..d32ff8409aa 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -95,6 +95,9 @@ static const char *imx8mm_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "s static const char *imx8mm_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; +static const char *imx8mm_usb_bus_sels[] = {"clock-osc-24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", }; + static const char *imx8mm_usdhc1_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; @@ -119,6 +122,15 @@ static const char *imx8mm_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ static const char *imx8mm_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", }; +static const char *imx8mm_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", + "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; + +static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + static ulong imx8mm_clk_get_rate(struct clk *clk) { struct clk *c; @@ -191,7 +203,10 @@ static int imx8mm_clk_set_parent(struct clk *clk, struct clk *parent) if (ret) return ret; - return clk_set_parent(c, cp); + ret = clk_set_parent(c, cp); + c->dev->parent = cp->dev; + + return ret; } static struct clk_ops imx8mm_clk_ops = { @@ -349,6 +364,8 @@ static int imx8mm_clk_probe(struct udevice *dev) imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900)); + clk_dm(IMX8MM_CLK_USB_BUS, + imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80)); /* IP */ clk_dm(IMX8MM_CLK_USDHC1, @@ -370,6 +387,12 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_USDHC3, imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80)); + clk_dm(IMX8MM_CLK_QSPI, + imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80)); + clk_dm(IMX8MM_CLK_USB_CORE_REF, + imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100)); + clk_dm(IMX8MM_CLK_USB_PHY_REF, + imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180)); clk_dm(IMX8MM_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); @@ -393,6 +416,10 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0)); clk_dm(IMX8MM_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); + clk_dm(IMX8MM_CLK_QSPI_ROOT, + imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); + clk_dm(IMX8MM_CLK_USB1_CTRL_ROOT, + imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); /* clks not needed in SPL stage */ #ifndef CONFIG_SPL_BUILD @@ -410,40 +437,6 @@ static int imx8mm_clk_probe(struct udevice *dev) base + 0x40a0, 0)); #endif -#ifdef CONFIG_SPL_BUILD - struct clk *clkp, *clkp1; - - clk_get_by_id(IMX8MM_CLK_WDOG1_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MM_CLK_WDOG2_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MM_CLK_WDOG3_ROOT, &clkp); - clk_enable(clkp); - - /* Configure SYS_PLL3 to 750MHz */ - clk_get_by_id(IMX8MM_SYS_PLL3, &clkp); - clk_set_rate(clkp, 750000000UL); - clk_enable(clkp); - - /* Configure ARM to sys_pll2_500m */ - clk_get_by_id(IMX8MM_CLK_A53_SRC, &clkp); - clk_get_by_id(IMX8MM_SYS_PLL2_OUT, &clkp1); - clk_enable(clkp1); - clk_get_by_id(IMX8MM_SYS_PLL2_500M, &clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure ARM PLL to 1.2GHz */ - clk_get_by_id(IMX8MM_ARM_PLL, &clkp1); - clk_set_rate(clkp1, 1200000000UL); - clk_get_by_id(IMX8MM_ARM_PLL_OUT, &clkp1); - clk_enable(clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure DIV to 1.2GHz */ - clk_get_by_id(IMX8MM_CLK_A53_DIV, &clkp1); - clk_set_rate(clkp1, 1200000000UL); -#endif - return 0; } diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 2d8e373131b..e29d902544c 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -81,9 +81,24 @@ static const char *imx8mn_ahb_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_p static const char *imx8mn_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; +#ifndef CONFIG_SPL_BUILD +static const char *imx8mn_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m", + "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", }; + +static const char *imx8mn_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4", "video_pll1_out", }; + +static const char *imx8mn_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m", + "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", }; +#endif + static const char *imx8mn_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; +static const char * const imx8mn_usb_bus_sels[] = {"clock-osc-24m", "sys_pll2_500m", "sys_pll1_800m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext4", "audio_pll2_out", }; + static const char *imx8mn_usdhc1_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; @@ -108,6 +123,17 @@ static const char *imx8mn_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ static const char *imx8mn_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", }; +static const char *imx8mn_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", + "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; + +static const char * const imx8mn_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mn_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + static ulong imx8mn_clk_get_rate(struct clk *clk) { struct clk *c; @@ -165,11 +191,33 @@ static int imx8mn_clk_enable(struct clk *clk) return __imx8mn_clk_enable(clk, 1); } +static int imx8mn_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *cp; + int ret; + + debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id); + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + ret = clk_get_by_id(parent->id, &cp); + if (ret) + return ret; + + ret = clk_set_parent(c, cp); + c->dev->parent = cp->dev; + + return ret; +} + static struct clk_ops imx8mn_clk_ops = { .set_rate = imx8mn_clk_set_rate, .get_rate = imx8mn_clk_get_rate, .enable = imx8mn_clk_enable, .disable = imx8mn_clk_disable, + .set_parent = imx8mn_clk_set_parent, }; static int imx8mn_clk_probe(struct udevice *dev) @@ -319,6 +367,8 @@ static int imx8mn_clk_probe(struct udevice *dev) imx8m_clk_composite_critical("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900)); + clk_dm(IMX8MN_CLK_USB_BUS, + imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80)); /* IP */ clk_dm(IMX8MN_CLK_USDHC1, @@ -340,6 +390,12 @@ static int imx8mn_clk_probe(struct udevice *dev) clk_dm(IMX8MN_CLK_USDHC3, imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80)); + clk_dm(IMX8MN_CLK_QSPI, + imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80)); + clk_dm(IMX8MN_CLK_USB_CORE_REF, + imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100)); + clk_dm(IMX8MN_CLK_USB_PHY_REF, + imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180)); clk_dm(IMX8MN_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); @@ -363,39 +419,25 @@ static int imx8mn_clk_probe(struct udevice *dev) imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0)); clk_dm(IMX8MN_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); - -#ifdef CONFIG_SPL_BUILD - struct clk *clkp, *clkp1; - - clk_get_by_id(IMX8MN_CLK_WDOG1_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MN_CLK_WDOG2_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MN_CLK_WDOG3_ROOT, &clkp); - clk_enable(clkp); - - /* Configure SYS_PLL3 to 600MHz */ - clk_get_by_id(IMX8MN_SYS_PLL3, &clkp); - clk_set_rate(clkp, 600000000UL); - clk_enable(clkp); - - /* Configure ARM to sys_pll2_500m */ - clk_get_by_id(IMX8MN_CLK_A53_SRC, &clkp); - clk_get_by_id(IMX8MN_SYS_PLL2_OUT, &clkp1); - clk_enable(clkp1); - clk_get_by_id(IMX8MN_SYS_PLL2_500M, &clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure ARM PLL to 1.2GHz */ - clk_get_by_id(IMX8MN_ARM_PLL, &clkp1); - clk_set_rate(clkp1, 1200000000UL); - clk_get_by_id(IMX8MN_ARM_PLL_OUT, &clkp1); - clk_enable(clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure DIV to 1.2GHz */ - clk_get_by_id(IMX8MN_CLK_A53_DIV, &clkp1); - clk_set_rate(clkp1, 1200000000UL); + clk_dm(IMX8MN_CLK_QSPI_ROOT, + imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); + clk_dm(IMX8MN_CLK_USB1_CTRL_ROOT, + imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); + + /* clks not needed in SPL stage */ +#ifndef CONFIG_SPL_BUILD + clk_dm(IMX8MN_CLK_ENET_REF, + imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels, + base + 0xa980)); + clk_dm(IMX8MN_CLK_ENET_TIMER, + imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels, + base + 0xaa00)); + clk_dm(IMX8MN_CLK_ENET_PHY_REF, + imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels, + base + 0xaa80)); + clk_dm(IMX8MN_CLK_ENET1_ROOT, + imx_clk_gate4("enet1_root_clk", "enet_axi", + base + 0x40a0, 0)); #endif return 0; diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 124138cf512..c77500bcce0 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -80,6 +80,10 @@ static const char *imx8mp_main_axi_sels[] = {"clock-osc-24m", "sys_pll2_333m", " "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",}; +static const char *imx8mp_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", + "video_pll1_out", "sys_pll3_out", }; + static const char *imx8mp_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; @@ -160,10 +164,26 @@ static const char *imx8mp_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m" }; +static const char *imx8mp_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", + "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", + "sys_pll3_out", "sys_pll1_100m", }; + static const char *imx8mp_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; +static const char *imx8mp_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", + "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", + "video_pll1_out", "clk_ext4", }; + +static const char *imx8mp_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", + "clk_ext1", "clk_ext2", "clk_ext3", + "clk_ext4", "video_pll1_out", }; + +static const char *imx8mp_enet_phy_ref_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", + "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + static const char *imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; @@ -224,11 +244,34 @@ static int imx8mp_clk_enable(struct clk *clk) return __imx8mp_clk_enable(clk, 1); } +static int imx8mp_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *cp; + int ret; + + debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id); + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + ret = clk_get_by_id(parent->id, &cp); + if (ret) + return ret; + + ret = clk_set_parent(c, cp); + + c->dev->parent = cp->dev; + + return ret; +} + static struct clk_ops imx8mp_clk_ops = { .set_rate = imx8mp_clk_set_rate, .get_rate = imx8mp_clk_get_rate, .enable = imx8mp_clk_enable, .disable = imx8mp_clk_disable, + .set_parent = imx8mp_clk_set_parent, }; static int imx8mp_clk_probe(struct udevice *dev) @@ -290,6 +333,7 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_A53_DIV, imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3)); clk_dm(IMX8MP_CLK_MAIN_AXI, imx8m_clk_composite_critical("main_axi", imx8mp_main_axi_sels, base + 0x8800)); + clk_dm(IMX8MP_CLK_ENET_AXI, imx8m_clk_composite_critical("enet_axi", imx8mp_enet_axi_sels, base + 0x8880)); clk_dm(IMX8MP_CLK_NAND_USDHC_BUS, imx8m_clk_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, base + 0x8900)); clk_dm(IMX8MP_CLK_NOC, imx8m_clk_composite_critical("noc", imx8mp_noc_sels, base + 0x8d00)); clk_dm(IMX8MP_CLK_NOC_IO, imx8m_clk_composite_critical("noc_io", imx8mp_noc_io_sels, base + 0x8d80)); @@ -302,6 +346,10 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_DRAM_APB, imx8m_clk_composite_critical("dram_apb", imx8mp_dram_apb_sels, base + 0xa080)); clk_dm(IMX8MP_CLK_I2C5, imx8m_clk_composite("i2c5", imx8mp_i2c5_sels, base + 0xa480)); clk_dm(IMX8MP_CLK_I2C6, imx8m_clk_composite("i2c6", imx8mp_i2c6_sels, base + 0xa500)); + clk_dm(IMX8MP_CLK_ENET_REF, imx8m_clk_composite("enet_ref", imx8mp_enet_ref_sels, base + 0xa980)); + clk_dm(IMX8MP_CLK_ENET_TIMER, imx8m_clk_composite("enet_timer", imx8mp_enet_timer_sels, base + 0xaa00)); + clk_dm(IMX8MP_CLK_ENET_PHY_REF, imx8m_clk_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, base + 0xaa80)); + clk_dm(IMX8MP_CLK_QSPI, imx8m_clk_composite("qspi", imx8mp_qspi_sels, base + 0xab80)); clk_dm(IMX8MP_CLK_USDHC1, imx8m_clk_composite("usdhc1", imx8mp_usdhc1_sels, base + 0xac00)); clk_dm(IMX8MP_CLK_USDHC2, imx8m_clk_composite("usdhc2", imx8mp_usdhc2_sels, base + 0xac80)); clk_dm(IMX8MP_CLK_I2C1, imx8m_clk_composite("i2c1", imx8mp_i2c1_sels, base + 0xad00)); @@ -322,6 +370,8 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_DRAM_CORE, imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL)); clk_dm(IMX8MP_CLK_DRAM1_ROOT, imx_clk_gate4_flags("dram1_root_clk", "dram_core_clk", base + 0x4050, 0, CLK_IS_CRITICAL)); + + clk_dm(IMX8MP_CLK_ENET1_ROOT, imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0)); clk_dm(IMX8MP_CLK_GPIO1_ROOT, imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0)); clk_dm(IMX8MP_CLK_GPIO2_ROOT, imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0)); clk_dm(IMX8MP_CLK_GPIO3_ROOT, imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0)); @@ -331,8 +381,10 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_I2C2_ROOT, imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0)); clk_dm(IMX8MP_CLK_I2C3_ROOT, imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0)); clk_dm(IMX8MP_CLK_I2C4_ROOT, imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0)); + clk_dm(IMX8MP_CLK_QSPI_ROOT, imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); clk_dm(IMX8MP_CLK_I2C5_ROOT, imx_clk_gate2("i2c5_root_clk", "i2c5", base + 0x4330, 0)); clk_dm(IMX8MP_CLK_I2C6_ROOT, imx_clk_gate2("i2c6_root_clk", "i2c6", base + 0x4340, 0)); + clk_dm(IMX8MP_CLK_SIM_ENET_ROOT, imx_clk_gate4("sim_enet_root_clk", "enet_axi", base + 0x4400, 0)); clk_dm(IMX8MP_CLK_UART1_ROOT, imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0)); clk_dm(IMX8MP_CLK_UART2_ROOT, imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0)); clk_dm(IMX8MP_CLK_UART3_ROOT, imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0)); diff --git a/drivers/ddr/imx/imx8m/Kconfig b/drivers/ddr/imx/imx8m/Kconfig index 5bf61eb2587..a5f5524fbec 100644 --- a/drivers/ddr/imx/imx8m/Kconfig +++ b/drivers/ddr/imx/imx8m/Kconfig @@ -29,4 +29,11 @@ config SAVED_DRAM_TIMING_BASE info into memory for low power use. OCRAM_S is used for this purpose on i.MX8MM. default 0x180000 + +config IMX8M_DRAM_INLINE_ECC + bool "imx8mp inline ECC" + depends on IMX8MP && IMX8M_LPDDR4 + help + Select this config if you want to use inline ecc feature for + imx8mp-evk board. endmenu diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c index bbddee6ca89..99a67edfb0a 100644 --- a/drivers/ddr/imx/imx8m/ddr_init.c +++ b/drivers/ddr/imx/imx8m/ddr_init.c @@ -21,6 +21,76 @@ void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num) } } +#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC +void ddrc_inline_ecc_scrub(unsigned int start_address, + unsigned int range_address) +{ + unsigned int tmp; + + /* Step1: Enable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000000); + /* Step2: Set ECCCFG1.ecc_parity_region_lock to 1 */ + reg32setbit(DDRC_ECCCFG1(0), 0x4); + /* Step3: Block the AXI ports from taking the transaction */ + reg32_write(DDRC_PCTRL_0(0), 0x0); + /* Step4: Set scrub start address */ + reg32_write(DDRC_SBRSTART0(0), start_address); + /* Step5: Set scrub range address */ + reg32_write(DDRC_SBRRANGE0(0), range_address); + /* Step6: Set scrub_mode to write */ + reg32_write(DDRC_SBRCTL(0), 0x00000014); + /* Step7: Set the desired pattern through SBRWDATA0 registers */ + reg32_write(DDRC_SBRWDATA0(0), 0x55aa55aa); + /* Step8: Enable the SBR by programming SBRCTL.scrub_en=1 */ + reg32setbit(DDRC_SBRCTL(0), 0x0); + /* Step9: Poll SBRSTAT.scrub_done=1 */ + tmp = reg32_read(DDRC_SBRSTAT(0)); + while (tmp != 0x00000002) + tmp = reg32_read(DDRC_SBRSTAT(0)) & 0x2; + /* Step10: Poll SBRSTAT.scrub_busy=0 */ + tmp = reg32_read(DDRC_SBRSTAT(0)); + while (tmp != 0x0) + tmp = reg32_read(DDRC_SBRSTAT(0)) & 0x1; + /* Step11: Disable SBR by programming SBRCTL.scrub_en=0 */ + clrbits_le32(DDRC_SBRCTL(0), 0x1); + /* Step12: Prepare for normal scrub operation(Read) and set scrub_interval*/ + reg32_write(DDRC_SBRCTL(0), 0x100); + /* Step13: Enable the SBR by programming SBRCTL.scrub_en=1 */ + reg32_write(DDRC_SBRCTL(0), 0x101); + /* Step14: Enable AXI ports by programming */ + reg32_write(DDRC_PCTRL_0(0), 0x1); + /* Step15: Disable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000001); +} + +void ddrc_inline_ecc_scrub_end(unsigned int start_address, + unsigned int range_address) +{ + /* Step1: Enable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000000); + /* Step2: Block the AXI ports from taking the transaction */ + reg32_write(DDRC_PCTRL_0(0), 0x0); + /* Step3: Set scrub start address */ + reg32_write(DDRC_SBRSTART0(0), start_address); + /* Step4: Set scrub range address */ + reg32_write(DDRC_SBRRANGE0(0), range_address); + /* Step5: Disable SBR by programming SBRCTL.scrub_en=0 */ + clrbits_le32(DDRC_SBRCTL(0), 0x1); + /* Step6: Prepare for normal scrub operation(Read) and set scrub_interval */ + reg32_write(DDRC_SBRCTL(0), 0x100); + /* Step7: Enable the SBR by programming SBRCTL.scrub_en=1 */ + reg32_write(DDRC_SBRCTL(0), 0x101); + /* Step8: Enable AXI ports by programming */ + reg32_write(DDRC_PCTRL_0(0), 0x1); + /* Step9: Disable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000001); +} +#endif + +void __weak board_dram_ecc_scrub(void) +{ +} + int ddr_init(struct dram_timing_info *dram_timing) { unsigned int tmp, initial_drate, target_freq; @@ -74,7 +144,7 @@ int ddr_init(struct dram_timing_info *dram_timing) /* if ddr type is LPDDR4, do it */ tmp = reg32_read(DDRC_MSTR(0)); - if (tmp & (0x1 << 5)) + if (tmp & (0x1 << 5) && !is_imx8mn()) reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */ /* determine the initial boot frequency */ @@ -120,6 +190,9 @@ int ddr_init(struct dram_timing_info *dram_timing) /* Step15: Set SWCTL.sw_done to 0 */ reg32_write(DDRC_SWCTL(0), 0x00000000); + /* Apply rank-to-rank workaround */ + update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1); + /* Step16: Set DFIMISC.dfi_init_start to 1 */ setbits_le32(DDRC_DFIMISC(0), (0x1 << 5)); @@ -163,12 +236,14 @@ int ddr_init(struct dram_timing_info *dram_timing) /* Step26: Set back register in Step4 to the original values if desired */ reg32_write(DDRC_RFSHCTL3(0), 0x0000000); /* enable selfref_en by default */ - setbits_le32(DDRC_PWRCTL(0), 0x1 << 3); + setbits_le32(DDRC_PWRCTL(0), 0x1); /* enable port 0 */ reg32_write(DDRC_PCTRL_0(0), 0x00000001); debug("DDRINFO: ddrmix config done\n"); + board_dram_ecc_scrub(); + /* save the dram timing config into memory */ dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE); diff --git a/drivers/ddr/imx/imx8m/ddrphy_train.c b/drivers/ddr/imx/imx8m/ddrphy_train.c index f2a997b50a6..08fed6178f3 100644 --- a/drivers/ddr/imx/imx8m/ddrphy_train.c +++ b/drivers/ddr/imx/imx8m/ddrphy_train.c @@ -8,6 +8,7 @@ #include <linux/kernel.h> #include <asm/arch/ddr.h> #include <asm/arch/lpddr4_define.h> +#include <asm/arch/sys_proto.h> int ddr_cfg_phy(struct dram_timing_info *dram_timing) { @@ -71,9 +72,15 @@ int ddr_cfg_phy(struct dram_timing_info *dram_timing) /* Read the Message Block results */ dwc_ddrphy_apb_wr(0xd0000, 0x0); + ddrphy_init_read_msg_block(fsp_msg->fw_type); + + if(fsp_msg->fw_type != FW_2D_IMAGE) + get_trained_CDD(i); + dwc_ddrphy_apb_wr(0xd0000, 0x1); + fsp_msg++; } diff --git a/drivers/ddr/imx/imx8m/ddrphy_utils.c b/drivers/ddr/imx/imx8m/ddrphy_utils.c index d5eef535739..20ae47bfb52 100644 --- a/drivers/ddr/imx/imx8m/ddrphy_utils.c +++ b/drivers/ddr/imx/imx8m/ddrphy_utils.c @@ -11,6 +11,12 @@ #include <asm/arch/clock.h> #include <asm/arch/ddr.h> #include <asm/arch/lpddr4_define.h> +#include <asm/arch/sys_proto.h> + +static unsigned int g_cdd_rr_max[4]; +static unsigned int g_cdd_rw_max[4]; +static unsigned int g_cdd_wr_max[4]; +static unsigned int g_cdd_ww_max[4]; static inline void poll_pmu_message_ready(void) { @@ -193,3 +199,161 @@ unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr) return tmp; } + +unsigned int look_for_max(unsigned int data[], + unsigned int addr_start, unsigned int addr_end) +{ + unsigned int i, imax = 0; + + for (i = addr_start; i <= addr_end; i++) { + if (((data[i] >> 7) == 0) && (data[i] > imax)) + imax = data[i]; + } + + return imax; +} + +void get_trained_CDD(u32 fsp) +{ + unsigned int i, ddr_type, tmp; + unsigned int cdd_cha[12], cdd_chb[12]; + unsigned int cdd_cha_rr_max, cdd_cha_rw_max, cdd_cha_wr_max, cdd_cha_ww_max; + unsigned int cdd_chb_rr_max, cdd_chb_rw_max, cdd_chb_wr_max, cdd_chb_ww_max; + + ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f; + if (ddr_type == 0x20) { + for (i = 0; i < 6; i++) { + tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54013 + i) * 4); + cdd_cha[i * 2] = tmp & 0xff; + cdd_cha[i * 2 + 1] = (tmp >> 8) & 0xff; + } + + for (i = 0; i < 7; i++) { + tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x5402c + i) * 4); + if (i == 0) { + cdd_cha[0] = (tmp >> 8) & 0xff; + } else if (i == 6) { + cdd_cha[11]=tmp & 0xff; + } else { + cdd_chb[ i * 2 - 1] = tmp & 0xff; + cdd_chb[i * 2] = (tmp >> 8) & 0xff; + } + } + + cdd_cha_rr_max = look_for_max(cdd_cha, 0, 1); + cdd_cha_rw_max = look_for_max(cdd_cha, 2, 5); + cdd_cha_wr_max = look_for_max(cdd_cha, 6, 9); + cdd_cha_ww_max = look_for_max(cdd_cha, 10, 11); + cdd_chb_rr_max = look_for_max(cdd_chb, 0, 1); + cdd_chb_rw_max = look_for_max(cdd_chb, 2, 5); + cdd_chb_wr_max = look_for_max(cdd_chb, 6, 9); + cdd_chb_ww_max = look_for_max(cdd_chb, 10, 11); + g_cdd_rr_max[fsp] = cdd_cha_rr_max > cdd_chb_rr_max ? cdd_cha_rr_max : cdd_chb_rr_max; + g_cdd_rw_max[fsp] = cdd_cha_rw_max > cdd_chb_rw_max ? cdd_cha_rw_max : cdd_chb_rw_max; + g_cdd_wr_max[fsp] = cdd_cha_wr_max > cdd_chb_wr_max ? cdd_cha_wr_max : cdd_chb_wr_max; + g_cdd_ww_max[fsp] = cdd_cha_ww_max > cdd_chb_ww_max ? cdd_cha_ww_max : cdd_chb_ww_max; + } else { + unsigned int ddr4_cdd[64]; + for( i = 0; i < 29; i++) { + tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54012 + i) * 4); + ddr4_cdd[i * 2] = tmp & 0xff; + ddr4_cdd[i * 2 + 1] = (tmp >> 8) & 0xff; + } + + g_cdd_rr_max[fsp] = look_for_max(ddr4_cdd, 1, 12); + g_cdd_ww_max[fsp] = look_for_max(ddr4_cdd, 13, 24); + g_cdd_rw_max[fsp] = look_for_max(ddr4_cdd, 25, 40); + g_cdd_wr_max[fsp] = look_for_max(ddr4_cdd, 41, 56); + } +} + +void update_umctl2_rank_space_setting(unsigned int pstat_num) +{ + unsigned int i,ddr_type; + unsigned int addr_slot, rdata, tmp, tmp_t; + unsigned int ddrc_w2r,ddrc_r2w,ddrc_wr_gap,ddrc_rd_gap; + + ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f; + for (i = 0; i < pstat_num; i++) { + addr_slot = i ? (i + 1) * 0x1000 : 0; + if (ddr_type == 0x20) { + /* update r2w:[13:8], w2r:[5:0] */ + rdata=reg32_read(DDRC_DRAMTMG2(0) + addr_slot); + ddrc_w2r = rdata & 0x3f; + if(is_imx8mp()) + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1); + else + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1; + ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp; + + ddrc_r2w = (rdata >> 8) & 0x3f; + if (is_imx8mp()) + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1); + else + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1; + ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp; + + tmp_t = (rdata & 0xffffc0c0) | (ddrc_r2w << 8) | ddrc_w2r; + reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t); + } else { + /* update w2r:[5:0] */ + rdata=reg32_read(DDRC_DRAMTMG9(0) + addr_slot); + ddrc_w2r = rdata & 0x3f; + if (is_imx8mp()) + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1); + else + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1; + ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp; + tmp_t = (rdata & 0xffffffc0) | ddrc_w2r; + reg32_write((DDRC_DRAMTMG9(0) + addr_slot), tmp_t); + + /* update r2w:[13:8] */ + rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot); + ddrc_r2w = (rdata >> 8) & 0x3f; + if(is_imx8mp()) + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1); + else + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1; + ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp; + + tmp_t = (rdata & 0xffffc0ff) | (ddrc_r2w << 8); + reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t); + } + + if (!is_imx8mq()) { + /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */ + rdata = reg32_read(DDRC_RANKCTL(0) + addr_slot); + ddrc_wr_gap = (rdata >> 8) & 0xf; + if(is_imx8mp()) + tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1); + else + tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1) + 1; + ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp; + + ddrc_rd_gap = (rdata >> 4) & 0xf; + if (is_imx8mp()) + tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1); + else + tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1) + 1; + ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp; + + tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4); + reg32_write((DDRC_RANKCTL(0) + addr_slot), tmp_t); + } + } + + if(is_imx8mq()) { + /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */ + rdata = reg32_read(DDRC_RANKCTL(0)); + ddrc_wr_gap = (rdata >> 8) & 0xf; + tmp = ddrc_wr_gap + (g_cdd_ww_max[0] >> 1) + 1; + ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp; + + ddrc_rd_gap = (rdata >> 4) & 0xf; + tmp = ddrc_rd_gap + (g_cdd_rr_max[0] >> 1) + 1; + ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp; + + tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4); + reg32_write(DDRC_RANKCTL(0), tmp_t); + } +} diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index 316dcc757b2..90d36fb87bb 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -295,46 +295,26 @@ static int mxc_gpio_probe(struct udevice *dev) return 0; } -static int mxc_gpio_bind(struct udevice *dev) +static int mxc_gpio_ofdata_to_platdata(struct udevice *dev) { - struct mxc_gpio_plat *plat = dev->platdata; fdt_addr_t addr; - - /* - * If platdata already exsits, directly return. - * Actually only when DT is not supported, platdata - * is statically initialized in U_BOOT_DEVICES.Here - * will return. - */ - if (plat) - return 0; + struct mxc_gpio_plat *plat = dev_get_platdata(dev); addr = devfdt_get_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; - /* - * TODO: - * When every board is converted to driver model and DT is supported, - * this can be done by auto-alloc feature, but not using calloc - * to alloc memory for platdata. - * - * For example mxc_plat below uses platform data rather than device - * tree. - * - * NOTE: DO NOT COPY this code if you are using device tree. - */ - plat = calloc(1, sizeof(*plat)); - if (!plat) - return -ENOMEM; - plat->regs = (struct gpio_regs *)addr; plat->bank_index = dev->req_seq; - dev->platdata = plat; return 0; } +static int mxc_gpio_bind(struct udevice *dev) +{ + return 0; +} + static const struct udevice_id mxc_gpio_ids[] = { { .compatible = "fsl,imx35-gpio" }, { } @@ -345,6 +325,8 @@ U_BOOT_DRIVER(gpio_mxc) = { .id = UCLASS_GPIO, .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, + .ofdata_to_platdata = mxc_gpio_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct mxc_gpio_plat), .priv_auto_alloc_size = sizeof(struct mxc_bank_info), .of_match = mxc_gpio_ids, .bind = mxc_gpio_bind, diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c index 4d7f2f524d0..be181229370 100644 --- a/drivers/misc/imx8/fuse.c +++ b/drivers/misc/imx8/fuse.c @@ -9,6 +9,7 @@ #include <fuse.h> #include <asm/arch/sci/sci.h> #include <asm/arch/sys_proto.h> +#include <linux/arm-smccc.h> DECLARE_GLOBAL_DATA_PTR; @@ -36,22 +37,24 @@ int fuse_read(u32 bank, u32 word, u32 *val) int fuse_sense(u32 bank, u32 word, u32 *val) { - unsigned long ret = 0, value = 0; + struct arm_smccc_res res; if (bank != 0) { printf("Invalid bank argument, ONLY bank 0 is supported\n"); return -EINVAL; } - ret = call_imx_sip_ret2(FSL_SIP_OTP_READ, (unsigned long)word, &value, - 0, 0); - *val = (u32)value; + arm_smccc_smc(FSL_SIP_OTP_READ, (unsigned long)word, 0, 0, + 0, 0, 0, 0, &res); + *val = (u32)res.a1; - return ret; + return res.a0; } int fuse_prog(u32 bank, u32 word, u32 val) { + struct arm_smccc_res res; + if (bank != 0) { printf("Invalid bank argument, ONLY bank 0 is supported\n"); return -EINVAL; @@ -78,8 +81,10 @@ int fuse_prog(u32 bank, u32 word, u32 val) } } - return call_imx_sip(FSL_SIP_OTP_WRITE, (unsigned long)word, - (unsigned long)val, 0, 0); + arm_smccc_smc(FSL_SIP_OTP_WRITE, (unsigned long)word, + (unsigned long)val, 0, 0, 0, 0, 0, &res); + + return res.a0; } int fuse_override(u32 bank, u32 word, u32 val) diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index 3e38edbf5dc..20b74fbb18d 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -374,6 +374,31 @@ void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status) __func__, status, RPC_R8(&msg)); } +int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx) +{ + struct udevice *dev = gd->arch.scu_dev; + int size = sizeof(struct sc_rpc_msg_s); + struct sc_rpc_msg_s msg; + int ret; + + if (!dev) + hang(); + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 1U; + RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC; + RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_CONTAINER; + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret < 0) + return ret; + + if (idx) + *idx = (u8)RPC_U8(&msg, 0U); + + return 0; +} + void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit) { struct udevice *dev = gd->arch.scu_dev; diff --git a/drivers/pinctrl/nxp/pinctrl-imx5.c b/drivers/pinctrl/nxp/pinctrl-imx5.c index 5d173809198..9c3423bef37 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx5.c +++ b/drivers/pinctrl/nxp/pinctrl-imx5.c @@ -10,7 +10,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info; +static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info __attribute__((section(".data"))); static int imx5_pinctrl_probe(struct udevice *dev) { diff --git a/drivers/pinctrl/nxp/pinctrl-imx7.c b/drivers/pinctrl/nxp/pinctrl-imx7.c index 769d428ddad..66b58ba472c 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx7.c +++ b/drivers/pinctrl/nxp/pinctrl-imx7.c @@ -9,7 +9,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info; +static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info __attribute__((section(".data"))); static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = { .flags = ZERO_OFFSET_VALID, diff --git a/drivers/pinctrl/nxp/pinctrl-imx8m.c b/drivers/pinctrl/nxp/pinctrl-imx8m.c index 5b7cbb69ae8..0626fde58f1 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx8m.c +++ b/drivers/pinctrl/nxp/pinctrl-imx8m.c @@ -8,7 +8,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info; +static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info __attribute__((section(".data"))); static int imx8mq_pinctrl_probe(struct udevice *dev) { diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c index 5b6467cda70..0ef460df8c2 100644 --- a/drivers/power/domain/imx8m-power-domain.c +++ b/drivers/power/domain/imx8m-power-domain.c @@ -13,6 +13,7 @@ #include <dm/device-internal.h> #include <dm/device.h> #include <imx_sip.h> +#include <linux/arm-smccc.h> DECLARE_GLOBAL_DATA_PTR; @@ -30,6 +31,7 @@ static int imx8m_power_domain_on(struct power_domain *power_domain) { struct udevice *dev = power_domain->dev; struct imx8m_power_domain_platdata *pdata; + pdata = dev_get_platdata(dev); if (pdata->resource_id < 0) @@ -38,8 +40,8 @@ static int imx8m_power_domain_on(struct power_domain *power_domain) if (pdata->has_pd) power_domain_on(&pdata->pd); - call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, - pdata->resource_id, 1, 0); + arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, + pdata->resource_id, 1, 0, 0, 0, 0, NULL); return 0; } @@ -53,8 +55,8 @@ static int imx8m_power_domain_off(struct power_domain *power_domain) if (pdata->resource_id < 0) return -EINVAL; - call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, - pdata->resource_id, 0, 0); + arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, + pdata->resource_id, 0, 0, 0, 0, 0, NULL); if (pdata->has_pd) power_domain_off(&pdata->pd); diff --git a/drivers/power/pmic/pmic_pca9450.c b/drivers/power/pmic/pmic_pca9450.c index 67a90902006..d4f27428bd1 100644 --- a/drivers/power/pmic/pmic_pca9450.c +++ b/drivers/power/pmic/pmic_pca9450.c @@ -11,26 +11,7 @@ static const char pca9450_name[] = "PCA9450"; -int power_pca9450a_init(unsigned char bus) -{ - struct pmic *p = pmic_alloc(); - - if (!p) { - printf("%s: POWER allocation error!\n", __func__); - return -ENOMEM; - } - - p->name = pca9450_name; - p->interface = PMIC_I2C; - p->number_of_regs = PCA9450_REG_NUM; - p->hw.i2c.addr = 0x35; - p->hw.i2c.tx_num = 1; - p->bus = bus; - - return 0; -} - -int power_pca9450b_init(unsigned char bus) +int power_pca9450_init(unsigned char bus) { struct pmic *p = pmic_alloc(); diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 3a8add98f76..30d808d7bb2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -155,6 +155,14 @@ config FSL_QSPI used to access the SPI NOR flash on platforms embedding this Freescale IP core. +config FSL_QSPI_AHB_FULL_MAP + bool "Use full AHB memory map space" + depends on FSL_QSPI + default y if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP || ARCH_IMX8M + help + Enable the Freescale QSPI driver to use full AHB memory map space for + flash access. + config ICH_SPI bool "Intel ICH SPI driver" help diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index e715f9838f1..eec968e5ec1 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -46,6 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; * read operation, so let's use the last entry (15). */ #define SEQID_LUT 15 +#define SEQID_LUT_AHB 14 /* Registers used by the driver */ #define QUADSPI_MCR 0x00 @@ -122,6 +123,10 @@ DECLARE_GLOBAL_DATA_PTR; #define QUADSPI_LUT_REG(idx) \ (QUADSPI_LUT_BASE + QUADSPI_LUT_OFFSET + (idx) * 4) +#define QUADSPI_AHB_LUT_OFFSET (SEQID_LUT_AHB * 4 * 4) +#define QUADSPI_AHB_LUT_REG(idx) \ + (QUADSPI_LUT_BASE + QUADSPI_AHB_LUT_OFFSET + (idx) * 4) + /* Instruction set for the LUT register */ #define LUT_STOP 0 #define LUT_CMD 1 @@ -189,6 +194,11 @@ DECLARE_GLOBAL_DATA_PTR; */ #define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5) +/* + * Controller only has Two CS on flash A, no flash B port + */ +#define QUADSPI_QUIRK_SINGLE_BUS BIT(6) + struct fsl_qspi_devtype_data { unsigned int rxfifo; unsigned int txfifo; @@ -231,6 +241,15 @@ static const struct fsl_qspi_devtype_data imx6ul_data = { .little_endian = true, }; +static const struct fsl_qspi_devtype_data imx7ulp_data = { + .rxfifo = SZ_64, + .txfifo = SZ_64, + .ahb_buf_size = SZ_128, + .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK | + QUADSPI_QUIRK_USE_TDH_SETTING | QUADSPI_QUIRK_SINGLE_BUS, + .little_endian = true, +}; + static const struct fsl_qspi_devtype_data ls1021a_data = { .rxfifo = SZ_128, .txfifo = SZ_64, @@ -260,6 +279,7 @@ struct fsl_qspi { void __iomem *iobase; void __iomem *ahb_addr; u32 memmap_phy; + u32 memmap_size; const struct fsl_qspi_devtype_data *devtype_data; int selected; }; @@ -294,6 +314,11 @@ static inline int needs_tdh_setting(struct fsl_qspi *q) return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING; } +static inline int needs_single_bus(struct fsl_qspi *q) +{ + return q->devtype_data->quirks & QUADSPI_QUIRK_SINGLE_BUS; +} + /* * An IC bug makes it necessary to rearrange the 32-bit data. * Later chips, such as IMX6SLX, have fixed this bug. @@ -396,18 +421,27 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q, lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth), op->cmd.opcode); - /* - * For some unknown reason, using LUT_ADDR doesn't work in some - * cases (at least with only one byte long addresses), so - * let's use LUT_MODE to write the address bytes one by one - */ - for (i = 0; i < op->addr.nbytes; i++) { - u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1)); - - lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE, - LUT_PAD(op->addr.buswidth), - addrbyte); - lutidx++; + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->addr.nbytes) { + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR, + LUT_PAD(op->addr.buswidth), + (op->addr.nbytes == 4) ? 0x20 : 0x18); + lutidx++; + } + } else { + /* + * For some unknown reason, using LUT_ADDR doesn't work in some + * cases (at least with only one byte long addresses), so + * let's use LUT_MODE to write the address bytes one by one + */ + for (i = 0; i < op->addr.nbytes; i++) { + u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1)); + + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE, + LUT_PAD(op->addr.buswidth), + addrbyte); + lutidx++; + } } if (op->dummy.nbytes) { @@ -440,6 +474,14 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q, for (i = 0; i < ARRAY_SIZE(lutval); i++) qspi_writel(q, lutval[i], base + QUADSPI_LUT_REG(i)); + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN && + op->addr.nbytes) { + for (i = 0; i < ARRAY_SIZE(lutval); i++) + qspi_writel(q, lutval[i], base + QUADSPI_AHB_LUT_REG(i)); + } + } + /* lock LUT */ qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR); @@ -482,10 +524,29 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_slave *slave) fsl_qspi_invalidate(q); } +static u32 fsl_qspi_memsize_per_cs(struct fsl_qspi *q) +{ + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (needs_single_bus(q)) + return q->memmap_size / 2; + else + return q->memmap_size / 4; + } else { + return ALIGN(q->devtype_data->ahb_buf_size, 0x400); + } +} + static void fsl_qspi_read_ahb(struct fsl_qspi *q, const struct spi_mem_op *op) { + void __iomem *ahb_read_addr = q->ahb_addr; + + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->addr.nbytes) + ahb_read_addr += op->addr.val; + } + memcpy_fromio(op->data.buf.in, - q->ahb_addr + q->selected * q->devtype_data->ahb_buf_size, + ahb_read_addr + q->selected * fsl_qspi_memsize_per_cs(q), op->data.nbytes); } @@ -588,8 +649,13 @@ static int fsl_qspi_exec_op(struct spi_slave *slave, if (needs_amba_base_offset(q)) addr_offset = q->memmap_phy; + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->addr.nbytes) + addr_offset += op->addr.val; + } + qspi_writel(q, - q->selected * q->devtype_data->ahb_buf_size + addr_offset, + q->selected * fsl_qspi_memsize_per_cs(q) + addr_offset, base + QUADSPI_SFAR); qspi_writel(q, qspi_readl(q, base + QUADSPI_MCR) | @@ -646,7 +712,7 @@ static int fsl_qspi_adjust_op_size(struct spi_slave *slave, static int fsl_qspi_default_setup(struct fsl_qspi *q) { void __iomem *base = q->iobase; - u32 reg, addr_offset = 0; + u32 reg, addr_offset = 0, memsize_cs; /* Reset the module */ qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK, @@ -678,8 +744,13 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) qspi_writel(q, 0, base + QUADSPI_BUF1IND); qspi_writel(q, 0, base + QUADSPI_BUF2IND); - qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT), - q->iobase + QUADSPI_BFGENCR); + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) + qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT_AHB), + q->iobase + QUADSPI_BFGENCR); + else + qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT), + q->iobase + QUADSPI_BFGENCR); + qspi_writel(q, QUADSPI_RBCT_WMRK_MASK, base + QUADSPI_RBCT); qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | QUADSPI_BUF3CR_ADATSZ(q->devtype_data->ahb_buf_size / 8), @@ -695,14 +766,17 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) * We use ahb_buf_size for each chip and set SFA1AD, SFA2AD, SFB1AD, * SFB2AD accordingly. */ - qspi_writel(q, q->devtype_data->ahb_buf_size + addr_offset, + memsize_cs = fsl_qspi_memsize_per_cs(q); + qspi_writel(q, memsize_cs + addr_offset, base + QUADSPI_SFA1AD); - qspi_writel(q, q->devtype_data->ahb_buf_size * 2 + addr_offset, + qspi_writel(q, memsize_cs * 2 + addr_offset, base + QUADSPI_SFA2AD); - qspi_writel(q, q->devtype_data->ahb_buf_size * 3 + addr_offset, - base + QUADSPI_SFB1AD); - qspi_writel(q, q->devtype_data->ahb_buf_size * 4 + addr_offset, - base + QUADSPI_SFB2AD); + if (!needs_single_bus(q)) { + qspi_writel(q, memsize_cs * 3 + addr_offset, + base + QUADSPI_SFB1AD); + qspi_writel(q, memsize_cs * 4 + addr_offset, + base + QUADSPI_SFB2AD); + } q->selected = -1; @@ -750,6 +824,7 @@ static int fsl_qspi_probe(struct udevice *bus) q->ahb_addr = map_physmem(res.start, res.end - res.start, MAP_NOCACHE); q->memmap_phy = res.start; + q->memmap_size = res.end - res.start; dm_bus->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 66000000); @@ -799,6 +874,7 @@ static const struct udevice_id fsl_qspi_ids[] = { { .compatible = "fsl,imx6sx-qspi", .data = (ulong)&imx6sx_data, }, { .compatible = "fsl,imx6ul-qspi", .data = (ulong)&imx6ul_data, }, { .compatible = "fsl,imx7d-qspi", .data = (ulong)&imx7d_data, }, + { .compatible = "fsl,imx7ulp-qspi", .data = (ulong)&imx7ulp_data, }, { .compatible = "fsl,ls1021a-qspi", .data = (ulong)&ls1021a_data, }, { .compatible = "fsl,ls1088a-qspi", .data = (ulong)&ls1088a_data, }, { .compatible = "fsl,ls2080a-qspi", .data = (ulong)&ls2080a_data, }, diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c index 01762df019b..b90c2daecee 100644 --- a/drivers/watchdog/imx_watchdog.c +++ b/drivers/watchdog/imx_watchdog.c @@ -16,6 +16,10 @@ #include <asm/arch/immap_lsch2.h> #endif #include <fsl_wdog.h> +#include <div64.h> + +#define TIMEOUT_MAX 128000 +#define TIMEOUT_MIN 500 static void imx_watchdog_expire_now(struct watchdog_regs *wdog, bool ext_reset) { @@ -57,9 +61,9 @@ static void imx_watchdog_reset(struct watchdog_regs *wdog) #endif /* CONFIG_WATCHDOG_RESET_DISABLE*/ } -static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset) +static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset, + u64 timeout) { - u16 timeout; u16 wcr; /* @@ -70,7 +74,11 @@ static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset) #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS #define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000 #endif - timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1; + + timeout = max_t(u64, timeout, TIMEOUT_MIN); + timeout = min_t(u64, timeout, TIMEOUT_MAX); + timeout = lldiv(timeout, 500) - 1; + #ifdef CONFIG_FSL_LSCH2 wcr = (WCR_WDA | WCR_SRS | WCR_WDE) << 8 | timeout; #else @@ -95,7 +103,7 @@ void hw_watchdog_init(void) { struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; - imx_watchdog_init(wdog, true); + imx_watchdog_init(wdog, true, CONFIG_WATCHDOG_TIMEOUT_MSECS); } #else struct imx_wdt_priv { @@ -126,7 +134,7 @@ static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags) { struct imx_wdt_priv *priv = dev_get_priv(dev); - imx_watchdog_init(priv->base, priv->ext_reset); + imx_watchdog_init(priv->base, priv->ext_reset, timeout); return 0; } diff --git a/include/configs/imx8mm_evk.h b/include/configs/imx8mm_evk.h index 382ba620ccf..d1c0e0ec2ed 100644 --- a/include/configs/imx8mm_evk.h +++ b/include/configs/imx8mm_evk.h @@ -10,6 +10,7 @@ #include <linux/stringify.h> #include <asm/arch/imx-regs.h> +#define CONFIG_SYS_BOOTM_LEN (32 * SZ_1M) #define CONFIG_SPL_MAX_SIZE (148 * 1024) #define CONFIG_SYS_MONITOR_LEN SZ_512K #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR diff --git a/include/configs/pcm058.h b/include/configs/pcm058.h index 7c27ebb811d..4f03699117b 100644 --- a/include/configs/pcm058.h +++ b/include/configs/pcm058.h @@ -3,7 +3,6 @@ * Copyright (C) Stefano Babic <sbabic@denx.de> */ - #ifndef __PCM058_CONFIG_H #define __PCM058_CONFIG_H @@ -13,48 +12,13 @@ #include "mx6_common.h" -/* Thermal */ -#define CONFIG_IMX_THERMAL - -/* Serial */ -#define CONFIG_MXC_UART -#define CONFIG_MXC_UART_BASE UART2_BASE -#define CONSOLE_DEV "ttymxc1" - #define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024) -/* Early setup */ - - /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (8 * SZ_1M) -/* Ethernet */ -#define CONFIG_FEC_MXC -#define IMX_FEC_BASE ENET_BASE_ADDR -#define CONFIG_FEC_XCV_TYPE RGMII -#define CONFIG_ETHPRIME "FEC" -#define CONFIG_FEC_MXC_PHYADDR 3 - -/* SPI Flash */ - -/* I2C Configs */ -#define CONFIG_SYS_I2C -#define CONFIG_SYS_I2C_MXC -#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 2 */ -#define CONFIG_SYS_I2C_SPEED 100000 - -#ifndef CONFIG_SPL_BUILD /* Enable NAND support */ #define CONFIG_SYS_MAX_NAND_DEVICE 1 -#define CONFIG_SYS_NAND_BASE 0x40000000 -#define CONFIG_SYS_NAND_5_ADDR_CYCLE -#define CONFIG_SYS_NAND_ONFI_DETECTION -#endif - -/* DMA stuff, needed for GPMI/MXS NAND support */ - -/* Filesystem support */ /* Physical Memory Map */ #define PHYS_SDRAM MMDC0_ARB_BASE_ADDR @@ -68,10 +32,33 @@ #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) -/* MMC Configs */ -#define CONFIG_SYS_FSL_ESDHC_ADDR 0 -#define CONFIG_SYS_FSL_USDHC_NUM 1 - /* Environment organization */ - +#define ENV_MMC \ + "mmcdev=0\0" \ + "mmcpart=2\0" \ + "fitpart=1\0" \ + "mmcrootfstype=ext4\0" \ + "fitname=fitImage\0" \ + "mmcloadfit=load mmc ${mmcdev}:${fitpart} ${loadaddr} ${fitname}\0" \ + "mmcargs=setenv bootargs root=/dev/mmcblk${mmcdev}p${mmcpart} " \ + "rootfstype=${mmcrootfstype} ${optargs}\0" \ + "mmcboot=run mmcloadfit;run mmcargs;bootm ${loadaddr}\0" + +#define ENV_NAND \ + "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \ + "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \ + "nandroot=ubi0:root ubi.mtd=rootfs\0" \ + "nandrootfstype=ubifs\0" \ + "nandargs=setenv bootargs root=${nandroot} " \ + "rootfstype=${nandrootfstype} ${mtdparts} ${optargs}\0" \ + "nandloadfit=ubi part rootfs;ubi readvol ${loadaddr} fit\0" \ + "nandboot=run nandloadfit;run nandargs;bootm ${loadaddr}\0" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootm_size=0x30000000\0" \ + "optargs=rw rootwait\0" \ + ENV_MMC \ + ENV_NAND + +#define CONFIG_BOOTCOMMAND "run mmcboot;run nandboot" #endif diff --git a/include/dt-bindings/regulator/dlg,da9063-regulator.h b/include/dt-bindings/regulator/dlg,da9063-regulator.h new file mode 100644 index 00000000000..1de710dd089 --- /dev/null +++ b/include/dt-bindings/regulator/dlg,da9063-regulator.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _DT_BINDINGS_REGULATOR_DLG_DA9063_H +#define _DT_BINDINGS_REGULATOR_DLG_DA9063_H + +/* + * These buck mode constants may be used to specify values in device tree + * properties (e.g. regulator-initial-mode). + * A description of the following modes is in the manufacturers datasheet. + */ + +#define DA9063_BUCK_MODE_SLEEP 1 +#define DA9063_BUCK_MODE_SYNC 2 +#define DA9063_BUCK_MODE_AUTO 3 + +#endif diff --git a/include/power/pca9450.h b/include/power/pca9450.h index 5d4f58ca44e..5a9a697d626 100644 --- a/include/power/pca9450.h +++ b/include/power/pca9450.h @@ -54,7 +54,6 @@ enum { PCA9450_REG_NUM, }; -int power_pca9450a_init(unsigned char bus); -int power_pca9450b_init(unsigned char bus); +int power_pca9450_init(unsigned char bus); #endif |