From 04bd6c8997642a2d3b9c74c494f1a0a2a039f17d Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Tue, 17 Jan 2023 16:59:21 +0800 Subject: [PATCH 01/22] ARM: dts: npcm8xx: add npcm845 function node Add functaion node list as below: 1. i2c 2. gmac 3. otp 4. aes 5. sha 6. rng 7. serial Signed-off-by: Jim Liu --- arch/arm/dts/nuvoton-common-npcm8xx.dtsi | 358 +++++++++++++++++++++++ arch/arm/dts/nuvoton-npcm845-evb.dts | 198 +++++++++++++ arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi | 134 +++++++++ 3 files changed, 690 insertions(+) diff --git a/arch/arm/dts/nuvoton-common-npcm8xx.dtsi b/arch/arm/dts/nuvoton-common-npcm8xx.dtsi index 4538345dda0..fabe5925b70 100644 --- a/arch/arm/dts/nuvoton-common-npcm8xx.dtsi +++ b/arch/arm/dts/nuvoton-common-npcm8xx.dtsi @@ -257,6 +257,364 @@ syscon = <&gcr>; status = "disabled"; }; + + i2c1: i2c@81000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x81000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb1_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c2: i2c@82000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x82000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb2_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c3: i2c@83000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x83000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb3_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c4: i2c@84000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x84000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb4_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c5: i2c@85000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x85000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb5_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c6: i2c@86000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x86000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb6_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c7: i2c@87000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x87000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb7_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c8: i2c@88000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x88000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb8_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c9: i2c@89000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x89000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb9_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c10: i2c@8a000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x8a000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb10_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c11: i2c@8b000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x8b000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb11_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c12: i2c@8c000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x8c000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb12_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c13: i2c@8d000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x8d000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb13_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c14: i2c@8e000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x8e000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb14_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c15: i2c@8f000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0x8f000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb15_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c16: i2c@fff00000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff00000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb16_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c17: i2c@fff01000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff01000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb17_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c18: i2c@fff02000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff02000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb18_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c19: i2c@fff03000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff03000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb19_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c20: i2c@fff04000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff04000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb20_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c21: i2c@fff05000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff05000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb21_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c22: i2c@fff06000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff06000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb22_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c23: i2c@fff07000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff07000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&smb23_pins>; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c24: i2c@fff08000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff08000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c25: i2c@fff09000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff09000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + syscon = <&gcr>; + status = "disabled"; + }; + + i2c26: i2c@fff0a000 { + compatible = "nuvoton,npcm845-i2c"; + reg = <0xfff0a000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = ; + syscon = <&gcr>; + status = "disabled"; + }; }; }; }; diff --git a/arch/arm/dts/nuvoton-npcm845-evb.dts b/arch/arm/dts/nuvoton-npcm845-evb.dts index 53f4c6aeca6..3cab7807e31 100644 --- a/arch/arm/dts/nuvoton-npcm845-evb.dts +++ b/arch/arm/dts/nuvoton-npcm845-evb.dts @@ -11,7 +11,37 @@ aliases { serial0 = &serial0; + ethernet0 = &gmac0; + ethernet1 = &gmac1; + ethernet2 = &gmac2; + ethernet3 = &gmac3; i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + i2c14 = &i2c14; + i2c15 = &i2c15; + i2c16 = &i2c16; + i2c17 = &i2c17; + i2c18 = &i2c18; + i2c19 = &i2c19; + i2c20 = &i2c20; + i2c21 = &i2c21; + i2c22 = &i2c22; + i2c23 = &i2c23; + i2c24 = &i2c24; + i2c25 = &i2c25; + i2c26 = &i2c26; spi0 = &fiu0; spi1 = &fiu1; spi3 = &fiu3; @@ -106,6 +136,49 @@ status = "okay"; }; +&gmac0 { + phy-mode = "sgmii"; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-gpio = <&gpio5 30 GPIO_ACTIVE_LOW>; /* gpio190 */ + status = "okay"; +}; + +&gmac1 { + phy-mode = "rgmii-id"; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-gpio = <&gpio5 2 GPIO_ACTIVE_LOW>; /* gpio162 */ + status = "okay"; +}; + +&gmac2 { + phy-mode = "NC-SI"; + max-speed = <100>; + use-ncsi; + pinctrl-0 = <&r1_pins + &r1en_pins + &r1oen_pins>; + status = "disabled"; +}; + +&gmac3 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&r2_pins + &r2oen_pins + &r2en_pins + &gpio91o_pins + &gpio92o_pins>; + snps,bitbang-mii; + snps,mdc-gpio = <&gpio2 27 GPIO_ACTIVE_HIGH>; /* gpio91 */ + snps,mdio-gpio = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* gpio92 */ + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-gpio = <&gpio2 29 GPIO_ACTIVE_LOW>; /* gpio93 */ + status = "okay"; +}; + &spi1 { status = "okay"; }; @@ -142,10 +215,135 @@ phys = <&usbphy3 4>; }; +&rng { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&sha { + status = "okay"; +}; + +&otp { + status = "okay"; +}; + &i2c0 { status = "okay"; }; +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&i2c6 { + status = "okay"; + tmp100@48 { + compatible = "tmp100"; + reg = <0x48>; + status = "okay"; + }; +}; + +&i2c7 { + status = "okay"; +}; + +&i2c8 { + status = "okay"; +}; + +&i2c9 { + status = "okay"; +}; + +&i2c10 { + status = "okay"; +}; + +&i2c11 { + status = "okay"; +}; + +&i2c12 { + status = "okay"; +}; + +&i2c13 { + status = "okay"; +}; + +&i2c14 { + status = "okay"; +}; + +&i2c15 { + status = "okay"; +}; + +&i2c16 { + status = "okay"; +}; + +&i2c17 { + status = "okay"; +}; + +&i2c18 { + status = "okay"; +}; + +&i2c19 { + status = "okay"; +}; + +&i2c20 { + status = "okay"; +}; + +&i2c21 { + status = "okay"; +}; + +&i2c22 { + status = "okay"; +}; + +&i2c23 { + status = "okay"; +}; + +&i2c24 { + status = "okay"; +}; + +&i2c25 { + status = "okay"; +}; + +&i2c26 { + status = "okay"; +}; + &pinctrl { pinctrl-names = "default"; pinctrl-0 = < diff --git a/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi b/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi index d21e5042a67..be2ad0cf6cd 100644 --- a/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi +++ b/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi @@ -59,6 +59,68 @@ clocks = <&clk_refclk>; }; + gmac0: eth@f0802000 { + device_type = "network"; + compatible = "nuvoton,npcm-dwmac", "st,stm32-dwmac"; + reg = <0x0 0xf0802000 0x0 0x2000>, + <0x0 0xf0780000 0x0 0x200>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "stmmaceth"; + pinctrl-names = "default"; + pinctrl-0 = <&rg1mdio_pins>; + resets = <&rstc2 NPCM8XX_RESET_GMAC1>; + status = "disabled"; + }; + + gmac1: eth@f0804000 { + device_type = "network"; + compatible = "nuvoton,npcm-dwmac", "st,stm32-dwmac"; + reg = <0x0 0xf0804000 0x0 0x2000>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "stmmaceth"; + pinctrl-names = "default"; + pinctrl-0 = <&rg2_pins + &rg2mdio_pins>; + resets = <&rstc2 NPCM8XX_RESET_GMAC2>; + status = "disabled"; + }; + + gmac2: eth@f0806000 { + device_type = "network"; + compatible = "nuvoton,npcm-dwmac", "st,stm32-dwmac"; + reg = <0x0 0xf0806000 0x0 0x2000>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "stmmaceth"; + pinctrl-names = "default"; + pinctrl-0 = <&r1_pins + &r1err_pins + &r1md_pins>; + resets = <&rstc1 NPCM8XX_RESET_GMAC3>; + status = "disabled"; + }; + + gmac3: eth@f0808000 { + device_type = "network"; + compatible = "nuvoton,npcm-dwmac", "st,stm32-dwmac"; + reg = <0x0 0xf0808000 0x0 0x2000>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "stmmaceth"; + pinctrl-names = "default"; + pinctrl-0 = <&r2_pins + &r2err_pins + &r2md_pins>; + resets = <&rstc1 NPCM8XX_RESET_GMAC4>; + status = "disabled"; + }; + ehci1: usb@f0828100 { compatible = "nuvoton,npcm845-ehci"; reg = <0x0 0xf0828100 0x0 0x1000>; @@ -236,6 +298,49 @@ status = "disabled"; }; + serial1: serial@1000 { + compatible = "nuvoton,npcm845-uart"; + reg = <0x1000 0x1000>; + clocks = <&clk NPCM8XX_CLK_UART>, <&clk NPCM8XX_CLK_PLL2DIV2>; + status = "disabled"; + }; + + serial2: serial@2000 { + compatible = "nuvoton,npcm845-uart"; + reg = <0x2000 0x1000>; + clocks = <&clk NPCM8XX_CLK_UART>, <&clk NPCM8XX_CLK_PLL2DIV2>; + status = "disabled"; + }; + + serial3: serial@3000 { + compatible = "nuvoton,npcm845-uart"; + reg = <0x3000 0x1000>; + clocks = <&clk NPCM8XX_CLK_UART>, <&clk NPCM8XX_CLK_PLL2DIV2>; + status = "disabled"; + }; + + serial4: serial@4000 { + compatible = "nuvoton,npcm845-uart"; + reg = <0x4000 0x1000>; + clocks = <&clk NPCM8XX_CLK_UART2>, <&clk NPCM8XX_CLK_PLL2DIV2>; + status = "disabled"; + }; + + serial5: serial@5000 { + compatible = "nuvoton,npcm845-uart"; + reg = <0x5000 0x1000>; + clocks = <&clk NPCM8XX_CLK_UART2>, <&clk NPCM8XX_CLK_PLL2DIV2>; + status = "disabled"; + }; + + serial6: serial@6000 { + compatible = "nuvoton,npcm845-uart"; + reg = <0x6000 0x1000>; + clocks = <&clk NPCM8XX_CLK_UART2>, <&clk NPCM8XX_CLK_PLL2DIV2>; + interrupts = ; + status = "disabled"; + }; + gpio0: gpio0@10000 { compatible = "nuvoton,npcm-gpio", "nuvoton,npcm845-gpio"; reg = <0x10000 0xB0>; @@ -299,6 +404,35 @@ gpio-controller; gpio-bank-name = "gpio7"; }; + + rng: rng@b000 { + compatible = "nuvoton,npcm845-rng"; + reg = <0xb000 0x8>; + status = "disabled"; + }; + + otp: otp@189000 { + compatible = "nuvoton,npcm845-otp"; + reg = <0x189000 0x1000>; + status = "disabled"; + }; + + aes: aes@f0858000 { + compatible = "nuvoton,npcm845-aes"; + reg = <0x0 0xf0858000 0x0 0x1000>, + <0x0 0xf0851000 0x0 0x1000>; + status = "disabled"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "clk_ahb"; + }; + + sha:sha@f085a000 { + compatible = "nuvoton,npcm845-sha"; + reg = <0x0 0xf085a000 0x0 0x1000>; + status = "disabled"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "clk_ahb"; + }; }; }; pinctrl: pinctrl@f0800000 { From a3c191aec0dcab9cc834545ab1a65e07ecd65b29 Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Tue, 17 Jan 2023 16:59:22 +0800 Subject: [PATCH 02/22] ARM: config: enable function for nuvoton npcm845 bmc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable npcm845 i2c、ethernet、REGULATOR and security feature Signed-off-by: Jim Liu --- configs/arbel_evb_defconfig | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/configs/arbel_evb_defconfig b/configs/arbel_evb_defconfig index aa857661d9b..8f8a603b503 100644 --- a/configs/arbel_evb_defconfig +++ b/configs/arbel_evb_defconfig @@ -38,6 +38,7 @@ CONFIG_SYSCON=y CONFIG_CLK=y CONFIG_NPCM_GPIO=y CONFIG_DM_I2C=y +CONFIG_NPCM_I2C=y # CONFIG_INPUT is not set CONFIG_NPCM_HOST=y CONFIG_MMC_SDHCI=y @@ -46,7 +47,6 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_PHY_BROADCOM=y -CONFIG_DM_MDIO=y CONFIG_PHY_GIGE=y CONFIG_ETH_DESIGNWARE=y CONFIG_RGMII=y @@ -75,3 +75,20 @@ CONFIG_USB_OHCI_GENERIC=y CONFIG_USB_OHCI_NPCM=y CONFIG_USB_STORAGE=y # CONFIG_EFI_LOADER is not set +CONFIG_NET=y +CONFIG_NETDEVICES=y +CONFIG_DM_ETH=y +CONFIG_MISC=y +CONFIG_SHA_HW_ACCEL=y +CONFIG_NPCM_SHA=y +CONFIG_RNG_NPCM=y +CONFIG_LIB_HW_RAND=y +CONFIG_DM_RNG=y +# CONFIG_AES is not set +CONFIG_CMD_RNG=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_HASH=y +CONFIG_NPCM_AES=y +CONFIG_NPCM_OTP=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_NPCM8XX=y From 337bc26f05e85bf06647a17bad9485a3428c9a2b Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Tue, 17 Jan 2023 16:59:23 +0800 Subject: [PATCH 03/22] arm: npcm8xx: add security feature header The NPCM driver can use on npcm7xx/npcm8xx so add npcm8xx header for driver. Signed-off-by: Jim Liu --- arch/arm/include/asm/arch-npcm8xx/aes.h | 53 ++++++++++++++ arch/arm/include/asm/arch-npcm8xx/otp.h | 93 +++++++++++++++++++++++++ arch/arm/include/asm/arch-npcm8xx/rng.h | 43 ++++++++++++ arch/arm/include/asm/arch-npcm8xx/sha.h | 34 +++++++++ 4 files changed, 223 insertions(+) create mode 100644 arch/arm/include/asm/arch-npcm8xx/aes.h create mode 100644 arch/arm/include/asm/arch-npcm8xx/otp.h create mode 100644 arch/arm/include/asm/arch-npcm8xx/rng.h create mode 100644 arch/arm/include/asm/arch-npcm8xx/sha.h diff --git a/arch/arm/include/asm/arch-npcm8xx/aes.h b/arch/arm/include/asm/arch-npcm8xx/aes.h new file mode 100644 index 00000000000..255efcb5ce0 --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/aes.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _NPCM_AES_H_ +#define _NPCM_AES_H_ + +#define AES_OP_ENCRYPT 0 +#define AES_OP_DECRYPT 1 +#define SIZE_AES_BLOCK (AES128_KEY_LENGTH) + +struct npcm_aes_regs { + unsigned char reserved_0[0x400]; // 0x000 + unsigned int aes_key_0; // 0x400 + unsigned int aes_key_1; // 0x404 + unsigned int aes_key_2; // 0x408 + unsigned int aes_key_3; // 0x40c + unsigned char reserved_1[0x30]; // 0x410 + unsigned int aes_iv_0; // 0x440 + unsigned char reserved_2[0x1c]; // 0x444 + unsigned int aes_ctr_0; // 0x460 + unsigned char reserved_3[0x0c]; // 0x464 + unsigned int aes_busy; // 0x470 + unsigned char reserved_4[0x04]; // 0x474 + unsigned int aes_sk; // 0x478 + unsigned char reserved_5[0x14]; // 0x47c + unsigned int aes_prev_iv_0; // 0x490 + unsigned char reserved_6[0x0c]; // 0x494 + unsigned int aes_din_dout; // 0x4a0 + unsigned char reserved_7[0x1c]; // 0x4a4 + unsigned int aes_control; // 0x4c0 + unsigned int aes_version; // 0x4c4 + unsigned int aes_hw_flags; // 0x4c8 + unsigned char reserved_8[0x28]; // 0x4cc + unsigned int aes_sw_reset; // 0x4f4 + unsigned char reserved_9[0x08]; // 0x4f8 + unsigned int aes_fifo_data; // 0x500 + unsigned char reserved_10[0xfc]; // 0x504 + unsigned int aes_fifo_status; // 0x600 +}; + +#define AES_BUSY_BIT BIT(0) +#define SW_RESET_BIT BIT(0) +#define AES_SK_BIT BIT(0) + +#define DIN_FIFO_FULL BIT(0) +#define DIN_FIFO_EMPTY BIT(1) +#define DOUT_FIFO_FULL BIT(2) +#define DOUT_FIFO_EMPTY BIT(3) +#define DIN_FIFO_OVERFLOW BIT(4) +#define DOUT_FIFO_UNDERFLOW BIT(5) + +int npcm_aes_select_key(u8 fkeyind); + +#endif diff --git a/arch/arm/include/asm/arch-npcm8xx/otp.h b/arch/arm/include/asm/arch-npcm8xx/otp.h new file mode 100644 index 00000000000..c8d50fb0ad8 --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/otp.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _NPCM_OTP_H_ +#define _NPCM_OTP_H_ + +#ifdef CONFIG_ARCH_NPCM8XX +enum { + NPCM_KEY_SA = 0, + NPCM_FUSE_SA = 0, + NPCM_NUM_OF_SA = 1 +}; +#else +enum { + NPCM_KEY_SA = 0, + NPCM_FUSE_SA = 1, + NPCM_NUM_OF_SA = 2 +}; +#endif + +/* arrray images in flash, to program during fisrt boot (offsets in sector) */ +#define SA_KEYS_FLASH_IMAGE_OFFSET (0x000) +#define SA_FUSE_FLASH_IMAGE_OFFSET (0x400) +#define SA_TAG_FLASH_IMAGE_OFFSET (0x800) +/* F U S E I M G S */ +#define SA_TAG_FLASH_IMAGE_VAL {0x46, 0x55, 0x53, 0x45, 0x49, 0x4d, 0x47, 0x53} +#define SA_TAG_FLASH_IMAGE_SIZE (8) + +#define SA_FUSE_FUSTRAP_OFFSET (0x00) +#define SA_FUSE_FUSTRAP_OSECBOOT_MASK (0x00800000) + +struct npcm_otp_regs { + unsigned int fst; + unsigned int faddr; + unsigned int fdata; + unsigned int fcfg; + unsigned int fustrap_fkeyind; + unsigned int fctl; +}; + +#define FST_RDY BIT(0) +#define FST_RDST BIT(1) +#define FST_RIEN BIT(2) + +#ifdef CONFIG_ARCH_NPCM8XX +#define FADDR_BYTEADDR(addr) ((addr) << 3) +#define FADDR_BITPOS(pos) ((pos) << 0) +#define FADDR_VAL(addr, pos) (FADDR_BITPOS(pos) | FADDR_BYTEADDR(addr)) +#define FADDR_IN_PROG BIT(16) +#else +#define FADDR_BYTEADDR(addr) ((addr) << 0) +#define FADDR_BITPOS(pos) ((pos) << 10) +#define FADDR_VAL(addr, pos) (FADDR_BYTEADDR(addr) | FADDR_BITPOS(pos)) +#endif + +#define FDATA_MASK (0xff) + +#define FUSTRAP_O_SECBOOT BIT(23) +#define FCFG_FDIS BIT(31) +#define FKEYIND_KVAL BIT(0) +#define FKEYIND_KSIZE_MASK (0x00000070) +#define FKEYIND_KSIZE_128 (0x4 << 4) +#define FKEYIND_KSIZE_192 (0x5 << 4) +#define FKEYIND_KSIZE_256 (0x6 << 4) +#define FKEYIND_KIND_MASK (0x000c0000) +#define FKEYIND_KIND_KEY(indx) ((indx) << 18) + +/* Program cycle initiation values (sequence of two adjacent writes) */ +#define PROGRAM_ARM 0x1 +#define PROGRAM_INIT 0xBF79E5D0 + +/* Read cycle initiation value */ +#define READ_INIT 0x02 + +/* Value to clean FDATA contents */ +#define FDATA_CLEAN_VALUE 0x01 + +#ifdef CONFIG_ARCH_NPCM8XX +#define NPCM_OTP_ARR_BYTE_SIZE 8192 +#else +#define NPCM_OTP_ARR_BYTE_SIZE 1024 +#endif + +#define MIN_PROGRAM_PULSES 4 +#define MAX_PROGRAM_PULSES 20 + +int fuse_prog_image(u32 bank, uintptr_t address); +int fuse_program_data(u32 bank, u32 word, u8 *data, u32 size); +int npcm_otp_select_key(u8 key_index); +bool npcm_otp_is_fuse_array_disabled(u32 arr); +void npcm_otp_nibble_parity_ecc_encode(u8 *datain, u8 *dataout, u32 size); +void npcm_otp_majority_rule_ecc_encode(u8 *datain, u8 *dataout, u32 size); + +#endif diff --git a/arch/arm/include/asm/arch-npcm8xx/rng.h b/arch/arm/include/asm/arch-npcm8xx/rng.h new file mode 100644 index 00000000000..897e8fea82a --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/rng.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _NPCM_RNG_H_ +#define _NPCM_RNG_H_ + +struct npcm_rng_regs { + unsigned int rngcs; + unsigned int rngd; + unsigned int rngmode; +}; + +#define RNGCS_RNGE (1 << 0) +#define RNGCS_DVALID (1 << 1) +#define RNGCS_CLKP(range) ((0x0f & (range)) << 2) +#define RNGMODE_M1ROSEL_VAL (0x02) /* Ring Oscillator Select for Method I */ + +/*----------------------------------------------------------------------------*/ +/* Core Domain Clock Frequency Range for the selected value is higher */ +/* than or equal to the actual Core domain clock frequency */ +/*----------------------------------------------------------------------------*/ +enum { + RNG_CLKP_80_100_MHZ = 0x00, /*default */ + RNG_CLKP_60_80_MHZ = 0x01, + RNG_CLKP_50_60_MHZ = 0x02, + RNG_CLKP_40_50_MHZ = 0x03, + RNG_CLKP_30_40_MHZ = 0x04, + RNG_CLKP_25_30_MHZ = 0x05, + RNG_CLKP_20_25_MHZ = 0x06, + RNG_CLKP_5_20_MHZ = 0x07, + RNG_CLKP_2_15_MHZ = 0x08, + RNG_CLKP_9_12_MHZ = 0x09, + RNG_CLKP_7_9_MHZ = 0x0A, + RNG_CLKP_6_7_MHZ = 0x0B, + RNG_CLKP_5_6_MHZ = 0x0C, + RNG_CLKP_4_5_MHZ = 0x0D, + RNG_CLKP_3_4_MHZ = 0x0E, + RNG_NUM_OF_CLKP +}; + +void npcm_rng_init(void); +void npcm_rng_disable(void); + +#endif diff --git a/arch/arm/include/asm/arch-npcm8xx/sha.h b/arch/arm/include/asm/arch-npcm8xx/sha.h new file mode 100644 index 00000000000..ec0ec9ce1f9 --- /dev/null +++ b/arch/arm/include/asm/arch-npcm8xx/sha.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _NPCM_SHA_H_ +#define _NPCM_SHA_H_ + +#define HASH_DIG_H_NUM 8 + +/* SHA type */ +enum npcm_sha_type { + npcm_sha_type_sha2 = 0, + npcm_sha_type_sha1, + npcm_sha_type_num +}; + +struct npcm_sha_regs { + unsigned int hash_data_in; + unsigned char hash_ctr_sts; + unsigned char reserved_0[0x03]; + unsigned char hash_cfg; + unsigned char reserved_1[0x03]; + unsigned char hash_ver; + unsigned char reserved_2[0x13]; + unsigned int hash_dig[HASH_DIG_H_NUM]; +}; + +#define HASH_CTR_STS_SHA_EN BIT(0) +#define HASH_CTR_STS_SHA_BUSY BIT(1) +#define HASH_CTR_STS_SHA_RST BIT(2) +#define HASH_CFG_SHA1_SHA2 BIT(0) + +int npcm_sha_calc(u8 type, const u8 *buf, u32 len, u8 *digest); +int npcm_sha_selftest(u8 type); + +#endif From 72b8c6d1ebfd40a6ee6be0345ff7abb30c9f9e3d Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 18 Jan 2023 13:12:22 +0100 Subject: [PATCH 04/22] pinctrl: don't fall back to pinctrl_select_state_simple() If CONFIG_PINCTRL_FULL is enabled, never fall back to the simple implementation. pinctrl_select_state() is called for each device and it is expected to fail. A fallback to the simple imeplementation doesn't make much sense. To keep the return code consistent, we need to change the -EINVAL (which was ignored before) to -ENOSYS. Signed-off-by: Michael Walle Reviewed-by: Marek Vasut Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-uclass.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index a1b85ca87e5..6978a93ef87 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -71,13 +71,13 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename) */ state = dectoul(statename, &end); if (*end) - return -EINVAL; + return -ENOSYS; } snprintf(propname, sizeof(propname), "pinctrl-%d", state); list = dev_read_prop(dev, propname, &size); if (!list) - return -EINVAL; + return -ENOSYS; size /= sizeof(*list); for (i = 0; i < size; i++) { @@ -162,11 +162,6 @@ U_BOOT_DRIVER(pinconfig_generic) = { }; #else -static int pinctrl_select_state_full(struct udevice *dev, const char *statename) -{ - return -ENODEV; -} - static int pinconfig_post_bind(struct udevice *dev) { return 0; @@ -317,10 +312,10 @@ int pinctrl_select_state(struct udevice *dev, const char *statename) * Try full-implemented pinctrl first. * If it fails or is not implemented, try simple one. */ - if (pinctrl_select_state_full(dev, statename)) - return pinctrl_select_state_simple(dev); + if (CONFIG_IS_ENABLED(PINCTRL_FULL)) + return pinctrl_select_state_full(dev, statename); - return 0; + return pinctrl_select_state_simple(dev); } int pinctrl_request(struct udevice *dev, int func, int flags) From 75013fa7240bb11ddca6d93dd96295daf3b769c1 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 18 Jan 2023 13:12:23 +0100 Subject: [PATCH 05/22] pinctrl: get rid of some ifdeffery Don't define an empty version for pinconfig_post_bind(). Just guard the call and let the linker garbage collection do the rest. This way, we also don't have to do any guesswork. Signed-off-by: Michael Walle Reviewed-by: Marek Vasut --- drivers/pinctrl/pinctrl-uclass.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index 6978a93ef87..4615b5c5dee 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -20,7 +20,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if CONFIG_IS_ENABLED(PINCTRL_FULL) /** * pinctrl_config_one() - apply pinctrl settings for a single node * @@ -148,6 +147,7 @@ static int pinconfig_post_bind(struct udevice *dev) return 0; } +#if CONFIG_IS_ENABLED(PINCTRL_FULL) UCLASS_DRIVER(pinconfig) = { .id = UCLASS_PINCONFIG, #if CONFIG_IS_ENABLED(PINCONF_RECURSIVE) @@ -160,12 +160,6 @@ U_BOOT_DRIVER(pinconfig_generic) = { .name = "pinconfig", .id = UCLASS_PINCONFIG, }; - -#else -static int pinconfig_post_bind(struct udevice *dev) -{ - return 0; -} #endif static int @@ -404,12 +398,11 @@ static int __maybe_unused pinctrl_post_bind(struct udevice *dev) } /* - * If set_state callback is set, we assume this pinctrl driver is the - * full implementation. In this case, its child nodes should be bound - * so that peripheral devices can easily search in parent devices - * during later DT-parsing. + * If the pinctrl driver has the full implementation, its child nodes + * should be bound so that peripheral devices can easily search in + * parent devices during later DT-parsing. */ - if (ops->set_state) + if (CONFIG_IS_ENABLED(PINCTRL_FULL)) return pinconfig_post_bind(dev); return 0; From e71505fc983ca1734d1033095cee23b66e2f06e8 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 18 Jan 2023 13:12:24 +0100 Subject: [PATCH 06/22] pinctrl: fix docstring Fix the copy and paste error. Signed-off-by: Michael Walle Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index 4615b5c5dee..8837726cc16 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -382,7 +382,7 @@ int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf, } /** - * pinconfig_post_bind() - post binding for PINCTRL uclass + * pinctrl_post_bind() - post binding for PINCTRL uclass * Recursively bind child nodes as pinconfig devices in case of full pinctrl. * * @dev: pinctrl device From a092f1e9064881a358fdf08cb1cee753cd680edf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 18 Jan 2023 13:13:17 -0700 Subject: [PATCH 07/22] ifwitool: Fix member access On a second and third look, a recent patch seems to be writing to the wrong place - updating offsets from the address of the pointer instead of what the pointer points to. Fix it. Signed-off-by: Simon Glass Fixes: 2d1b2ac13fe ("tool: ifwitool: Fix buffer overflow") Acked-by: Sean Anderson --- tools/ifwitool.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tools/ifwitool.c b/tools/ifwitool.c index 31591863b2e..c1defe57737 100644 --- a/tools/ifwitool.c +++ b/tools/ifwitool.c @@ -721,7 +721,7 @@ static size_t read_member(void *src, size_t offset, size_t size_bytes, */ static size_t fix_member(void *data, size_t offset, size_t size_bytes) { - uint8_t *src = (uint8_t *)data + offset; + void *src = (uint8_t *)data + offset; switch (size_bytes) { case 1: @@ -1441,20 +1441,20 @@ static void bpdt_fixup_write_buffer(struct buffer *buf) size_t offset = 0; - offset = fix_member(&s, offset, sizeof(h->signature)); - offset = fix_member(&s, offset, sizeof(h->descriptor_count)); - offset = fix_member(&s, offset, sizeof(h->bpdt_version)); - offset = fix_member(&s, offset, sizeof(h->xor_redundant_block)); - offset = fix_member(&s, offset, sizeof(h->ifwi_version)); - offset = fix_member(&s, offset, sizeof(h->fit_tool_version)); + offset = fix_member(s, offset, sizeof(h->signature)); + offset = fix_member(s, offset, sizeof(h->descriptor_count)); + offset = fix_member(s, offset, sizeof(h->bpdt_version)); + offset = fix_member(s, offset, sizeof(h->xor_redundant_block)); + offset = fix_member(s, offset, sizeof(h->ifwi_version)); + offset = fix_member(s, offset, sizeof(h->fit_tool_version)); uint32_t i; for (i = 0; i < count; i++) { - offset = fix_member(&s, offset, sizeof(e[i].type)); - offset = fix_member(&s, offset, sizeof(e[i].flags)); - offset = fix_member(&s, offset, sizeof(e[i].offset)); - offset = fix_member(&s, offset, sizeof(e[i].size)); + offset = fix_member(s, offset, sizeof(e[i].type)); + offset = fix_member(s, offset, sizeof(e[i].flags)); + offset = fix_member(s, offset, sizeof(e[i].offset)); + offset = fix_member(s, offset, sizeof(e[i].size)); } } @@ -1654,21 +1654,21 @@ static void subpart_dir_fixup_write_buffer(struct buffer *buf) size_t count = h->num_entries; size_t offset = 0; - offset = fix_member(&s, offset, sizeof(h->marker)); - offset = fix_member(&s, offset, sizeof(h->num_entries)); - offset = fix_member(&s, offset, sizeof(h->header_version)); - offset = fix_member(&s, offset, sizeof(h->entry_version)); - offset = fix_member(&s, offset, sizeof(h->header_length)); - offset = fix_member(&s, offset, sizeof(h->checksum)); + offset = fix_member(s, offset, sizeof(h->marker)); + offset = fix_member(s, offset, sizeof(h->num_entries)); + offset = fix_member(s, offset, sizeof(h->header_version)); + offset = fix_member(s, offset, sizeof(h->entry_version)); + offset = fix_member(s, offset, sizeof(h->header_length)); + offset = fix_member(s, offset, sizeof(h->checksum)); offset += sizeof(h->name); uint32_t i; for (i = 0; i < count; i++) { offset += sizeof(e[i].name); - offset = fix_member(&s, offset, sizeof(e[i].offset)); - offset = fix_member(&s, offset, sizeof(e[i].length)); - offset = fix_member(&s, offset, sizeof(e[i].rsvd)); + offset = fix_member(s, offset, sizeof(e[i].offset)); + offset = fix_member(s, offset, sizeof(e[i].length)); + offset = fix_member(s, offset, sizeof(e[i].rsvd)); } } From 69c82fa2ea39b767f179305164198ec913c4af0f Mon Sep 17 00:00:00 2001 From: John Keeping Date: Thu, 19 Jan 2023 12:55:19 +0000 Subject: [PATCH 08/22] MAINTAINERS: add include/power/ to POWER Add the related include files to the power MAINTAINERS entry. Signed-off-by: John Keeping Reviewed-by: Simon Glass --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8dcce886b87..eb6289d6a9d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1245,6 +1245,7 @@ M: Jaehoon Chung S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-pmic.git F: drivers/power/ +F: include/power/ POWERPC M: Wolfgang Denk From ab977c8b91b4a22d5afa9dfa34af7ce8c143c83e Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:47 +0530 Subject: [PATCH 09/22] configs: j721s2_evm_r5: Enable support for building multiple dtbs into FIT Enable configs for building multiple dtbs into a single fit image and load the right dtb for next stage. This will help to use same defconfig for both EVM and SK. Signed-off-by: Sinthu Raja --- configs/j721s2_evm_r5_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig index cd250169980..7cdded66e4c 100644 --- a/configs/j721s2_evm_r5_defconfig +++ b/configs/j721s2_evm_r5_defconfig @@ -84,6 +84,9 @@ CONFIG_CMD_TIME=y CONFIG_CMD_FAT=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_OF_LIST="k3-j721s2-r5-common-proc-board k3-am68-sk-r5-base-board" +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y From 7b6e7270c06ba0a8e06c595e120308464e343907 Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:48 +0530 Subject: [PATCH 10/22] configs: j721s2_evm_a72: Enable support for building multiple dtbs into FIT Enable configs for building multiple dtbs into a single fit image and load the right dtb for next stage. Add k3-am68-sk-base-board dtb along with evm dtb inside DTB FIT image. This helps to use same defconfig for both EVM and SK Signed-off-by: Sinthu Raja --- configs/j721s2_evm_a72_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig index 99a0eee12d9..9c40730d212 100644 --- a/configs/j721s2_evm_a72_defconfig +++ b/configs/j721s2_evm_a72_defconfig @@ -89,6 +89,7 @@ CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_OF_LIST="k3-j721s2-common-proc-board k3-am68-sk-base-board" CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_MMC=y From 76361af76cf2addf903fe8a0ab139134b0cddfc2 Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:49 +0530 Subject: [PATCH 11/22] configs: j721s2_evm: Enable configs to store env in MMC FAT partition J721S2 EVM used to store env on eMMC, since EVM and SK uses same defconfig and there is no eMMC on SK, we need to keep env in an interface which available on both EVM and SK. So, save env in FAT partition of MMC SD Card. Enable defconfigs relevant for storing env on FAT partition of MMC. Signed-off-by: Sinthu Raja --- configs/j721s2_evm_a72_defconfig | 3 ++- configs/j721s2_evm_r5_defconfig | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig index 9c40730d212..84b4fb08319 100644 --- a/configs/j721s2_evm_a72_defconfig +++ b/configs/j721s2_evm_a72_defconfig @@ -92,7 +92,8 @@ CONFIG_SPL_MULTI_DTB_FIT=y CONFIG_OF_LIST="k3-j721s2-common-proc-board k3-am68-sk-base-board" CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_ENV_OVERWRITE=y -CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_IS_IN_FAT=y +CONFIG_ENV_FAT_DEVICE_AND_PART="1:1" CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig index 7cdded66e4c..1f2102a9f91 100644 --- a/configs/j721s2_evm_r5_defconfig +++ b/configs/j721s2_evm_r5_defconfig @@ -88,6 +88,7 @@ CONFIG_SPL_MULTI_DTB_FIT=y CONFIG_SPL_OF_LIST="k3-j721s2-r5-common-proc-board k3-am68-sk-r5-base-board" CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_ENV_OVERWRITE=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y From 24bbe09a91a1594a58cb059696b4e4e591945506 Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:50 +0530 Subject: [PATCH 12/22] board: ti: j721s2: Add support to update board_name for am68-sk Update setup_board_eeprom_env() to choose the right board name for am68-sk. Signed-off-by: Sinthu Raja Reviewed-by: Tom Rini --- board/ti/j721s2/evm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c index 4d28582311b..063fc8c688c 100644 --- a/board/ti/j721s2/evm.c +++ b/board/ti/j721s2/evm.c @@ -26,8 +26,6 @@ #include "../common/board_detect.h" -#define board_is_j721s2_som() board_ti_k3_is("J721S2X-PM1-SOM") - DECLARE_GLOBAL_DATA_PTR; int board_init(void) @@ -101,6 +99,14 @@ int ft_board_setup(void *blob, struct bd_info *bd) #endif #ifdef CONFIG_TI_I2C_BOARD_DETECT +/* + * Functions specific to EVM and SK designs of J721S2/AM68 family. + */ + +#define board_is_j721s2_som() board_ti_k3_is("J721S2X-PM1-SOM") + +#define board_is_am68_sk_som() board_ti_k3_is("AM68-SK-SOM") + int do_board_detect(void) { int ret; @@ -136,6 +142,8 @@ static void setup_board_eeprom_env(void) if (board_is_j721s2_som()) name = "j721s2"; + else if (board_is_am68_sk_som()) + name = "am68-sk"; else printf("Unidentified board claims %s in eeprom header\n", board_ti_get_name()); From ad45a17578a6fa4f8cbd77dec9cea0c55fef7a89 Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:51 +0530 Subject: [PATCH 13/22] board: ti: j721s2: Enable support for reading EEPROM at next alternate address J721S2 EVM has EEPROM populated at 0x50. AM68 SK has EEPROM populated at next address 0x51 in order to be compatible with RPi. So start looking for TI specific EEPROM at 0x50, if not found look for EEPROM at 0x51. Signed-off-by: Sinthu Raja Reviewed-by: Tom Rini --- board/ti/j721s2/evm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c index 063fc8c688c..db69aa15073 100644 --- a/board/ti/j721s2/evm.c +++ b/board/ti/j721s2/evm.c @@ -113,9 +113,15 @@ int do_board_detect(void) ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS, CONFIG_EEPROM_CHIP_ADDRESS); - if (ret) - pr_err("Reading on-board EEPROM at 0x%02x failed %d\n", - CONFIG_EEPROM_CHIP_ADDRESS, ret); + if (ret) { + printf("EEPROM not available at 0x%02x, trying to read at 0x%02x\n", + CONFIG_EEPROM_CHIP_ADDRESS, CONFIG_EEPROM_CHIP_ADDRESS + 1); + ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS, + CONFIG_EEPROM_CHIP_ADDRESS + 1); + if (ret) + pr_err("Reading on-board EEPROM at 0x%02x failed %d\n", + CONFIG_EEPROM_CHIP_ADDRESS + 1, ret); + } return ret; } From 1aaf9df19776b3ba0d9f18f1d292f7fb979b64e1 Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:52 +0530 Subject: [PATCH 14/22] board: ti: j721s2: Add support for detecting multiple device trees Update the board_fit_config_name_match() to choose the right dtb based on the board name read from EEPROM. Also restrict multpile EEPROM reads by verifying if EEPROM is already read Signed-off-by: Sinthu Raja Reviewed-by: Tom Rini --- board/ti/j721s2/evm.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c index db69aa15073..9b159e3d5c6 100644 --- a/board/ti/j721s2/evm.c +++ b/board/ti/j721s2/evm.c @@ -72,16 +72,6 @@ int dram_init_banksize(void) return 0; } -#ifdef CONFIG_SPL_LOAD_FIT -int board_fit_config_name_match(const char *name) -{ - if (!strcmp(name, "k3-j721s2-common-proc-board")) - return 0; - - return -1; -} -#endif - #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) int ft_board_setup(void *blob, struct bd_info *bd) { @@ -111,6 +101,9 @@ int do_board_detect(void) { int ret; + if (board_ti_was_eeprom_read()) + return 0; + ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS, CONFIG_EEPROM_CHIP_ADDRESS); if (ret) { @@ -179,6 +172,28 @@ static void setup_serial(void) } #endif +/* + * This function chooses the right dtb based on the board name read from + * EEPROM if the EEPROM is programmed. Also, by default the boot chooses + * the EVM DTB if there is no EEPROM is programmed or not detected. + */ +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + bool eeprom_read = board_ti_was_eeprom_read(); + + if (!eeprom_read || board_is_j721s2_som()) { + if (!strcmp(name, "k3-j721s2-common-proc-board")) + return 0; + } else if (!eeprom_read || board_is_am68_sk_som()) { + if (!strcmp(name, "k3-am68-sk-base-board")) + return 0; + } + + return -1; +} +#endif + int board_late_init(void) { if (IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) { From fca27ee8b993bd1a5752fc2156b1e86358fa8041 Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:53 +0530 Subject: [PATCH 15/22] arch: mach-k3: Update board specific API name to K3 generic API name Although the board_init_f API initialises the SoC, the API name is incorrectly specified and misleads the functionality. This file should only include k3-specific functionality. Change the API's name to something more K3-specific and separate the function to make it more modular. Signed-off-by: Sinthu Raja Reviewed-by: Tom Rini --- arch/arm/mach-k3/include/mach/sys_proto.h | 3 +++ arch/arm/mach-k3/j721s2_init.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-k3/include/mach/sys_proto.h b/arch/arm/mach-k3/include/mach/sys_proto.h index 60287b261c8..3d3d90d02d6 100644 --- a/arch/arm/mach-k3/include/mach/sys_proto.h +++ b/arch/arm/mach-k3/include/mach/sys_proto.h @@ -19,4 +19,7 @@ int fdt_disable_node(void *blob, char *node_path); bool soc_is_j721e(void); bool soc_is_j7200(void); +void k3_spl_init(void); +void k3_mem_init(void); +bool check_rom_loaded_sysfw(void); #endif diff --git a/arch/arm/mach-k3/j721s2_init.c b/arch/arm/mach-k3/j721s2_init.c index 0206b01d9e3..09e55ed4566 100644 --- a/arch/arm/mach-k3/j721s2_init.c +++ b/arch/arm/mach-k3/j721s2_init.c @@ -93,7 +93,7 @@ static void store_boot_info_from_rom(void) sizeof(struct rom_extended_boot_data)); } -void board_init_f(ulong dummy) +void k3_spl_init(void) { struct udevice *dev; int ret; @@ -154,6 +154,17 @@ void board_init_f(ulong dummy) /* Output System Firmware version info */ k3_sysfw_print_ver(); +} + +bool check_rom_loaded_sysfw(void) +{ + return is_rom_loaded_sysfw(&bootdata); +} + +void k3_mem_init(void) +{ + struct udevice *dev; + int ret; if (IS_ENABLED(CONFIG_TARGET_J721S2_R5_EVM)) { ret = uclass_get_device_by_name(UCLASS_MISC, "msmc", &dev); From 554f8e84b63e90f92d59a91820c81ff0635340dd Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:54 +0530 Subject: [PATCH 16/22] board: ti: j721s2: Add board_init and support for selecting DT based on EEPROM Add the board_init_f API for SPL and run the platform-required SoC initialization. Add the functionality for board name-based DTB selection from FIT within SPL. This will make it easier to utilise one defconfig for both the EVM and the SK. Signed-off-by: Sinthu Raja Reviewed-by: Tom Rini --- board/ti/j721s2/evm.c | 64 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c index 9b159e3d5c6..c86715fa211 100644 --- a/board/ti/j721s2/evm.c +++ b/board/ti/j721s2/evm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "../common/board_detect.h" @@ -207,3 +208,66 @@ int board_late_init(void) void spl_board_init(void) { } + +/* Support for the various EVM / SK families */ +#if defined(CONFIG_SPL_OF_LIST) && defined(CONFIG_TI_I2C_BOARD_DETECT) +void do_dt_magic(void) +{ + int ret, rescan, mmc_dev = -1; + static struct mmc *mmc; + + do_board_detect(); + + /* + * Board detection has been done. + * Let us see if another dtb wouldn't be a better match + * for our board + */ + if (IS_ENABLED(CONFIG_CPU_V7R)) { + ret = fdtdec_resetup(&rescan); + if (!ret && rescan) { + dm_uninit(); + dm_init_and_scan(true); + } + } + + /* + * Because of multi DTB configuration, the MMC device has + * to be re-initialized after reconfiguring FDT inorder to + * boot from MMC. Do this when boot mode is MMC and ROM has + * not loaded SYSFW. + */ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + mmc_dev = 0; + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + mmc_dev = 1; + break; + } + + if (mmc_dev > 0 && !check_rom_loaded_sysfw()) { + ret = mmc_init_device(mmc_dev); + if (!ret) { + mmc = find_mmc_device(mmc_dev); + if (mmc) { + ret = mmc_init(mmc); + if (ret) + printf("mmc init failed with error: %d\n", ret); + } + } + } +} +#endif + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong dummy) +{ + k3_spl_init(); +#if defined(CONFIG_SPL_OF_LIST) && defined(CONFIG_TI_I2C_BOARD_DETECT) + do_dt_magic(); +#endif + k3_mem_init(); +} +#endif From 3499deaf284e030a42b15c9b34d3f02ebbfee1ec Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:55 +0530 Subject: [PATCH 17/22] arm: dts: Add initial support for AM68 Starter Kit System on Module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AM68 Starter Kit (SK) is a low cost, small form factor board designed for TI’s AM68 SoC. TI’s AM68 SoC comprises of dual core A72, high performance vision accelerators, hardware accelerators, latest C71x DSP, high bandwidth real-time IPs for capture and display. The SoC is power optimized to provide best in class performance for industrial applications. AM68 SK supports the following interfaces: * 16 GB LPDDR4 RAM * x1 Gigabit Ethernet interface * x1 USB 3.1 Type-C port * x2 USB 3.1 Type-A ports * x1 PCIe M.2 M Key * 512 Mbit OSPI flash * x2 CSI2 Camera interface (RPi and TI Camera connector) * 40-pin Raspberry Pi GPIO header SK's System on Module (SoM) contains the SoC, PMIC, DDR and OSPI flash. Therefore, add support for the components present on the SoM. Schematics: https://www.ti.com/lit/zip/SPRR463 TRM: http://www.ti.com/lit/pdf/spruj28 Signed-off-by: Sinthu Raja --- arch/arm/dts/k3-am68-sk-som.dtsi | 127 +++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 arch/arm/dts/k3-am68-sk-som.dtsi diff --git a/arch/arm/dts/k3-am68-sk-som.dtsi b/arch/arm/dts/k3-am68-sk-som.dtsi new file mode 100644 index 00000000000..cb1c58fcd15 --- /dev/null +++ b/arch/arm/dts/k3-am68-sk-som.dtsi @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ + */ + +/dts-v1/; + +#include "k3-j721s2.dtsi" +#include + +/ { + memory@80000000 { + device_type = "memory"; + /* 16 GB RAM */ + reg = <0x00 0x80000000 0x00 0x80000000>, + <0x08 0x80000000 0x03 0x80000000>; + }; + + /* Reserving memory regions still pending */ + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + secure_ddr: optee@9e800000 { + reg = <0x00 0x9e800000 0x00 0x01800000>; + alignment = <0x1000>; + no-map; + }; + }; +}; + +&mailbox0_cluster0 { + status = "disabled"; +}; + +&mailbox0_cluster1 { + status = "disabled"; +}; + +&mailbox0_cluster2 { + status = "disabled"; +}; + +&mailbox0_cluster3 { + status = "disabled"; +}; + +&mailbox0_cluster4 { + status = "disabled"; +}; + +&mailbox0_cluster5 { + status = "disabled"; +}; + +&mailbox0_cluster6 { + status = "disabled"; +}; + +&mailbox0_cluster7 { + status = "disabled"; +}; + +&mailbox0_cluster8 { + status = "disabled"; +}; + +&mailbox0_cluster9 { + status = "disabled"; +}; + +&mailbox0_cluster10 { + status = "disabled"; +}; + +&mailbox0_cluster11 { + status = "disabled"; +}; + +&mailbox1_cluster0 { + status = "disabled"; +}; + +&mailbox1_cluster1 { + status = "disabled"; +}; + +&mailbox1_cluster2 { + status = "disabled"; +}; + +&mailbox1_cluster3 { + status = "disabled"; +}; + +&mailbox1_cluster4 { + status = "disabled"; +}; + +&mailbox1_cluster5 { + status = "disabled"; +}; + +&mailbox1_cluster6 { + status = "disabled"; +}; + +&mailbox1_cluster7 { + status = "disabled"; +}; + +&mailbox1_cluster8 { + status = "disabled"; +}; + +&mailbox1_cluster9 { + status = "disabled"; +}; + +&mailbox1_cluster10 { + status = "disabled"; +}; + +&mailbox1_cluster11 { + status = "disabled"; +}; From cc07b6c346ad02af96b550f72c95f36f8ff3656f Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:56 +0530 Subject: [PATCH 18/22] arm: dts: Add support for A72 specific AM68 Starter Kit Base Board The SK architecture comprises of baseboard and a SOM board. The AM68 Starter Kit's baseboard contains most of the actual connectors, power supply etc. The System on Module (SoM) is plugged on to the base board. Therefore, add support for peripherals brought out in the base board. Schematics: https://www.ti.com/lit/zip/SPRR463 Signed-off-by: Sinthu Raja --- arch/arm/dts/Makefile | 3 +- .../arm/dts/k3-am68-sk-base-board-u-boot.dtsi | 150 ++++++++ arch/arm/dts/k3-am68-sk-base-board.dts | 353 ++++++++++++++++++ 3 files changed, 505 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi create mode 100644 arch/arm/dts/k3-am68-sk-base-board.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 8e83194249d..d3970767603 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1254,7 +1254,8 @@ dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \ k3-j7200-r5-common-proc-board.dtb \ k3-j721e-sk.dtb \ k3-j721e-r5-sk.dtb -dtb-$(CONFIG_SOC_K3_J721S2) += k3-j721s2-common-proc-board.dtb\ +dtb-$(CONFIG_SOC_K3_J721S2) += k3-am68-sk-base-board.dtb\ + k3-j721s2-common-proc-board.dtb\ k3-j721s2-r5-common-proc-board.dtb dtb-$(CONFIG_SOC_K3_AM642) += k3-am642-evm.dtb \ k3-am642-r5-evm.dtb \ diff --git a/arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi b/arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi new file mode 100644 index 00000000000..12faaae59b1 --- /dev/null +++ b/arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ + */ + +/ { + chosen { + stdout-path = "serial2:115200n8"; + tick-timer = &timer1; + }; + + aliases { + serial0 = &wkup_uart0; + serial1 = &mcu_uart0; + serial2 = &main_uart8; + i2c0 = &wkup_i2c0; + i2c1 = &mcu_i2c0; + i2c2 = &mcu_i2c1; + i2c3 = &main_i2c0; + ethernet0 = &cpsw_port1; + mmc1 = &main_sdhci1; + }; +}; + +&wkup_i2c0 { + u-boot,dm-spl; +}; + +&cbass_main { + u-boot,dm-spl; +}; + +&main_navss { + u-boot,dm-spl; +}; + +&cbass_mcu_wakeup { + u-boot,dm-spl; + + timer1: timer@40400000 { + compatible = "ti,omap5430-timer"; + reg = <0x0 0x40400000 0x0 0x80>; + ti,timer-alwon; + clock-frequency = <250000000>; + u-boot,dm-spl; + }; + + chipid@43000014 { + u-boot,dm-spl; + }; +}; + +&mcu_navss { + u-boot,dm-spl; +}; + +&mcu_ringacc { + reg = <0x0 0x2b800000 0x0 0x400000>, + <0x0 0x2b000000 0x0 0x400000>, + <0x0 0x28590000 0x0 0x100>, + <0x0 0x2a500000 0x0 0x40000>, + <0x0 0x28440000 0x0 0x40000>; + reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target", "cfg"; + u-boot,dm-spl; +}; + +&mcu_udmap { + reg = <0x0 0x285c0000 0x0 0x100>, + <0x0 0x284c0000 0x0 0x4000>, + <0x0 0x2a800000 0x0 0x40000>, + <0x0 0x284a0000 0x0 0x4000>, + <0x0 0x2aa00000 0x0 0x40000>, + <0x0 0x28400000 0x0 0x2000>; + reg-names = "gcfg", "rchan", "rchanrt", "tchan", + "tchanrt", "rflow"; + u-boot,dm-spl; +}; + +&secure_proxy_main { + u-boot,dm-spl; +}; + +&sms { + u-boot,dm-spl; + k3_sysreset: sysreset-controller { + compatible = "ti,sci-sysreset"; + u-boot,dm-spl; + }; +}; + +&main_pmx0 { + u-boot,dm-spl; +}; + +&main_uart8_pins_default { + u-boot,dm-spl; +}; + +&main_mmc1_pins_default { + u-boot,dm-spl; +}; + +&wkup_pmx0 { + u-boot,dm-spl; +}; + +&k3_pds { + u-boot,dm-spl; +}; + +&k3_clks { + u-boot,dm-spl; +}; + +&k3_reset { + u-boot,dm-spl; +}; + +&main_uart8 { + u-boot,dm-spl; +}; + +&mcu_uart0 { + u-boot,dm-spl; +}; + +&wkup_uart0 { + u-boot,dm-spl; +}; + +&mcu_cpsw { + reg = <0x0 0x46000000 0x0 0x200000>, + <0x0 0x40f00200 0x0 0x8>; + reg-names = "cpsw_nuss", "mac_efuse"; + /delete-property/ ranges; + + cpsw-phy-sel@40f04040 { + compatible = "ti,am654-cpsw-phy-sel"; + reg= <0x0 0x40f04040 0x0 0x4>; + reg-names = "gmii-sel"; + }; +}; + +&main_sdhci0 { + status = "disabled"; +}; + +&main_sdhci1 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/k3-am68-sk-base-board.dts b/arch/arm/dts/k3-am68-sk-base-board.dts new file mode 100644 index 00000000000..8fc03324ab8 --- /dev/null +++ b/arch/arm/dts/k3-am68-sk-base-board.dts @@ -0,0 +1,353 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ + * + * Base Board: **Yet to Add** + */ + +/dts-v1/; + +#include "k3-am68-sk-som.dtsi" +#include +#include +#include + +/ { + compatible = "ti,am68-sk", "ti,j721s2"; + model = "Texas Instruments AM68 SK"; + + chosen { + stdout-path = "serial2:115200n8"; + bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x2880000"; + }; + + aliases { + serial2 = &main_uart8; + mmc1 = &main_sdhci1; + }; + + vusb_main: fixedregulator-vusb-main5v0 { + /* USB MAIN INPUT 5V DC */ + compatible = "regulator-fixed"; + regulator-name = "vusb-main5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + vsys_3v3: fixedregulator-vsys3v3 { + /* Output of LM5141 */ + compatible = "regulator-fixed"; + regulator-name = "vsys_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vusb_main>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_mmc1: fixedregulator-sd { + /* Output of TPS22918 */ + compatible = "regulator-fixed"; + regulator-name = "vdd_mmc1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + enable-active-high; + vin-supply = <&vsys_3v3>; + gpio = <&exp1 10 GPIO_ACTIVE_HIGH>; + }; + + vdd_sd_dv: gpio-regulator-TLV71033 { + /* Output of TLV71033 */ + compatible = "regulator-gpio"; + regulator-name = "tlv71033"; + pinctrl-names = "default"; + pinctrl-0 = <&vdd_sd_dv_pins_default>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + vin-supply = <&vsys_3v3>; + gpios = <&main_gpio0 49 GPIO_ACTIVE_HIGH>; + states = <1800000 0x0>, + <3300000 0x1>; + }; +}; + +&main_pmx0 { + main_uart8_pins_default: main-uart8-pins-default { + pinctrl-single,pins = < + J721S2_IOPAD(0x040, PIN_INPUT, 14) /* (AC28) MCASP0_AXR0.UART8_CTSn */ + J721S2_IOPAD(0x044, PIN_OUTPUT, 14) /* (Y26) MCASP0_AXR1.UART8_RTSn */ + J721S2_IOPAD(0x0d0, PIN_INPUT, 11) /* (AF26) SPI0_CS1.UART8_RXD */ + J721S2_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AH27) SPI0_CLK.UART8_TXD */ + >; + }; + + main_i2c0_pins_default: i2c0-pins-default { + pinctrl-single,pins = < + J721S2_IOPAD(0x0e0, PIN_INPUT_PULLUP, 0) /* (AH25) I2C0_SCL */ + J721S2_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AE24) I2C0_SDA */ + >; + }; + + main_mmc1_pins_default: main-mmc1-pins-default { + pinctrl-single,pins = < + J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */ + J721S2_IOPAD(0x108, PIN_INPUT, 0) /* (N24) MMC1_CMD */ + J721S2_IOPAD(0x100, PIN_INPUT, 0) /* (###) MMC1_CLKLB */ + J721S2_IOPAD(0x0fc, PIN_INPUT, 0) /* (M23) MMC1_DAT0 */ + J721S2_IOPAD(0x0f8, PIN_INPUT, 0) /* (P24) MMC1_DAT1 */ + J721S2_IOPAD(0x0f4, PIN_INPUT, 0) /* (R24) MMC1_DAT2 */ + J721S2_IOPAD(0x0f0, PIN_INPUT, 0) /* (R22) MMC1_DAT3 */ + J721S2_IOPAD(0x0e8, PIN_INPUT, 8) /* (AE25) TIMER_IO0.MMC1_SDCD */ + >; + }; + + vdd_sd_dv_pins_default: vdd-sd-dv-pins-default { + pinctrl-single,pins = < + J721S2_IOPAD(0x0c4, PIN_INPUT, 7) /* (AB26) ECAP0_IN_APWM_OUT.GPIO0_49 */ + >; + }; +}; + +&wkup_pmx0 { + mcu_cpsw_pins_default: mcu-cpsw-pins-default { + pinctrl-single,pins = < + J721S2_WKUP_IOPAD(0x094, PIN_INPUT, 0) /* (B22) MCU_RGMII1_RD0 */ + J721S2_WKUP_IOPAD(0x090, PIN_INPUT, 0) /* (B21) MCU_RGMII1_RD1 */ + J721S2_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (C22) MCU_RGMII1_RD2 */ + J721S2_WKUP_IOPAD(0x088, PIN_INPUT, 0) /* (D23) MCU_RGMII1_RD3 */ + J721S2_WKUP_IOPAD(0x084, PIN_INPUT, 0) /* (D22) MCU_RGMII1_RXC */ + J721S2_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (E23) MCU_RGMII1_RX_CTL */ + J721S2_WKUP_IOPAD(0x07c, PIN_OUTPUT, 0) /* (F23) MCU_RGMII1_TD0 */ + J721S2_WKUP_IOPAD(0x078, PIN_OUTPUT, 0) /* (G22) MCU_RGMII1_TD1 */ + J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (E21) MCU_RGMII1_TD2 */ + J721S2_WKUP_IOPAD(0x070, PIN_OUTPUT, 0) /* (E22) MCU_RGMII1_TD3 */ + J721S2_WKUP_IOPAD(0x080, PIN_OUTPUT, 0) /* (F21) MCU_RGMII1_TXC */ + J721S2_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (F22) MCU_RGMII1_TX_CTL */ + >; + }; + + mcu_mdio_pins_default: mcu-mdio-pins-default { + pinctrl-single,pins = < + J721S2_WKUP_IOPAD(0x09c, PIN_OUTPUT, 0) /* (A21) MCU_MDIO0_MDC */ + J721S2_WKUP_IOPAD(0x098, PIN_INPUT, 0) /* (A22) MCU_MDIO0_MDIO */ + >; + }; +}; + +&main_gpio2 { + status = "disabled"; +}; + +&main_gpio4 { + status = "disabled"; +}; + +&main_gpio6 { + status = "disabled"; +}; + +&wkup_gpio1 { + status = "disabled"; +}; + +&wkup_uart0 { + status = "reserved"; +}; + +&main_uart0 { + status = "disabled"; +}; + +&main_uart1 { + status = "disabled"; +}; + +&main_uart2 { + status = "disabled"; +}; + +&main_uart3 { + status = "disabled"; +}; + +&main_uart4 { + status = "disabled"; +}; + +&main_uart5 { + status = "disabled"; +}; + +&main_uart6 { + status = "disabled"; +}; + +&main_uart7 { + status = "disabled"; +}; + +&main_uart8 { + pinctrl-names = "default"; + pinctrl-0 = <&main_uart8_pins_default>; + /* Shared with TFA on this platform */ + power-domains = <&k3_pds 357 TI_SCI_PD_SHARED>; +}; + +&main_uart9 { + status = "disabled"; +}; + +&main_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c0_pins_default>; + clock-frequency = <400000>; + + exp1: gpio@21 { + compatible = "ti,tca6416"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "CSI_VIO_SEL", "CSI_SEL_FPC_EXPN", "HDMI_PDN", + "HDMI_LS_OE", "DP0_3V3_EN", "BOARDID_EEPROM_WP", + "CAN_STB", "","GPIO_uSD_PWR_EN", "EDP_ENABLE", + "IO_EXP_PCIE1_M2_RSTZ", "IO_EXP_MCU_RGMII_RSTZ", + "IO_EXP_CSI1_EXP_RSTZ", "","CSI0_B_GPIO1", + "CSI1_B_GPIO1"; + }; +}; + +&main_i2c1 { + status = "disabled"; +}; + +&main_i2c2 { + status = "disabled"; +}; + +&main_i2c3 { + status = "disabled"; +}; + +&main_i2c4 { + status = "disabled"; +}; + +&main_i2c5 { + status = "disabled"; +}; + +&main_i2c6 { + status = "disabled"; +}; + +&main_sdhci0 { + status = "disabled"; +}; + +&main_sdhci1 { + /* SD card */ + pinctrl-0 = <&main_mmc1_pins_default>; + pinctrl-names = "default"; + disable-wp; + vmmc-supply = <&vdd_mmc1>; + vqmmc-supply = <&vdd_sd_dv>; +}; + +&mcu_cpsw { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>; +}; + +&davinci_mdio { + phy0: ethernet-phy@0 { + reg = <0>; + ti,rx-internal-delay = ; + ti,fifo-depth = ; + ti,min-output-impedance; + }; +}; + +&cpsw_port1 { + phy-mode = "rgmii-rxid"; + phy-handle = <&phy0>; +}; + +&mcu_mcan0 { + status = "disabled"; +}; + +&mcu_mcan1 { + status = "disabled"; +}; + +&main_mcan0 { + status = "disabled"; +}; + +&main_mcan1 { + status = "disabled"; +}; + +&main_mcan2 { + status = "disabled"; +}; + +&main_mcan3 { + status = "disabled"; +}; + +&main_mcan4 { + status = "disabled"; +}; + +&main_mcan5 { + status = "disabled"; +}; + +&main_mcan6 { + status = "disabled"; +}; + +&main_mcan7 { + status = "disabled"; +}; + +&main_mcan8 { + status = "disabled"; +}; + +&main_mcan9 { + status = "disabled"; +}; + +&main_mcan10 { + status = "disabled"; +}; + +&main_mcan11 { + status = "disabled"; +}; + +&main_mcan12 { + status = "disabled"; +}; + +&main_mcan13 { + status = "disabled"; +}; + +&main_mcan14 { + status = "disabled"; +}; + +&main_mcan15 { + status = "disabled"; +}; + +&main_mcan17 { + status = "disabled"; +}; From ca04b7da6d9a153e6fe8a846d2baf892d5b69aae Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:57 +0530 Subject: [PATCH 19/22] arm: dts: k3-am68-sk: Add r5 specific dt support Add initial support for AM68 SK device tree that runs on R5. Signed-off-by: Sinthu Raja --- arch/arm/dts/Makefile | 1 + arch/arm/dts/k3-am68-sk-r5-base-board.dts | 194 ++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 arch/arm/dts/k3-am68-sk-r5-base-board.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d3970767603..3ecd6a86e95 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1255,6 +1255,7 @@ dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \ k3-j721e-sk.dtb \ k3-j721e-r5-sk.dtb dtb-$(CONFIG_SOC_K3_J721S2) += k3-am68-sk-base-board.dtb\ + k3-am68-sk-r5-base-board.dtb\ k3-j721s2-common-proc-board.dtb\ k3-j721s2-r5-common-proc-board.dtb dtb-$(CONFIG_SOC_K3_AM642) += k3-am642-evm.dtb \ diff --git a/arch/arm/dts/k3-am68-sk-r5-base-board.dts b/arch/arm/dts/k3-am68-sk-r5-base-board.dts new file mode 100644 index 00000000000..46ee6c4422b --- /dev/null +++ b/arch/arm/dts/k3-am68-sk-r5-base-board.dts @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ + */ + +/dts-v1/; + +#include "k3-am68-sk-som.dtsi" +#include "k3-j721s2-ddr-evm-lp4-4266.dtsi" +#include "k3-j721s2-ddr.dtsi" + +/ { + chosen { + firmware-loader = &fs_loader0; + stdout-path = &main_uart8; + tick-timer = &timer1; + }; + + aliases { + remoteproc0 = &sysctrler; + remoteproc1 = &a72_0; + }; + + fs_loader0: fs_loader@0 { + compatible = "u-boot,fs-loader"; + u-boot,dm-pre-reloc; + }; + + a72_0: a72@0 { + compatible = "ti,am654-rproc"; + reg = <0x0 0x00a90000 0x0 0x10>; + power-domains = <&k3_pds 61 TI_SCI_PD_EXCLUSIVE>, + <&k3_pds 202 TI_SCI_PD_EXCLUSIVE>; + resets = <&k3_reset 202 0>; + clocks = <&k3_clks 61 1>; + assigned-clocks = <&k3_clks 61 1>, <&k3_clks 202 0>; + assigned-clock-parents = <&k3_clks 61 2>; + assigned-clock-rates = <200000000>, <2000000000>; + ti,sci = <&sms>; + ti,sci-proc-id = <32>; + ti,sci-host-id = <10>; + u-boot,dm-spl; + }; + + clk_200mhz: dummy_clock_200mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + u-boot,dm-spl; + }; + + clk_19_2mhz: dummy_clock_19_2mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + u-boot,dm-spl; + }; +}; + +&cbass_mcu_wakeup { + sa3_secproxy: secproxy@44880000 { + u-boot,dm-spl; + compatible = "ti,am654-secure-proxy"; + reg = <0x0 0x44880000 0x0 0x20000>, + <0x0 0x44860000 0x0 0x20000>, + <0x0 0x43600000 0x0 0x10000>; + reg-names = "rt", "scfg", "target_data"; + #mbox-cells = <1>; + }; + + mcu_secproxy: secproxy@2a380000 { + compatible = "ti,am654-secure-proxy"; + reg = <0x0 0x2a380000 0x0 0x80000>, + <0x0 0x2a400000 0x0 0x80000>, + <0x0 0x2a480000 0x0 0x80000>; + reg-names = "rt", "scfg", "target_data"; + #mbox-cells = <1>; + u-boot,dm-spl; + }; + + sysctrler: sysctrler { + compatible = "ti,am654-system-controller"; + mboxes= <&mcu_secproxy 4>, <&mcu_secproxy 5>, <&sa3_secproxy 5>; + mbox-names = "tx", "rx", "boot_notify"; + u-boot,dm-spl; + }; + + dm_tifs: dm-tifs { + compatible = "ti,j721e-dm-sci"; + ti,host-id = <3>; + ti,secure-host; + mbox-names = "rx", "tx"; + mboxes= <&mcu_secproxy 21>, + <&mcu_secproxy 23>; + u-boot,dm-spl; + }; +}; + +&main_pmx0 { + main_uart8_pins_default: main-uart8-pins-default { + pinctrl-single,pins = < + J721S2_IOPAD(0x0d0, PIN_INPUT, 11) /* (AF26) SPI0_CS1.UART8_RXD */ + J721S2_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AH27) SPI0_CLK.UART8_TXD */ + >; + }; + + main_mmc1_pins_default: main-mmc1-pins-default { + pinctrl-single,pins = < + J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */ + J721S2_IOPAD(0x108, PIN_INPUT, 0) /* (N24) MMC1_CMD */ + J721S2_IOPAD(0x100, PIN_INPUT, 0) /* (###) MMC1_CLKLB */ + J721S2_IOPAD(0x0fc, PIN_INPUT, 0) /* (M23) MMC1_DAT0 */ + J721S2_IOPAD(0x0f8, PIN_INPUT, 0) /* (P24) MMC1_DAT1 */ + J721S2_IOPAD(0x0f4, PIN_INPUT, 0) /* (R24) MMC1_DAT2 */ + J721S2_IOPAD(0x0f0, PIN_INPUT, 0) /* (R22) MMC1_DAT3 */ + J721S2_IOPAD(0x0e8, PIN_INPUT, 8) /* (AE25) TIMER_IO0.MMC1_SDCD */ + >; + }; + + main_usbss0_pins_default: main-usbss0-pins-default { + pinctrl-single,pins = < + J721S2_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AG25) TIMER_IO1.USB0_DRVVBUS */ + >; + }; +}; + +&wkup_pmx0 { + mcu_uart0_pins_default: mcu-uart0-pins-default { + u-boot,dm-spl; + pinctrl-single,pins = < + J721S2_WKUP_IOPAD(0x0f4, PIN_INPUT, 0) /*(C24) WKUP_GPIO0_13.MCU_UART0_RXD*/ + J721S2_WKUP_IOPAD(0x0f0, PIN_OUTPUT, 0) /*(C25) WKUP_GPIO0_12.MCU_UART0_TXD*/ + >; + }; + + wkup_uart0_pins_default: wkup-uart0-pins-default { + u-boot,dm-spl; + pinctrl-single,pins = < + J721S2_WKUP_IOPAD(0x0d8, PIN_INPUT, 0) /*(E25) WKUP_GPIO0_6.WKUP_UART0_CTSn*/ + J721S2_WKUP_IOPAD(0x0dc, PIN_OUTPUT, 0) /*(F28) WKUP_GPIO0_7.WKUP_UART0_RTSn*/ + J721S2_WKUP_IOPAD(0x0b0, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */ + J721S2_WKUP_IOPAD(0x0b4, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */ + >; + }; + +}; + +&sms { + mboxes= <&mcu_secproxy 8>, <&mcu_secproxy 6>, <&mcu_secproxy 5>; + mbox-names = "tx", "rx", "notify"; + ti,host-id = <4>; + ti,secure-host; + u-boot,dm-spl; +}; + +&wkup_uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&wkup_uart0_pins_default>; +}; + +&mcu_uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_uart0_pins_default>; +}; + +&main_uart8 { + pinctrl-names = "default"; + pinctrl-0 = <&main_uart8_pins_default>; +}; + +&main_sdhci0 { + status = "disabled"; +}; + +&main_sdhci1 { + /delete-property/ power-domains; + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; + pinctrl-0 = <&main_mmc1_pins_default>; + pinctrl-names = "default"; + clock-names = "clk_xin"; + clocks = <&clk_200mhz>; + ti,driver-strength-ohm = <50>; +}; + +&mcu_ringacc { + ti,sci = <&dm_tifs>; +}; + +&mcu_udmap { + ti,sci = <&dm_tifs>; +}; + +#include "k3-am68-sk-base-board-u-boot.dtsi" From 9787ecfd0d8fbfd1835a8afe4fe815cad7e7e46b Mon Sep 17 00:00:00 2001 From: Sinthu Raja Date: Tue, 10 Jan 2023 21:17:58 +0530 Subject: [PATCH 20/22] include: configs: Update env for selecting right dtb Now that single defconfig shall be used for booting J721S2 EVM and AM68 SK, the default device tree will not work for selecting dtb for kernel. Update the findfdt env to select right dtb based on board_name env variable. Signed-off-by: Sinthu Raja Reviewed-by: Tom Rini --- include/configs/j721s2_evm.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/j721s2_evm.h b/include/configs/j721s2_evm.h index 54dfea6952e..bfada9eebc2 100644 --- a/include/configs/j721s2_evm.h +++ b/include/configs/j721s2_evm.h @@ -32,6 +32,10 @@ "default_device_tree=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ "findfdt=" \ "setenv name_fdt ${default_device_tree};" \ + "if test $board_name = j721s2; then " \ + "setenv name_fdt k3-j721s2-common-proc-board.dtb; fi;" \ + "if test $board_name = am68-sk; then " \ + "setenv name_fdt k3-am68-sk-base-board.dtb; fi;"\ "setenv fdtfile ${name_fdt}\0" \ "name_kern=Image\0" \ "console=ttyS2,115200n8\0" \ From b75ca26b227a6fef9d5fffb9738655cbcbd8379b Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Fri, 6 Jan 2023 12:02:50 -0600 Subject: [PATCH 21/22] common: bouncebuf: Use dma-mapping for cache ops This matches how this would be done in Linux and these functions do the alignment for us which makes the code look cleaner. Signed-off-by: Andrew Davis Reviewed-by: Simon Glass --- common/bouncebuf.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/common/bouncebuf.c b/common/bouncebuf.c index 6d98920de66..93a35668cc2 100644 --- a/common/bouncebuf.c +++ b/common/bouncebuf.c @@ -12,6 +12,7 @@ #include #include #include +#include static int addr_aligned(struct bounce_buffer *state) { @@ -59,9 +60,9 @@ int bounce_buffer_start_extalign(struct bounce_buffer *state, void *data, * Flush data to RAM so DMA reads can pick it up, * and any CPU writebacks don't race with DMA writes */ - flush_dcache_range((unsigned long)state->bounce_buffer, - (unsigned long)(state->bounce_buffer) + - state->len_aligned); + dma_map_single(state->bounce_buffer, + state->len_aligned, + DMA_BIDIRECTIONAL); return 0; } @@ -78,9 +79,9 @@ int bounce_buffer_stop(struct bounce_buffer *state) { if (state->flags & GEN_BB_WRITE) { /* Invalidate cache so that CPU can see any newly DMA'd data */ - invalidate_dcache_range((unsigned long)state->bounce_buffer, - (unsigned long)(state->bounce_buffer) + - state->len_aligned); + dma_unmap_single((dma_addr_t)state->bounce_buffer, + state->len_aligned, + DMA_BIDIRECTIONAL); } if (state->bounce_buffer == state->user_buffer) From b93a65209c4afae3f929262761b48b228ef58828 Mon Sep 17 00:00:00 2001 From: Massimo Pegorer Date: Thu, 5 Jan 2023 10:31:09 +0100 Subject: [PATCH 22/22] mkimage: fit: Support signed configurations in 'auto' FITs Extend support for signing in auto-generated (-f auto) FIT. Previously, it was possible to get signed 'images' subnodes in the FIT using options -g and -o together with -f auto. This patch allows signing 'configurations' subnodes instead of 'images' ones (which are hashed), using option -f auto-conf instead of -f auto. Adding also -K and -r options, will add public key to file with required = "conf" property. Summary: -f auto => FIT with crc32 images -f auto -g ... -o ... => FIT with signed images -f auto-conf -g ... -o ... => FIT with sha1 images and signed confs Example: FIT with kernel, two device tree files, and signed configurations; public key (needed to verify signatures) is added to u-boot.dtb with required = "conf" property. mkimage -f auto-conf -A arm -O linux -T kernel -C none -a 43e00000 \ -e 0 -d vmlinuz -b /path/to/first.dtb -b /path/to/second.dtb \ -k /folder/with/key-files -g keyname -o sha256,rsa4096 \ -K u-boot.dtb -r kernel.itb Example: Add public key with required = "conf" property to u-boot.dtb without needing to sign anything. This will also create a useless FIT named unused.itb. mkimage -f auto-conf -d /dev/null -k /folder/with/key-files \ -g keyname -o sha256,rsa4096 -K u-boot.dtb -r unused.itb Signed-off-by: Massimo Pegorer Reviewed-by: Simon Glass --- doc/mkimage.1 | 125 +++++++++++------ test/py/tests/test_fit_auto_signed.py | 195 ++++++++++++++++++++++++++ tools/fit_image.c | 79 +++++++---- tools/imagetool.h | 10 +- tools/mkimage.c | 21 ++- 5 files changed, 358 insertions(+), 72 deletions(-) create mode 100644 test/py/tests/test_fit_auto_signed.py diff --git a/doc/mkimage.1 b/doc/mkimage.1 index 353ea8b2f76..d8727ec73cc 100644 --- a/doc/mkimage.1 +++ b/doc/mkimage.1 @@ -22,7 +22,8 @@ mkimage \- generate images for U-Boot .SY mkimage .RI [ option\~ .\|.\|.\&] .BI \-f\~ image-tree-source-file\c -.RB | auto +.RB | auto\c +.RB | auto-conf .I image-file-name .YS . @@ -296,9 +297,9 @@ FIT. See for details on using external data. . .TP -\fB\-f \fIimage-tree-source-file\fR | \fBauto +\fB\-f \fIimage-tree-source-file\fR | \fBauto\fR | \fBauto-conf .TQ -\fB\-\-fit \fIimage-tree-source-file\fR | \fBauto +\fB\-\-fit \fIimage-tree-source-file\fR | \fBauto\fR | \fBauto-conf Image tree source file that describes the structure and contents of the FIT image. .IP @@ -317,7 +318,25 @@ and options may be used to specify the image to include in the FIT and its attributes. No .I image-tree-source-file -is required. +is required. The +.BR \-g , +.BR \-o , +and +.B \-k +or +.B \-G +options may be used to get \(oqimages\(cq signed subnodes in the generated +auto FIT. Instead, to get \(oqconfigurations\(cq signed subnodes and +\(oqimages\(cq hashed subnodes, pass +.BR "\-f auto-conf". +In this case +.BR \-g , +.BR \-o , +and +.B \-k +or +.B \-G +are mandatory options. . .TP .B \-F @@ -348,16 +367,16 @@ for use with signing, and a certificate necessary when embedding it into another device tree using .BR \-K . .I name -defaults to the value of the signature node's \(oqkey-name-hint\(cq property, -but may be overridden using -.BR \-g . +is the value of the signature node's \(oqkey-name-hint\(cq property. . .TP .BI \-G " key-file" .TQ .BI \-\-key\-file " key-file" Specifies the private key file to use when signing. This option may be used -instead of \-k. +instead of \-k. Useful when the private key file basename does not match +\(oqkey-name-hint\(cq value. But note that it may lead to unexpected results +when used together with -K and/or -k options. . .TP .BI \-K " key-destination" @@ -373,24 +392,39 @@ CONFIG_OF_CONTROL in U-Boot. .BI \-g " key-name-hint" .TQ .BI \-\-key\-name\-hint " key-name-hint" -Overrides the signature node's \(oqkey-name-hint\(cq property. This is -especially useful when signing an image with -.BR "\-f auto" . -This is the -.I name -part of the key. The directory part is set by -.BR \-k . -This option also indicates that the images included in the FIT should be signed. -If this option is specified, then +Specifies the value of signature node \(oqkey-name-hint\(cq property for +an automatically generated FIT image. It makes sense only when used with +.B "\-f auto" +or +.BR "\-f auto-conf". +This option also indicates that the images or configurations included in +the FIT should be signed. If this option is specified, then .B \-o must be specified as well. . .TP -.BI \-o " crypto" , checksum +.BI \-o " checksum" , crypto .TQ -.BI \-\-algo " crypto" , checksum -Specifies the algorithm to be used for signing a FIT image. The default is -taken from the signature node's \(oqalgo\(cq property. +.BI \-\-algo " checksum" , crypto +Specifies the algorithm to be used for signing a FIT image, overriding value +taken from the signature node \(oqalgo\(cq property in the +.IR image-tree-source-file . +It is mandatory for automatically generated FIT. +.IP +The valid values for +.I checksum +are: +.RS +.IP +.TS +lb. +sha1 +sha256 +sha384 +sha512 +.TE +.RE +.IP The valid values for .I crypto are: @@ -404,28 +438,18 @@ rsa4096 ecdsa256 .TE .RE -.IP -The valid values for -.I checksum -are -.RS -.IP -.TS -lb. -sha1 -sha256 -sha384 -sha512 -.TE -.RE . .TP .B \-r .TQ .B \-\-key\-required -Specifies that keys used to sign the FIT are required. This means that they -must be verified for the image to boot. Without this option, the verification -will be optional (useful for testing but not for release). +Specifies that keys used to sign the FIT are required. This means that images +or configurations signatures must be verified before using them (i.e. to +boot). Without this option, the verification will be optional (useful for +testing but not for release). It makes sense only when used with +.BR \-K. +When both, images and configurations, are signed, \(oqrequired\(cq property +value will be "conf". . .TP .BI \-N " engine" @@ -716,7 +740,7 @@ skipping those for which keys cannot be found. Also add a comment. .EE .RE .P -Add public keys to u\-boot.dtb without needing a FIT to sign. This will also +Add public key to u\-boot.dtb without needing a FIT to sign. This will also create a FIT containing an images node with no data named unused.itb. .RS .P @@ -726,6 +750,16 @@ create a FIT containing an images node with no data named unused.itb. .EE .RE .P +Add public key with required = "conf" property to u\-boot.dtb without needing +a FIT to sign. This will also create a useless FIT named unused.itb. +.RS +.P +.EX +\fBmkimage \-f auto-conf \-d /dev/null \-k /public/signing\-keys \-g dev \\ + \-o sha256,rsa2048 \-K u\-boot.dtb -r unused.itb +.EE +.RE +.P Update an existing FIT image, signing it with additional keys. Add corresponding public keys into u\-boot.dtb. This will resign all images with keys that are available in the new directory. Images that request signing @@ -768,6 +802,19 @@ file is required. \-d vmlinuz \-k /secret/signing\-keys \-g dev \-o sha256,rsa2048 kernel.itb .EE .RE +.P +Create a FIT image containing a kernel and some device tree files, signing +each configuration, using automatic mode. Moreover, the public key needed to +verify signatures is added to u\-boot.dtb with required = "conf" property. +.RS +.P +.EX +\fBmkimage \-f auto-conf \-A arm \-O linux \-T kernel \-C none \-a 43e00000 \\ + \-e 0 \-d vmlinuz \-b /path/to/file\-1.dtb \-b /path/to/file\-2.dtb \\ + \-k /folder/with/signing\-keys \-g dev \-o sha256,rsa2048 \\ + \-K u\-boot.dtb -r kernel.itb +.EE +.RE . .SH SEE ALSO .BR dtc (1), diff --git a/test/py/tests/test_fit_auto_signed.py b/test/py/tests/test_fit_auto_signed.py new file mode 100644 index 00000000000..9ea3351619f --- /dev/null +++ b/test/py/tests/test_fit_auto_signed.py @@ -0,0 +1,195 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2022 Massimo Pegorer + +""" +Test that mkimage generates auto-FIT with signatures and/or hashes as expected. + +The mkimage tool can create auto generated (i.e. without an ITS file +provided as input) FIT in three different flavours: with crc32 checksums +of 'images' subnodes; with signatures of 'images' subnodes; with sha1 +hashes of 'images' subnodes and signatures of 'configurations' subnodes. +This test verifies that auto-FIT are generated as expected, in all of +the three flavours, including check of hashes and signatures (except for +configurations ones). + +The test does not run the sandbox. It only checks the host tool mkimage. +""" + +import os +import pytest +import u_boot_utils as util +import binascii +from Cryptodome.Hash import SHA1 +from Cryptodome.Hash import SHA256 +from Cryptodome.PublicKey import RSA +from Cryptodome.Signature import pkcs1_15 + +class SignedFitHelper(object): + """Helper to manipulate a FIT with signed/hashed images/configs.""" + def __init__(self, cons, file_name): + self.fit = file_name + self.cons = cons + self.images_nodes = set() + self.confgs_nodes = set() + + def __fdt_list(self, path): + return util.run_and_log(self.cons, + f'fdtget -l {self.fit} {path}') + + def __fdt_get_string(self, node, prop): + return util.run_and_log(self.cons, + f'fdtget -ts {self.fit} {node} {prop}') + + def __fdt_get_binary(self, node, prop): + numbers = util.run_and_log(self.cons, + f'fdtget -tbi {self.fit} {node} {prop}') + + bignum = bytearray() + for little_num in numbers.split(): + bignum.append(int(little_num)) + + return bignum + + def build_nodes_sets(self): + """Fill sets with FIT images and configurations subnodes.""" + for node in self.__fdt_list('/images').split(): + subnode = f'/images/{node}' + self.images_nodes.add(subnode) + + for node in self.__fdt_list('/configurations').split(): + subnode = f'/configurations/{node}' + self.confgs_nodes.add(subnode) + + return len(self.images_nodes) + len(self.confgs_nodes) + + def check_fit_crc32_images(self): + """Test that all images in the set are hashed as expected. + + Each image must have an hash with algo=crc32 and hash value must match + the one calculated over image data. + """ + for node in self.images_nodes: + algo = self.__fdt_get_string(f'{node}/hash', 'algo') + assert algo == "crc32\n", "Missing expected crc32 image hash!" + + raw_crc32 = self.__fdt_get_binary(f'{node}/hash', 'value') + raw_bin = self.__fdt_get_binary(node, 'data') + assert raw_crc32 == (binascii.crc32(raw_bin) & + 0xffffffff).to_bytes(4, 'big'), "Wrong crc32 hash!" + + def check_fit_signed_images(self, key_name, sign_algo, verifier): + """Test that all images in the set are signed as expected. + + Each image must have a signature with: key-name-hint matching key_name + argument; algo matching sign_algo argument; value matching the one + calculated over image data using verifier argument. + """ + for node in self.images_nodes: + hint = self.__fdt_get_string(f'{node}/signature', 'key-name-hint') + assert hint == key_name + "\n", "Missing expected key name hint!" + algo = self.__fdt_get_string(f'{node}/signature', 'algo') + assert algo == sign_algo + "\n", "Missing expected signature algo!" + + raw_sig = self.__fdt_get_binary(f'{node}/signature', 'value') + raw_bin = self.__fdt_get_binary(node, 'data') + verifier.verify(SHA256.new(raw_bin), bytes(raw_sig)) + + def check_fit_signed_confgs(self, key_name, sign_algo): + """Test that all configs are signed, and images hashed, as expected. + + Each image must have an hash with algo=sha1 and hash value must match + the one calculated over image data. Each configuration must have a + signature with key-name-hint matching key_name argument and algo + matching sign_algo argument. + TODO: configurations signature checking. + """ + for node in self.images_nodes: + algo = self.__fdt_get_string(f'{node}/hash', 'algo') + assert algo == "sha1\n", "Missing expected sha1 image hash!" + + raw_hash = self.__fdt_get_binary(f'{node}/hash', 'value') + raw_bin = self.__fdt_get_binary(node, 'data') + assert raw_hash == SHA1.new(raw_bin).digest(), "Wrong sha1 hash!" + + for node in self.confgs_nodes: + hint = self.__fdt_get_string(f'{node}/signature', 'key-name-hint') + assert hint == key_name + "\n", "Missing expected key name hint!" + algo = self.__fdt_get_string(f'{node}/signature', 'algo') + assert algo == sign_algo + "\n", "Missing expected signature algo!" + + +@pytest.mark.buildconfigspec('fit_signature') +@pytest.mark.requiredtool('fdtget') +def test_fit_auto_signed(u_boot_console): + """Test that mkimage generates auto-FIT with signatures/hashes as expected. + + The mkimage tool can create auto generated (i.e. without an ITS file + provided as input) FIT in three different flavours: with crc32 checksums + of 'images' subnodes; with signatures of 'images' subnodes; with sha1 + hashes of 'images' subnodes and signatures of 'configurations' subnodes. + This test verifies that auto-FIT are generated as expected, in all of + the three flavours, including check of hashes and signatures (except for + configurations ones). + + The test does not run the sandbox. It only checks the host tool mkimage. + """ + cons = u_boot_console + mkimage = cons.config.build_dir + '/tools/mkimage' + tempdir = os.path.join(cons.config.result_dir, 'auto_fit') + os.makedirs(tempdir, exist_ok=True) + kernel_file = f'{tempdir}/vmlinuz' + dt1_file = f'{tempdir}/dt-1.dtb' + dt2_file = f'{tempdir}/dt-2.dtb' + key_name = 'sign-key' + sign_algo = 'sha256,rsa4096' + key_file = f'{tempdir}/{key_name}.key' + fit_file = f'{tempdir}/test.fit' + + # Create a fake kernel image and two dtb files with random data + with open(kernel_file, 'wb') as fd: + fd.write(os.urandom(512)) + + with open(dt1_file, 'wb') as fd: + fd.write(os.urandom(256)) + + with open(dt2_file, 'wb') as fd: + fd.write(os.urandom(256)) + + # Create 4096 RSA key and write to file to be read by mkimage + key = RSA.generate(bits=4096) + verifier = pkcs1_15.new(key) + + with open(key_file, 'w') as fd: + fd.write(str(key.export_key(format='PEM').decode('ascii'))) + + b_args = " -d" + kernel_file + " -b" + dt1_file + " -b" + dt2_file + s_args = " -k" + tempdir + " -g" + key_name + " -o" + sign_algo + + # 1 - Create auto FIT with images crc32 checksum, and verify it + util.run_and_log(cons, mkimage + ' -fauto' + b_args + " " + fit_file) + + fit = SignedFitHelper(cons, fit_file) + if fit.build_nodes_sets() == 0: + raise ValueError('FIT-1 has no "/image" nor "/configuration" nodes') + + fit.check_fit_crc32_images() + + # 2 - Create auto FIT with signed images, and verify it + util.run_and_log(cons, mkimage + ' -fauto' + b_args + s_args + " " + + fit_file) + + fit = SignedFitHelper(cons, fit_file) + if fit.build_nodes_sets() == 0: + raise ValueError('FIT-2 has no "/image" nor "/configuration" nodes') + + fit.check_fit_signed_images(key_name, sign_algo, verifier) + + # 3 - Create auto FIT with signed configs and hashed images, and verify it + util.run_and_log(cons, mkimage + ' -fauto-conf' + b_args + s_args + " " + + fit_file) + + fit = SignedFitHelper(cons, fit_file) + if fit.build_nodes_sets() == 0: + raise ValueError('FIT-3 has no "/image" nor "/configuration" nodes') + + fit.check_fit_signed_confgs(key_name, sign_algo) diff --git a/tools/fit_image.c b/tools/fit_image.c index 8a18b1b0ba9..8763a36d01e 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -201,36 +201,59 @@ static void get_basename(char *str, int size, const char *fname) } /** - * add_hash_node() - Add a hash or signature node + * fit_add_hash_or_sign() - Add a hash or signature node * * @params: Image parameters * @fdt: Device tree to add to (in sequential-write mode) + * @is_images_subnode: true to add hash even if key name hint is provided * - * If there is a key name hint, try to sign the images. Otherwise, just add a - * CRC. - * - * Return: 0 on success, or -1 on failure + * If do_add_hash is false (default) and there is a key name hint, try to add + * a sign node to parent. Otherwise, just add a CRC. Rationale: if conf have + * to be signed, image/dt have to be hashed even if there is a key name hint. */ -static int add_hash_node(struct image_tool_params *params, void *fdt) +static void fit_add_hash_or_sign(struct image_tool_params *params, void *fdt, + bool is_images_subnode) { - if (params->keyname) { - if (!params->algo_name) { - fprintf(stderr, - "%s: Algorithm name must be specified\n", - params->cmdname); - return -1; - } + const char *hash_algo = "crc32"; + bool do_hash = false; + bool do_sign = false; - fdt_begin_node(fdt, "signature-1"); - fdt_property_string(fdt, FIT_ALGO_PROP, params->algo_name); - fdt_property_string(fdt, FIT_KEY_HINT, params->keyname); - } else { - fdt_begin_node(fdt, "hash-1"); - fdt_property_string(fdt, FIT_ALGO_PROP, "crc32"); + switch (params->auto_fit) { + case AF_OFF: + break; + case AF_HASHED_IMG: + do_hash = is_images_subnode; + break; + case AF_SIGNED_IMG: + do_sign = is_images_subnode; + break; + case AF_SIGNED_CONF: + if (is_images_subnode) { + do_hash = true; + hash_algo = "sha1"; + } else { + do_sign = true; + } + break; + default: + fprintf(stderr, + "%s: Unsupported auto FIT mode %u\n", + params->cmdname, params->auto_fit); + break; } - fdt_end_node(fdt); - return 0; + if (do_hash) { + fdt_begin_node(fdt, FIT_HASH_NODENAME); + fdt_property_string(fdt, FIT_ALGO_PROP, hash_algo); + fdt_end_node(fdt); + } + + if (do_sign) { + fdt_begin_node(fdt, FIT_SIG_NODENAME); + fdt_property_string(fdt, FIT_ALGO_PROP, params->algo_name); + fdt_property_string(fdt, FIT_KEY_HINT, params->keyname); + fdt_end_node(fdt); + } } /** @@ -271,9 +294,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->datafile); if (ret) return ret; - ret = add_hash_node(params, fdt); - if (ret) - return ret; + fit_add_hash_or_sign(params, fdt, true); fdt_end_node(fdt); /* Now the device tree files if available */ @@ -296,7 +317,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) genimg_get_arch_short_name(params->arch)); fdt_property_string(fdt, FIT_COMP_PROP, genimg_get_comp_short_name(IH_COMP_NONE)); - ret = add_hash_node(params, fdt); + fit_add_hash_or_sign(params, fdt, true); if (ret) return ret; fdt_end_node(fdt); @@ -316,7 +337,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) params->fit_ramdisk); if (ret) return ret; - ret = add_hash_node(params, fdt); + fit_add_hash_or_sign(params, fdt, true); if (ret) return ret; fdt_end_node(fdt); @@ -368,6 +389,7 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt) snprintf(str, sizeof(str), FIT_FDT_PROP "-%d", upto); fdt_property_string(fdt, FIT_FDT_PROP, str); + fit_add_hash_or_sign(params, fdt, false); fdt_end_node(fdt); } @@ -380,6 +402,7 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt) if (params->fit_ramdisk) fdt_property_string(fdt, FIT_RAMDISK_PROP, FIT_RAMDISK_PROP "-1"); + fit_add_hash_or_sign(params, fdt, false); fdt_end_node(fdt); } @@ -723,7 +746,7 @@ static int fit_handle_file(struct image_tool_params *params) sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX); /* We either compile the source file, or use the existing FIT image */ - if (params->auto_its) { + if (params->auto_fit) { if (fit_build(params, tmpfile)) { fprintf(stderr, "%s: failed to build FIT\n", params->cmdname); @@ -907,7 +930,7 @@ static int fit_extract_contents(void *ptr, struct image_tool_params *params) static int fit_check_params(struct image_tool_params *params) { - if (params->auto_its) + if (params->auto_fit) return 0; return ((params->dflag && params->fflag) || (params->fflag && params->lflag) || diff --git a/tools/imagetool.h b/tools/imagetool.h index ca7c2e48ba9..fdceea46c09 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -39,6 +39,14 @@ struct content_info { const char *fname; }; +/* FIT auto generation modes */ +enum af_mode { + AF_OFF = 0, /* Needs .its or existing FIT to be provided */ + AF_HASHED_IMG, /* Auto FIT with crc32 hashed images subnodes */ + AF_SIGNED_IMG, /* Auto FIT with signed images subnodes */ + AF_SIGNED_CONF, /* Auto FIT with sha1 images and signed configs */ +}; + /* * This structure defines all such variables those are initialized by * mkimage and dumpimage main core and need to be referred by image @@ -79,7 +87,7 @@ struct image_tool_params { int require_keys; /* 1 to mark signing keys as 'required' */ int file_size; /* Total size of output file */ int orig_file_size; /* Original size for file before padding */ - bool auto_its; /* Automatically create the .its file */ + enum af_mode auto_fit; /* Automatically create the FIT */ int fit_image_type; /* Image type to put into the FIT */ char *fit_ramdisk; /* Ramdisk file to include */ struct content_info *content_head; /* List of files to include */ diff --git a/tools/mkimage.c b/tools/mkimage.c index 8306861ce51..af7b0e09b3b 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -104,7 +104,7 @@ static void usage(const char *msg) " -v ==> verbose\n", params.cmdname); fprintf(stderr, - " %s [-D dtc_options] [-f fit-image.its|-f auto|-F] [-b [-b ]] [-E] [-B size] [-i ] fit-image\n" + " %s [-D dtc_options] [-f fit-image.its|-f auto|-f auto-conf|-F] [-b [-b ]] [-E] [-B size] [-i ] fit-image\n" " file is used with -f auto, it may occur multiple times.\n", params.cmdname); fprintf(stderr, @@ -271,7 +271,10 @@ static void process_args(int argc, char **argv) break; case 'f': datafile = optarg; - params.auto_its = !strcmp(datafile, "auto"); + if (!strcmp(datafile, "auto")) + params.auto_fit = AF_HASHED_IMG; + else if (!strcmp(datafile, "auto-conf")) + params.auto_fit = AF_SIGNED_CONF; /* fallthrough */ case 'F': /* @@ -283,6 +286,7 @@ static void process_args(int argc, char **argv) break; case 'g': params.keyname = optarg; + break; case 'G': params.keyfile = optarg; break; @@ -370,6 +374,15 @@ static void process_args(int argc, char **argv) if (optind < argc) params.imagefile = argv[optind]; + if (params.auto_fit == AF_SIGNED_CONF) { + if (!params.keyname || !params.algo_name) + usage("Missing key/algo for auto-FIT with signed configs (use -g -o)"); + } else if (params.auto_fit == AF_HASHED_IMG && params.keyname) { + params.auto_fit = AF_SIGNED_IMG; + if (!params.algo_name) + usage("Missing algorithm for auto-FIT with signed images (use -g)"); + } + /* * For auto-generated FIT images we need to know the image type to put * in the FIT, which is separate from the file's image type (which @@ -377,8 +390,8 @@ static void process_args(int argc, char **argv) */ if (params.type == IH_TYPE_FLATDT) { params.fit_image_type = type ? type : IH_TYPE_KERNEL; - /* For auto_its, datafile is always 'auto' */ - if (!params.auto_its) + /* For auto-FIT, datafile has to be provided with -d */ + if (!params.auto_fit) params.datafile = datafile; else if (!params.datafile) usage("Missing data file for auto-FIT (use -d)");