diff options
author | Tom Rini <trini@konsulko.com> | 2023-03-31 12:50:34 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-03-31 12:50:34 -0400 |
commit | 942ac73afc37fb98695af4489ea1549c21615a5e (patch) | |
tree | be4a122569d256f3c82392ca4a9c5f15fcc3636b /arch | |
parent | b8deed53fe6a55ef76b4f9038bb419a9c853a9fa (diff) | |
parent | f216580b642c7244aeb3619aeceecb331e025ad3 (diff) |
Merge tag 'u-boot-imx-next-20230331' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx into next
u-boot-imx-next-20230331 for next
---------------------------------
CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/15819
i.MX patches queued for next:
- Conversions to DM_SERIAL
- Fixes for Toradex boards
- Gateworks Boards
- i.MX8ULP
- EQoS support / fixes, changes in boards
Diffstat (limited to 'arch')
36 files changed, 1597 insertions, 996 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b25570d1d7..97a48327c4 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -996,6 +996,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ imx8mq-mnt-reform2.dtb \ imx8mq-phanbell.dtb \ imx8mp-dhcom-pdk2.dtb \ + imx8mp-dhcom-pdk3.dtb \ imx8mp-evk.dtb \ imx8mp-icore-mx8mp-edimm2.2.dtb \ imx8mp-msc-sm2s.dtb \ diff --git a/arch/arm/dts/fsl-imx8qxp-colibri-u-boot.dtsi b/arch/arm/dts/fsl-imx8qxp-colibri-u-boot.dtsi index de014c8651..a6af4e5e2b 100644 --- a/arch/arm/dts/fsl-imx8qxp-colibri-u-boot.dtsi +++ b/arch/arm/dts/fsl-imx8qxp-colibri-u-boot.dtsi @@ -3,8 +3,6 @@ * Copyright 2019 Toradex AG */ -#include "imx8qxp-u-boot.dtsi" - &{/imx8qx-pm} { bootph-some-ram; diff --git a/arch/arm/dts/imx6dl-pico-u-boot.dtsi b/arch/arm/dts/imx6dl-pico-u-boot.dtsi new file mode 100644 index 0000000000..e2ef9bcc14 --- /dev/null +++ b/arch/arm/dts/imx6dl-pico-u-boot.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +/ { + aliases { + mmc0 = &usdhc3; + }; +}; diff --git a/arch/arm/dts/imx8mp-dhcom-pdk2.dts b/arch/arm/dts/imx8mp-dhcom-pdk2.dts index 382fbedaf6..8f4eff37c4 100644 --- a/arch/arm/dts/imx8mp-dhcom-pdk2.dts +++ b/arch/arm/dts/imx8mp-dhcom-pdk2.dts @@ -104,20 +104,10 @@ }; }; -/* - * PDK2 carrier board uses SoM with KSZ9131 populated and connected to - * SoM EQoS ethernet RGMII interface. Remove the other SoM PHY DT node. - */ -/delete-node/ ðphy0f; - -/* - * PDK2 carrier board has KSZ9021 PHY populated and connected to SoM FEC - * ethernet RGMII interface. The SoM is not populated with second FEC PHY. - */ -/delete-node/ ðphy1f; - &fec { /* Second ethernet */ + pinctrl-0 = <&pinctrl_fec_rgmii>; phy-handle = <ðphypdk>; + phy-mode = "rgmii"; mdio { ethphypdk: ethernet-phy@7 { /* KSZ 9021 */ diff --git a/arch/arm/dts/imx8mp-dhcom-pdk3-u-boot.dtsi b/arch/arm/dts/imx8mp-dhcom-pdk3-u-boot.dtsi new file mode 100644 index 0000000000..040f333c52 --- /dev/null +++ b/arch/arm/dts/imx8mp-dhcom-pdk3-u-boot.dtsi @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023 Marek Vasut <marex@denx.de> + */ + +#include "imx8mp-dhcom-u-boot.dtsi" diff --git a/arch/arm/dts/imx8mp-dhcom-pdk3.dts b/arch/arm/dts/imx8mp-dhcom-pdk3.dts new file mode 100644 index 0000000000..c5f0607f43 --- /dev/null +++ b/arch/arm/dts/imx8mp-dhcom-pdk3.dts @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023 Marek Vasut <marex@denx.de> + * + * DHCOM iMX8MP variant: + * DHCM-iMX8ML8-C160-R409-F1638-SPI16-GE-CAN2-SD-RTC-WBTA-ADC-T-RGB-CSI2-HS-I-01D2 + * DHCOM PCB number: 660-100 or newer + * PDK3 PCB number: 669-100 or newer + */ + +/dts-v1/; + +#include <dt-bindings/leds/common.h> +#include <dt-bindings/phy/phy-imx8-pcie.h> +#include "imx8mp-dhcom-som.dtsi" + +/ { + model = "DH electronics i.MX8M Plus DHCOM Premium Developer Kit (3)"; + compatible = "dh,imx8mp-dhcom-pdk3", "dh,imx8mp-dhcom-som", + "fsl,imx8mp"; + + chosen { + stdout-path = &uart1; + }; + + clk_ext_audio_codec: clock-codec { + #clock-cells = <0>; + clock-frequency = <24000000>; + compatible = "fixed-clock"; + }; + + clk_xtal25: clk-xtal25 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_c_0_hs_ep: endpoint { + remote-endpoint = <&dwc3_0_hs_ep>; + }; + }; + + port@1 { + reg = <1>; + + usb_c_0_ss_ep: endpoint { + remote-endpoint = <&ptn5150_in_ep>; + }; + }; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + button-0 { + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; /* GPIO A */ + label = "TA1-GPIO-A"; + linux,code = <KEY_A>; + pinctrl-0 = <&pinctrl_dhcom_a>; + pinctrl-names = "default"; + wakeup-source; + }; + + button-1 { + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; /* GPIO B */ + label = "TA2-GPIO-B"; + linux,code = <KEY_B>; + pinctrl-0 = <&pinctrl_dhcom_b>; + pinctrl-names = "default"; + wakeup-source; + }; + + button-2 { + gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; /* GPIO C */ + label = "TA3-GPIO-C"; + linux,code = <KEY_C>; + pinctrl-0 = <&pinctrl_dhcom_c>; + pinctrl-names = "default"; + wakeup-source; + }; + + button-3 { + gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; /* GPIO E */ + label = "TA4-GPIO-E"; + linux,code = <KEY_E>; + pinctrl-0 = <&pinctrl_dhcom_e>; + pinctrl-names = "default"; + wakeup-source; + }; + }; + + led { + compatible = "gpio-leds"; + + led-0 { + color = <LED_COLOR_ID_GREEN>; + default-state = "off"; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <0>; + gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>; /* GPIO D */ + pinctrl-0 = <&pinctrl_dhcom_d>; + pinctrl-names = "default"; + }; + + led-1 { + color = <LED_COLOR_ID_GREEN>; + default-state = "off"; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <1>; + gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; /* GPIO F */ + pinctrl-0 = <&pinctrl_dhcom_f>; + pinctrl-names = "default"; + }; + + led-2 { + color = <LED_COLOR_ID_GREEN>; + default-state = "off"; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <2>; + gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>; /* GPIO G */ + pinctrl-0 = <&pinctrl_dhcom_g>; + pinctrl-names = "default"; + }; + + led-3 { + color = <LED_COLOR_ID_GREEN>; + default-state = "off"; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <3>; + gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; /* GPIO I */ + pinctrl-0 = <&pinctrl_dhcom_i>; + pinctrl-names = "default"; + }; + }; + + reg_avdd: regulator-avdd { /* AUDIO_VDD */ + compatible = "regulator-fixed"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "AUDIO_VDD"; + }; +}; + +&i2c5 { + i2cmux@70 { + compatible = "nxp,pca9540"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2cmuxed0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + typec@3d { + compatible = "nxp,ptn5150"; + reg = <0x3d>; + interrupt-parent = <&gpio4>; + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ptn5150>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + ptn5150_in_ep: endpoint { + remote-endpoint = <&usb_c_0_ss_ep>; + }; + }; + + port@1 { + reg = <1>; + + ptn5150_out_ep: endpoint { + remote-endpoint = <&dwc3_0_ss_ep>; + }; + }; + }; + }; + + power-sensor@40 { + compatible = "ti,ina238"; + reg = <0x40>; + shunt-resistor = <20000>; /* 0.02 R */ + ti,shunt-gain = <1>; /* Drop cca. 40mV */ + }; + + eeprom_board: eeprom@54 { + compatible = "atmel,24c04"; + pagesize = <16>; + reg = <0x54>; + }; + + pcieclk: clk@6b { + compatible = "skyworks,si52144"; + reg = <0x6b>; + clocks = <&clk_xtal25>; + #clock-cells = <1>; + }; + }; + + i2cmuxed1: i2c@1 { /* HDMI DDC I2C */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; +}; + +ðphy0g { + reg = <7>; +}; + +&fec { /* Second ethernet */ + pinctrl-0 = <&pinctrl_fec_rgmii>; + phy-handle = <ðphypdk>; + phy-mode = "rgmii-id"; + + mdio { + ethphypdk: ethernet-phy@7 { /* Micrel KSZ9131RNXI */ + compatible = "ethernet-phy-id0022.1642", + "ethernet-phy-ieee802.3-c22"; + interrupt-parent = <&gpio4>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&pinctrl_ethphy1>; + pinctrl-names = "default"; + reg = <7>; + reset-assert-us = <1000>; + /* RESET_N signal rise time ~100ms */ + reset-deassert-us = <120000>; + reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + }; +}; + +&flexcan1 { + status = "okay"; +}; + +&pcie_phy { + clocks = <&pcieclk 1>; + clock-names = "ref"; + fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>; + status = "okay"; +}; + +&pcie { + fsl,max-link-speed = <3>; + reset-gpio = <&gpio1 6 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usb_dwc3_0 { + usb-role-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + + dwc3_0_hs_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&usb_c_0_hs_ep>; + }; + + dwc3_0_ss_ep: endpoint@1 { + reg = <1>; + remote-endpoint = <&ptn5150_out_ep>; + }; + }; +}; + +&usb3_1 { + fsl,disable-port-power-control; + fsl,permanently-attached; +}; + +&usb_dwc3_1 { + /* This port has USB5734 Hub connected to it, PWR/OC pins are unused */ + /delete-property/ pinctrl-names; + /delete-property/ pinctrl-0; +}; + +&iomuxc { + /* + * GPIO_A,B,C,E are connected to buttons. + * GPIO_D,F,G,I are connected to LEDs. + * GPIO_H is connected to USB Hub RESET_N. + * GPIO_M is connected to CLKOUT2. + */ + pinctrl-0 = <&pinctrl_hog_base + &pinctrl_dhcom_h &pinctrl_dhcom_j &pinctrl_dhcom_k + &pinctrl_dhcom_l + &pinctrl_dhcom_int>; + + pinctrl_ptn5150: ptn5150grp { + fsl,pins = < + MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x40000000 + >; + }; +}; diff --git a/arch/arm/dts/imx8mp-dhcom-som.dtsi b/arch/arm/dts/imx8mp-dhcom-som.dtsi index 0f13ee3627..9fd8bce806 100644 --- a/arch/arm/dts/imx8mp-dhcom-som.dtsi +++ b/arch/arm/dts/imx8mp-dhcom-som.dtsi @@ -83,7 +83,7 @@ &eqos { /* First ethernet */ pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_eqos>; + pinctrl-0 = <&pinctrl_eqos_rgmii>; phy-handle = <ðphy0g>; phy-mode = "rgmii-id"; status = "okay"; @@ -94,14 +94,14 @@ #size-cells = <0>; /* Up to one of these two PHYs may be populated. */ - ethphy0f: ethernet-phy@1 { /* SMSC LAN8740Ai */ + ethphy0f: ethernet-phy@0 { /* SMSC LAN8740Ai */ compatible = "ethernet-phy-id0007.c110", "ethernet-phy-ieee802.3-c22"; interrupt-parent = <&gpio3>; interrupts = <19 IRQ_TYPE_LEVEL_LOW>; pinctrl-0 = <&pinctrl_ethphy0>; pinctrl-names = "default"; - reg = <1>; + reg = <0>; reset-assert-us = <1000>; reset-deassert-us = <1000>; reset-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>; @@ -129,9 +129,9 @@ &fec { /* Second ethernet */ pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_fec>; + pinctrl-0 = <&pinctrl_fec_rmii>; phy-handle = <ðphy1f>; - phy-mode = "rgmii"; + phy-mode = "rmii"; fsl,magic-packet; status = "okay"; @@ -664,7 +664,7 @@ >; }; - pinctrl_eqos: dhcom-eqos-grp { /* RGMII */ + pinctrl_eqos_rgmii: dhcom-eqos-rgmii-grp { /* RGMII */ fsl,pins = < MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 @@ -683,6 +683,22 @@ >; }; + pinctrl_eqos_rmii: dhcom-eqos-rmii-grp { /* RMII */ + fsl,pins = < + MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 + MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 + MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f + MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f + MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f + MX8MP_IOMUXC_ENET_RXC__ENET_QOS_RX_ER 0x1f + MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 + MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 + MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 + /* Clock */ + MX8MP_IOMUXC_ENET_TD2__CCM_ENET_QOS_CLOCK_GENERATE_REF_CLK 0x4000001f + >; + }; + pinctrl_enet_vio: dhcom-enet-vio-grp { fsl,pins = < MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x22 @@ -707,7 +723,7 @@ >; }; - pinctrl_fec: dhcom-fec-grp { + pinctrl_fec_rgmii: dhcom-fec-rgmii-grp { /* RGMII */ fsl,pins = < MX8MP_IOMUXC_SAI1_MCLK__ENET1_TX_CLK 0x1f MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 @@ -728,6 +744,22 @@ >; }; + pinctrl_fec_rmii: dhcom-fec-rmii-grp { /* RMII */ + fsl,pins = < + MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 + MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 + MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 + MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 + MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 + MX8MP_IOMUXC_SAI1_TXD6__ENET1_RX_ER 0x91 + MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f + MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f + MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f + /* Clock */ + MX8MP_IOMUXC_SAI1_MCLK__ENET1_TX_CLK 0x4000001f + >; + }; + pinctrl_flexcan1: dhcom-flexcan1-grp { fsl,pins = < MX8MP_IOMUXC_SPDIF_RX__CAN1_RX 0x154 diff --git a/arch/arm/dts/imx8mp-dhcom-u-boot.dtsi b/arch/arm/dts/imx8mp-dhcom-u-boot.dtsi index b69e714794..59d31eebc3 100644 --- a/arch/arm/dts/imx8mp-dhcom-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-dhcom-u-boot.dtsi @@ -33,12 +33,6 @@ bootph-pre-ram; }; -&eqos { - /delete-property/ assigned-clocks; - /delete-property/ assigned-clock-parents; - /delete-property/ assigned-clock-rates; -}; - &gpio1 { bootph-pre-ram; }; diff --git a/arch/arm/dts/imx8mp-evk-u-boot.dtsi b/arch/arm/dts/imx8mp-evk-u-boot.dtsi index 0d489a781d..6784ed2e7c 100644 --- a/arch/arm/dts/imx8mp-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-evk-u-boot.dtsi @@ -131,12 +131,6 @@ bootph-pre-ram; }; -&eqos { - /delete-property/ assigned-clocks; - /delete-property/ assigned-clock-parents; - /delete-property/ assigned-clock-rates; -}; - ðphy0 { reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; reset-delay-us = <15000>; diff --git a/arch/arm/dts/imx8mp-icore-mx8mp-edimm2.2-u-boot.dtsi b/arch/arm/dts/imx8mp-icore-mx8mp-edimm2.2-u-boot.dtsi index 9918f81534..d411cf79e8 100644 --- a/arch/arm/dts/imx8mp-icore-mx8mp-edimm2.2-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-icore-mx8mp-edimm2.2-u-boot.dtsi @@ -130,12 +130,6 @@ bootph-pre-ram; }; -&eqos { - /delete-property/ assigned-clocks; - /delete-property/ assigned-clock-parents; - /delete-property/ assigned-clock-rates; -}; - ðphy0 { reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; reset-delay-us = <15000>; diff --git a/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi b/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi index 3e1d36a4b0..c3fb040080 100644 --- a/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-venice-gw74xx-u-boot.dtsi @@ -20,12 +20,6 @@ }; }; -&eqos { - /delete-property/ assigned-clocks; - /delete-property/ assigned-clock-parents; - /delete-property/ assigned-clock-rates; -}; - ðphy0 { reset-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>; reset-delay-us = <1000>; diff --git a/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi b/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi index 271d511518..9c6c417f7e 100644 --- a/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi @@ -39,12 +39,6 @@ bootph-pre-ram; }; -&eqos { - /delete-property/ assigned-clocks; - /delete-property/ assigned-clock-parents; - /delete-property/ assigned-clock-rates; -}; - &gpio1 { bootph-pre-ram; }; diff --git a/arch/arm/include/asm/arch-imx8m/clock.h b/arch/arm/include/asm/arch-imx8m/clock.h index e4433763bc..a861cd6db3 100644 --- a/arch/arm/include/asm/arch-imx8m/clock.h +++ b/arch/arm/include/asm/arch-imx8m/clock.h @@ -276,5 +276,4 @@ int set_clk_qspi(void); void enable_ocotp_clk(unsigned char enable); int enable_i2c_clk(unsigned char enable, unsigned int i2c_num); int set_clk_enet(enum enet_freq type); -int set_clk_eqos(enum enet_freq type); void hab_caam_clock_enable(unsigned char enable); diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h index 1559bf6d21..6e2fc82a0e 100644 --- a/arch/arm/include/asm/arch-imx8m/imx-regs.h +++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h @@ -89,7 +89,15 @@ #define DDRC_IPS_BASE_ADDR(X) (0x3d400000 + ((X) * 0x2000000)) #define DDR_CSD1_BASE_ADDR 0x40000000 -#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK 0x70000 +#define IOMUXC_GPR_GPR1_GPR_ENET1_RGMII_EN BIT(22) +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_RGMII_EN BIT(21) +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_TX_CLK_SEL BIT(20) +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN BIT(19) +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK GENMASK(18, 16) +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MII (0 << 16) +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_RGMII (1 << 16) +#define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_RMII (4 << 16) +#define IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL BIT(13) #define FEC_QUIRK_ENET_MAC #ifdef CONFIG_ARMV8_PSCI /* Final jump location */ diff --git a/arch/arm/include/asm/arch-imx8ulp/imx-regs.h b/arch/arm/include/asm/arch-imx8ulp/imx-regs.h index 723bab584c..a038cc1df3 100644 --- a/arch/arm/include/asm/arch-imx8ulp/imx-regs.h +++ b/arch/arm/include/asm/arch-imx8ulp/imx-regs.h @@ -10,6 +10,7 @@ #include <linux/bitops.h> #include <linux/sizes.h> +#define SRAM0_BASE 0x22010000 #define PBRIDGE0_BASE 0x28000000 #define CMC0_RBASE 0x28025000 @@ -62,6 +63,8 @@ #define FEC_QUIRK_ENET_MAC +#define IMG_CONTAINER_BASE (0x22010000UL) + #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) #include <asm/types.h> diff --git a/arch/arm/include/asm/arch-imx8ulp/rdc.h b/arch/arm/include/asm/arch-imx8ulp/rdc.h index 97463756b0..5d555c498d 100644 --- a/arch/arm/include/asm/arch-imx8ulp/rdc.h +++ b/arch/arm/include/asm/arch-imx8ulp/rdc.h @@ -23,5 +23,6 @@ int trdc_mrc_region_set_access(u32 mrc_x, u32 dom_x, u32 addr_start, u32 addr_en void xrdc_init_mda(void); void xrdc_init_mrc(void); +void xrdc_init_pdac_msc(void); #endif diff --git a/arch/arm/include/asm/arch-imx8ulp/sys_proto.h b/arch/arm/include/asm/arch-imx8ulp/sys_proto.h index a7869fbb57..5bbae21e37 100644 --- a/arch/arm/include/asm/arch-imx8ulp/sys_proto.h +++ b/arch/arm/include/asm/arch-imx8ulp/sys_proto.h @@ -14,5 +14,7 @@ int xrdc_config_pdac_openacc(u32 bridge, u32 index); void set_lpav_qos(void); void load_lposc_fuse(void); bool m33_image_booted(void); +bool is_m33_handshake_necessary(void); int m33_image_handshake(ulong timeout_ms); +int imx8ulp_dm_post_init(void); #endif diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h index f575805c7d..065fd1f96d 100644 --- a/arch/arm/include/asm/arch-imx9/imx-regs.h +++ b/arch/arm/include/asm/arch-imx9/imx-regs.h @@ -40,6 +40,8 @@ #define SRC_MIX_SLICE_FUNC_STAT_ISO_STAT BIT(4) #define SRC_MIX_SLICE_FUNC_STAT_MEM_STAT BIT(12) +#define IMG_CONTAINER_BASE (0x80000000UL) + #define BCTRL_GPR_ENET_QOS_INTF_MODE_MASK GENMASK(3, 1) #define BCTRL_GPR_ENET_QOS_INTF_SEL_MII (0x0 << 1) #define BCTRL_GPR_ENET_QOS_INTF_SEL_RMII (0x4 << 1) diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 9e746e380a..86987838f4 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -97,6 +97,9 @@ struct arch_global_data { u32 uid[4]; #endif +#ifdef CONFIG_ARCH_IMX8ULP + bool m33_handshake_done; +#endif }; #include <asm-generic/global_data.h> diff --git a/arch/arm/include/asm/mach-imx/s400_api.h b/arch/arm/include/asm/mach-imx/s400_api.h index 89fa373d06..5582ff1a25 100644 --- a/arch/arm/include/asm/mach-imx/s400_api.h +++ b/arch/arm/include/asm/mach-imx/s400_api.h @@ -10,19 +10,104 @@ #define AHAB_CMD_TAG 0x17 #define AHAB_RESP_TAG 0xe1 -#define AHAB_LOG_CID 0x21 -#define AHAB_AUTH_OEM_CTNR_CID 0x87 -#define AHAB_VERIFY_IMG_CID 0x88 -#define AHAB_RELEASE_CTNR_CID 0x89 -#define AHAB_WRITE_SECURE_FUSE_REQ_CID 0x91 -#define AHAB_FWD_LIFECYCLE_UP_REQ_CID 0x95 -#define AHAB_READ_FUSE_REQ_CID 0x97 -#define AHAB_GET_FW_VERSION_CID 0x9D -#define AHAB_RELEASE_RDC_REQ_CID 0xC4 -#define AHAB_GET_FW_STATUS_CID 0xC5 -#define AHAB_WRITE_FUSE_REQ_CID 0xD6 -#define AHAB_CAAM_RELEASE_CID 0xD7 -#define AHAB_GET_INFO_CID 0xDA +/* ELE commands */ +#define ELE_PING_REQ (0x01) +#define ELE_FW_AUTH_REQ (0x02) +#define ELE_RESTART_RST_TIMER_REQ (0x04) +#define ELE_DUMP_DEBUG_BUFFER_REQ (0x21) +#define ELE_OEM_CNTN_AUTH_REQ (0x87) +#define ELE_VERIFY_IMAGE_REQ (0x88) +#define ELE_RELEASE_CONTAINER_REQ (0x89) +#define ELE_WRITE_SECURE_FUSE_REQ (0x91) +#define ELE_FWD_LIFECYCLE_UP_REQ (0x95) +#define ELE_READ_FUSE_REQ (0x97) +#define ELE_GET_FW_VERSION_REQ (0x9D) +#define ELE_RET_LIFECYCLE_UP_REQ (0xA0) +#define ELE_GET_EVENTS_REQ (0xA2) +#define ELE_ENABLE_PATCH_REQ (0xC3) +#define ELE_RELEASE_RDC_REQ (0xC4) +#define ELE_GET_FW_STATUS_REQ (0xC5) +#define ELE_ENABLE_OTFAD_REQ (0xC6) +#define ELE_RESET_REQ (0xC7) +#define ELE_UPDATE_OTP_CLKDIV_REQ (0xD0) +#define ELE_POWER_DOWN_REQ (0xD1) +#define ELE_ENABLE_APC_REQ (0xD2) +#define ELE_ENABLE_RTC_REQ (0xD3) +#define ELE_DEEP_POWER_DOWN_REQ (0xD4) +#define ELE_STOP_RST_TIMER_REQ (0xD5) +#define ELE_WRITE_FUSE_REQ (0xD6) +#define ELE_RELEASE_CAAM_REQ (0xD7) +#define ELE_RESET_A35_CTX_REQ (0xD8) +#define ELE_MOVE_TO_UNSECURED_REQ (0xD9) +#define ELE_GET_INFO_REQ (0xDA) +#define ELE_ATTEST_REQ (0xDB) +#define ELE_RELEASE_PATCH_REQ (0xDC) +#define ELE_OTP_SEQ_SWITH_REQ (0xDD) + +/* ELE failure indications */ +#define ELE_ROM_PING_FAILURE_IND (0x0A) +#define ELE_FW_PING_FAILURE_IND (0x1A) +#define ELE_BAD_SIGNATURE_FAILURE_IND (0xF0) +#define ELE_BAD_HASH_FAILURE_IND (0xF1) +#define ELE_INVALID_LIFECYCLE_IND (0xF2) +#define ELE_PERMISSION_DENIED_FAILURE_IND (0xF3) +#define ELE_INVALID_MESSAGE_FAILURE_IND (0xF4) +#define ELE_BAD_VALUE_FAILURE_IND (0xF5) +#define ELE_BAD_FUSE_ID_FAILURE_IND (0xF6) +#define ELE_BAD_CONTAINER_FAILURE_IND (0xF7) +#define ELE_BAD_VERSION_FAILURE_IND (0xF8) +#define ELE_INVALID_KEY_FAILURE_IND (0xF9) +#define ELE_BAD_KEY_HASH_FAILURE_IND (0xFA) +#define ELE_NO_VALID_CONTAINER_FAILURE_IND (0xFB) +#define ELE_BAD_CERTIFICATE_FAILURE_IND (0xFC) +#define ELE_BAD_UID_FAILURE_IND (0xFD) +#define ELE_BAD_MONOTONIC_COUNTER_FAILURE_IND (0xFE) +#define ELE_MUST_SIGNED_FAILURE_IND (0xE0) +#define ELE_NO_AUTHENTICATION_FAILURE_IND (0xEE) +#define ELE_BAD_SRK_SET_FAILURE_IND (0xEF) +#define ELE_UNALIGNED_PAYLOAD_FAILURE_IND (0xA6) +#define ELE_WRONG_SIZE_FAILURE_IND (0xA7) +#define ELE_ENCRYPTION_FAILURE_IND (0xA8) +#define ELE_DECRYPTION_FAILURE_IND (0xA9) +#define ELE_OTP_PROGFAIL_FAILURE_IND (0xAA) +#define ELE_OTP_LOCKED_FAILURE_IND (0xAB) +#define ELE_OTP_INVALID_IDX_FAILURE_IND (0xAD) +#define ELE_TIME_OUT_FAILURE_IND (0xB0) +#define ELE_BAD_PAYLOAD_FAILURE_IND (0xB1) +#define ELE_WRONG_ADDRESS_FAILURE_IND (0xB4) +#define ELE_DMA_FAILURE_IND (0xB5) +#define ELE_DISABLED_FEATURE_FAILURE_IND (0xB6) +#define ELE_MUST_ATTEST_FAILURE_IND (0xB7) +#define ELE_RNG_NOT_STARTED_FAILURE_IND (0xB8) +#define ELE_CRC_ERROR_IND (0xB9) +#define ELE_AUTH_SKIPPED_OR_FAILED_FAILURE_IND (0xBB) +#define ELE_INCONSISTENT_PAR_FAILURE_IND (0xBC) +#define ELE_RNG_INST_FAILURE_FAILURE_IND (0xBD) +#define ELE_LOCKED_REG_FAILURE_IND (0xBE) +#define ELE_BAD_ID_FAILURE_IND (0xBF) +#define ELE_INVALID_OPERATION_FAILURE_IND (0xC0) +#define ELE_NON_SECURE_STATE_FAILURE_IND (0xC1) +#define ELE_MSG_TRUNCATED_IND (0xC2) +#define ELE_BAD_IMAGE_NUM_FAILURE_IND (0xC3) +#define ELE_BAD_IMAGE_ADDR_FAILURE_IND (0xC4) +#define ELE_BAD_IMAGE_PARAM_FAILURE_IND (0xC5) +#define ELE_BAD_IMAGE_TYPE_FAILURE_IND (0xC6) +#define ELE_CORRUPTED_SRK_FAILURE_IND (0xD0) +#define ELE_OUT_OF_MEMORY_IND (0xD1) +#define ELE_CSTM_FAILURE_IND (0xCF) +#define ELE_OLD_VERSION_FAILURE_IND (0xCE) +#define ELE_WRONG_BOOT_MODE_FAILURE_IND (0xCD) +#define ELE_APC_ALREADY_ENABLED_FAILURE_IND (0xCB) +#define ELE_RTC_ALREADY_ENABLED_FAILURE_IND (0xCC) +#define ELE_ABORT_IND (0xFF) + +/* ELE IPC identifier */ +#define ELE_IPC_MU_RTD (0x1) +#define ELE_IPC_MU_APD (0x2) + +/* ELE Status*/ +#define ELE_SUCCESS_IND (0xD6) +#define ELE_FAILURE_IND (0x29) #define S400_MAX_MSG 255U @@ -41,6 +126,8 @@ struct sentinel_get_info_data { u32 uid[4]; u32 sha256_rom_patch[8]; u32 sha_fw[8]; + u32 oem_srkh[16]; + u32 state; }; int ahab_release_rdc(u8 core_id, u8 xrdc, u32 *response); @@ -56,5 +143,6 @@ int ahab_dump_buffer(u32 *buffer, u32 buffer_length); int ahab_get_info(struct sentinel_get_info_data *info, u32 *response); int ahab_get_fw_status(u32 *status, u32 *response); int ahab_release_m33_trout(void); +int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response); #endif diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 27fdc16cd5..2eacddb51f 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -172,6 +172,13 @@ enum boot_dev_type_e { BT_DEV_TYPE_INVALID = 0xFF }; +enum boot_stage_type { + BT_STAGE_PRIMARY = 0x6, + BT_STAGE_SECONDARY = 0x9, + BT_STAGE_RECOVERY = 0xa, + BT_STAGE_USB = 0x5, +}; + #define QUERY_ROM_VER 1 #define QUERY_BT_DEV 2 #define QUERY_PAGE_SZ 3 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 4dfc60eedc..9bcb23c4da 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -77,6 +77,10 @@ ifeq ($(CONFIG_SPL_BUILD),y) obj-$(CONFIG_SPL_LOAD_IMX_CONTAINER) += image-container.o parse-container.o endif +ifeq ($(SOC),$(filter $(SOC),imx8ulp imx9)) +obj-$(CONFIG_AHAB_BOOT) += ele_ahab.o +endif + PLUGIN = board/$(BOARDDIR)/plugin ifeq ($(CONFIG_USE_IMXIMG_PLUGIN),y) diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c new file mode 100644 index 0000000000..99fc540271 --- /dev/null +++ b/arch/arm/mach-imx/ele_ahab.c @@ -0,0 +1,586 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 NXP + */ + +#include <common.h> +#include <command.h> +#include <errno.h> +#include <asm/io.h> +#include <asm/mach-imx/s400_api.h> +#include <asm/mach-imx/sys_proto.h> +#include <asm/arch-imx/cpu.h> +#include <asm/arch/sys_proto.h> +#include <asm/mach-imx/image.h> +#include <console.h> +#include <cpu_func.h> +#include <asm/mach-imx/ahab.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define IMG_CONTAINER_END_BASE (IMG_CONTAINER_BASE + 0xFFFFUL) + +#define AHAB_MAX_EVENTS 8 + +static char *ele_ipc_str[] = { + "IPC = MU RTD (0x1)\n", + "IPC = MU APD (0x2)\n", + "IPC = INVALID\n", + NULL +}; + +static char *ele_status_str[] = { + "STA = ELE_SUCCESS_IND (0xD6)\n", + "STA = ELE_FAILURE_IND (0x29)\n", + "STA = INVALID\n", + NULL +}; + +static char *ele_cmd_str[] = { + "CMD = ELE_PING_REQ (0x01)\n", + "CMD = ELE_FW_AUTH_REQ (0x02)\n", + "CMD = ELE_RESTART_RST_TIMER_REQ (0x04)\n", + "CMD = ELE_DUMP_DEBUG_BUFFER_REQ (0x21)\n", + "CMD = ELE_OEM_CNTN_AUTH_REQ (0x87)\n", + "CMD = ELE_VERIFY_IMAGE_REQ (0x88)\n", + "CMD = ELE_RELEASE_CONTAINER_REQ (0x89)\n", + "CMD = ELE_WRITE_SECURE_FUSE_REQ (0x91)\n", + "CMD = ELE_FWD_LIFECYCLE_UP_REQ (0x95)\n", + "CMD = ELE_READ_FUSE_REQ (0x97)\n", + "CMD = ELE_GET_FW_VERSION_REQ (0x9D)\n", + "CMD = ELE_RET_LIFECYCLE_UP_REQ (0xA0)\n", + "CMD = ELE_GET_EVENTS_REQ (0xA2)\n", + "CMD = ELE_ENABLE_PATCH_REQ (0xC3)\n", + "CMD = ELE_RELEASE_RDC_REQ (0xC4)\n", + "CMD = ELE_GET_FW_STATUS_REQ (0xC5)\n", + "CMD = ELE_ENABLE_OTFAD_REQ (0xC6)\n", + "CMD = ELE_RESET_REQ (0xC7)\n", + "CMD = ELE_UPDATE_OTP_CLKDIV_REQ (0xD0)\n", + "CMD = ELE_POWER_DOWN_REQ (0xD1)\n", + "CMD = ELE_ENABLE_APC_REQ (0xD2)\n", + "CMD = ELE_ENABLE_RTC_REQ (0xD3)\n", + "CMD = ELE_DEEP_POWER_DOWN_REQ (0xD4)\n", + "CMD = ELE_STOP_RST_TIMER_REQ (0xD5)\n", + "CMD = ELE_WRITE_FUSE_REQ (0xD6)\n", + "CMD = ELE_RELEASE_CAAM_REQ (0xD7)\n", + "CMD = ELE_RESET_A35_CTX_REQ (0xD8)\n", + "CMD = ELE_MOVE_TO_UNSECURED_REQ (0xD9)\n", + "CMD = ELE_GET_INFO_REQ (0xDA)\n", + "CMD = ELE_ATTEST_REQ (0xDB)\n", + "CMD = ELE_RELEASE_PATCH_REQ (0xDC)\n", + "CMD = ELE_OTP_SEQ_SWITH_REQ (0xDD)\n", + "CMD = INVALID\n", + NULL +}; + +static char *ele_ind_str[] = { + "IND = ELE_ROM_PING_FAILURE_IND (0x0A)\n", + "IND = ELE_FW_PING_FAILURE_IND (0x1A)\n", + "IND = ELE_BAD_SIGNATURE_FAILURE_IND (0xF0)\n", + "IND = ELE_BAD_HASH_FAILURE_IND (0xF1)\n", + "IND = ELE_INVALID_LIFECYCLE_IND (0xF2)\n", + "IND = ELE_PERMISSION_DENIED_FAILURE_IND (0xF3)\n", + "IND = ELE_INVALID_MESSAGE_FAILURE_IND (0xF4)\n", + "IND = ELE_BAD_VALUE_FAILURE_IND (0xF5)\n", + "IND = ELE_BAD_FUSE_ID_FAILURE_IND (0xF6)\n", + "IND = ELE_BAD_CONTAINER_FAILURE_IND (0xF7)\n", + "IND = ELE_BAD_VERSION_FAILURE_IND (0xF8)\n", + "IND = ELE_INVALID_KEY_FAILURE_IND (0xF9)\n", + "IND = ELE_BAD_KEY_HASH_FAILURE_IND (0xFA)\n", + "IND = ELE_NO_VALID_CONTAINER_FAILURE_IND (0xFB)\n", + "IND = ELE_BAD_CERTIFICATE_FAILURE_IND (0xFC)\n", + "IND = ELE_BAD_UID_FAILURE_IND (0xFD)\n", + "IND = ELE_BAD_MONOTONIC_COUNTER_FAILURE_IND (0xFE)\n", + "IND = ELE_MUST_SIGNED_FAILURE_IND (0xE0)\n", + "IND = ELE_NO_AUTHENTICATION_FAILURE_IND (0xEE)\n", + "IND = ELE_BAD_SRK_SET_FAILURE_IND (0xEF)\n", + "IND = ELE_UNALIGNED_PAYLOAD_FAILURE_IND (0xA6)\n", + "IND = ELE_WRONG_SIZE_FAILURE_IND (0xA7)\n", + "IND = ELE_ENCRYPTION_FAILURE_IND (0xA8)\n", + "IND = ELE_DECRYPTION_FAILURE_IND (0xA9)\n", + "IND = ELE_OTP_PROGFAIL_FAILURE_IND (0xAA)\n", + "IND = ELE_OTP_LOCKED_FAILURE_IND (0xAB)\n", + "IND = ELE_OTP_INVALID_IDX_FAILURE_IND (0xAD)\n", + "IND = ELE_TIME_OUT_FAILURE_IND (0xB0)\n", + "IND = ELE_BAD_PAYLOAD_FAILURE_IND (0xB1)\n", + "IND = ELE_WRONG_ADDRESS_FAILURE_IND (0xB4)\n", + "IND = ELE_DMA_FAILURE_IND (0xB5)\n", + "IND = ELE_DISABLED_FEATURE_FAILURE_IND (0xB6)\n", + "IND = ELE_MUST_ATTEST_FAILURE_IND (0xB7)\n", + "IND = ELE_RNG_NOT_STARTED_FAILURE_IND (0xB8)\n", + "IND = ELE_CRC_ERROR_IND (0xB9)\n", + "IND = ELE_AUTH_SKIPPED_OR_FAILED_FAILURE_IND (0xBB)\n", + "IND = ELE_INCONSISTENT_PAR_FAILURE_IND (0xBC)\n", + "IND = ELE_RNG_INST_FAILURE_FAILURE_IND (0xBD)\n", + "IND = ELE_LOCKED_REG_FAILURE_IND (0xBE)\n", + "IND = ELE_BAD_ID_FAILURE_IND (0xBF)\n", + "IND = ELE_INVALID_OPERATION_FAILURE_IND (0xC0)\n", + "IND = ELE_NON_SECURE_STATE_FAILURE_IND (0xC1)\n", + "IND = ELE_MSG_TRUNCATED_IND (0xC2)\n", + "IND = ELE_BAD_IMAGE_NUM_FAILURE_IND (0xC3)\n", + "IND = ELE_BAD_IMAGE_ADDR_FAILURE_IND (0xC4)\n", + "IND = ELE_BAD_IMAGE_PARAM_FAILURE_IND (0xC5)\n", + "IND = ELE_BAD_IMAGE_TYPE_FAILURE_IND (0xC6)\n", + "IND = ELE_CORRUPTED_SRK_FAILURE_IND (0xD0)\n", + "IND = ELE_OUT_OF_MEMORY_IND (0xD1)\n", + "IND = ELE_CSTM_FAILURE_IND (0xCF)\n", + "IND = ELE_OLD_VERSION_FAILURE_IND (0xCE)\n", + "IND = ELE_WRONG_BOOT_MODE_FAILURE_IND (0xCD)\n", + "IND = ELE_APC_ALREADY_ENABLED_FAILURE_IND (0xCB)\n", + "IND = ELE_RTC_ALREADY_ENABLED_FAILURE_IND (0xCC)\n", + "IND = ELE_ABORT_IND (0xFF)\n", + "IND = INVALID\n", + NULL +}; + +static u8 ele_cmd[] = { + ELE_PING_REQ, + ELE_FW_AUTH_REQ, + ELE_RESTART_RST_TIMER_REQ, + ELE_DUMP_DEBUG_BUFFER_REQ, + ELE_OEM_CNTN_AUTH_REQ, + ELE_VERIFY_IMAGE_REQ, + ELE_RELEASE_CONTAINER_REQ, + ELE_WRITE_SECURE_FUSE_REQ, + ELE_FWD_LIFECYCLE_UP_REQ, + ELE_READ_FUSE_REQ, + ELE_GET_FW_VERSION_REQ, + ELE_RET_LIFECYCLE_UP_REQ, + ELE_GET_EVENTS_REQ, + ELE_ENABLE_PATCH_REQ, + ELE_RELEASE_RDC_REQ, + ELE_GET_FW_STATUS_REQ, + ELE_ENABLE_OTFAD_REQ, + ELE_RESET_REQ, + ELE_UPDATE_OTP_CLKDIV_REQ, + ELE_POWER_DOWN_REQ, + ELE_ENABLE_APC_REQ, + ELE_ENABLE_RTC_REQ, + ELE_DEEP_POWER_DOWN_REQ, + ELE_STOP_RST_TIMER_REQ, + ELE_WRITE_FUSE_REQ, + ELE_RELEASE_CAAM_REQ, + ELE_RESET_A35_CTX_REQ, + ELE_MOVE_TO_UNSECURED_REQ, + ELE_GET_INFO_REQ, + ELE_ATTEST_REQ, + ELE_RELEASE_PATCH_REQ, + ELE_OTP_SEQ_SWITH_REQ +}; + +static u8 ele_ind[] = { + ELE_ROM_PING_FAILURE_IND, + ELE_FW_PING_FAILURE_IND, + ELE_BAD_SIGNATURE_FAILURE_IND, + ELE_BAD_HASH_FAILURE_IND, + ELE_INVALID_LIFECYCLE_IND, + ELE_PERMISSION_DENIED_FAILURE_IND, + ELE_INVALID_MESSAGE_FAILURE_IND, + ELE_BAD_VALUE_FAILURE_IND, + ELE_BAD_FUSE_ID_FAILURE_IND, + ELE_BAD_CONTAINER_FAILURE_IND, + ELE_BAD_VERSION_FAILURE_IND, + ELE_INVALID_KEY_FAILURE_IND, + ELE_BAD_KEY_HASH_FAILURE_IND, + ELE_NO_VALID_CONTAINER_FAILURE_IND, + ELE_BAD_CERTIFICATE_FAILURE_IND, + ELE_BAD_UID_FAILURE_IND, + ELE_BAD_MONOTONIC_COUNTER_FAILURE_IND, + ELE_MUST_SIGNED_FAILURE_IND, + ELE_NO_AUTHENTICATION_FAILURE_IND, + ELE_BAD_SRK_SET_FAILURE_IND, + ELE_UNALIGNED_PAYLOAD_FAILURE_IND, + ELE_WRONG_SIZE_FAILURE_IND, + ELE_ENCRYPTION_FAILURE_IND, + ELE_DECRYPTION_FAILURE_IND, + ELE_OTP_PROGFAIL_FAILURE_IND, + ELE_OTP_LOCKED_FAILURE_IND, + ELE_OTP_INVALID_IDX_FAILURE_IND, + ELE_TIME_OUT_FAILURE_IND, + ELE_BAD_PAYLOAD_FAILURE_IND, + ELE_WRONG_ADDRESS_FAILURE_IND, + ELE_DMA_FAILURE_IND, + ELE_DISABLED_FEATURE_FAILURE_IND, + ELE_MUST_ATTEST_FAILURE_IND, + ELE_RNG_NOT_STARTED_FAILURE_IND, + ELE_CRC_ERROR_IND, + ELE_AUTH_SKIPPED_OR_FAILED_FAILURE_IND, + ELE_INCONSISTENT_PAR_FAILURE_IND, + ELE_RNG_INST_FAILURE_FAILURE_IND, + ELE_LOCKED_REG_FAILURE_IND, + ELE_BAD_ID_FAILURE_IND, + ELE_INVALID_OPERATION_FAILURE_IND, + ELE_NON_SECURE_STATE_FAILURE_IND, + ELE_MSG_TRUNCATED_IND, + ELE_BAD_IMAGE_NUM_FAILURE_IND, + ELE_BAD_IMAGE_ADDR_FAILURE_IND, + ELE_BAD_IMAGE_PARAM_FAILURE_IND, + ELE_BAD_IMAGE_TYPE_FAILURE_IND, + ELE_CORRUPTED_SRK_FAILURE_IND, + ELE_OUT_OF_MEMORY_IND, + ELE_CSTM_FAILURE_IND, + ELE_OLD_VERSION_FAILURE_IND, + ELE_WRONG_BOOT_MODE_FAILURE_IND, + ELE_APC_ALREADY_ENABLED_FAILURE_IND, + ELE_RTC_ALREADY_ENABLED_FAILURE_IND, + ELE_ABORT_IND +}; + +static u8 ele_ipc[] = { + ELE_IPC_MU_RTD, + ELE_IPC_MU_APD +}; + +static u8 ele_status[] = { + ELE_SUCCESS_IND, + ELE_FAILURE_IND +}; + +static inline u32 get_idx(u8 *list, u8 tgt, u32 size) +{ + u32 i; + + for (i = 0; i < size; i++) { + if (list[i] == tgt) + return i; + } + + return i; /* last str is invalid */ +} + +static void display_ahab_auth_ind(u32 event) +{ + u8 resp_ind = (event >> 8) & 0xff; + + printf("%s\n", ele_ind_str[get_idx(ele_ind, resp_ind, ARRAY_SIZE(ele_ind))]); +} + +int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length) +{ + int err; + u32 resp; + + memcpy((void *)IMG_CONTAINER_BASE, (const void *)container, + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); + + flush_dcache_range(IMG_CONTAINER_BASE, + IMG_CONTAINER_BASE + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE) - 1); + + err = ahab_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp); + if (err) { + printf("Authenticate container hdr failed, return %d, resp 0x%x\n", + err, resp); + display_ahab_auth_ind(resp); + } + + return err; +} + +int ahab_auth_release(void) +{ + int err; + u32 resp; + + err = ahab_release_container(&resp); + if (err) { + printf("Error: release container failed, resp 0x%x!\n", resp); + display_ahab_auth_ind(resp); + } + + return err; +} + +int ahab_verify_cntr_image(struct boot_img_t *img, int image_index) +{ + int err; + u32 resp; + + err = ahab_verify_image(image_index, &resp); + if (err) { + printf("Authenticate img %d failed, return %d, resp 0x%x\n", + image_index, err, resp); + display_ahab_auth_ind(resp); + + return -EIO; + } + + return 0; +} + +static inline bool check_in_dram(ulong addr) +{ + int i; + struct bd_info *bd = gd->bd; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { + if (bd->bi_dram[i].size) { + if (addr >= bd->bi_dram[i].start && + addr < (bd->bi_dram[i].start + bd->bi_dram[i].size)) + return true; + } + } + + return false; +} + +int authenticate_os_container(ulong addr) +{ + struct container_hdr *phdr; + int i, ret = 0; + int err; + u16 length; + struct boot_img_t *img; + unsigned long s, e; + + if (addr % 4) { + puts("Error: Image's address is not 4 byte aligned\n"); + return -EINVAL; + } + + if (!check_in_dram(addr)) { + puts("Error: Image's address is invalid\n"); + return -EINVAL; + } + + phdr = (struct container_hdr *)addr; + if (phdr->tag != 0x87 || phdr->version != 0x0) { + printf("Error: Wrong container header\n"); + return -EFAULT; + } + + if (!phdr->num_images) { + printf("Error: Wrong container, no image found\n"); + return -EFAULT; + } + + length = phdr->length_lsb + (phdr->length_msb << 8); + + debug("container length %u\n", length); + + err = ahab_auth_cntr_hdr(phdr, length); + if (err) { + ret = -EIO; + goto exit; + } + + debug("Verify images\n"); + + /* Copy images to dest address */ + for (i = 0; i < phdr->num_images; i++) { + img = (struct boot_img_t *)(addr + + sizeof(struct container_hdr) + + i * sizeof(struct boot_img_t)); + + debug("img %d, dst 0x%x, src 0x%lx, size 0x%x\n", + i, (uint32_t)img->dst, img->offset + addr, img->size); + + memcpy((void *)img->dst, (const void *)(img->offset + addr), + img->size); + + s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); + e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1; + + flush_dcache_range(s, e); + + ret = ahab_verify_cntr_image(img, i); + if (ret) + goto exit; + } + +exit: + debug("ahab_auth_release, 0x%x\n", ret); + ahab_auth_release(); + + return ret; +} + +static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + ulong addr; + + if (argc < 2) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[1], NULL, 16); + + printf("Authenticate OS container at 0x%lx\n", addr); + + if (authenticate_os_container(addr)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static void display_life_cycle(u32 lc) +{ + printf("Lifecycle: 0x%08X, ", lc); + switch (lc) { + case 0x1: + printf("BLANK\n\n"); + break; + case 0x2: + printf("FAB\n\n"); + break; + case 0x4: + printf("NXP Provisioned\n\n"); + break; + case 0x8: + printf("OEM Open\n\n"); + break; + case 0x20: + printf("OEM closed\n\n"); + break; + case 0x40: + printf("Field Return OEM\n\n"); + break; + case 0x80: + printf("Field Return NXP\n\n"); + break; + case 0x100: + printf("OEM Locked\n\n"); + break; + case 0x200: + printf("BRICKED\n\n"); + break; + default: + printf("Unknown\n\n"); + break; + } +} + +static int confirm_close(void) +{ + puts("Warning: Please ensure your sample is in NXP closed state, " + "OEM SRK hash has been fused, \n" + " and you are able to boot a signed image successfully " + "without any SECO events reported.\n" + " If not, your sample will be unrecoverable.\n" + "\nReally perform this operation? <y/N>\n"); + + if (confirm_yesno()) + return 1; + + puts("Ahab close aborted\n"); + return 0; +} + +static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int err; + u32 resp; + u32 lc; + + if (!confirm_close()) + return -EACCES; + + lc = readl(FSB_BASE_ADDR + 0x41c); + lc &= 0x3ff; + + if (lc != 0x8) { + puts("Current lifecycle is NOT OEM open, can't move to OEM closed\n"); + display_life_cycle(lc); + return -EPERM; + } + + err = ahab_forward_lifecycle(8, &resp); + if (err != 0) { + printf("Error in forward lifecycle to OEM closed\n"); + return -EIO; + } + + printf("Change to OEM closed successfully\n"); + + return 0; +} + +int ahab_dump(void) +{ + u32 buffer[32]; + int ret, i = 0; + + do { + ret = ahab_dump_buffer(buffer, 32); + if (ret < 0) { + printf("Error in dump AHAB log\n"); + return -EIO; + } + + if (ret == 1) + break; + for (i = 0; i < ret; i++) + printf("0x%x\n", buffer[i]); + } while (ret >= 21); + + return 0; +} + +static int do_ahab_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + return ahab_dump(); +} + +static void display_event(u32 event) +{ + printf("\n\t0x%08x\n", event); + printf("\t%s", ele_ipc_str[get_idx(ele_ipc, + (event >> 24) & 0xFF, ARRAY_SIZE(ele_ipc))]); + printf("\t%s", ele_cmd_str[get_idx(ele_cmd, + (event >> 16) & 0xFF, ARRAY_SIZE(ele_cmd))]); + printf("\t%s", ele_ind_str[get_idx(ele_ind, + (event >> 8) & 0xFF, ARRAY_SIZE(ele_ind))]); + printf("\t%s", ele_status_str[get_idx(ele_status, + event & 0xFF, ARRAY_SIZE(ele_status))]); +} + +static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + u32 lc, i; + u32 events[AHAB_MAX_EVENTS]; + u32 cnt = AHAB_MAX_EVENTS; + int ret; + + lc = readl(FSB_BASE_ADDR + 0x41c); + lc &= 0x3ff; + + display_life_cycle(lc); + + ret = ahab_get_events(events, &cnt, NULL); + if (ret) { + printf("Get ELE EVENTS error %d\n", ret); + return CMD_RET_FAILURE; + } + + if (!cnt) { + puts("\n\tNo Events Found!\n"); + return 0; + } + + for (i = 0; i < cnt; i++) + display_event(events[i]); + + return 0; +} + +U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, + "autenticate OS container via AHAB", + "addr\n" + "addr - OS container hex address\n" +); + +U_BOOT_CMD(ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close, + "Change AHAB lifecycle to OEM closed", + "" +); + +U_BOOT_CMD(ahab_dump, CONFIG_SYS_MAXARGS, 1, do_ahab_dump, + "Dump AHAB log for debug", + "" +); + +U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, + "display AHAB lifecycle only", + "" +); diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index 37d12d1895..018b87b85b 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -51,7 +51,6 @@ config TARGET_APALIS_IMX8 config TARGET_COLIBRI_IMX8X bool "Support Colibri iMX8X module" - select BINMAN select BOARD_LATE_INIT select IMX8QXP diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index 64ad57e9b3..31c34b6031 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -15,6 +15,7 @@ #include <errno.h> #include <linux/bitops.h> #include <linux/delay.h> +#include <phy.h> DECLARE_GLOBAL_DATA_PTR; @@ -36,14 +37,14 @@ void enable_ocotp_clk(unsigned char enable) int enable_i2c_clk(unsigned char enable, unsigned i2c_num) { - u8 i2c_ccgr[6] = { + u8 i2c_ccgr[] = { CCGR_I2C1, CCGR_I2C2, CCGR_I2C3, CCGR_I2C4, #if (IS_ENABLED(CONFIG_IMX8MP)) CCGR_I2C5_8MP, CCGR_I2C6_8MP #endif }; - if (i2c_num > ARRAY_SIZE(i2c_ccgr)) + if (i2c_num >= ARRAY_SIZE(i2c_ccgr)) return -EINVAL; clock_enable(i2c_ccgr[i2c_num], !!enable); @@ -825,141 +826,108 @@ u32 mxc_get_clock(enum mxc_clock clk) return 0; } -#ifdef CONFIG_DWC_ETH_QOS -int set_clk_eqos(enum enet_freq type) +#if defined(CONFIG_IMX8MP) && defined(CONFIG_DWC_ETH_QOS) +static int imx8mp_eqos_interface_init(struct udevice *dev, + phy_interface_t interface_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; + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + clrbits_le32(&gpr->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_RGMII_EN | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_TX_CLK_SEL | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN); + + switch (interface_type) { + case PHY_INTERFACE_MODE_MII: + setbits_le32(&gpr->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MII); + break; + case PHY_INTERFACE_MODE_RMII: + setbits_le32(&gpr->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_TX_CLK_SEL | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_RMII); + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + setbits_le32(&gpr->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET_QOS_RGMII_EN | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN | + IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_RGMII); 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(ulong rate) +#else +static int imx8mp_eqos_interface_init(struct udevice *dev, + phy_interface_t interface_type) { - 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) +static int imx8mp_fec_interface_init(struct udevice *dev, + phy_interface_t interface_type, + bool mx8mp) { - 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; + /* i.MX8MP has extra RGMII_EN bit in IOMUXC GPR1 register */ + const u32 rgmii_en = mx8mp ? IOMUXC_GPR_GPR1_GPR_ENET1_RGMII_EN : 0; + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + clrbits_le32(&gpr->gpr[1], + rgmii_en | + IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL); + + switch (interface_type) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_RMII: + setbits_le32(&gpr->gpr[1], IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL); + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + setbits_le32(&gpr->gpr[1], rgmii_en); break; default: return -EINVAL; } - /* disable the clock first */ - clock_enable(CCGR_ENET1, 0); - clock_enable(CCGR_SIM_ENET, 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_REF_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_TIMER_CLK_ROOT, target); - - /* enable clock */ - clock_enable(CCGR_SIM_ENET, 1); - clock_enable(CCGR_ENET1, 1); - return 0; } #endif + +int board_interface_eth_init(struct udevice *dev, phy_interface_t interface_type) +{ + if (IS_ENABLED(CONFIG_IMX8MM) && + IS_ENABLED(CONFIG_FEC_MXC) && + device_is_compatible(dev, "fsl,imx8mm-fec")) + return imx8mp_fec_interface_init(dev, interface_type, false); + + if (IS_ENABLED(CONFIG_IMX8MN) && + IS_ENABLED(CONFIG_FEC_MXC) && + device_is_compatible(dev, "fsl,imx8mn-fec")) + return imx8mp_fec_interface_init(dev, interface_type, false); + + if (IS_ENABLED(CONFIG_IMX8MP) && + IS_ENABLED(CONFIG_FEC_MXC) && + device_is_compatible(dev, "fsl,imx8mp-fec")) + return imx8mp_fec_interface_init(dev, interface_type, true); + + if (IS_ENABLED(CONFIG_IMX8MP) && + IS_ENABLED(CONFIG_DWC_ETH_QOS) && + device_is_compatible(dev, "nxp,imx8mp-dwmac-eqos")) + return imx8mp_eqos_interface_init(dev, interface_type); + + return -EINVAL; +} diff --git a/arch/arm/mach-imx/imx8ulp/Kconfig b/arch/arm/mach-imx/imx8ulp/Kconfig index bbdeaac07b..c1c1aa08c5 100644 --- a/arch/arm/mach-imx/imx8ulp/Kconfig +++ b/arch/arm/mach-imx/imx8ulp/Kconfig @@ -20,6 +20,7 @@ config TARGET_IMX8ULP_EVK bool "imx8ulp_evk" select IMX8ULP select SUPPORT_SPL + select IMX8ULP_DRAM endchoice diff --git a/arch/arm/mach-imx/imx8ulp/ahab.c b/arch/arm/mach-imx/imx8ulp/ahab.c deleted file mode 100644 index 87c4c66a08..0000000000 --- a/arch/arm/mach-imx/imx8ulp/ahab.c +++ /dev/null @@ -1,345 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2020 NXP - */ - -#include <common.h> -#include <command.h> -#include <errno.h> -#include <asm/io.h> -#include <asm/mach-imx/s400_api.h> -#include <asm/mach-imx/sys_proto.h> -#include <asm/arch-imx/cpu.h> -#include <asm/arch/sys_proto.h> -#include <asm/mach-imx/image.h> -#include <console.h> -#include <cpu_func.h> -#include <asm/mach-imx/ahab.h> -#include <asm/global_data.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define IMG_CONTAINER_BASE (0x22010000UL) -#define IMG_CONTAINER_END_BASE (IMG_CONTAINER_BASE + 0xFFFFUL) - -#define AHAB_NO_AUTHENTICATION_IND 0xee -#define AHAB_BAD_KEY_HASH_IND 0xfa -#define AHAB_INVALID_KEY_IND 0xf9 -#define AHAB_BAD_SIGNATURE_IND 0xf0 -#define AHAB_BAD_HASH_IND 0xf1 - -static void display_ahab_auth_ind(u32 event) -{ - u8 resp_ind = (event >> 8) & 0xff; - - switch (resp_ind) { - case AHAB_NO_AUTHENTICATION_IND: - printf("AHAB_NO_AUTHENTICATION_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_BAD_KEY_HASH_IND: - printf("AHAB_BAD_KEY_HASH_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_INVALID_KEY_IND: - printf("AHAB_INVALID_KEY_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_BAD_SIGNATURE_IND: - printf("AHAB_BAD_SIGNATURE_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_BAD_HASH_IND: - printf("AHAB_BAD_HASH_IND (0x%02X)\n\n", resp_ind); - break; - default: - printf("Unknown Indicator (0x%02X)\n\n", resp_ind); - break; - } -} - -int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length) -{ - int err; - u32 resp; - - memcpy((void *)IMG_CONTAINER_BASE, (const void *)container, - ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); - - flush_dcache_range(IMG_CONTAINER_BASE, - IMG_CONTAINER_BASE + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE) - 1); - - err = ahab_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp); - if (err) { - printf("Authenticate container hdr failed, return %d, resp 0x%x\n", - err, resp); - display_ahab_auth_ind(resp); - } - - return err; -} - -int ahab_auth_release(void) -{ - int err; - u32 resp; - - err = ahab_release_container(&resp); - if (err) { - printf("Error: release container failed, resp 0x%x!\n", resp); - display_ahab_auth_ind(resp); - } - - return err; -} - -int ahab_verify_cntr_image(struct boot_img_t *img, int image_index) -{ - int err; - u32 resp; - - err = ahab_verify_image(image_index, &resp); - if (err) { - printf("Authenticate img %d failed, return %d, resp 0x%x\n", - image_index, err, resp); - display_ahab_auth_ind(resp); - return -EIO; - } - - return 0; -} - -static inline bool check_in_dram(ulong addr) -{ - int i; - struct bd_info *bd = gd->bd; - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { - if (bd->bi_dram[i].size) { - if (addr >= bd->bi_dram[i].start && - addr < (bd->bi_dram[i].start + bd->bi_dram[i].size)) - return true; - } - } - - return false; -} - -int authenticate_os_container(ulong addr) -{ - struct container_hdr *phdr; - int i, ret = 0; - int err; - u16 length; - struct boot_img_t *img; - unsigned long s, e; - - if (addr % 4) { - puts("Error: Image's address is not 4 byte aligned\n"); - return -EINVAL; - } - - if (!check_in_dram(addr)) { - puts("Error: Image's address is invalid\n"); - return -EINVAL; - } - - phdr = (struct container_hdr *)addr; - if (phdr->tag != 0x87 || phdr->version != 0x0) { - printf("Error: Wrong container header\n"); - return -EFAULT; - } - - if (!phdr->num_images) { - printf("Error: Wrong container, no image found\n"); - return -EFAULT; - } - - length = phdr->length_lsb + (phdr->length_msb << 8); - - debug("container length %u\n", length); - - err = ahab_auth_cntr_hdr(phdr, length); - if (err) { - ret = -EIO; - goto exit; - } - - debug("Verify images\n"); - - /* Copy images to dest address */ - for (i = 0; i < phdr->num_images; i++) { - img = (struct boot_img_t *)(addr + - sizeof(struct container_hdr) + - i * sizeof(struct boot_img_t)); - - debug("img %d, dst 0x%x, src 0x%lx, size 0x%x\n", - i, (uint32_t)img->dst, img->offset + addr, img->size); - - memcpy((void *)img->dst, (const void *)(img->offset + addr), img->size); - - s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); - e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1; - - flush_dcache_range(s, e); - - ret = ahab_verify_cntr_image(img, i); - if (ret) - goto exit; - } - -exit: - debug("ahab_auth_release, 0x%x\n", ret); - ahab_auth_release(); - - return ret; -} - -static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - ulong addr; - - if (argc < 2) - return CMD_RET_USAGE; - - addr = simple_strtoul(argv[1], NULL, 16); - - printf("Authenticate OS container at 0x%lx\n", addr); - - if (authenticate_os_container(addr)) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; -} - -static void display_life_cycle(u32 lc) -{ - printf("Lifecycle: 0x%08X, ", lc); - switch (lc) { - case 0x1: - printf("BLANK\n\n"); - break; - case 0x2: - printf("FAB\n\n"); - break; - case 0x4: - printf("NXP Provisioned\n\n"); - break; - case 0x8: - printf("OEM Open\n\n"); - break; - case 0x10: - printf("OEM Secure World Closed\n\n"); - break; - case 0x20: - printf("OEM closed\n\n"); - break; - case 0x40: - printf("Field Return OEM\n\n"); - break; - case 0x80: - printf("Field Return NXP\n\n"); - break; - case 0x100: - printf("OEM Locked\n\n"); - break; - case 0x200: - printf("BRICKED\n\n"); - break; - default: - printf("Unknown\n\n"); - break; - } -} - -static int confirm_close(void) -{ - puts("Warning: Please ensure your sample is in NXP closed state, " - "OEM SRK hash has been fused, \n" - " and you are able to boot a signed image successfully " - "without any SECO events reported.\n" - " If not, your sample will be unrecoverable.\n" - "\nReally perform this operation? <y/N>\n"); - - if (confirm_yesno()) - return 1; - - puts("Ahab close aborted\n"); - return 0; -} - -static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - int err; - u32 resp; - - if (!confirm_close()) - return -EACCES; - - err = ahab_forward_lifecycle(8, &resp); - if (err != 0) { - printf("Error in forward lifecycle to OEM closed\n"); - return -EIO; - } - - printf("Change to OEM closed successfully\n"); - - return 0; -} - -int ahab_dump(void) -{ - u32 buffer[32]; - int ret, i = 0; - - do { - ret = ahab_dump_buffer(buffer, 32); - if (ret < 0) { - printf("Error in dump AHAB log\n"); - return -EIO; - } - - if (ret == 1) - break; - - for (i = 0; i < ret; i++) - printf("0x%x\n", buffer[i]); - } while (ret >= 21); - - return 0; -} - -static int do_ahab_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - return ahab_dump(); -} - -static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - u32 lc; - - lc = readl(FSB_BASE_ADDR + 0x41c); - lc &= 0x3f; - - display_life_cycle(lc); - return 0; -} - -U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, - "autenticate OS container via AHAB", - "addr\n" - "addr - OS container hex address\n" -); - -U_BOOT_CMD(ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close, - "Change AHAB lifecycle to OEM closed", - "" -); - -U_BOOT_CMD(ahab_dump, CONFIG_SYS_MAXARGS, 1, do_ahab_dump, - "Dump AHAB log for debug", - "" -); - -U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, - "display AHAB lifecycle only", - "" -); diff --git a/arch/arm/mach-imx/imx8ulp/cgc.c b/arch/arm/mach-imx/imx8ulp/cgc.c index d240abaee4..d2fadb4877 100644 --- a/arch/arm/mach-imx/imx8ulp/cgc.c +++ b/arch/arm/mach-imx/imx8ulp/cgc.c @@ -136,39 +136,34 @@ void cgc1_pll3_init(ulong freq) clrbits_le32(&cgc1_regs->pll3div_vco, BIT(7)); clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F); - - if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { - setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 0); - clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 3 << 21); /* 195M */ - } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { - setbits_le32(&cgc1_regs->pll3pfdcfg, 21 << 0); - clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 1 << 21); /* 231M */ - } else { - setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 0); /* 324M */ - } - + setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 0); /* PFD0 324M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(7)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(6))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 8); - setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 8); + setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 8); /* PFD1 389M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(15)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(14))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 16); - setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 16); + setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 16); /* PFD2 324M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(23)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(22))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 24); - setbits_le32(&cgc1_regs->pll3pfdcfg, 29 << 24); + setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 24); /* PFD3 389M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(31)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(30))) ; + clrbits_le32(&cgc1_regs->pll3div_pfd0, 0x3f3f3f3f); + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) + clrsetbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f, 0x03010000); /* Set PFD3 DIV1 to 194M, PFD3 DIV2 to 97M */ + else + clrsetbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f, 0x01000000); /* Set PFD3 DIV1 to 389M, PFD3 DIV2 to 194M */ clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(7)); clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(15)); clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(23)); @@ -179,6 +174,17 @@ void cgc1_pll3_init(ulong freq) clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(23)); clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(31)); + /* NIC_AP: + * OD source PLL3 PFD0, 324M + * ND source FRO192, 192M + * LD source FRO192, 96M + */ + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { + clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 1 << 21); + } else { + clrbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21)); + } + if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { /* nicclk select pll3 pfd0 */ clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(29, 28), BIT(28)); @@ -219,20 +225,9 @@ void cgc2_pll4_init(bool pll4_reset) /* Enable all 4 PFDs */ setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 0); /* 528 */ - if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { - setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8); - /* 99Mhz for NIC_LPAV */ - clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 3 << 21); - } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { - setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8); - /* 198Mhz for NIC_LPAV */ - clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 1 << 21); - } else { - setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */ - clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21)); - } - setbits_le32(&cgc2_regs->pll4pfdcfg, 12 << 16); /* 792 */ - setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); /* 396 */ + setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */ + setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 16); /* 316.8Mhz */ + setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); /* 396Mhz */ clrbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) | BIT(15) | BIT(23) | BIT(31)); @@ -244,9 +239,22 @@ void cgc2_pll4_init(bool pll4_reset) clrbits_le32(&cgc2_regs->pll4div_pfd0, BIT(7) | BIT(15) | BIT(23) | BIT(31)); clrbits_le32(&cgc2_regs->pll4div_pfd1, BIT(7) | BIT(15) | BIT(23) | BIT(31)); - clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28), BIT(28)); - while (!(readl(&cgc2_regs->niclpavclk) & BIT(27))) - ; + /* NIC_LPAV: + * OD source PLL4 PFD1, 316.8M + * ND source FRO192, 192M + * LD source FRO192, 96M + */ + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { + clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 1 << 21); + } else { + clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21)); + } + + if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { + clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28), BIT(28)); + while (!(readl(&cgc2_regs->niclpavclk) & BIT(27))) + ; + } } void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd) diff --git a/arch/arm/mach-imx/imx8ulp/clock.c b/arch/arm/mach-imx/imx8ulp/clock.c index 3e88f4633c..36d12943a0 100644 --- a/arch/arm/mach-imx/imx8ulp/clock.c +++ b/arch/arm/mach-imx/imx8ulp/clock.c @@ -182,37 +182,20 @@ void clock_init_late(void) */ cgc1_pll3_init(540672000); - if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { - pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD2_DIV2); - pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV2); - pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV2); - pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); - } else { - pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD1_DIV2); - pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV1); - pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV1); - pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); - } + pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD3_DIV1); /* 389M for OD, 194M for LD/ND*/ + pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND */ + pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND*/ + pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); /* enable MU0_MUB clock before access the register of MU0_MUB */ pcc_clock_enable(3, MU0_B_PCC3_SLOT, true); @@ -425,6 +408,8 @@ void reset_lcdclk(void) pcc_reset_peripheral(5, DCNANO_PCC5_SLOT, true); } +/* PLL4 PFD0 max frequency */ +#define PLL4_PFD0_MAX_RATE 600000 /*khz*/ void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz) { u8 pcd, best_pcd = 0; @@ -443,6 +428,9 @@ void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz) for (div = 1; div <= 64; div++) { parent_rate = pll4_rate; parent_rate = parent_rate * 18 / pfd; + if (parent_rate > PLL4_PFD0_MAX_RATE) + continue; + parent_rate = parent_rate / div; for (pcd = 0; pcd < 8; pcd++) { diff --git a/arch/arm/mach-imx/imx8ulp/rdc.c b/arch/arm/mach-imx/imx8ulp/rdc.c index e24eeff8a2..50b097b035 100644 --- a/arch/arm/mach-imx/imx8ulp/rdc.c +++ b/arch/arm/mach-imx/imx8ulp/rdc.c @@ -181,6 +181,25 @@ int xrdc_config_pdac(u32 bridge, u32 index, u32 dom, u32 perm) return 0; } +int xrdc_config_msc(u32 msc, u32 index, u32 dom, u32 perm) +{ + ulong w0_addr; + u32 val; + + if (msc > 2) + return -EINVAL; + + w0_addr = XRDC_ADDR + 0x4000 + 0x400 * msc + 0x8 * index; + + val = readl(w0_addr); + writel((val & ~(0x7 << (dom * 3))) | (perm << (dom * 3)), w0_addr); + + val = readl(w0_addr + 4); + writel(val | BIT(31), w0_addr + 4); + + return 0; +} + int release_rdc(enum rdc_type type) { ulong s_mu_base = 0x27020000UL; @@ -191,7 +210,7 @@ int release_rdc(enum rdc_type type) msg.version = AHAB_VERSION; msg.tag = AHAB_CMD_TAG; msg.size = 2; - msg.command = AHAB_RELEASE_RDC_REQ_CID; + msg.command = ELE_RELEASE_RDC_REQ; msg.data[0] = (rdc_id << 8) | 0x2; /* A35 XRDC */ mu_hal_init(s_mu_base); @@ -276,6 +295,36 @@ void xrdc_init_mda(void) void xrdc_init_mrc(void) { + /* Re-config MRC3 for SRAM0 in case protected by S400 */ + xrdc_config_mrc_w0_w1(3, 0, 0x22010000, 0x10000); + xrdc_config_mrc_dx_perm(3, 0, 0, 1); + xrdc_config_mrc_dx_perm(3, 0, 1, 1); + xrdc_config_mrc_dx_perm(3, 0, 4, 1); + xrdc_config_mrc_dx_perm(3, 0, 5, 1); + xrdc_config_mrc_dx_perm(3, 0, 6, 1); + xrdc_config_mrc_dx_perm(3, 0, 7, 1); + xrdc_config_mrc_w3_w4(3, 0, 0x0, 0x80000FFF); + + /* Clear other 3 regions of MRC3 to invalid */ + xrdc_config_mrc_w3_w4(3, 1, 0x0, 0x0); + xrdc_config_mrc_w3_w4(3, 2, 0x0, 0x0); + xrdc_config_mrc_w3_w4(3, 3, 0x0, 0x0); + + /* Set MRC4 and MRC5 for DDR access from A35 and AP NIC PER masters */ + xrdc_config_mrc_w0_w1(4, 0, CFG_SYS_SDRAM_BASE, PHYS_SDRAM_SIZE); + xrdc_config_mrc_dx_perm(4, 0, 1, 1); + xrdc_config_mrc_dx_perm(4, 0, 7, 1); + xrdc_config_mrc_w3_w4(4, 0, 0x0, 0x80000FFF); + + xrdc_config_mrc_w0_w1(5, 0, CFG_SYS_SDRAM_BASE, PHYS_SDRAM_SIZE); + xrdc_config_mrc_dx_perm(5, 0, 1, 1); + xrdc_config_mrc_w3_w4(5, 0, 0x0, 0x80000FFF); + + /* Set MRC6 for DDR access from Sentinel */ + xrdc_config_mrc_w0_w1(6, 0, CFG_SYS_SDRAM_BASE, PHYS_SDRAM_SIZE); + xrdc_config_mrc_dx_perm(6, 0, 4, 1); + xrdc_config_mrc_w3_w4(6, 0, 0x0, 0x80000FFF); + /* The MRC8 is for SRAM1 */ xrdc_config_mrc_w0_w1(8, 0, 0x21000000, 0x10000); /* Allow for all domains: So domain 2/3 (HIFI DSP/LPAV) is ok to access */ @@ -295,6 +344,28 @@ void xrdc_init_mrc(void) xrdc_config_mrc_w3_w4(6, 0, 0x0, 0x80000FFF); } +void xrdc_init_pdac_msc(void) +{ + /* Init LPAV PDAC and MSC for DDR init */ + xrdc_config_pdac(5, 36, 6, 0x7); /* CMC2*/ + xrdc_config_pdac(5, 36, 7, 0x7); + xrdc_config_pdac(5, 37, 6, 0x7); /* SIM2 */ + xrdc_config_pdac(5, 37, 7, 0x7); + xrdc_config_pdac(5, 38, 6, 0x7); /* CGC2 */ + xrdc_config_pdac(5, 38, 7, 0x7); + xrdc_config_pdac(5, 39, 6, 0x7); /* PCC5 */ + xrdc_config_pdac(5, 39, 7, 0x7); + + xrdc_config_msc(0, 0, 6, 0x7); /* GPIOE */ + xrdc_config_msc(0, 0, 7, 0x7); + xrdc_config_msc(0, 1, 6, 0x7); /* GPIOF */ + xrdc_config_msc(0, 1, 7, 0x7); + xrdc_config_msc(1, 0, 6, 0x7); /* GPIOD */ + xrdc_config_msc(1, 0, 7, 0x7); + xrdc_config_msc(2, 6, 6, 0x7); /* DDR controller */ + xrdc_config_msc(2, 6, 7, 0x7); +} + int trdc_mbc_set_access(u32 mbc_x, u32 dom_x, u32 mem_x, u32 blk_x, bool sec_access) { struct trdc *trdc_base = (struct trdc *)0x28031000U; diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c index 5d95fb89a6..8424332f42 100644 --- a/arch/arm/mach-imx/imx8ulp/soc.c +++ b/arch/arm/mach-imx/imx8ulp/soc.c @@ -70,9 +70,18 @@ int mmc_get_env_dev(void) } #endif +static void set_cpu_info(struct sentinel_get_info_data *info) +{ + gd->arch.soc_rev = info->soc; + gd->arch.lifecycle = info->lc; + memcpy((void *)&gd->arch.uid, &info->uid, 4 * sizeof(u32)); +} + u32 get_cpu_rev(void) { - return (MXC_CPU_IMX8ULP << 12) | CHIP_REV_1_0; + u32 rev = (gd->arch.soc_rev >> 24) - 0xa0; + + return (MXC_CPU_IMX8ULP << 12) | (CHIP_REV_1_0 + rev); } enum bt_mode get_boot_mode(void) @@ -95,14 +104,70 @@ enum bt_mode get_boot_mode(void) bool m33_image_booted(void) { - u32 gp6; + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + u32 gp6 = 0; + + /* DGO_GP6 */ + gp6 = readl(SIM_SEC_BASE_ADDR + 0x28); + if (gp6 & BIT(5)) + return true; + + return false; + } else { + u32 gpr0 = readl(SIM1_BASE_ADDR); + if (gpr0 & BIT(0)) + return true; + + return false; + } +} + +bool rdc_enabled_in_boot(void) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + u32 val = 0; + int ret; + bool rdc_en = true; /* Default assume DBD_EN is set */ + + /* Read DBD_EN fuse */ + ret = fuse_read(8, 1, &val); + if (!ret) + rdc_en = !!(val & 0x200); /* only A1 part uses DBD_EN, so check DBD_EN new place*/ + + return rdc_en; + } else { + u32 gpr0 = readl(SIM1_BASE_ADDR); + if (gpr0 & 0x2) + return true; + + return false; + } +} + +static void spl_pass_boot_info(void) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + bool m33_booted = m33_image_booted(); + bool rdc_en = rdc_enabled_in_boot(); + u32 val = 0; + + if (m33_booted) + val |= 0x1; - /* DGO_GP6 */ - gp6 = readl(SIM_SEC_BASE_ADDR + 0x28); - if (gp6 & BIT(5)) - return true; + if (rdc_en) + val |= 0x2; - return false; + writel(val, SIM1_BASE_ADDR); + } +} + +bool is_m33_handshake_necessary(void) +{ + /* Only need handshake in u-boot */ + if (!IS_ENABLED(CONFIG_SPL_BUILD)) + return (m33_image_booted() || rdc_enabled_in_boot()); + else + return false; } int m33_image_handshake(ulong timeout_ms) @@ -547,33 +612,65 @@ static void set_core0_reset_vector(u32 entry) setbits_le32(SIM1_BASE_ADDR + 0x8, (0x1 << 26)); } -static int trdc_set_access(void) +/* Not used now */ +int trdc_set_access(void) { /* * TRDC mgr + 4 MBC + 2 MRC. - * S400 should already configure when release RDC - * A35 only map non-secure region for pbridge0 and 1, set sec_access to false */ - trdc_mbc_set_access(2, 7, 0, 49, false); - trdc_mbc_set_access(2, 7, 0, 50, false); - trdc_mbc_set_access(2, 7, 0, 51, false); - trdc_mbc_set_access(2, 7, 0, 52, false); - trdc_mbc_set_access(2, 7, 0, 53, false); - trdc_mbc_set_access(2, 7, 0, 54, false); - - /* CGC0: PBridge0 slot 47 */ + trdc_mbc_set_access(2, 7, 0, 49, true); + trdc_mbc_set_access(2, 7, 0, 50, true); + trdc_mbc_set_access(2, 7, 0, 51, true); + trdc_mbc_set_access(2, 7, 0, 52, true); + trdc_mbc_set_access(2, 7, 0, 53, true); + trdc_mbc_set_access(2, 7, 0, 54, true); + + /* 0x1fff8000 used for resource table by remoteproc */ + trdc_mbc_set_access(0, 7, 2, 31, false); + + /* CGC0: PBridge0 slot 47 and PCC0 slot 48 */ trdc_mbc_set_access(2, 7, 0, 47, false); + trdc_mbc_set_access(2, 7, 0, 48, false); + + /* PCC1 */ + trdc_mbc_set_access(2, 7, 1, 17, false); + trdc_mbc_set_access(2, 7, 1, 34, false); /* Iomuxc0: : PBridge1 slot 33 */ trdc_mbc_set_access(2, 7, 1, 33, false); /* flexspi0 */ + trdc_mbc_set_access(2, 7, 0, 57, false); trdc_mrc_region_set_access(0, 7, 0x04000000, 0x0c000000, false); /* tpm0: PBridge1 slot 21 */ trdc_mbc_set_access(2, 7, 1, 21, false); /* lpi2c0: PBridge1 slot 24 */ trdc_mbc_set_access(2, 7, 1, 24, false); + + /* Allow M33 to access TRDC MGR */ + trdc_mbc_set_access(2, 6, 0, 49, true); + trdc_mbc_set_access(2, 6, 0, 50, true); + trdc_mbc_set_access(2, 6, 0, 51, true); + trdc_mbc_set_access(2, 6, 0, 52, true); + trdc_mbc_set_access(2, 6, 0, 53, true); + trdc_mbc_set_access(2, 6, 0, 54, true); + + /* Set SAI0 for eDMA 0, NS */ + trdc_mbc_set_access(2, 0, 1, 28, false); + + /* Set SSRAM for eDMA0 access */ + trdc_mbc_set_access(0, 0, 2, 0, false); + trdc_mbc_set_access(0, 0, 2, 1, false); + trdc_mbc_set_access(0, 0, 2, 2, false); + trdc_mbc_set_access(0, 0, 2, 3, false); + trdc_mbc_set_access(0, 0, 2, 4, false); + trdc_mbc_set_access(0, 0, 2, 5, false); + trdc_mbc_set_access(0, 0, 2, 6, false); + trdc_mbc_set_access(0, 0, 2, 7, false); + + writel(0x800000a0, 0x28031840); + return 0; } @@ -620,10 +717,6 @@ void set_lpav_qos(void) int arch_cpu_init(void) { if (IS_ENABLED(CONFIG_SPL_BUILD)) { - u32 val = 0; - int ret; - bool rdc_en = true; /* Default assume DBD_EN is set */ - /* Enable System Reset Interrupt using WDOG_AD */ setbits_le32(CMC1_BASE_ADDR + 0x8C, BIT(13)); /* Clear AD_PERIPH Power switch domain out of reset interrupt flag */ @@ -640,52 +733,82 @@ int arch_cpu_init(void) /* Disable wdog */ init_wdog(); - /* Read DBD_EN fuse */ - ret = fuse_read(8, 1, &val); - if (!ret) - rdc_en = !!(val & 0x4000); - - if (get_boot_mode() == SINGLE_BOOT) { - if (rdc_en) - release_rdc(RDC_TRDC); - - trdc_set_access(); + if (get_boot_mode() == SINGLE_BOOT) lpav_configure(false); - } else { + else lpav_configure(true); - } /* Release xrdc, then allow A35 to write SRAM2 */ - if (rdc_en) + if (rdc_enabled_in_boot()) release_rdc(RDC_XRDC); xrdc_mrc_region_set_access(2, CONFIG_SPL_TEXT_BASE, 0xE00); clock_init_early(); + + spl_pass_boot_info(); } else { + int ret; /* reconfigure core0 reset vector to ROM */ set_core0_reset_vector(0x1000); + + if (is_m33_handshake_necessary()) { + /* Start handshake with M33 to ensure TRDC configuration completed */ + ret = m33_image_handshake(1000); + if (!ret) + gd->arch.m33_handshake_done = true; + else /* Skip and go through to panic in checkcpu as console is ready then */ + gd->arch.m33_handshake_done = false; + } } return 0; } -static int imx8ulp_check_mu(void *ctx, struct event *event) +int checkcpu(void) { - struct udevice *devp; - int node, ret; + if (is_m33_handshake_necessary()) { + if (!gd->arch.m33_handshake_done) { + puts("M33 Sync: Timeout, Boot Stop!\n"); + hang(); + } else { + puts("M33 Sync: OK\n"); + } + } + return 0; +} - node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8ulp-mu"); +int imx8ulp_dm_post_init(void) +{ + struct udevice *devp; + int ret; + u32 res; + struct sentinel_get_info_data *info = (struct sentinel_get_info_data *)SRAM0_BASE; - ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp); + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(imx8ulp_mu), &devp); if (ret) { printf("could not get S400 mu %d\n", ret); return ret; } + ret = ahab_get_info(info, &res); + if (ret) { + printf("ahab_get_info failed %d\n", ret); + /* fallback to A0.1 revision */ + memset((void *)info, 0, sizeof(struct sentinel_get_info_data)); + info->soc = 0xa000084d; + } + + set_cpu_info(info); + return 0; } -EVENT_SPY(EVT_DM_POST_INIT, imx8ulp_check_mu); + +static int imx8ulp_evt_dm_post_init(void *ctx, struct event *event) +{ + return imx8ulp_dm_post_init(); +} +EVENT_SPY(EVT_DM_POST_INIT, imx8ulp_evt_dm_post_init); #if defined(CONFIG_SPL_BUILD) __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) @@ -737,7 +860,8 @@ int (*card_emmc_is_boot_part_en)(void) = (void *)0x67cc; u32 spl_arch_boot_image_offset(u32 image_offset, u32 rom_bt_dev) { /* Hard code for eMMC image_offset on 8ULP ROM, need fix by ROM, temp workaround */ - if (((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_MMC && card_emmc_is_boot_part_en()) + if (is_soc_rev(CHIP_REV_1_0) && ((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_MMC && + card_emmc_is_boot_part_en()) image_offset = 0; return image_offset; diff --git a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c index b6811d56c9..fcb02ed3af 100644 --- a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c +++ b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c @@ -11,6 +11,25 @@ #include "upower_api.h" #define UPOWER_AP_MU1_ADDR 0x29280000 + +#define PS_RTD BIT(0) +#define PS_DSP BIT(1) +#define PS_A35_0 BIT(2) +#define PS_A35_1 BIT(3) +#define PS_L2 BIT(4) +#define PS_FAST_NIC BIT(5) +#define PS_APD_PERIPH BIT(6) +#define PS_GPU3D BIT(7) +#define PS_HIFI4 BIT(8) +#define PS_DDR GENMASK(12, 9) +#define PS_PXP_EPDC BIT(13) +#define PS_MIPI_DSI BIT(14) +#define PS_MIPI_CSI BIT(15) +#define PS_NIC_LPAV BIT(16) +#define PS_FUSION_AO BIT(17) +#define PS_FUSE BIT(18) +#define PS_UPOWER BIT(19) + static struct mu_type *muptr = (struct mu_type *)UPOWER_AP_MU1_ADDR; void upower_wait_resp(void) @@ -110,6 +129,7 @@ int upower_init(void) u32 fw_major, fw_minor, fw_vfixes; u32 soc_id; int status; + enum upwr_resp err_code; u32 swton; u64 memon; @@ -140,27 +160,92 @@ int upower_init(void) } } while (0); - swton = 0xfff80; + swton = PS_UPOWER | PS_FUSE | PS_FUSION_AO | PS_NIC_LPAV | PS_PXP_EPDC | PS_DDR | + PS_HIFI4 | PS_GPU3D | PS_MIPI_DSI; ret = upwr_pwm_power_on(&swton, NULL, NULL); if (ret) printf("Turn on switches fail %d\n", ret); else - printf("Turn on switches ok\n"); + printf("Turning on switches...\n"); + upower_wait_resp(); - ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000); + ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, &err_code, &ret_val, 1000); if (ret != UPWR_REQ_OK) - printf("Failure %d\n", ret); + printf("Turn on switches faliure %d, err_code %d, ret_val 0x%x\n", ret, err_code, ret_val); + else + printf("Turn on switches ok\n"); - memon = 0x3FFFFFFFFFFFFCUL; - ret = upwr_pwm_power_on(NULL, (const u32 *)&memon, NULL); + /* + * Ascending Order -> bit [0:54) + * CA35 Core 0 L1 cache + * CA35 Core 1 L1 cache + * L2 Cache 0 + * L2 Cache 1 + * L2 Cache victim/tag + * CAAM Secure RAM + * DMA1 RAM + * FlexSPI2 FIFO, Buffer + * SRAM0 + * AD ROM + * USB0 TX/RX RAM + * uSDHC0 FIFO RAM + * uSDHC1 FIFO RAM + * uSDHC2 FIFO and USB1 TX/RX RAM + * GIC RAM + * ENET TX FIXO + * Reserved(Brainshift) + * DCNano Tile2Linear and RGB Correction + * DCNano Cursor and FIFO + * EPDC LUT + * EPDC FIFO + * DMA2 RAM + * GPU2D RAM Group 1 + * GPU2D RAM Group 2 + * GPU3D RAM Group 1 + * GPU3D RAM Group 2 + * HIFI4 Caches, IRAM, DRAM + * ISI Buffers + * MIPI-CSI FIFO + * MIPI-DSI FIFO + * PXP Caches, Buffers + * SRAM1 + * Casper RAM + * DMA0 RAM + * FlexCAN RAM + * FlexSPI0 FIFO, Buffer + * FlexSPI1 FIFO, Buffer + * CM33 Cache + * PowerQuad RAM + * ETF RAM + * Sentinel PKC, Data RAM1, Inst RAM0/1 + * Sentinel ROM + * uPower IRAM/DRAM + * uPower ROM + * CM33 ROM + * SSRAM Partition 0 + * SSRAM Partition 1 + * SSRAM Partition 2,3,4 + * SSRAM Partition 5 + * SSRAM Partition 6 + * SSRAM Partition 7_a(128KB) + * SSRAM Partition 7_b(64KB) + * SSRAM Partition 7_c(64KB) + * Sentinel Data RAM0, Inst RAM2 + */ + /* MIPI-CSI FIFO BIT28 not set */ + memon = 0x3FFFFFEFFFFFFCUL; + ret = upwr_pwm_power_on(NULL, (const uint32_t *)&memon, NULL); if (ret) printf("Turn on memories fail %d\n", ret); else - printf("Turn on memories ok\n"); + printf("Turning on memories...\n"); + upower_wait_resp(); - ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000); + ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, &err_code, &ret_val, 1000); if (ret != UPWR_REQ_OK) - printf("Failure %d\n", ret); + printf("Turn on memories faliure %d, err_code %d, ret_val 0x%x\n", ret, err_code, ret_val); + else + printf("Turn on memories ok\n"); mdelay(1); @@ -168,13 +253,14 @@ int upower_init(void) if (ret) printf("Clear DDR retention fail %d\n", ret); else - printf("Clear DDR retention ok\n"); + printf("Clearing DDR retention...\n"); upower_wait_resp(); - - ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, NULL, &ret_val, 1000); + ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000); if (ret != UPWR_REQ_OK) - printf("Failure %d\n", ret); + printf("Clear DDR retention fail %d, err_code %d, ret_val 0x%x\n", ret, err_code, ret_val); + else + printf("Clear DDR retention ok\n"); return 0; } diff --git a/arch/arm/mach-imx/imx9/Makefile b/arch/arm/mach-imx/imx9/Makefile index 6d038a60c6..e1b09ab534 100644 --- a/arch/arm/mach-imx/imx9/Makefile +++ b/arch/arm/mach-imx/imx9/Makefile @@ -4,7 +4,6 @@ obj-y += lowlevel_init.o obj-y += soc.o clock.o clock_root.o trdc.o -obj-$(CONFIG_AHAB_BOOT) += ahab.o #ifndef CONFIG_SPL_BUILD obj-y += imx_bootaux.o diff --git a/arch/arm/mach-imx/imx9/ahab.c b/arch/arm/mach-imx/imx9/ahab.c deleted file mode 100644 index 6aa949619b..0000000000 --- a/arch/arm/mach-imx/imx9/ahab.c +++ /dev/null @@ -1,346 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2022 NXP - */ - -#include <common.h> -#include <command.h> -#include <errno.h> -#include <asm/io.h> -#include <asm/mach-imx/s400_api.h> -#include <asm/mach-imx/sys_proto.h> -#include <asm/arch-imx/cpu.h> -#include <asm/arch/sys_proto.h> -#include <asm/mach-imx/image.h> -#include <console.h> -#include <cpu_func.h> -#include <asm/mach-imx/ahab.h> -#include <asm/global_data.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define IMG_CONTAINER_BASE (0x80000000UL) -#define IMG_CONTAINER_END_BASE (IMG_CONTAINER_BASE + 0xFFFFUL) - -#define AHAB_NO_AUTHENTICATION_IND 0xee -#define AHAB_BAD_KEY_HASH_IND 0xfa -#define AHAB_INVALID_KEY_IND 0xf9 -#define AHAB_BAD_SIGNATURE_IND 0xf0 -#define AHAB_BAD_HASH_IND 0xf1 - -static void display_ahab_auth_ind(u32 event) -{ - u8 resp_ind = (event >> 8) & 0xff; - - switch (resp_ind) { - case AHAB_NO_AUTHENTICATION_IND: - printf("AHAB_NO_AUTHENTICATION_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_BAD_KEY_HASH_IND: - printf("AHAB_BAD_KEY_HASH_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_INVALID_KEY_IND: - printf("AHAB_INVALID_KEY_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_BAD_SIGNATURE_IND: - printf("AHAB_BAD_SIGNATURE_IND (0x%02X)\n\n", resp_ind); - break; - case AHAB_BAD_HASH_IND: - printf("AHAB_BAD_HASH_IND (0x%02X)\n\n", resp_ind); - break; - default: - printf("Unknown Indicator (0x%02X)\n\n", resp_ind); - break; - } -} - -int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length) -{ - int err; - u32 resp; - - memcpy((void *)IMG_CONTAINER_BASE, (const void *)container, - ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); - - flush_dcache_range(IMG_CONTAINER_BASE, - IMG_CONTAINER_BASE + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE) - 1); - - err = ahab_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp); - if (err) { - printf("Authenticate container hdr failed, return %d, resp 0x%x\n", - err, resp); - display_ahab_auth_ind(resp); - } - - return err; -} - -int ahab_auth_release(void) -{ - int err; - u32 resp; - - err = ahab_release_container(&resp); - if (err) { - printf("Error: release container failed, resp 0x%x!\n", resp); - display_ahab_auth_ind(resp); - } - - return err; -} - -int ahab_verify_cntr_image(struct boot_img_t *img, int image_index) -{ - int err; - u32 resp; - - err = ahab_verify_image(image_index, &resp); - if (err) { - printf("Authenticate img %d failed, return %d, resp 0x%x\n", - image_index, err, resp); - display_ahab_auth_ind(resp); - - return -EIO; - } - - return 0; -} - -static inline bool check_in_dram(ulong addr) -{ - int i; - struct bd_info *bd = gd->bd; - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { - if (bd->bi_dram[i].size) { - if (addr >= bd->bi_dram[i].start && - addr < (bd->bi_dram[i].start + bd->bi_dram[i].size)) - return true; - } - } - - return false; -} - -int authenticate_os_container(ulong addr) -{ - struct container_hdr *phdr; - int i, ret = 0; - int err; - u16 length; - struct boot_img_t *img; - unsigned long s, e; - - if (addr % 4) { - puts("Error: Image's address is not 4 byte aligned\n"); - return -EINVAL; - } - - if (!check_in_dram(addr)) { - puts("Error: Image's address is invalid\n"); - return -EINVAL; - } - - phdr = (struct container_hdr *)addr; - if (phdr->tag != 0x87 || phdr->version != 0x0) { - printf("Error: Wrong container header\n"); - return -EFAULT; - } - - if (!phdr->num_images) { - printf("Error: Wrong container, no image found\n"); - return -EFAULT; - } - - length = phdr->length_lsb + (phdr->length_msb << 8); - - debug("container length %u\n", length); - - err = ahab_auth_cntr_hdr(phdr, length); - if (err) { - ret = -EIO; - goto exit; - } - - debug("Verify images\n"); - - /* Copy images to dest address */ - for (i = 0; i < phdr->num_images; i++) { - img = (struct boot_img_t *)(addr + - sizeof(struct container_hdr) + - i * sizeof(struct boot_img_t)); - - debug("img %d, dst 0x%x, src 0x%lx, size 0x%x\n", - i, (uint32_t)img->dst, img->offset + addr, img->size); - - memcpy((void *)img->dst, (const void *)(img->offset + addr), - img->size); - - s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); - e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1; - - flush_dcache_range(s, e); - - ret = ahab_verify_cntr_image(img, i); - if (ret) - goto exit; - } - -exit: - debug("ahab_auth_release, 0x%x\n", ret); - ahab_auth_release(); - - return ret; -} - -static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - ulong addr; - - if (argc < 2) - return CMD_RET_USAGE; - - addr = simple_strtoul(argv[1], NULL, 16); - - printf("Authenticate OS container at 0x%lx\n", addr); - - if (authenticate_os_container(addr)) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; -} - -static void display_life_cycle(u32 lc) -{ - printf("Lifecycle: 0x%08X, ", lc); - switch (lc) { - case 0x1: - printf("BLANK\n\n"); - break; - case 0x2: - printf("FAB\n\n"); - break; - case 0x4: - printf("NXP Provisioned\n\n"); - break; - case 0x8: - printf("OEM Open\n\n"); - break; - case 0x10: - printf("OEM Secure World Closed\n\n"); - break; - case 0x20: - printf("OEM closed\n\n"); - break; - case 0x40: - printf("Field Return OEM\n\n"); - break; - case 0x80: - printf("Field Return NXP\n\n"); - break; - case 0x100: - printf("OEM Locked\n\n"); - break; - case 0x200: - printf("BRICKED\n\n"); - break; - default: - printf("Unknown\n\n"); - break; - } -} - -static int confirm_close(void) -{ - puts("Warning: Please ensure your sample is in NXP closed state, " - "OEM SRK hash has been fused, \n" - " and you are able to boot a signed image successfully " - "without any SECO events reported.\n" - " If not, your sample will be unrecoverable.\n" - "\nReally perform this operation? <y/N>\n"); - - if (confirm_yesno()) - return 1; - - puts("Ahab close aborted\n"); - return 0; -} - -static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - int err; - u32 resp; - - if (!confirm_close()) - return -EACCES; - - err = ahab_forward_lifecycle(8, &resp); - if (err != 0) { - printf("Error in forward lifecycle to OEM closed\n"); - return -EIO; - } - - printf("Change to OEM closed successfully\n"); - - return 0; -} - -int ahab_dump(void) -{ - u32 buffer[32]; - int ret, i = 0; - - do { - ret = ahab_dump_buffer(buffer, 32); - if (ret < 0) { - printf("Error in dump AHAB log\n"); - return -EIO; - } - - if (ret == 1) - break; - for (i = 0; i < ret; i++) - printf("0x%x\n", buffer[i]); - } while (ret >= 21); - - return 0; -} - -static int do_ahab_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - return ahab_dump(); -} - -static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - u32 lc; - - lc = readl(FSB_BASE_ADDR + 0x41c); - lc &= 0x3ff; - - display_life_cycle(lc); - return 0; -} - -U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, - "autenticate OS container via AHAB", - "addr\n" - "addr - OS container hex address\n" -); - -U_BOOT_CMD(ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close, - "Change AHAB lifecycle to OEM closed", - "" -); - -U_BOOT_CMD(ahab_dump, CONFIG_SYS_MAXARGS, 1, do_ahab_dump, - "Dump AHAB log for debug", - "" -); - -U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, - "display AHAB lifecycle only", - "" -); diff --git a/arch/arm/mach-imx/imx9/trdc.c b/arch/arm/mach-imx/imx9/trdc.c index 3f37ce712c..e05c704810 100644 --- a/arch/arm/mach-imx/imx9/trdc.c +++ b/arch/arm/mach-imx/imx9/trdc.c @@ -339,7 +339,7 @@ int release_rdc(u8 xrdc) msg.version = AHAB_VERSION; msg.tag = AHAB_CMD_TAG; msg.size = 2; - msg.command = AHAB_RELEASE_RDC_REQ_CID; + msg.command = ELE_RELEASE_RDC_REQ; msg.data[0] = (rdc_id << 8) | 0x2; /* A55 */ mu_hal_init(s_mu_base); diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index aa5d23a6fb..830d5d12c2 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -341,15 +341,35 @@ int board_return_to_bootrom(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int ret; - u32 boot; + u32 boot, bstage; ret = rom_api_query_boot_infor(QUERY_BT_DEV, &boot); + ret |= rom_api_query_boot_infor(QUERY_BT_STAGE, &bstage); if (ret != ROM_API_OKAY) { puts("ROMAPI: failure at query_boot_info\n"); return -1; } + printf("Boot Stage: "); + + switch (bstage) { + case BT_STAGE_PRIMARY: + printf("Primary boot\n"); + break; + case BT_STAGE_SECONDARY: + printf("Secondary boot\n"); + break; + case BT_STAGE_RECOVERY: + printf("Recovery boot\n"); + break; + case BT_STAGE_USB: + printf("USB boot\n"); + break; + default: + printf("Unknow (0x%x)\n", bstage); + } + if (is_boot_from_stream_device(boot)) return spl_romapi_load_image_stream(spl_image, bootdev); |