Merge branch '2019-10-11-ti-imports'

- Various improvements to dra7xx, keystone 3, am65x SoCs
- Platform updates
- remoteproc improvements
This commit is contained in:
Tom Rini 2019-10-12 10:09:13 -04:00
commit 36317705cb
67 changed files with 3142 additions and 200 deletions

View file

@ -32,12 +32,19 @@
gpio_keys { gpio_keys {
compatible = "gpio-keys"; compatible = "gpio-keys";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&gpio_keys_pins>; pinctrl-0 = <&guardian_button_pins>;
button21 { select-button {
label = "guardian-select-button";
linux,code = <KEY_5>;
gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
wakeup-source;
};
power-button {
label = "guardian-power-button"; label = "guardian-power-button";
linux,code = <KEY_POWER>; linux,code = <KEY_POWER>;
gpios = <&gpio2 21 0>; gpios = <&gpio2 21 GPIO_ACTIVE_LOW>;
wakeup-source; wakeup-source;
}; };
}; };
@ -45,19 +52,12 @@
leds { leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&leds_pins>; pinctrl-0 = <&guardian_led_pins>;
led1 { life-led {
label = "green:heartbeat"; label = "guardian:life-led";
gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
default-state = "off";
};
led2 {
label = "green:mmc0";
gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc0"; linux,default-trigger = "heartbeat";
default-state = "off"; default-state = "off";
}; };
}; };
@ -140,22 +140,25 @@
gpmc,device-width = <1>; gpmc,device-width = <1>;
gpmc,sync-clk-ps = <0>; gpmc,sync-clk-ps = <0>;
gpmc,cs-on-ns = <0>; gpmc,cs-on-ns = <0>;
gpmc,cs-rd-off-ns = <44>; gpmc,cs-rd-off-ns = <30>;
gpmc,cs-wr-off-ns = <44>; gpmc,cs-wr-off-ns = <30>;
gpmc,adv-on-ns = <6>; gpmc,adv-on-ns = <0>;
gpmc,adv-rd-off-ns = <34>; gpmc,adv-rd-off-ns = <30>;
gpmc,adv-wr-off-ns = <44>; gpmc,adv-wr-off-ns = <30>;
gpmc,we-on-ns = <0>; gpmc,we-on-ns = <0>;
gpmc,we-off-ns = <40>; gpmc,we-off-ns = <15>;
gpmc,oe-on-ns = <0>; gpmc,oe-on-ns = <1>;
gpmc,oe-off-ns = <54>; gpmc,oe-off-ns = <15>;
gpmc,access-ns = <64>; gpmc,access-ns = <30>;
gpmc,rd-cycle-ns = <82>; gpmc,rd-cycle-ns = <30>;
gpmc,wr-cycle-ns = <82>; gpmc,wr-cycle-ns = <30>;
gpmc,wait-on-read = "true";
gpmc,wait-on-write = "true";
gpmc,bus-turnaround-ns = <0>; gpmc,bus-turnaround-ns = <0>;
gpmc,cycle2cycle-delay-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>;
gpmc,clk-activation-ns = <0>; gpmc,clk-activation-ns = <0>;
gpmc,wr-access-ns = <40>; gpmc,wait-monitoring-ns = <0>;
gpmc,wr-access-ns = <0>;
gpmc,wr-data-mux-bus-ns = <0>; gpmc,wr-data-mux-bus-ns = <0>;
/* /*
@ -199,18 +202,8 @@
}; };
partition@6 { partition@6 {
label = "u-boot-env";
reg = <0x300000 0x40000>;
};
partition@7 {
label = "u-boot-env.backup1";
reg = <0x340000 0x40000>;
};
partition@8 {
label = "UBI"; label = "UBI";
reg = <0x380000 0x1fc80000>; reg = <0x300000 0x1fd00000>;
}; };
}; };
}; };
@ -326,6 +319,12 @@
status = "okay"; status = "okay";
}; };
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>;
status = "okay";
};
&usb { &usb {
status = "okay"; status = "okay";
}; };
@ -354,7 +353,7 @@
&am33xx_pinmux { &am33xx_pinmux {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&clkout2_pin &gpio_pins>; pinctrl-0 = <&clkout2_pin &guardian_interface_pins>;
clkout2_pin: pinmux_clkout2_pin { clkout2_pin: pinmux_clkout2_pin {
pinctrl-single,pins = < pinctrl-single,pins = <
@ -368,16 +367,25 @@
>; >;
}; };
gpio_keys_pins: pinmux_gpio_keys_pins { guardian_button_pins: pinmux_gpio_keys_pins {
pinctrl-single,pins = < pinctrl-single,pins = <
AM33XX_IOPAD(0x940, PIN_INPUT | MUX_MODE7) AM33XX_IOPAD(0x940, PIN_INPUT | MUX_MODE7)
AM33XX_IOPAD(0x884, PIN_INPUT | MUX_MODE7)
>; >;
}; };
gpio_pins: pinmux_gpio_pins { guardian_interface_pins: pinmux_guardian_interface_pins {
pinctrl-single,pins = < pinctrl-single,pins = <
AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE7) AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE7)
AM33XX_IOPAD(0x990, PIN_OUTPUT | MUX_MODE7) AM33XX_IOPAD(0x990, PIN_OUTPUT | MUX_MODE7)
AM33XX_IOPAD(0x9ac, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
AM33XX_IOPAD(0x980, PIN_INPUT | MUX_MODE7)
AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE7)
AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLUP | MUX_MODE7)
AM33XX_IOPAD(0x90c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
AM33XX_IOPAD(0x944, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
AM33XX_IOPAD(0x91c, PIN_INPUT | MUX_MODE7)
AM33XX_IOPAD(0x918, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
>; >;
}; };
@ -452,10 +460,9 @@
>; >;
}; };
leds_pins: pinmux_leds_pins { guardian_led_pins: pinmux_leds_pins {
pinctrl-single,pins = < pinctrl-single,pins = <
AM33XX_IOPAD(0x868, PIN_OUTPUT | MUX_MODE7) AM33XX_IOPAD(0x868, PIN_OUTPUT | MUX_MODE7)
AM33XX_IOPAD(0x86c, PIN_OUTPUT | MUX_MODE7)
>; >;
}; };
@ -487,6 +494,13 @@
>; >;
}; };
uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE1)
AM33XX_IOPAD(0x930, PIN_OUTPUT_PULLDOWN | MUX_MODE1)
>;
};
nandflash_pins: pinmux_nandflash_pins { nandflash_pins: pinmux_nandflash_pins {
pinctrl-single,pins = < pinctrl-single,pins = <
AM33XX_IOPAD(0x800, PIN_INPUT | MUX_MODE0) AM33XX_IOPAD(0x800, PIN_INPUT | MUX_MODE0)

View file

@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
/ {
xtal25mhz: xtal25mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
};
&i2c0 {
cdce913: cdce913@65 {
compatible = "ti,cdce913";
reg = <0x65>;
clocks = <&xtal25mhz>;
#clock-cells = <1>;
xtal-load-pf = <0>;
};
};

View file

@ -9,6 +9,12 @@
ocp { ocp {
u-boot,dm-spl; u-boot,dm-spl;
}; };
xtal25mhz: xtal25mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
}; };
&uart0 { &uart0 {
@ -17,6 +23,14 @@
&i2c0 { &i2c0 {
u-boot,dm-spl; u-boot,dm-spl;
cdce913: cdce913@65 {
compatible = "ti,cdce913";
reg = <0x65>;
clocks = <&xtal25mhz>;
#clock-cells = <1>;
xtal-load-pf = <0>;
};
}; };
&mmc1 { &mmc1 {

View file

@ -0,0 +1,5 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
#include "am57xx-idk-common-u-boot.dtsi"

View file

@ -0,0 +1,5 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
#include "am57xx-idk-common-u-boot.dtsi"

View file

@ -0,0 +1,5 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
#include "am57xx-idk-common-u-boot.dtsi"

View file

@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
#include "omap5-u-boot.dtsi"
/ {
xtal25mhz: xtal25mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
};
&i2c1 {
cdce913: cdce913@65 {
compatible = "ti,cdce913";
reg = <0x65>;
clocks = <&xtal25mhz>;
#clock-cells = <1>;
xtal-load-pf = <0>;
};
};

View file

@ -2,7 +2,7 @@
/* /*
* Device Tree Source for AM6 SoC Family MCU Domain peripherals * Device Tree Source for AM6 SoC Family MCU Domain peripherals
* *
* Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/ * Copyright (C) 2016-2019 Texas Instruments Incorporated - http://www.ti.com/
*/ */
&cbass_mcu { &cbass_mcu {
@ -26,4 +26,42 @@
clocks = <&k3_clks 114 1>; clocks = <&k3_clks 114 1>;
power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>; power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
}; };
mcu_r5fss0: r5fss@41000000 {
compatible = "ti,am654-r5fss";
lockstep-mode = <0>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x41000000 0x00 0x41000000 0x20000>,
<0x41400000 0x00 0x41400000 0x20000>;
power-domains = <&k3_pds 129 TI_SCI_PD_EXCLUSIVE>;
mcu_r5fss0_core0: r5f@41000000 {
compatible = "ti,am654-r5f";
reg = <0x41000000 0x00008000>,
<0x41010000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <159>;
ti,sci-proc-ids = <0x01 0xFF>;
resets = <&k3_reset 159 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
mcu_r5fss0_core1: r5f@41400000 {
compatible = "ti,am654-r5f";
reg = <0x41400000 0x00008000>,
<0x41410000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <245>;
ti,sci-proc-ids = <0x02 0xFF>;
resets = <&k3_reset 245 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
};
}; };

View file

@ -17,6 +17,11 @@
bootargs = "earlycon=ns16550a,mmio32,0x02800000"; bootargs = "earlycon=ns16550a,mmio32,0x02800000";
}; };
aliases {
remoteproc0 = &mcu_r5fss0_core0;
remoteproc1 = &mcu_r5fss0_core1;
};
memory@80000000 { memory@80000000 {
device_type = "memory"; device_type = "memory";
/* 4G RAM */ /* 4G RAM */

View file

@ -16,6 +16,7 @@
aliases { aliases {
serial0 = &wkup_uart0; serial0 = &wkup_uart0;
serial1 = &mcu_uart0;
serial2 = &main_uart0; serial2 = &main_uart0;
}; };
@ -118,6 +119,14 @@
status = "okay"; status = "okay";
}; };
&mcu_uart0 {
u-boot,dm-spl;
pinctrl-names = "default";
pinctrl-0 = <&mcu_uart0_pins_default>;
clock-frequency = <48000000>;
status = "okay";
};
&main_uart0 { &main_uart0 {
power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>; power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
}; };
@ -141,6 +150,16 @@
u-boot,dm-spl; u-boot,dm-spl;
}; };
mcu_uart0_pins_default: mcu_uart0_pins_default {
pinctrl-single,pins = <
AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 4) /* (P4) MCU_OSPI1_D1.MCU_UART0_RXD */
AM65X_WKUP_IOPAD(0x0048, PIN_OUTPUT, 4) /* (P5) MCU_OSPI1_D2.MCU_UART0_TXD */
AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 4) /* (P1) MCU_OSPI1_D3.MCU_UART0_CTSn */
AM65X_WKUP_IOPAD(0x0054, PIN_OUTPUT, 4) /* (N3) MCU_OSPI1_CSn1.MCU_UART0_RTSn */
>;
u-boot,dm-spl;
};
wkup_i2c0_pins_default: wkup-i2c0-pins-default { wkup_i2c0_pins_default: wkup-i2c0-pins-default {
pinctrl-single,pins = < pinctrl-single,pins = <
AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0) /* (AC7) WKUP_I2C0_SCL */ AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0) /* (AC7) WKUP_I2C0_SCL */

View file

@ -12,6 +12,18 @@
stdout-path = "serial2:115200n8"; stdout-path = "serial2:115200n8";
bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000"; bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000";
}; };
aliases {
remoteproc0 = &mcu_r5fss0_core0;
remoteproc1 = &mcu_r5fss0_core1;
remoteproc2 = &main_r5fss0_core0;
remoteproc3 = &main_r5fss0_core1;
remoteproc4 = &main_r5fss1_core0;
remoteproc5 = &main_r5fss1_core1;
remoteproc6 = &c66_0;
remoteproc7 = &c66_1;
remoteproc8 = &c71_0;
};
}; };
&wkup_uart0 { &wkup_uart0 {
@ -19,6 +31,10 @@
status = "disabled"; status = "disabled";
}; };
&main_uart0 {
power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
};
&main_uart3 { &main_uart3 {
/* UART not brought out */ /* UART not brought out */
status = "disabled"; status = "disabled";

View file

@ -228,4 +228,115 @@
ti,trm-icp = <0x8>; ti,trm-icp = <0x8>;
dma-coherent; dma-coherent;
}; };
main_r5fss0: r5fss@5c00000 {
compatible = "ti,j721e-r5fss";
lockstep-mode = <0>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x5c00000 0x00 0x5c00000 0x20000>,
<0x5d00000 0x00 0x5d00000 0x20000>;
power-domains = <&k3_pds 243 TI_SCI_PD_EXCLUSIVE>;
main_r5fss0_core0: r5f@5c00000 {
compatible = "ti,j721e-r5f";
reg = <0x5c00000 0x00008000>,
<0x5c10000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <245>;
ti,sci-proc-ids = <0x06 0xFF>;
resets = <&k3_reset 245 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
main_r5fss0_core1: r5f@5d00000 {
compatible = "ti,j721e-r5f";
reg = <0x5d00000 0x00008000>,
<0x5d10000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <246>;
ti,sci-proc-ids = <0x07 0xFF>;
resets = <&k3_reset 246 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
};
main_r5fss1: r5fss@5e00000 {
compatible = "ti,j721e-r5fss";
lockstep-mode = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x5e00000 0x00 0x5e00000 0x20000>,
<0x5f00000 0x00 0x5f00000 0x20000>;
power-domains = <&k3_pds 244 TI_SCI_PD_EXCLUSIVE>;
main_r5fss1_core0: r5f@5e00000 {
compatible = "ti,j721e-r5f";
reg = <0x5e00000 0x00008000>,
<0x5e10000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <247>;
ti,sci-proc-ids = <0x08 0xFF>;
resets = <&k3_reset 247 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
main_r5fss1_core1: r5f@5f00000 {
compatible = "ti,j721e-r5f";
reg = <0x5f00000 0x00008000>,
<0x5f10000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <248>;
ti,sci-proc-ids = <0x09 0xFF>;
resets = <&k3_reset 248 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
};
c66_0: dsp@4d80800000 {
compatible = "ti,j721e-c66-dsp";
reg = <0x4d 0x80800000 0x00 0x00048000>,
<0x4d 0x80e00000 0x00 0x00008000>,
<0x4d 0x80f00000 0x00 0x00008000>;
reg-names = "l2sram", "l1pram", "l1dram";
ti,sci = <&dmsc>;
ti,sci-dev-id = <142>;
ti,sci-proc-ids = <0x03 0xFF>;
resets = <&k3_reset 142 1>;
};
c66_1: dsp@4d81800000 {
compatible = "ti,j721e-c66-dsp";
reg = <0x4d 0x81800000 0x00 0x00048000>,
<0x4d 0x81e00000 0x00 0x00008000>,
<0x4d 0x81f00000 0x00 0x00008000>;
reg-names = "l2sram", "l1pram", "l1dram";
ti,sci = <&dmsc>;
ti,sci-dev-id = <143>;
ti,sci-proc-ids = <0x04 0xFF>;
resets = <&k3_reset 143 1>;
};
c71_0: dsp@64800000 {
compatible = "ti,j721e-c71-dsp";
reg = <0x00 0x64800000 0x00 0x00080000>,
<0x00 0x64e00000 0x00 0x0000c000>;
reg-names = "l2sram", "l1dram";
ti,sci = <&dmsc>;
ti,sci-dev-id = <15>;
ti,sci-proc-ids = <0x30 0xFF>;
resets = <&k3_reset 15 1>;
};
}; };

View file

@ -69,4 +69,42 @@
clocks = <&k3_clks 149 0>; clocks = <&k3_clks 149 0>;
clock-names = "fclk"; clock-names = "fclk";
}; };
mcu_r5fss0: r5fss@41000000 {
compatible = "ti,j721e-r5fss";
lockstep-mode = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x41000000 0x00 0x41000000 0x20000>,
<0x41400000 0x00 0x41400000 0x20000>;
power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>;
mcu_r5fss0_core0: r5f@41000000 {
compatible = "ti,j721e-r5f";
reg = <0x41000000 0x00008000>,
<0x41010000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <250>;
ti,sci-proc-ids = <0x01 0xFF>;
resets = <&k3_reset 250 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
mcu_r5fss0_core1: r5f@41400000 {
compatible = "ti,j721e-r5f";
reg = <0x41400000 0x00008000>,
<0x41410000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <251>;
ti,sci-proc-ids = <0x02 0xFF>;
resets = <&k3_reset 251 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
};
}; };

View file

@ -66,6 +66,27 @@ config SYS_K3_BOOT_CORE_ID
int int
default 16 default 16
config K3_EARLY_CONS
bool "Activate to allow for an early console during SPL"
depends on SPL
help
Turn this option on to enable an early console functionality in SPL
before the main console is being brought up. This can be useful in
situations where the main console is dependent on System Firmware
(SYSFW) being up and running, which is usually not the case during
the very early stages of boot. Using this early console functionality
will allow for an alternate serial port to be used to support things
like UART-based boot and early diagnostic messages until the main
console is ready to get activated.
config K3_EARLY_CONS_IDX
depends on K3_EARLY_CONS
int "Index of serial device to use for SPL early console"
default 1
help
Use this option to set the index of the serial device to be used
for the early console during SPL execution.
config K3_LOAD_SYSFW config K3_LOAD_SYSFW
bool bool
depends on SPL depends on SPL

View file

@ -14,7 +14,7 @@
#ifdef CONFIG_SOC_K3_AM6 #ifdef CONFIG_SOC_K3_AM6
/* NR_DRAM_BANKS + 32bit IO + 64bit IO + terminator */ /* NR_DRAM_BANKS + 32bit IO + 64bit IO + terminator */
#define NR_MMU_REGIONS (CONFIG_NR_DRAM_BANKS + 3) #define NR_MMU_REGIONS (CONFIG_NR_DRAM_BANKS + 5)
/* ToDo: Add 64bit IO */ /* ToDo: Add 64bit IO */
struct mm_region am654_mem_map[NR_MMU_REGIONS] = { struct mm_region am654_mem_map[NR_MMU_REGIONS] = {
@ -28,7 +28,19 @@ struct mm_region am654_mem_map[NR_MMU_REGIONS] = {
}, { }, {
.virt = 0x80000000UL, .virt = 0x80000000UL,
.phys = 0x80000000UL, .phys = 0x80000000UL,
.size = 0x80000000UL, .size = 0x20000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0xa0000000UL,
.phys = 0xa0000000UL,
.size = 0x02100000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0xa2100000UL,
.phys = 0xa2100000UL,
.size = 0x5df00000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
@ -68,13 +80,13 @@ struct mm_region j721e_mem_map[NR_MMU_REGIONS] = {
}, { }, {
.virt = 0xa0000000UL, .virt = 0xa0000000UL,
.phys = 0xa0000000UL, .phys = 0xa0000000UL,
.size = 0x0bc00000UL, .size = 0x1bc00000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
PTE_BLOCK_NON_SHARE PTE_BLOCK_NON_SHARE
}, { }, {
.virt = 0xabc00000UL, .virt = 0xbbc00000UL,
.phys = 0xabc00000UL, .phys = 0xbbc00000UL,
.size = 0x54400000UL, .size = 0x44400000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {

View file

@ -14,19 +14,48 @@
#include <linux/soc/ti/ti_sci_protocol.h> #include <linux/soc/ti/ti_sci_protocol.h>
#include <fdt_support.h> #include <fdt_support.h>
#include <asm/arch/sys_proto.h> #include <asm/arch/sys_proto.h>
#include <asm/hardware.h>
#include <asm/io.h>
struct ti_sci_handle *get_ti_sci_handle(void) struct ti_sci_handle *get_ti_sci_handle(void)
{ {
struct udevice *dev; struct udevice *dev;
int ret; int ret;
ret = uclass_get_device(UCLASS_FIRMWARE, 0, &dev); ret = uclass_get_device_by_driver(UCLASS_FIRMWARE,
DM_GET_DRIVER(ti_sci), &dev);
if (ret) if (ret)
panic("Failed to get SYSFW (%d)\n", ret); panic("Failed to get SYSFW (%d)\n", ret);
return (struct ti_sci_handle *)ti_sci_get_handle_from_sysfw(dev); return (struct ti_sci_handle *)ti_sci_get_handle_from_sysfw(dev);
} }
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_K3_EARLY_CONS
int early_console_init(void)
{
struct udevice *dev;
int ret;
gd->baudrate = CONFIG_BAUDRATE;
ret = uclass_get_device_by_seq(UCLASS_SERIAL, CONFIG_K3_EARLY_CONS_IDX,
&dev);
if (ret) {
printf("Error getting serial dev for early console! (%d)\n",
ret);
return ret;
}
gd->cur_serial_dev = dev;
gd->flags |= GD_FLG_SERIAL_READY;
gd->have_console = 1;
return 0;
}
#endif
#ifdef CONFIG_SYS_K3_SPL_ATF #ifdef CONFIG_SYS_K3_SPL_ATF
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{ {
@ -164,3 +193,43 @@ void reset_cpu(ulong ignored)
{ {
} }
#endif #endif
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
u32 soc, rev;
char *name;
soc = (readl(CTRLMMR_WKUP_JTAG_DEVICE_ID) &
DEVICE_ID_FAMILY_MASK) >> DEVICE_ID_FAMILY_SHIFT;
rev = (readl(CTRLMMR_WKUP_JTAG_ID) &
JTAG_ID_VARIANT_MASK) >> JTAG_ID_VARIANT_SHIFT;
printf("SoC: ");
switch (soc) {
case AM654:
name = "AM654";
break;
case J721E:
name = "J721E";
break;
default:
name = "Unknown Silicon";
};
printf("%s PG ", name);
switch (rev) {
case REV_PG1_0:
name = "1.0";
break;
case REV_PG2_0:
name = "2.0";
break;
default:
name = "Unknown Revision";
};
printf("%s\n", name);
return 0;
}
#endif

View file

@ -8,4 +8,11 @@
#include <asm/armv7_mpu.h> #include <asm/armv7_mpu.h>
#define AM654 2
#define J721E 4
#define REV_PG1_0 0
#define REV_PG2_0 1
void setup_k3_mpu_regions(void); void setup_k3_mpu_regions(void);
int early_console_init(void);

View file

@ -13,4 +13,22 @@
#ifdef CONFIG_SOC_K3_J721E #ifdef CONFIG_SOC_K3_J721E
#include "j721e_hardware.h" #include "j721e_hardware.h"
#endif #endif
/* Assuming these addresses and definitions stay common across K3 devices */
#define CTRLMMR_WKUP_JTAG_DEVICE_ID 0x43000018
#define DEVICE_ID_FAMILY_SHIFT 26
#define DEVICE_ID_FAMILY_MASK (0x3f << 26)
#define DEVICE_ID_BASE_SHIFT 11
#define DEVICE_ID_BASE_MASK (0x1fff << 11)
#define DEVICE_ID_SPEED_SHIFT 6
#define DEVICE_ID_SPEED_MASK (0x1f << 6)
#define DEVICE_ID_TEMP_SHIFT 3
#define DEVICE_ID_TEMP_MASK (0x7 << 3)
#define CTRLMMR_WKUP_JTAG_ID 0x43000014
#define JTAG_ID_VARIANT_SHIFT 28
#define JTAG_ID_VARIANT_MASK (0xf << 28)
#define JTAG_ID_PARTNO_SHIFT 12
#define JTAG_ID_PARTNO_MASK (0x7ff << 1)
#endif /* _ASM_ARCH_HARDWARE_H_ */ #endif /* _ASM_ARCH_HARDWARE_H_ */

View file

@ -12,6 +12,9 @@
#include <remoteproc.h> #include <remoteproc.h>
#include <linux/soc/ti/ti_sci_protocol.h> #include <linux/soc/ti/ti_sci_protocol.h>
#include <asm/arch/sys_proto.h> #include <asm/arch/sys_proto.h>
#include "common.h"
DECLARE_GLOBAL_DATA_PTR;
/* Name of the FIT image nodes for SYSFW and its config data */ /* Name of the FIT image nodes for SYSFW and its config data */
#define SYSFW_FIRMWARE "sysfw.bin" #define SYSFW_FIRMWARE "sysfw.bin"
@ -214,6 +217,24 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void))
0); 0);
#endif #endif
break; break;
#endif
#if CONFIG_IS_ENABLED(YMODEM_SUPPORT)
case BOOT_DEVICE_UART:
#ifdef CONFIG_K3_EARLY_CONS
/*
* Establish a serial console if not yet available as required
* for UART-based boot. For this use the early console feature
* that allows setting up a UART for use before SYSFW has been
* brought up. Note that the associated UART module's clocks
* must have gotten enabled by the ROM bootcode which will be
* the case when continuing to boot serially from the same
* UART that the ROM loaded the initial bootloader from.
*/
if (!gd->have_console)
early_console_init();
#endif
ret = spl_ymodem_load_image(&spl_image, &bootdev);
break;
#endif #endif
default: default:
panic("Loading SYSFW image from device %u not supported!\n", panic("Loading SYSFW image from device %u not supported!\n",

View file

@ -89,6 +89,7 @@ config TARGET_AM335X_SHC
config TARGET_AM335X_GUARDIAN config TARGET_AM335X_GUARDIAN
bool "Support am335x based guardian board from bosch" bool "Support am335x based guardian board from bosch"
select BOARD_LATE_INIT
select DM select DM
select DM_SERIAL select DM_SERIAL
select DM_GPIO select DM_GPIO

View file

@ -348,52 +348,63 @@ static void dra7_reset_ddr_data(u32 base, u32 size)
static void dra7_enable_ecc(u32 base, const struct emif_regs *regs) static void dra7_enable_ecc(u32 base, const struct emif_regs *regs)
{ {
struct emif_reg_struct *emif = (struct emif_reg_struct *)base; struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
u32 rgn, size; u32 rgn, rgn_start, size, ctrl_reg;
/* ECC available only on dra76x EMIF1 */ /* ECC available only on dra76x EMIF1 */
if ((base != EMIF1_BASE) || !is_dra76x()) if ((base != EMIF1_BASE) || !is_dra76x())
return; return;
if (regs->emif_ecc_ctrl_reg & EMIF_ECC_CTRL_REG_ECC_EN_MASK) { if (regs->emif_ecc_ctrl_reg & EMIF_ECC_CTRL_REG_ECC_EN_MASK) {
writel(regs->emif_ecc_address_range_1, /* Disable high-order interleaving */
&emif->emif_ecc_address_range_1); clrbits_le32(MA_PRIORITY, MA_HIMEM_INTERLEAVE_UN_MASK);
writel(regs->emif_ecc_address_range_2,
&emif->emif_ecc_address_range_2);
writel(regs->emif_ecc_ctrl_reg, &emif->emif_ecc_ctrl_reg);
/* Set region1 memory with 0 */
rgn = ((regs->emif_ecc_address_range_1 &
EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) +
CONFIG_SYS_SDRAM_BASE;
size = (regs->emif_ecc_address_range_1 &
EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000;
if (regs->emif_ecc_ctrl_reg &
EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK)
dra7_reset_ddr_data(rgn, size);
/* Set region2 memory with 0 */
rgn = ((regs->emif_ecc_address_range_2 &
EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) +
CONFIG_SYS_SDRAM_BASE;
size = (regs->emif_ecc_address_range_2 &
EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000;
if (regs->emif_ecc_ctrl_reg &
EMIF_ECC_REG_ECC_ADDR_RGN_2_EN_MASK)
dra7_reset_ddr_data(rgn, size);
#ifdef CONFIG_DRA7XX #ifdef CONFIG_DRA7XX
/* Clear the status flags and other history */ /* Clear the status flags and other history */
writel(readl(&emif->emif_1b_ecc_err_cnt), writel(readl(&emif->emif_1b_ecc_err_cnt),
&emif->emif_1b_ecc_err_cnt); &emif->emif_1b_ecc_err_cnt);
writel(0xffffffff, &emif->emif_1b_ecc_err_dist_1); writel(0xffffffff, &emif->emif_1b_ecc_err_dist_1);
writel(0x2, &emif->emif_1b_ecc_err_addr_log);
writel(0x1, &emif->emif_2b_ecc_err_addr_log); writel(0x1, &emif->emif_2b_ecc_err_addr_log);
writel(EMIF_INT_WR_ECC_ERR_SYS_MASK | writel(EMIF_INT_WR_ECC_ERR_SYS_MASK |
EMIF_INT_TWOBIT_ECC_ERR_SYS_MASK | EMIF_INT_TWOBIT_ECC_ERR_SYS_MASK |
EMIF_INT_ONEBIT_ECC_ERR_SYS_MASK, EMIF_INT_ONEBIT_ECC_ERR_SYS_MASK,
&emif->emif_irqstatus_sys); &emif->emif_irqstatus_sys);
#endif #endif
writel(regs->emif_ecc_address_range_1,
&emif->emif_ecc_address_range_1);
writel(regs->emif_ecc_address_range_2,
&emif->emif_ecc_address_range_2);
/* Disable RMW and ECC verification for read accesses */
ctrl_reg = (regs->emif_ecc_ctrl_reg &
~EMIF_ECC_REG_RMW_EN_MASK) |
EMIF_ECC_CTRL_REG_ECC_VERIFY_DIS_MASK;
writel(ctrl_reg, &emif->emif_ecc_ctrl_reg);
/* Set region1 memory with 0 */
rgn_start = (regs->emif_ecc_address_range_1 &
EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16;
rgn = rgn_start + CONFIG_SYS_SDRAM_BASE;
size = (regs->emif_ecc_address_range_1 &
EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000 - rgn_start;
if (regs->emif_ecc_ctrl_reg &
EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK)
dra7_reset_ddr_data(rgn, size);
/* Set region2 memory with 0 */
rgn_start = (regs->emif_ecc_address_range_2 &
EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16;
rgn = rgn_start + CONFIG_SYS_SDRAM_BASE;
size = (regs->emif_ecc_address_range_2 &
EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000 - rgn_start;
if (regs->emif_ecc_ctrl_reg &
EMIF_ECC_REG_ECC_ADDR_RGN_2_EN_MASK)
dra7_reset_ddr_data(rgn, size);
/* Default value enables RMW and ECC verification */
writel(regs->emif_ecc_ctrl_reg, &emif->emif_ecc_ctrl_reg);
} }
} }

View file

@ -202,8 +202,9 @@ void __recalibrate_iodelay_end(int ret)
return; return;
} }
if (!ret) /* Deisolate IO if it is already isolated */
ret = isolate_io(DEISOLATE_IO); if (readl((*ctrl)->ctrl_core_sma_sw_0) & CTRL_ISOLATE_MASK)
isolate_io(DEISOLATE_IO);
/* lock IODELAY CONFIG registers */ /* lock IODELAY CONFIG registers */
writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base + writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base +
@ -240,6 +241,12 @@ void __recalibrate_iodelay_end(int ret)
debug("IODELAY: IO delay recalibration successfully completed\n"); debug("IODELAY: IO delay recalibration successfully completed\n");
} }
/* If there is an error during iodelay recalibration, SoC is in a bad
* state. Do not progress any further.
*/
if (ret)
hang();
return; return;
} }

View file

@ -172,6 +172,8 @@ void sdram_init(void)
int board_init(void) int board_init(void)
{ {
save_omap_boot_params();
#if defined(CONFIG_HW_WATCHDOG) #if defined(CONFIG_HW_WATCHDOG)
hw_watchdog_init(); hw_watchdog_init();
#endif #endif
@ -183,3 +185,54 @@ int board_init(void)
#endif #endif
return 0; return 0;
} }
#ifdef CONFIG_BOARD_LATE_INIT
static void set_bootmode_env(void)
{
char *boot_device_name = NULL;
char *boot_mode_gpio = "gpio@44e07000_14";
int ret;
int value;
struct gpio_desc boot_mode_desc;
switch (gd->arch.omap_boot_device) {
case BOOT_DEVICE_NAND:
boot_device_name = "nand";
break;
case BOOT_DEVICE_USBETH:
boot_device_name = "usbeth";
break;
default:
break;
}
if (boot_device_name)
env_set("boot_device", boot_device_name);
ret = dm_gpio_lookup_name(boot_mode_gpio, &boot_mode_desc);
if (ret) {
printf("%s is not found\n", boot_mode_gpio);
goto err;
}
ret = dm_gpio_request(&boot_mode_desc, "setup_bootmode_env");
if (ret && ret != -EBUSY) {
printf("requesting gpio: %s failed\n", boot_mode_gpio);
goto err;
}
value = dm_gpio_get_value(&boot_mode_desc);
value ? env_set("swi_status", "0") : env_set("swi_status", "1");
return;
err:
env_set("swi_status", "err");
}
int board_late_init(void)
{
set_bootmode_env();
return 0;
}
#endif /* CONFIG_BOARD_LATE_INIT */

View file

@ -26,24 +26,16 @@ static struct module_pin_mux i2c0_pin_mux[] = {
{-1}, {-1},
}; };
static struct module_pin_mux adc_voltages_en[] = { static struct module_pin_mux guardian_interfaces_pin_mux[] = {
{OFFSET(mcasp0_ahclkx), (MODE(7) | PULLUP_EN)}, {OFFSET(mcasp0_ahclkx), (MODE(7) | PULLDOWN_EN)},
{-1}, {OFFSET(mcasp0_aclkx), (MODE(7) | PULLUP_EN)},
}; {OFFSET(mii1_txd0), (MODE(7) | PULLUP_EN)},
{OFFSET(uart1_rxd), (MODE(7) | RXACTIVE | PULLUDDIS)},
static struct module_pin_mux asp_power_en[] = { {OFFSET(uart1_txd), (MODE(7) | PULLUDDIS)},
{OFFSET(mcasp0_aclkx), (MODE(7) | PULLUP_EN)}, {OFFSET(mii1_crs), (MODE(7) | PULLDOWN_EN)},
{-1}, {OFFSET(rmii1_refclk), (MODE(7) | PULLDOWN_EN)},
}; {OFFSET(mii1_txd3), (MODE(7) | PULLUDDIS)},
{OFFSET(mii1_rxdv), (MODE(7) | PULLDOWN_EN)},
static struct module_pin_mux switch_off_3v6_pin_mux[] = {
{OFFSET(mii1_txd0), (MODE(7) | PULLUP_EN)},
/*
* The uart1 lines are made floating inputs, based on the Guardian
* A2 Sample Power Supply Schematics
*/
{OFFSET(uart1_rxd), (MODE(7) | PULLUDDIS)},
{OFFSET(uart1_txd), (MODE(7) | PULLUDDIS)},
{-1}, {-1},
}; };
@ -93,7 +85,5 @@ void enable_board_pin_mux(void)
#ifdef CONFIG_NAND #ifdef CONFIG_NAND
configure_module_pin_mux(nand_pin_mux); configure_module_pin_mux(nand_pin_mux);
#endif #endif
configure_module_pin_mux(adc_voltages_en); configure_module_pin_mux(guardian_interfaces_pin_mux);
configure_module_pin_mux(asp_power_en);
configure_module_pin_mux(switch_off_3v6_pin_mux);
} }

View file

@ -791,6 +791,7 @@ int board_init(void)
#ifdef CONFIG_BOARD_LATE_INIT #ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void) int board_late_init(void)
{ {
struct udevice *dev;
#if !defined(CONFIG_SPL_BUILD) #if !defined(CONFIG_SPL_BUILD)
uint8_t mac_addr[6]; uint8_t mac_addr[6];
uint32_t mac_hi, mac_lo; uint32_t mac_hi, mac_lo;
@ -871,6 +872,9 @@ int board_late_init(void)
env_set("serial#", board_serial); env_set("serial#", board_serial);
} }
/* Just probe the potentially supported cdce913 device */
uclass_get_device(UCLASS_CLK, 0, &dev);
return 0; return 0;
} }
#endif #endif

View file

@ -720,6 +720,7 @@ static int device_okay(const char *path)
int board_late_init(void) int board_late_init(void)
{ {
struct udevice *dev;
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
set_board_info_env(NULL); set_board_info_env(NULL);
@ -737,6 +738,10 @@ int board_late_init(void)
if (device_okay("/ocp/omap_dwc3@483c0000")) if (device_okay("/ocp/omap_dwc3@483c0000"))
enable_usb_clocks(1); enable_usb_clocks(1);
#endif #endif
/* Just probe the potentially supported cdce913 device */
uclass_get_device(UCLASS_CLK, 0, &dev);
return 0; return 0;
} }
#endif #endif

View file

@ -30,6 +30,7 @@
#include <dwc3-omap-uboot.h> #include <dwc3-omap-uboot.h>
#include <ti-usb-phy-uboot.h> #include <ti-usb-phy-uboot.h>
#include <mmc.h> #include <mmc.h>
#include <dm/uclass.h>
#include "../common/board_detect.h" #include "../common/board_detect.h"
#include "mux_data.h" #include "mux_data.h"
@ -689,6 +690,7 @@ int board_late_init(void)
{ {
setup_board_eeprom_env(); setup_board_eeprom_env();
u8 val; u8 val;
struct udevice *dev;
/* /*
* DEV_CTRL.DEV_ON = 1 please - else palmas switches off in 8 seconds * DEV_CTRL.DEV_ON = 1 please - else palmas switches off in 8 seconds
@ -720,6 +722,9 @@ int board_late_init(void)
am57x_idk_lcd_detect(); am57x_idk_lcd_detect();
/* Just probe the potentially supported cdce913 device */
uclass_get_device(UCLASS_CLK, 0, &dev);
#if !defined(CONFIG_SPL_BUILD) #if !defined(CONFIG_SPL_BUILD)
board_ti_set_ethaddr(2); board_ti_set_ethaddr(2);
#endif #endif

View file

@ -261,3 +261,35 @@ To boot kernel from eMMC, use the following commands:
=> setenv mmcdev 0 => setenv mmcdev 0
=> setenv bootpart 0 => setenv bootpart 0
=> boot => boot
UART:
-----
ROM supports booting from MCU_UART0 via X-Modem protocol. The entire UART-based
boot process up to U-Boot (proper) prompt goes through different stages and uses
different UART peripherals as follows:
WHO | Loading WHAT | HW Module | Protocol
----------+---------------+-------------+------------
Boot ROM | tiboot3.bin | MCU_UART0 | X-Modem(*)
R5 SPL | sysfw.itb | MCU_UART0 | Y-Modem(*)
R5 SPL | tispl.bin | MAIN_UART0 | Y-Modem
A53 SPL | u-boot.img | MAIN_UART0 | Y-Modem
(*) Note that in addition to X/Y-Modem related protocol timeouts the DMSC
watchdog timeout of 3min (typ.) needs to be observed until System Firmware
is fully loaded (from sysfw.itb) and started.
Example bash script sequence for running on a Linux host PC feeding all boot
artifacts needed to the device:
MCU_DEV=/dev/ttyUSB1
MAIN_DEV=/dev/ttyUSB0
stty -F $MCU_DEV 115200 cs8 -cstopb -parenb
stty -F $MAIN_DEV 115200 cs8 -cstopb -parenb
sb --xmodem tiboot3.bin > $MCU_DEV < $MCU_DEV
sb --ymodem sysfw.itb > $MCU_DEV < $MCU_DEV
sb --ymodem tispl.bin > $MAIN_DEV < $MAIN_DEV
sleep 1
sb --xmodem u-boot.img > $MAIN_DEV < $MAIN_DEV

View file

@ -127,6 +127,19 @@ int do_board_detect(void)
return ret; return ret;
} }
int checkboard(void)
{
struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
if (do_board_detect())
/* EEPROM not populated */
printf("Board: %s rev %s\n", "AM6-COMPROCEVM", "E3");
else
printf("Board: %s rev %s\n", ep->name, ep->version);
return 0;
}
static void setup_board_eeprom_env(void) static void setup_board_eeprom_env(void)
{ {
char *name = "am65x"; char *name = "am65x";
@ -272,7 +285,7 @@ static int probe_daughtercards(void)
if (strncmp(ep.name, cards[i].card_name, sizeof(ep.name))) if (strncmp(ep.name, cards[i].card_name, sizeof(ep.name)))
continue; continue;
printf("detected %s\n", cards[i].card_name); printf("Detected: %s rev %s\n", ep.name, ep.version);
/* /*
* Populate any MAC addresses from daughtercard into the U-Boot * Populate any MAC addresses from daughtercard into the U-Boot

227
board/ti/j721e/README Normal file
View file

@ -0,0 +1,227 @@
Introduction:
-------------
The J721e family of SoCs are part of K3 Multicore SoC architecture platform
targeting automotive applications. They are designed as a low power, high
performance and highly integrated device architecture, adding significant
enhancement on processing power, graphics capability, video and imaging
processing, virtualization and coherent memory support.
The device is partitioned into three functional domains, each containing
specific processing cores and peripherals:
1. Wake-up (WKUP) domain:
- Device Management and Security Controller (DMSC)
2. Microcontroller (MCU) domain:
- Dual Core ARM Cortex-R5F processor
3. MAIN domain:
- Dual core 64-bit ARM Cortex-A72
- 2 x Dual cortex ARM Cortex-R5 subsystem
- 2 x C66x Digital signal processor sub system
- C71x Digital signal processor sub-system with MMA.
More info can be found in TRM: http://www.ti.com/lit/pdf/spruil1
Boot Flow:
----------
Boot flow is similar to that of AM65x SoC and extending it with remoteproc
support. Below is the pictorial representation of boot flow:
+------------------------------------------------------------------------+-----------------------+
| DMSC | MCU R5 | A72 | MAIN R5/C66x/C7x |
+------------------------------------------------------------------------+-----------------------+
| +--------+ | | | |
| | Reset | | | | |
| +--------+ | | | |
| : | | | |
| +--------+ | +-----------+ | | |
| | *ROM* |----------|-->| Reset rls | | | |
| +--------+ | +-----------+ | | |
| | | | : | | |
| | ROM | | : | | |
| |services| | : | | |
| | | | +-------------+ | | |
| | | | | *R5 ROM* | | | |
| | | | +-------------+ | | |
| | |<---------|---|Load and auth| | | |
| | | | | tiboot3.bin | | | |
| | | | +-------------+ | | |
| | | | : | | |
| | | | : | | |
| | | | : | | |
| | | | +-------------+ | | |
| | | | | *R5 SPL* | | | |
| | | | +-------------+ | | |
| | | | | Load | | | |
| | | | | sysfw.itb | | | |
| | Start | | +-------------+ | | |
| | System |<---------|---| Start | | | |
| |Firmware| | | SYSFW | | | |
| +--------+ | +-------------+ | | |
| : | | | | | |
| +---------+ | | Load | | | |
| | *SYSFW* | | | system | | | |
| +---------+ | | Config data | | | |
| | |<--------|---| | | | |
| | | | +-------------+ | | |
| | | | | DDR | | | |
| | | | | config | | | |
| | | | +-------------+ | | |
| | | | | Load | | | |
| | | | | tispl.bin | | | |
| | | | +-------------+ | | |
| | | | | Load R5 | | | |
| | | | | firmware | | | |
| | | | +-------------+ | | |
| | |<--------|---| Start A72 | | | |
| | | | | and jump to | | | |
| | | | | next image | | | |
| | | | +-------------+ | | |
| | | | | +-----------+ | |
| | |---------|-----------------------|---->| Reset rls | | |
| | | | | +-----------+ | |
| | DMSC | | | : | |
| |Services | | | +-----------+ | |
| | |<--------|-----------------------|---->|*ATF/OPTEE*| | |
| | | | | +-----------+ | |
| | | | | : | |
| | | | | +-----------+ | |
| | |<--------|-----------------------|---->| *A72 SPL* | | |
| | | | | +-----------+ | |
| | | | | | Load | | |
| | | | | | u-boot.img| | |
| | | | | +-----------+ | |
| | | | | : | |
| | | | | +-----------+ | |
| | |<--------|-----------------------|---->| *U-Boot* | | |
| | | | | +-----------+ | |
| | | | | | prompt | | |
| | | | | +-----------+ | |
| | | | | | Load R5 | | |
| | | | | | Firmware | | |
| | | | | +-----------+ | |
| | |<--------|-----------------------|-----| Start R5 | | +-----------+ |
| | |---------|-----------------------|-----+-----------+-----|----->| R5 starts | |
| | | | | | Load C6 | | +-----------+ |
| | | | | | Firmware | | |
| | | | | +-----------+ | |
| | |<--------|-----------------------|-----| Start C6 | | +-----------+ |
| | |---------|-----------------------|-----+-----------+-----|----->| C6 starts | |
| | | | | | Load C7 | | +-----------+ |
| | | | | | Firmware | | |
| | | | | +-----------+ | |
| | |<--------|-----------------------|-----| Start C7 | | +-----------+ |
| | |---------|-----------------------|-----+-----------+-----|----->| C7 starts | |
| +---------+ | | | +-----------+ |
| | | | |
+------------------------------------------------------------------------+-----------------------+
- Here DMSC acts as master and provides all the critical services. R5/A72
requests DMSC to get these services done as shown in the above diagram.
Sources:
--------
1. SYSFW:
Tree: git://git.ti.com/processor-firmware/system-firmware-image-gen.git
Branch: master
2. ATF:
Tree: https://github.com/ARM-software/arm-trusted-firmware.git
Branch: master
3. OPTEE:
Tree: https://github.com/OP-TEE/optee_os.git
Branch: master
4. U-Boot:
Tree: https://gitlab.denx.de/u-boot/u-boot
Branch: master
Build procedure:
----------------
1. SYSFW:
$ make CROSS_COMPILE=arm-linux-gnueabihf-
2. ATF:
$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=aarch64 PLAT=k3 TARGET_BOARD=generic SPD=opteed
3. OPTEE:
$ make PLATFORM=k3-j721e CFG_ARM64_core=y
4. U-Boot:
4.1. R5:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- j721e_evm_r5_defconfig O=/tmp/r5
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=/tmp/r5
4.2. A72:
$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- j721e_evm_a72_defconfig O=/tmp/a72
$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager.bin O=/tmp/a72
Target Images
--------------
Copy the below images to an SD card and boot:
- sysfw.itb from step 1
- tiboot3.bin from step 4.1
- tispl.bin, u-boot.img from 4.2
Image formats:
--------------
- tiboot3.bin:
+-----------------------+
| X.509 |
| Certificate |
| +-------------------+ |
| | | |
| | R5 | |
| | u-boot-spl.bin | |
| | | |
| +-------------------+ |
| | | |
| | FIT header | |
| | +---------------+ | |
| | | | | |
| | | DTB 1...N | | |
| | +---------------+ | |
| +-------------------+ |
+-----------------------+
- tispl.bin
+-----------------------+
| |
| FIT HEADER |
| +-------------------+ |
| | | |
| | A72 ATF | |
| +-------------------+ |
| | | |
| | A72 OPTEE | |
| +-------------------+ |
| | | |
| | A72 SPL | |
| +-------------------+ |
| | | |
| | SPL DTB 1...N | |
| +-------------------+ |
+-----------------------+
- sysfw.itb
+-----------------------+
| |
| FIT HEADER |
| +-------------------+ |
| | | |
| | sysfw.bin | |
| +-------------------+ |
| | | |
| | board config | |
| +-------------------+ |
| | | |
| | PM config | |
| +-------------------+ |
| | | |
| | RM config | |
| +-------------------+ |
| | | |
| | Secure config | |
| +-------------------+ |
+-----------------------+

View file

@ -202,10 +202,6 @@ static int ddr_memory_ecc_err(u32 addr, u32 ecc_err)
writel(val2, addr); writel(val2, addr);
val3 = readl(addr); val3 = readl(addr);
printf("\tECC test: addr 0x%x, read data 0x%x, written data 0x%x, err pattern: 0x%x, read after write data 0x%x\n",
addr, val1, val2, ecc_err, val3);
puts("\tECC test: Enabling DDR ECC ...\n");
#ifdef CONFIG_ARCH_KEYSTONE #ifdef CONFIG_ARCH_KEYSTONE
ecc_ctrl = ECC_START_ADDR1 | (ECC_END_ADDR1 << 16); ecc_ctrl = ECC_START_ADDR1 | (ECC_END_ADDR1 << 16);
writel(ecc_ctrl, EMIF1_BASE + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); writel(ecc_ctrl, EMIF1_BASE + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET);
@ -214,6 +210,11 @@ static int ddr_memory_ecc_err(u32 addr, u32 ecc_err)
writel(ecc_ctrl, &emif->emif_ecc_ctrl_reg); writel(ecc_ctrl, &emif->emif_ecc_ctrl_reg);
#endif #endif
printf("\tECC test: addr 0x%x, read data 0x%x, written data 0x%x, err pattern: 0x%x, read after write data 0x%x\n",
addr, val1, val2, ecc_err, val3);
puts("\tECC test: Enabled DDR ECC ...\n");
val1 = readl(addr); val1 = readl(addr);
printf("\tECC test: addr 0x%x, read data 0x%x\n", addr, val1); printf("\tECC test: addr 0x%x, read data 0x%x\n", addr, val1);
@ -242,8 +243,8 @@ static int is_addr_valid(u32 addr)
if (ecc_ctrl & EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK) { if (ecc_ctrl & EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK) {
start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16)
+ CONFIG_SYS_SDRAM_BASE; + CONFIG_SYS_SDRAM_BASE;
end_addr = start_addr + (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) end_addr = (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0xFFFF +
+ 0xFFFF; CONFIG_SYS_SDRAM_BASE;
if ((addr >= start_addr) && (addr <= end_addr)) if ((addr >= start_addr) && (addr <= end_addr))
/* addr within ecc address range 1 */ /* addr within ecc address range 1 */
return 1; return 1;
@ -254,8 +255,8 @@ static int is_addr_valid(u32 addr)
range = readl(&emif->emif_ecc_address_range_2); range = readl(&emif->emif_ecc_address_range_2);
start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16)
+ CONFIG_SYS_SDRAM_BASE; + CONFIG_SYS_SDRAM_BASE;
end_addr = start_addr + (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) end_addr = (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0xFFFF +
+ 0xFFFF; CONFIG_SYS_SDRAM_BASE;
if ((addr >= start_addr) && (addr <= end_addr)) if ((addr >= start_addr) && (addr <= end_addr))
/* addr within ecc address range 2 */ /* addr within ecc address range 2 */
return 1; return 1;

View file

@ -44,7 +44,8 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
while (info->image_read < offset) { while (info->image_read < offset) {
res = xyzModem_stream_read(buf, BUF_SIZE, &err); res = xyzModem_stream_read(buf, BUF_SIZE, &err);
if (res <= 0) if (res <= 0)
return res; break;
info->image_read += res; info->image_read += res;
} }
@ -57,7 +58,7 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
while (info->image_read < offset + size) { while (info->image_read < offset + size) {
res = xyzModem_stream_read(buf, BUF_SIZE, &err); res = xyzModem_stream_read(buf, BUF_SIZE, &err);
if (res <= 0) if (res <= 0)
return res; break;
memcpy(addr, buf, res); memcpy(addr, buf, res);
info->image_read += res; info->image_read += res;
@ -67,8 +68,8 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
return size; return size;
} }
static int spl_ymodem_load_image(struct spl_image_info *spl_image, int spl_ymodem_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev) struct spl_boot_device *bootdev)
{ {
ulong size = 0; ulong size = 0;
int err; int err;

View file

@ -77,3 +77,5 @@ CONFIG_DYNAMIC_CRC_TABLE=y
CONFIG_RSA=y CONFIG_RSA=y
CONFIG_LZO=y CONFIG_LZO=y
# CONFIG_OF_LIBFDT_OVERLAY is not set # CONFIG_OF_LIBFDT_OVERLAY is not set
CONFIG_CLK=y
CONFIG_CLK_CDCE9XX=y

View file

@ -6,11 +6,10 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_AM33XX=y CONFIG_AM33XX=y
CONFIG_TARGET_AM335X_GUARDIAN=y CONFIG_TARGET_AM335X_GUARDIAN=y
CONFIG_SPL_MMC_SUPPORT=y # CONFIG_SPL_MMC_SUPPORT is not set
CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_ENV_SIZE=0x040000 CONFIG_ENV_SIZE=0x040000
CONFIG_ENV_OFFSET=0x300000
CONFIG_SPL=y CONFIG_SPL=y
CONFIG_BOOTSTAGE_STASH_ADDR=0x0 CONFIG_BOOTSTAGE_STASH_ADDR=0x0
CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_LIBDISK_SUPPORT=y
@ -21,6 +20,7 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y CONFIG_ARCH_MISC_INIT=y
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_SEPARATE_BSS=y
# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_ENV_SUPPORT=y
CONFIG_SPL_ETH_SUPPORT=y CONFIG_SPL_ETH_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_I2C_SUPPORT=y
@ -30,8 +30,8 @@ CONFIG_SPL_NET_VCI_STRING="Guardian U-Boot SPL"
CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_POWER_SUPPORT=y
CONFIG_SPL_USB_GADGET=y CONFIG_SPL_USB_GADGET=y
CONFIG_SPL_USB_ETHER=y CONFIG_SPL_USB_ETHER=y
CONFIG_SPL_WATCHDOG_SUPPORT=y # CONFIG_SPL_WATCHDOG_SUPPORT is not set
CONFIG_SPL_YMODEM_SUPPORT=y # CONFIG_SPL_YMODEM_SUPPORT is not set
CONFIG_AUTOBOOT_KEYED=y CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
CONFIG_AUTOBOOT_DELAY_STR="d" CONFIG_AUTOBOOT_DELAY_STR="d"
@ -43,14 +43,14 @@ CONFIG_CMD_ASKENV=y
CONFIG_CMD_GPIO=y CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y # CONFIG_CMD_MMC is not set
CONFIG_CMD_MTD=y CONFIG_CMD_MTD=y
CONFIG_CMD_NAND=y CONFIG_CMD_NAND=y
CONFIG_CMD_USB=y CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_MTDPARTS=y CONFIG_CMD_MTDPARTS=y
CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(SPL),256k(SPL.backup1),256k(SPL.backup2),256k(SPL.backup3),1m(u-boot),1m(u-boot.backup1),256k(u-boot-env),256k(u-boot-env.backup1),-(UBI)" CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(SPL),256k(SPL.backup1),256k(SPL.backup2),256k(SPL.backup3),1m(u-boot),1m(u-boot.backup1),-(UBI)"
CONFIG_CMD_UBI=y CONFIG_CMD_UBI=y
# CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_ISO_PARTITION is not set # CONFIG_ISO_PARTITION is not set
@ -58,14 +58,17 @@ CONFIG_CMD_UBI=y
CONFIG_OF_CONTROL=y CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="am335x-guardian" CONFIG_DEFAULT_DEVICE_TREE="am335x-guardian"
CONFIG_ENV_IS_IN_NAND=y CONFIG_OF_SEPARATE=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_SPL_ENV_IS_NOWHERE=y CONFIG_SPL_ENV_IS_NOWHERE=y
CONFIG_SPL_DM=y CONFIG_SPL_DM=y
CONFIG_SPL_DM_USB=y
CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_ENV=y CONFIG_BOOTCOUNT_ENV=y
CONFIG_MISC=y CONFIG_MISC=y
CONFIG_DM_MMC=y # CONFIG_DM_MMC is not set
CONFIG_MMC_OMAP_HS=y # CONFIG_MMC is not set
# CONFIG_MMC_OMAP_HS is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_NAND=y CONFIG_NAND=y
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
@ -78,15 +81,19 @@ CONFIG_PHY=y
CONFIG_NOP_PHY=y CONFIG_NOP_PHY=y
CONFIG_PINCTRL=y CONFIG_PINCTRL=y
CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_SINGLE=y
# CONFIG_WATCHDOG is not set
CONFIG_SPL_WDT=y
CONFIG_USB=y CONFIG_USB=y
CONFIG_DM_USB_GADGET=y CONFIG_DM_USB_GADGET=y
CONFIG_SPL_DM_USB_GADGET=y CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_MUSB_HOST=y CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_GADGET=y CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
CONFIG_USB_ETHER=y CONFIG_USB_ETHER=y
# CONFIG_USB_STORAGE is not set
CONFIG_FAT_WRITE=y CONFIG_FAT_WRITE=y

View file

@ -18,6 +18,7 @@ CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_NET_SUPPORT=y CONFIG_SPL_NET_SUPPORT=y
CONFIG_SPL_NET_VCI_STRING="AM43xx U-Boot SPL" CONFIG_SPL_NET_VCI_STRING="AM43xx U-Boot SPL"
CONFIG_SPL_OS_BOOT=y CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_USB_HOST_SUPPORT=y
CONFIG_SPL_USB_GADGET=y CONFIG_SPL_USB_GADGET=y
CONFIG_SPL_USB_ETHER=y CONFIG_SPL_USB_ETHER=y
CONFIG_CMD_SPL=y CONFIG_CMD_SPL=y
@ -78,3 +79,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0403
CONFIG_USB_GADGET_PRODUCT_NUM=0xbd00 CONFIG_USB_GADGET_PRODUCT_NUM=0xbd00
CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_USB_ETHER=y CONFIG_USB_ETHER=y
CONFIG_CLK=y
CONFIG_CLK_CDCE9XX=y

View file

@ -98,3 +98,5 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
CONFIG_CLK=y
CONFIG_CLK_CDCE9XX=y

View file

@ -12,13 +12,13 @@ CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL_STACK_R_ADDR=0x82000000 CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FS_FAT=y CONFIG_SPL_FS_FAT=y
CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_LIBDISK_SUPPORT=y
# CONFIG_PSCI_RESET is not set
CONFIG_SPL_TEXT_BASE=0x80080000 CONFIG_SPL_TEXT_BASE=0x80080000
CONFIG_DISTRO_DEFAULTS=y CONFIG_DISTRO_DEFAULTS=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT=y
CONFIG_OF_BOARD_SETUP=y CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern" CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_SEPARATE_BSS=y
@ -35,6 +35,7 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y CONFIG_CMD_PCI=y
CONFIG_CMD_REMOTEPROC=y
# CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y CONFIG_CMD_TIME=y
# CONFIG_ISO_PARTITION is not set # CONFIG_ISO_PARTITION is not set
@ -83,6 +84,7 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_SINGLE=y
CONFIG_POWER_DOMAIN=y CONFIG_POWER_DOMAIN=y
CONFIG_TI_SCI_POWER_DOMAIN=y CONFIG_TI_SCI_POWER_DOMAIN=y
CONFIG_REMOTEPROC_TI_K3_R5F=y
CONFIG_DM_RESET=y CONFIG_DM_RESET=y
CONFIG_RESET_TI_SCI=y CONFIG_RESET_TI_SCI=y
CONFIG_DM_SERIAL=y CONFIG_DM_SERIAL=y

View file

@ -5,6 +5,7 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x55000 CONFIG_SYS_MALLOC_F_LEN=0x55000
CONFIG_SOC_K3_AM6=y CONFIG_SOC_K3_AM6=y
CONFIG_K3_EARLY_CONS=y
CONFIG_TARGET_AM654_R5_EVM=y CONFIG_TARGET_AM654_R5_EVM=y
CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y

View file

@ -21,7 +21,6 @@ CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
CONFIG_OF_BOARD_SETUP=y CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_fit_${boot}; run get_overlaystring; run run_fit" CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_fit_${boot}; run get_overlaystring; run run_fit"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_SEPARATE_BSS=y

View file

@ -14,12 +14,12 @@ CONFIG_SPL_FS_FAT=y
CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y
# CONFIG_PSCI_RESET is not set
CONFIG_SPL_TEXT_BASE=0x80080000 CONFIG_SPL_TEXT_BASE=0x80080000
CONFIG_DISTRO_DEFAULTS=y CONFIG_DISTRO_DEFAULTS=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT=y
CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern" CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_SEPARATE_BSS=y
@ -34,6 +34,7 @@ CONFIG_SPL_YMODEM_SUPPORT=y
CONFIG_CMD_ASKENV=y CONFIG_CMD_ASKENV=y
# CONFIG_CMD_FLASH is not set # CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y CONFIG_CMD_MMC=y
CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SF=y CONFIG_CMD_SF=y
# CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y CONFIG_CMD_TIME=y
@ -72,6 +73,8 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_SINGLE=y
CONFIG_POWER_DOMAIN=y CONFIG_POWER_DOMAIN=y
CONFIG_TI_SCI_POWER_DOMAIN=y CONFIG_TI_SCI_POWER_DOMAIN=y
CONFIG_REMOTEPROC_TI_K3_DSP=y
CONFIG_REMOTEPROC_TI_K3_R5F=y
CONFIG_DM_RESET=y CONFIG_DM_RESET=y
CONFIG_RESET_TI_SCI=y CONFIG_RESET_TI_SCI=y
CONFIG_DM_SERIAL=y CONFIG_DM_SERIAL=y

View file

@ -0,0 +1,49 @@
Binding for TI CDCE913/925/937/949 programmable I2C clock synthesizers.
Reference
This binding uses the common clock binding[1].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] http://www.ti.com/product/cdce913
[3] http://www.ti.com/product/cdce925
[4] http://www.ti.com/product/cdce937
[5] http://www.ti.com/product/cdce949
The driver provides clock sources for each output Y1 through Y5.
Required properties:
- compatible: Shall be one of the following:
- "ti,cdce913": 1-PLL, 3 Outputs
- "ti,cdce925": 2-PLL, 5 Outputs
- "ti,cdce937": 3-PLL, 7 Outputs
- "ti,cdce949": 4-PLL, 9 Outputs
- reg: I2C device address.
- clocks: Points to a fixed parent clock that provides the input frequency.
- #clock-cells: From common clock bindings: Shall be 1.
Optional properties:
- xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a
board, or to compensate for external influences.
For all PLL1, PLL2, ... an optional child node can be used to specify spread
spectrum clocking parameters for a board.
- spread-spectrum: SSC mode as defined in the data sheet.
- spread-spectrum-center: Use "centered" mode instead of "max" mode. When
present, the clock runs at the requested frequency on average. Otherwise
the requested frequency is the maximum value of the SCC range.
Example:
clockgen: cdce925pw@64 {
compatible = "cdce925";
reg = <0x64>;
clocks = <&xtal_27Mhz>;
#clock-cells = <1>;
xtal-load-pf = <5>;
/* PLL options to get SSC 1% centered */
PLL2 {
spread-spectrum = <4>;
spread-spectrum-center;
};
};

View file

@ -0,0 +1,101 @@
TI K3 DSP devices
=================
The TI K3 family of SoCs usually have one or more TI DSP Core sub-systems that
are used to offload some of the processor-intensive tasks or algorithms, for
achieving various system level goals.
These processor sub-systems usually contain additional sub-modules like L1
and/or L2 caches/SRAMs, an Interrupt Controller, an external memory controller,
a dedicated local power/sleep controller etc. The DSP processor cores in the
K3 SoCs is usually either a TMS320C66x CorePac processor or a TMS320C71x CorePac
processor.
DSP Device Node:
================
Each DSP Core sub-system is represented as a single DT node. Each node has a
number of required or optional properties that enable the OS running on the
host processor (Arm CorePac) to perform the device management of the remote
processor and to communicate with the remote processor.
Required properties:
--------------------
The following are the mandatory properties:
- compatible: Should be one of the following,
"ti,j721e-c66-dsp" for C66x DSPs on K3 J721E SoCs
"ti,j721e-c71-dsp" for C71x DSPs on K3 J721E SoCs
- reg: Should contain an entry for each value in 'reg-names'.
Each entry should have the memory region's start address
and the size of the region, the representation matching
the parent node's '#address-cells' and '#size-cells' values.
- reg-names: Should contain strings with the following names, each
representing a specific internal memory region (if
present), and should be defined in this order,
"l2sram", "l1pram", "l1dram"
NOTE: C71x DSPs do not have a "l1pram" memory.
- ti,sci: Should be a phandle to the TI-SCI System Controller node
- ti,sci-dev-id: Should contain the TI-SCI device id corresponding to the
DSP Core. Please refer to the corresponding System
Controller documentation for valid values for the DSP
cores.
- ti,sci-proc-ids: Should contain 2 integer values. The first cell should
contain the TI-SCI processor id for the DSP core device
and the second cell should contain the TI-SCI host id to
which the processor control ownership should be
transferred to.
- resets: Should contain the phandle to the reset controller node
managing the resets for this device, and a reset
specifier. Please refer to the following reset bindings
for the reset argument specifier,
Documentation/devicetree/bindings/reset/ti,sci-reset.txt
Example:
---------
1. J721E SoC
/* J721E remoteproc alias */
aliases {
rproc6 = &c66_0;
rproc8 = &c71_0;
};
cbass_main: interconnect@100000 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x64800000 0x00 0x64800000 0x00 0x00800000>, /* C71_0 */
<0x4d 0x80800000 0x4d 0x80800000 0x00 0x00800000>, /* C66_0 */
<0x4d 0x81800000 0x4d 0x81800000 0x00 0x00800000>; /* C66_1 */
/* J721E C66_0 DSP node */
c66_0: dsp@4d80800000 {
compatible = "ti,j721e-c66-dsp";
reg = <0x4d 0x80800000 0x00 0x00048000>,
<0x4d 0x80e00000 0x00 0x00008000>,
<0x4d 0x80f00000 0x00 0x00008000>;
reg-names = "l2sram", "l1pram", "l1dram";
ti,sci = <&dmsc>;
ti,sci-dev-id = <142>;
ti,sci-proc-ids = <0x03 0xFF>;
resets = <&k3_reset 142 1>;
};
/* J721E C71_0 DSP node */
c71_0: dsp@64800000 {
compatible = "ti,j721e-c71-dsp";
reg = <0x00 0x64800000 0x00 0x00080000>,
<0x00 0x64e00000 0x00 0x0000c000>;
reg-names = "l2sram", "l1dram";
ti,sci = <&dmsc>;
ti,sci-dev-id = <15>;
ti,sci-proc-ids = <0x30 0xFF>;
resets = <&k3_reset 15 1>;
};
};

View file

@ -0,0 +1,164 @@
TI K3 R5F processor subsystems
==============================
The TI K3 family of SoCs usually have one or more dual-core Arm Cortex
R5F processor subsystems/clusters (R5FSS). The dual core cluster can be
used either in a LockStep mode providing safety/fault tolerance features
or in a Split mode providing two individual compute cores for doubling
the compute capacity. These are used together with other processors
present on the SoC to achieve various system level goals.
R5F Sub-System Device Node:
===========================
Each Dual-Core R5F sub-system is represented as a single DTS node representing
the cluster, with a pair of child DT nodes representing the individual R5F
cores. Each node has a number of required or optional properties that enable
the OS running on the host processor to perform the device management of the
remote processor and to communicate with the remote processor.
Required properties:
--------------------
The following are the mandatory properties:
- compatible: Should be one of the following,
"ti,am654-r5fss" for R5F clusters/subsystems on
K3 AM65x SoCs
"ti,j721e-r5fss" for R5F clusters/subsystems on
K3 J721E SoCs
- power-domains: Should contain a phandle to a PM domain provider node
and an args specifier containing the R5FSS device id
value. This property is as per the binding,
Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
- #address-cells: Should be 1
- #size-cells: Should be 1
- ranges: Standard ranges definition providing translations for
R5F TCM address spaces
Optional properties:
--------------------
- lockstep-mode: Configuration Mode for the Dual R5F cores within the R5F
cluster. Should be either a value of 1 (LockStep mode) or
0 (Split mode), default is LockStep mode if omitted.
R5F Processor Child Nodes:
==========================
The R5F Sub-System device node should define two R5F child nodes, each node
representing a TI instantiation of the Arm Cortex R5F core. There are some
specific integration differences for the IP like the usage of a Region Address
Translator (RAT) for translating the larger SoC bus addresses into a 32-bit
address space for the processor.
Required properties:
--------------------
The following are the mandatory properties:
- compatible: Should be one of the following,
"ti,am654-r5f" for the R5F cores in K3 AM65x SoCs
"ti,j721e-r5f" for the R5F cores in K3 J721E SOCs
- reg: Should contain an entry for each value in 'reg-names'.
Each entry should have the memory region's start address
and the size of the region, the representation matching
the parent node's '#address-cells' and '#size-cells' values.
- reg-names: Should contain strings with the following names, each
representing a specific internal memory region, and
should be defined in this order,
"atcm", "btcm"
- ti,sci: Should be a phandle to the TI-SCI System Controller node
- ti,sci-dev-id: Should contain the TI-SCI device id corresponding to the
R5F Core. Please refer to the corresponding System
Controller documentation for valid values for the R5F
cores.
- ti,sci-proc-ids: Should contain 2 integer values. The first cell should
contain the TI-SCI processor id for the R5F core device
and the second cell should contain the TI-SCI host id to
which the processor control ownership should be
transferred to.
- resets: Should contain the phandle to the reset controller node
managing the resets for this device, and a reset
specifier. Please refer to the following reset bindings
for the reset argument specifier,
Documentation/devicetree/bindings/reset/ti,sci-reset.txt
for AM65x and J721E SoCs
Optional properties:
--------------------
The following properties are optional properties for each of the R5F cores:
- atcm-enable: R5F core configuration mode dictating if ATCM should be
enabled. Should be either a value of 1 (enabled) or
0 (disabled), default is disabled if omitted. R5F view
of ATCM dictated by loczrama property.
- btcm-enable: R5F core configuration mode dictating if BTCM should be
enabled. Should be either a value of 1 (enabled) or
0 (disabled), default is enabled if omitted. R5F view
of BTCM dictated by loczrama property.
- loczrama: R5F core configuration mode dictating which TCM should
appear at address 0 (from core's view). Should be either
a value of 1 (ATCM at 0x0) or 0 (BTCM at 0x0), default
value is 1 if omitted.
Example:
--------
1. AM654 SoC
/* AM65x remoteproc alias */
aliases {
remoteproc0 = &mcu_r5fss0_core0;
};
cbass_main: interconnect@100000 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>,
<0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>,
<0x00 0x41c00000 0x00 0x41c00000 0x00 0x00080000>;
cbass_mcu: interconnect@28380000 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>, /* MCU R5F Core0 */
<0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>, /* MCU R5F Core1 */
<0x00 0x41c00000 0x00 0x41c00000 0x00 0x00080000>; /* MCU SRAM */
/* AM65x MCU R5FSS node */
mcu_r5fss0: r5fss@41000000 {
compatible = "ti,am654-r5fss";
power-domains = <&k3_pds 129>;
lockstep-mode = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x41000000 0x00 0x41000000 0x20000>,
<0x41400000 0x00 0x41400000 0x20000>;
mcu_r5f0: r5f@41000000 {
compatible = "ti,am654-r5f";
reg = <0x41000000 0x00008000>,
<0x41010000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <159>;
ti,sci-proc-ids = <0x01 0xFF>;
resets = <&k3_reset 159 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
mcu_r5f1: r5f@41400000 {
compatible = "ti,am654-r5f";
reg = <0x41400000 0x00008000>,
<0x41410000 0x00008000>;
reg-names = "atcm", "btcm";
ti,sci = <&dmsc>;
ti,sci-dev-id = <245>;
ti,sci-proc-ids = <0x02 0xFF>;
resets = <&k3_reset 245 1>;
atcm-enable = <1>;
btcm-enable = <1>;
loczrama = <1>;
};
};
};
};

View file

@ -134,6 +134,13 @@ config CLK_STM32MP1
Enable the STM32 clock (RCC) driver. Enable support for Enable the STM32 clock (RCC) driver. Enable support for
manipulating STM32MP1's on-SoC clocks. manipulating STM32MP1's on-SoC clocks.
config CLK_CDCE9XX
bool "Enable CDCD9XX clock driver"
depends on CLK
help
Enable the clock synthesizer driver for CDCE913/925/937/949
series of chips.
source "drivers/clk/analogbits/Kconfig" source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/at91/Kconfig" source "drivers/clk/at91/Kconfig"
source "drivers/clk/exynos/Kconfig" source "drivers/clk/exynos/Kconfig"

View file

@ -44,3 +44,4 @@ obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
obj-$(CONFIG_STM32H7) += clk_stm32h7.o obj-$(CONFIG_STM32H7) += clk_stm32h7.o
obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o
obj-$(CONFIG_CLK_VERSAL) += clk_versal.o obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o

254
drivers/clk/clk-cdce9xx.c Normal file
View file

@ -0,0 +1,254 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Texas Instruments CDCE913/925/937/949 clock synthesizer driver
*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
* Tero Kristo <t-kristo@ti.com>
*
* Based on Linux kernel clk-cdce925.c.
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <clk-uclass.h>
#include <i2c.h>
#define MAX_NUMBER_OF_PLLS 4
#define MAX_NUMER_OF_OUTPUTS 9
#define CDCE9XX_REG_GLOBAL1 0x01
#define CDCE9XX_REG_Y1SPIPDIVH 0x02
#define CDCE9XX_REG_PDIV1L 0x03
#define CDCE9XX_REG_XCSEL 0x05
#define CDCE9XX_PDIV1_H_MASK 0x3
#define CDCE9XX_REG_PDIV(clk) (0x16 + (((clk) - 1) & 1) + \
((clk) - 1) / 2 * 0x10)
#define CDCE9XX_PDIV_MASK 0x7f
#define CDCE9XX_BYTE_TRANSFER BIT(7)
struct cdce9xx_chip_info {
int num_plls;
int num_outputs;
};
struct cdce9xx_clk_data {
struct udevice *i2c;
struct cdce9xx_chip_info *chip;
u32 xtal_rate;
};
static const struct cdce9xx_chip_info cdce913_chip_info = {
.num_plls = 1, .num_outputs = 3,
};
static const struct cdce9xx_chip_info cdce925_chip_info = {
.num_plls = 2, .num_outputs = 5,
};
static const struct cdce9xx_chip_info cdce937_chip_info = {
.num_plls = 3, .num_outputs = 7,
};
static const struct cdce9xx_chip_info cdce949_chip_info = {
.num_plls = 4, .num_outputs = 9,
};
static int cdce9xx_reg_read(struct udevice *dev, u8 addr, u8 *buf)
{
struct cdce9xx_clk_data *data = dev_get_priv(dev);
int ret;
ret = dm_i2c_read(data->i2c, addr | CDCE9XX_BYTE_TRANSFER, buf, 1);
if (ret)
dev_err(dev, "%s: failed for addr:%x, ret:%d\n", __func__,
addr, ret);
return ret;
}
static int cdce9xx_reg_write(struct udevice *dev, u8 addr, u8 val)
{
struct cdce9xx_clk_data *data = dev_get_priv(dev);
int ret;
ret = dm_i2c_write(data->i2c, addr | CDCE9XX_BYTE_TRANSFER, &val, 1);
if (ret)
dev_err(dev, "%s: failed for addr:%x, ret:%d\n", __func__,
addr, ret);
return ret;
}
static int cdce9xx_clk_of_xlate(struct clk *clk,
struct ofnode_phandle_args *args)
{
struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);
if (args->args_count != 1)
return -EINVAL;
if (args->args[0] > data->chip->num_outputs)
return -EINVAL;
clk->id = args->args[0];
return 0;
}
static int cdce9xx_clk_probe(struct udevice *dev)
{
struct cdce9xx_clk_data *data = dev_get_priv(dev);
struct cdce9xx_chip_info *chip = (void *)dev_get_driver_data(dev);
int ret;
u32 val;
struct clk clk;
val = (u32)dev_read_addr_ptr(dev);
ret = i2c_get_chip(dev->parent, val, 1, &data->i2c);
if (ret) {
dev_err(dev, "I2C probe failed.\n");
return ret;
}
data->chip = chip;
ret = clk_get_by_index(dev, 0, &clk);
data->xtal_rate = clk_get_rate(&clk);
val = dev_read_u32_default(dev, "xtal-load-pf", -1);
if (val >= 0)
cdce9xx_reg_write(dev, CDCE9XX_REG_XCSEL, val << 3);
return 0;
}
static u16 cdce9xx_clk_get_pdiv(struct clk *clk)
{
u8 val;
u16 pdiv;
int ret;
if (clk->id == 0) {
ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, &val);
if (ret)
return 0;
pdiv = (val & CDCE9XX_PDIV1_H_MASK) << 8;
ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV1L, &val);
if (ret)
return 0;
pdiv |= val;
} else {
ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV(clk->id),
&val);
if (ret)
return 0;
pdiv = val & CDCE9XX_PDIV_MASK;
}
return pdiv;
}
static u32 cdce9xx_clk_get_parent_rate(struct clk *clk)
{
struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);
return data->xtal_rate;
}
static ulong cdce9xx_clk_get_rate(struct clk *clk)
{
u32 parent_rate;
u16 pdiv;
parent_rate = cdce9xx_clk_get_parent_rate(clk);
pdiv = cdce9xx_clk_get_pdiv(clk);
return parent_rate / pdiv;
}
static ulong cdce9xx_clk_set_rate(struct clk *clk, ulong rate)
{
u32 parent_rate;
int pdiv;
u32 diff;
u8 val;
int ret;
parent_rate = cdce9xx_clk_get_parent_rate(clk);
pdiv = parent_rate / rate;
diff = rate - parent_rate / pdiv;
if (rate - parent_rate / (pdiv + 1) < diff)
pdiv++;
if (clk->id == 0) {
ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, &val);
if (ret)
return ret;
val &= ~CDCE9XX_PDIV1_H_MASK;
val |= (pdiv >> 8);
ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, val);
if (ret)
return ret;
ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_PDIV1L,
(pdiv & 0xff));
if (ret)
return ret;
} else {
ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV(clk->id),
&val);
if (ret)
return ret;
val &= ~CDCE9XX_PDIV_MASK;
val |= pdiv;
ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_PDIV(clk->id),
val);
if (ret)
return ret;
}
return 0;
}
static const struct udevice_id cdce9xx_clk_of_match[] = {
{ .compatible = "ti,cdce913", .data = (u32)&cdce913_chip_info },
{ .compatible = "ti,cdce925", .data = (u32)&cdce925_chip_info },
{ .compatible = "ti,cdce937", .data = (u32)&cdce937_chip_info },
{ .compatible = "ti,cdce949", .data = (u32)&cdce949_chip_info },
{ /* sentinel */ },
};
static const struct clk_ops cdce9xx_clk_ops = {
.of_xlate = cdce9xx_clk_of_xlate,
.get_rate = cdce9xx_clk_get_rate,
.set_rate = cdce9xx_clk_set_rate,
};
U_BOOT_DRIVER(cdce9xx_clk) = {
.name = "cdce9xx-clk",
.id = UCLASS_CLK,
.of_match = cdce9xx_clk_of_match,
.probe = cdce9xx_clk_probe,
.priv_auto_alloc_size = sizeof(struct cdce9xx_clk_data),
.ops = &cdce9xx_clk_ops,
};

View file

@ -568,6 +568,17 @@ int device_get_child(struct udevice *parent, int index, struct udevice **devp)
return -ENODEV; return -ENODEV;
} }
int device_get_child_count(struct udevice *parent)
{
struct udevice *dev;
int count = 0;
list_for_each_entry(dev, &parent->child_head, sibling_node)
count++;
return count;
}
int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq, int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
bool find_req_seq, struct udevice **devp) bool find_req_seq, struct udevice **devp)
{ {

View file

@ -219,23 +219,10 @@ static int am654_sdhci_probe(struct udevice *dev)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sdhci_host *host = dev_get_priv(dev); struct sdhci_host *host = dev_get_priv(dev);
struct mmc_config *cfg = &plat->cfg; struct mmc_config *cfg = &plat->cfg;
struct power_domain sdhci_pwrdmn;
struct clk clk; struct clk clk;
unsigned long clock; unsigned long clock;
int ret; int ret;
ret = power_domain_get_by_index(dev, &sdhci_pwrdmn, 0);
if (!ret) {
ret = power_domain_on(&sdhci_pwrdmn);
if (ret) {
dev_err(dev, "Power domain on failed (%d)\n", ret);
return ret;
}
} else if (ret != -ENOENT && ret != -ENODEV && ret != -ENOSYS) {
dev_err(dev, "failed to get power domain (%d)\n", ret);
return ret;
}
ret = clk_get_by_index(dev, 0, &clk); ret = clk_get_by_index(dev, 0, &clk);
if (ret) { if (ret) {
dev_err(dev, "failed to get clock\n"); dev_err(dev, "failed to get clock\n");

View file

@ -52,6 +52,26 @@ config REMOTEPROC_TI_K3_ARM64
on various TI K3 family of SoCs through the remote processor on various TI K3 family of SoCs through the remote processor
framework. framework.
config REMOTEPROC_TI_K3_DSP
bool "TI K3 C66 and C71 remoteproc support"
select REMOTEPROC
depends on ARCH_K3
depends on TI_SCI_PROTOCOL
help
Say y here to support TI's C66/C71 remote processor subsystems
on various TI K3 family of SoCs through the remote processor
framework.
config REMOTEPROC_TI_K3_R5F
bool "TI K3 R5F remoteproc support"
select REMOTEPROC
depends on ARCH_K3
depends on TI_SCI_PROTOCOL
help
Say y here to support TI's R5F remote processor subsystems
on various TI K3 family of SoCs through the remote processor
framework.
config REMOTEPROC_TI_POWER config REMOTEPROC_TI_POWER
bool "Support for TI Power processor" bool "Support for TI Power processor"
select REMOTEPROC select REMOTEPROC

View file

@ -11,4 +11,6 @@ obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o
obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o
obj-$(CONFIG_REMOTEPROC_TI_K3_ARM64) += ti_k3_arm64_rproc.o obj-$(CONFIG_REMOTEPROC_TI_K3_ARM64) += ti_k3_arm64_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_K3_DSP) += ti_k3_dsp_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_K3_R5F) += ti_k3_r5f_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o

View file

@ -64,13 +64,90 @@ int rproc_elf32_sanity_check(ulong addr, ulong size)
return 0; return 0;
} }
/* A very simple elf loader, assumes the image is valid */ /* Basic function to verify ELF64 image format */
int rproc_elf32_load_image(struct udevice *dev, unsigned long addr) int rproc_elf64_sanity_check(ulong addr, ulong size)
{
Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
char class;
if (!addr) {
pr_debug("Invalid fw address?\n");
return -EFAULT;
}
if (size < sizeof(Elf64_Ehdr)) {
pr_debug("Image is too small\n");
return -ENOSPC;
}
class = ehdr->e_ident[EI_CLASS];
if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS64) {
pr_debug("Not an executable ELF64 image\n");
return -EPROTONOSUPPORT;
}
/* We assume the firmware has the same endianness as the host */
# ifdef __LITTLE_ENDIAN
if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
# else /* BIG ENDIAN */
if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
# endif
pr_debug("Unsupported firmware endianness\n");
return -EILSEQ;
}
if (size < ehdr->e_shoff + sizeof(Elf64_Shdr)) {
pr_debug("Image is too small\n");
return -ENOSPC;
}
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
pr_debug("Image is corrupted (bad magic)\n");
return -EBADF;
}
if (ehdr->e_phnum == 0) {
pr_debug("No loadable segments\n");
return -ENOEXEC;
}
if (ehdr->e_phoff > size) {
pr_debug("Firmware size is too small\n");
return -ENOSPC;
}
return 0;
}
/* Basic function to verify ELF image format */
int rproc_elf_sanity_check(ulong addr, ulong size)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
if (!addr) {
dev_err(dev, "Invalid firmware address\n");
return -EFAULT;
}
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
return rproc_elf64_sanity_check(addr, size);
else
return rproc_elf32_sanity_check(addr, size);
}
int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size)
{ {
Elf32_Ehdr *ehdr; /* Elf header structure pointer */ Elf32_Ehdr *ehdr; /* Elf header structure pointer */
Elf32_Phdr *phdr; /* Program header structure pointer */ Elf32_Phdr *phdr; /* Program header structure pointer */
const struct dm_rproc_ops *ops; const struct dm_rproc_ops *ops;
unsigned int i; unsigned int i, ret;
ret = rproc_elf32_sanity_check(addr, size);
if (ret) {
dev_err(dev, "Invalid ELF32 Image %d\n", ret);
return ret;
}
ehdr = (Elf32_Ehdr *)addr; ehdr = (Elf32_Ehdr *)addr;
phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
@ -86,7 +163,8 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr)
continue; continue;
if (ops->device_to_virt) if (ops->device_to_virt)
dst = ops->device_to_virt(dev, (ulong)dst); dst = ops->device_to_virt(dev, (ulong)dst,
phdr->p_memsz);
dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n", dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n",
i, dst, phdr->p_filesz); i, dst, phdr->p_filesz);
@ -104,3 +182,96 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr)
return 0; return 0;
} }
int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
{
const struct dm_rproc_ops *ops = rproc_get_ops(dev);
u64 da, memsz, filesz, offset;
Elf64_Ehdr *ehdr;
Elf64_Phdr *phdr;
int i, ret = 0;
void *ptr;
dev_dbg(dev, "%s: addr = 0x%lx size = 0x%lx\n", __func__, addr, size);
if (rproc_elf64_sanity_check(addr, size))
return -EINVAL;
ehdr = (Elf64_Ehdr *)addr;
phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
/* go through the available ELF segments */
for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
da = phdr->p_paddr;
memsz = phdr->p_memsz;
filesz = phdr->p_filesz;
offset = phdr->p_offset;
if (phdr->p_type != PT_LOAD)
continue;
dev_dbg(dev, "%s:phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
__func__, phdr->p_type, da, memsz, filesz);
ptr = (void *)(uintptr_t)da;
if (ops->device_to_virt) {
ptr = ops->device_to_virt(dev, da, phdr->p_memsz);
if (!ptr) {
dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
memsz);
ret = -EINVAL;
break;
}
}
if (filesz)
memcpy(ptr, (void *)addr + offset, filesz);
if (filesz != memsz)
memset(ptr + filesz, 0x00, memsz - filesz);
flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN),
roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
}
return ret;
}
int rproc_elf_load_image(struct udevice *dev, ulong addr, ulong size)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
if (!addr) {
dev_err(dev, "Invalid firmware address\n");
return -EFAULT;
}
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
return rproc_elf64_load_image(dev, addr, size);
else
return rproc_elf32_load_image(dev, addr, size);
}
static ulong rproc_elf32_get_boot_addr(ulong addr)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
return ehdr->e_entry;
}
static ulong rproc_elf64_get_boot_addr(ulong addr)
{
Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
return ehdr->e_entry;
}
ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
return rproc_elf64_get_boot_addr(addr);
else
return rproc_elf32_get_boot_addr(addr);
}

View file

@ -306,9 +306,11 @@ static int sandbox_testproc_ping(struct udevice *dev)
* sandbox_testproc_device_to_virt() - Convert device address to virtual address * sandbox_testproc_device_to_virt() - Convert device address to virtual address
* @dev: device to operate upon * @dev: device to operate upon
* @da: device address * @da: device address
* @size: Size of the memory region @da is pointing to
* @return converted virtual address * @return converted virtual address
*/ */
static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da) static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da,
ulong size)
{ {
u64 paddr; u64 paddr;

View file

@ -107,11 +107,13 @@ static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold)
* stm32_copro_device_to_virt() - Convert device address to virtual address * stm32_copro_device_to_virt() - Convert device address to virtual address
* @dev: corresponding STM32 remote processor device * @dev: corresponding STM32 remote processor device
* @da: device address * @da: device address
* @size: Size of the memory region @da is pointing to
* @return converted virtual address * @return converted virtual address
*/ */
static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da) static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da,
ulong size)
{ {
fdt32_t in_addr = cpu_to_be32(da); fdt32_t in_addr = cpu_to_be32(da), end_addr;
u64 paddr; u64 paddr;
paddr = dev_translate_dma_address(dev, &in_addr); paddr = dev_translate_dma_address(dev, &in_addr);
@ -120,6 +122,12 @@ static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da)
return NULL; return NULL;
} }
end_addr = cpu_to_be32(da + size - 1);
if (dev_translate_dma_address(dev, &end_addr) == OF_BAD_ADDR) {
dev_err(dev, "Unable to convert address %ld\n", da + size - 1);
return NULL;
}
return phys_to_virt(paddr); return phys_to_virt(paddr);
} }
@ -147,14 +155,7 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size)
return ret; return ret;
} }
/* Support only ELF32 image */ return rproc_elf32_load_image(dev, addr, size);
ret = rproc_elf32_sanity_check(addr, size);
if (ret) {
dev_err(dev, "Invalid ELF32 image (%d)\n", ret);
return ret;
}
return rproc_elf32_load_image(dev, addr);
} }
/** /**

View file

@ -0,0 +1,354 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Texas Instruments' K3 DSP Remoteproc driver
*
* Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
* Lokesh Vutla <lokeshvutla@ti.com>
*
*/
#include <common.h>
#include <dm.h>
#include <remoteproc.h>
#include <errno.h>
#include <clk.h>
#include <reset.h>
#include <asm/io.h>
#include <power-domain.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include "ti_sci_proc.h"
#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK (SZ_16M - 1)
/**
* struct k3_dsp_mem - internal memory structure
* @cpu_addr: MPU virtual address of the memory region
* @bus_addr: Bus address used to access the memory region
* @dev_addr: Device address from remoteproc view
* @size: Size of the memory region
*/
struct k3_dsp_mem {
void __iomem *cpu_addr;
phys_addr_t bus_addr;
phys_addr_t dev_addr;
size_t size;
};
/**
* struct k3_dsp_privdata - Structure representing Remote processor data.
* @rproc_rst: rproc reset control data
* @tsp: Pointer to TISCI proc contrl handle
* @mem: Array of available memories
* @num_mem: Number of available memories
*/
struct k3_dsp_privdata {
struct reset_ctl dsp_rst;
struct ti_sci_proc tsp;
struct k3_dsp_mem *mem;
int num_mems;
};
/**
* k3_dsp_load() - Load up the Remote processor image
* @dev: rproc device pointer
* @addr: Address at which image is available
* @size: size of the image
*
* Return: 0 if all goes good, else appropriate error message.
*/
static int k3_dsp_load(struct udevice *dev, ulong addr, ulong size)
{
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
u32 boot_vector;
int ret;
dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
ret = ti_sci_proc_request(&dsp->tsp);
if (ret)
return ret;
ret = rproc_elf_load_image(dev, addr, size);
if (ret < 0) {
dev_err(dev, "Loading elf failed %d\n", ret);
goto proc_release;
}
boot_vector = rproc_elf_get_boot_addr(dev, addr);
dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
ret = ti_sci_proc_set_config(&dsp->tsp, boot_vector, 0, 0);
proc_release:
ti_sci_proc_release(&dsp->tsp);
return ret;
}
/**
* k3_dsp_start() - Start the remote processor
* @dev: rproc device pointer
*
* Return: 0 if all went ok, else return appropriate error
*/
static int k3_dsp_start(struct udevice *dev)
{
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
int ret;
dev_dbg(dev, "%s\n", __func__);
ret = ti_sci_proc_request(&dsp->tsp);
if (ret)
return ret;
/*
* Setting the right clock frequency would have taken care by
* assigned-clock-rates during the device probe. So no need to
* set the frequency again here.
*/
ret = ti_sci_proc_power_domain_on(&dsp->tsp);
if (ret)
goto proc_release;
ret = reset_deassert(&dsp->dsp_rst);
proc_release:
ti_sci_proc_release(&dsp->tsp);
return ret;
}
static int k3_dsp_stop(struct udevice *dev)
{
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
dev_dbg(dev, "%s\n", __func__);
ti_sci_proc_request(&dsp->tsp);
reset_assert(&dsp->dsp_rst);
ti_sci_proc_power_domain_off(&dsp->tsp);
ti_sci_proc_release(&dsp->tsp);
return 0;
}
/**
* k3_dsp_init() - Initialize the remote processor
* @dev: rproc device pointer
*
* Return: 0 if all went ok, else return appropriate error
*/
static int k3_dsp_init(struct udevice *dev)
{
dev_dbg(dev, "%s\n", __func__);
return 0;
}
static int k3_dsp_reset(struct udevice *dev)
{
dev_dbg(dev, "%s\n", __func__);
return 0;
}
static void *k3_dsp_da_to_va(struct udevice *dev, ulong da, ulong len)
{
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
phys_addr_t bus_addr, dev_addr;
void __iomem *va = NULL;
size_t size;
u32 offset;
int i;
dev_dbg(dev, "%s\n", __func__);
if (len <= 0)
return NULL;
for (i = 0; i < dsp->num_mems; i++) {
bus_addr = dsp->mem[i].bus_addr;
dev_addr = dsp->mem[i].dev_addr;
size = dsp->mem[i].size;
if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
offset = da - dev_addr;
va = dsp->mem[i].cpu_addr + offset;
return (__force void *)va;
}
if (da >= bus_addr && (da + len) <= (bus_addr + size)) {
offset = da - bus_addr;
va = dsp->mem[i].cpu_addr + offset;
return (__force void *)va;
}
}
/* Assume it is DDR region and return da */
return map_physmem(da, len, MAP_NOCACHE);
}
static const struct dm_rproc_ops k3_dsp_ops = {
.init = k3_dsp_init,
.load = k3_dsp_load,
.start = k3_dsp_start,
.stop = k3_dsp_stop,
.reset = k3_dsp_reset,
.device_to_virt = k3_dsp_da_to_va,
};
static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
{
u32 ids[2];
int ret;
dev_dbg(dev, "%s\n", __func__);
tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(tsp->sci)) {
dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
return PTR_ERR(tsp->sci);
}
ret = dev_read_u32_array(dev, "ti,sci-proc-ids", ids, 2);
if (ret) {
dev_err(dev, "Proc IDs not populated %d\n", ret);
return ret;
}
tsp->ops = &tsp->sci->ops.proc_ops;
tsp->proc_id = ids[0];
tsp->host_id = ids[1];
tsp->dev_id = dev_read_u32_default(dev, "ti,sci-dev-id",
TI_SCI_RESOURCE_NULL);
if (tsp->dev_id == TI_SCI_RESOURCE_NULL) {
dev_err(dev, "Device ID not populated %d\n", ret);
return -ENODEV;
}
return 0;
}
static int k3_dsp_of_get_memories(struct udevice *dev)
{
static const char * const mem_names[] = {"l2sram", "l1pram", "l1dram"};
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
int i;
dev_dbg(dev, "%s\n", __func__);
dsp->num_mems = ARRAY_SIZE(mem_names);
dsp->mem = calloc(dsp->num_mems, sizeof(*dsp->mem));
if (!dsp->mem)
return -ENOMEM;
for (i = 0; i < dsp->num_mems; i++) {
/* C71 cores only have a L1P Cache, there are no L1P SRAMs */
if (device_is_compatible(dev, "ti,j721e-c71-dsp") &&
!strcmp(mem_names[i], "l1pram")) {
dsp->mem[i].bus_addr = FDT_ADDR_T_NONE;
dsp->mem[i].dev_addr = FDT_ADDR_T_NONE;
dsp->mem[i].cpu_addr = NULL;
dsp->mem[i].size = 0;
continue;
}
dsp->mem[i].bus_addr = dev_read_addr_size_name(dev, mem_names[i],
(fdt_addr_t *)&dsp->mem[i].size);
if (dsp->mem[i].bus_addr == FDT_ADDR_T_NONE) {
dev_err(dev, "%s bus address not found\n", mem_names[i]);
return -EINVAL;
}
dsp->mem[i].cpu_addr = map_physmem(dsp->mem[i].bus_addr,
dsp->mem[i].size,
MAP_NOCACHE);
dsp->mem[i].dev_addr = dsp->mem[i].bus_addr &
KEYSTONE_RPROC_LOCAL_ADDRESS_MASK;
dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da %pa\n",
mem_names[i], &dsp->mem[i].bus_addr,
dsp->mem[i].size, dsp->mem[i].cpu_addr,
&dsp->mem[i].dev_addr);
}
return 0;
}
/**
* k3_of_to_priv() - generate private data from device tree
* @dev: corresponding k3 dsp processor device
* @dsp: pointer to driver specific private data
*
* Return: 0 if all goes good, else appropriate error message.
*/
static int k3_dsp_of_to_priv(struct udevice *dev, struct k3_dsp_privdata *dsp)
{
int ret;
dev_dbg(dev, "%s\n", __func__);
ret = reset_get_by_index(dev, 0, &dsp->dsp_rst);
if (ret) {
dev_err(dev, "reset_get() failed: %d\n", ret);
return ret;
}
ret = ti_sci_proc_of_to_priv(dev, &dsp->tsp);
if (ret)
return ret;
ret = k3_dsp_of_get_memories(dev);
if (ret)
return ret;
return 0;
}
/**
* k3_dsp_probe() - Basic probe
* @dev: corresponding k3 remote processor device
*
* Return: 0 if all goes good, else appropriate error message.
*/
static int k3_dsp_probe(struct udevice *dev)
{
struct k3_dsp_privdata *dsp;
int ret;
dev_dbg(dev, "%s\n", __func__);
dsp = dev_get_priv(dev);
ret = k3_dsp_of_to_priv(dev, dsp);
if (ret) {
dev_dbg(dev, "%s: Probe failed with error %d\n", __func__, ret);
return ret;
}
dev_dbg(dev, "Remoteproc successfully probed\n");
return 0;
}
static int k3_dsp_remove(struct udevice *dev)
{
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
free(dsp->mem);
return 0;
}
static const struct udevice_id k3_dsp_ids[] = {
{ .compatible = "ti,j721e-c66-dsp"},
{ .compatible = "ti,j721e-c71-dsp"},
{}
};
U_BOOT_DRIVER(k3_dsp) = {
.name = "k3_dsp",
.of_match = k3_dsp_ids,
.id = UCLASS_REMOTEPROC,
.ops = &k3_dsp_ops,
.probe = k3_dsp_probe,
.remove = k3_dsp_remove,
.priv_auto_alloc_size = sizeof(struct k3_dsp_privdata),
};

View file

@ -0,0 +1,816 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Texas Instruments' K3 R5 Remoteproc driver
*
* Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
* Lokesh Vutla <lokeshvutla@ti.com>
*/
#include <common.h>
#include <dm.h>
#include <remoteproc.h>
#include <errno.h>
#include <clk.h>
#include <reset.h>
#include <asm/io.h>
#include <linux/kernel.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include "ti_sci_proc.h"
/*
* R5F's view of this address can either be for ATCM or BTCM with the other
* at address 0x0 based on loczrama signal.
*/
#define K3_R5_TCM_DEV_ADDR 0x41010000
/* R5 TI-SCI Processor Configuration Flags */
#define PROC_BOOT_CFG_FLAG_R5_DBG_EN 0x00000001
#define PROC_BOOT_CFG_FLAG_R5_DBG_NIDEN 0x00000002
#define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100
#define PROC_BOOT_CFG_FLAG_R5_TEINIT 0x00000200
#define PROC_BOOT_CFG_FLAG_R5_NMFI_EN 0x00000400
#define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE 0x00000800
#define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000
#define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000
#define PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR 0x10000000
/* R5 TI-SCI Processor Control Flags */
#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
/* R5 TI-SCI Processor Status Flags */
#define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001
#define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002
#define PROC_BOOT_STATUS_FLAG_R5_CLK_GATED 0x00000004
#define PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED 0x00000100
#define NR_CORES 2
enum cluster_mode {
CLUSTER_MODE_SPLIT = 0,
CLUSTER_MODE_LOCKSTEP,
};
/**
* struct k3_r5_mem - internal memory structure
* @cpu_addr: MPU virtual address of the memory region
* @bus_addr: Bus address used to access the memory region
* @dev_addr: Device address from remoteproc view
* @size: Size of the memory region
*/
struct k3_r5f_mem {
void __iomem *cpu_addr;
phys_addr_t bus_addr;
u32 dev_addr;
size_t size;
};
/**
* struct k3_r5f_core - K3 R5 core structure
* @dev: cached device pointer
* @cluster: pointer to the parent cluster.
* @reset: reset control handle
* @tsp: TI-SCI processor control handle
* @mem: Array of available internal memories
* @num_mem: Number of available memories
* @atcm_enable: flag to control ATCM enablement
* @btcm_enable: flag to control BTCM enablement
* @loczrama: flag to dictate which TCM is at device address 0x0
* @in_use: flag to tell if the core is already in use.
*/
struct k3_r5f_core {
struct udevice *dev;
struct k3_r5f_cluster *cluster;
struct reset_ctl reset;
struct ti_sci_proc tsp;
struct k3_r5f_mem *mem;
int num_mems;
u32 atcm_enable;
u32 btcm_enable;
u32 loczrama;
bool in_use;
};
/**
* struct k3_r5f_cluster - K3 R5F Cluster structure
* @mode: Mode to configure the Cluster - Split or LockStep
* @cores: Array of pointers to R5 cores within the cluster
*/
struct k3_r5f_cluster {
enum cluster_mode mode;
struct k3_r5f_core *cores[NR_CORES];
};
static bool is_primary_core(struct k3_r5f_core *core)
{
return core == core->cluster->cores[0];
}
static int k3_r5f_proc_request(struct k3_r5f_core *core)
{
struct k3_r5f_cluster *cluster = core->cluster;
int i, ret;
if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
for (i = 0; i < NR_CORES; i++) {
ret = ti_sci_proc_request(&cluster->cores[i]->tsp);
if (ret)
goto proc_release;
}
} else {
ret = ti_sci_proc_request(&core->tsp);
}
return 0;
proc_release:
while (i >= 0) {
ti_sci_proc_release(&cluster->cores[i]->tsp);
i--;
}
return ret;
}
static void k3_r5f_proc_release(struct k3_r5f_core *core)
{
struct k3_r5f_cluster *cluster = core->cluster;
int i;
if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
for (i = 0; i < NR_CORES; i++)
ti_sci_proc_release(&cluster->cores[i]->tsp);
else
ti_sci_proc_release(&core->tsp);
}
static int k3_r5f_lockstep_release(struct k3_r5f_cluster *cluster)
{
int ret, c;
dev_dbg(dev, "%s\n", __func__);
for (c = NR_CORES - 1; c >= 0; c--) {
ret = ti_sci_proc_power_domain_on(&cluster->cores[c]->tsp);
if (ret)
goto unroll_module_reset;
}
/* deassert local reset on all applicable cores */
for (c = NR_CORES - 1; c >= 0; c--) {
ret = reset_deassert(&cluster->cores[c]->reset);
if (ret)
goto unroll_local_reset;
}
return 0;
unroll_local_reset:
while (c < NR_CORES) {
reset_assert(&cluster->cores[c]->reset);
c++;
}
c = 0;
unroll_module_reset:
while (c < NR_CORES) {
ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp);
c++;
}
return ret;
}
static int k3_r5f_split_release(struct k3_r5f_core *core)
{
int ret;
dev_dbg(dev, "%s\n", __func__);
ret = ti_sci_proc_power_domain_on(&core->tsp);
if (ret) {
dev_err(core->dev, "module-reset deassert failed, ret = %d\n",
ret);
return ret;
}
ret = reset_deassert(&core->reset);
if (ret) {
dev_err(core->dev, "local-reset deassert failed, ret = %d\n",
ret);
if (ti_sci_proc_power_domain_off(&core->tsp))
dev_warn(core->dev, "module-reset assert back failed\n");
}
return ret;
}
static int k3_r5f_prepare(struct udevice *dev)
{
struct k3_r5f_core *core = dev_get_priv(dev);
struct k3_r5f_cluster *cluster = core->cluster;
int ret = 0;
dev_dbg(dev, "%s\n", __func__);
if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
ret = k3_r5f_lockstep_release(cluster);
else
ret = k3_r5f_split_release(core);
if (ret)
dev_err(dev, "Unable to enable cores for TCM loading %d\n",
ret);
return ret;
}
static int k3_r5f_core_sanity_check(struct k3_r5f_core *core)
{
struct k3_r5f_cluster *cluster = core->cluster;
if (core->in_use) {
dev_err(dev, "Invalid op: Trying to load/start on already running core %d\n",
core->tsp.proc_id);
return -EINVAL;
}
if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !cluster->cores[1]) {
printf("Secondary core is not probed in this cluster\n");
return -EAGAIN;
}
if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !is_primary_core(core)) {
dev_err(dev, "Invalid op: Trying to start secondary core %d in lockstep mode\n",
core->tsp.proc_id);
return -EINVAL;
}
if (cluster->mode == CLUSTER_MODE_SPLIT && !is_primary_core(core)) {
if (!core->cluster->cores[0]->in_use) {
dev_err(dev, "Invalid seq: Enable primary core before loading secondary core\n");
return -EINVAL;
}
}
return 0;
}
/**
* k3_r5f_load() - Load up the Remote processor image
* @dev: rproc device pointer
* @addr: Address at which image is available
* @size: size of the image
*
* Return: 0 if all goes good, else appropriate error message.
*/
static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
{
struct k3_r5f_core *core = dev_get_priv(dev);
u32 boot_vector;
int ret;
dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
ret = k3_r5f_core_sanity_check(core);
if (ret)
return ret;
ret = k3_r5f_proc_request(core);
if (ret)
return ret;
ret = k3_r5f_prepare(dev);
if (ret) {
dev_err(dev, "R5f prepare failed for core %d\n",
core->tsp.proc_id);
goto proc_release;
}
/* Zero out TCMs so that ECC can be effective on all TCM addresses */
if (core->atcm_enable)
memset(core->mem[0].cpu_addr, 0x00, core->mem[0].size);
if (core->btcm_enable)
memset(core->mem[1].cpu_addr, 0x00, core->mem[1].size);
ret = rproc_elf_load_image(dev, addr, size);
if (ret < 0) {
dev_err(dev, "Loading elf failedi %d\n", ret);
goto proc_release;
}
boot_vector = rproc_elf_get_boot_addr(dev, addr);
dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
ret = ti_sci_proc_set_config(&core->tsp, boot_vector, 0, 0);
proc_release:
k3_r5f_proc_release(core);
return ret;
}
static int k3_r5f_core_halt(struct k3_r5f_core *core)
{
int ret;
ret = ti_sci_proc_set_control(&core->tsp,
PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0);
if (ret)
dev_err(core->dev, "Core %d failed to stop\n",
core->tsp.proc_id);
return ret;
}
static int k3_r5f_core_run(struct k3_r5f_core *core)
{
int ret;
ret = ti_sci_proc_set_control(&core->tsp,
0, PROC_BOOT_CTRL_FLAG_R5_CORE_HALT);
if (ret) {
dev_err(core->dev, "Core %d failed to start\n",
core->tsp.proc_id);
return ret;
}
return 0;
}
/**
* k3_r5f_start() - Start the remote processor
* @dev: rproc device pointer
*
* Return: 0 if all went ok, else return appropriate error
*/
static int k3_r5f_start(struct udevice *dev)
{
struct k3_r5f_core *core = dev_get_priv(dev);
struct k3_r5f_cluster *cluster = core->cluster;
int ret, c;
dev_dbg(dev, "%s\n", __func__);
ret = k3_r5f_core_sanity_check(core);
if (ret)
return ret;
ret = k3_r5f_proc_request(core);
if (ret)
return ret;
if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
if (is_primary_core(core)) {
for (c = NR_CORES - 1; c >= 0; c--) {
ret = k3_r5f_core_run(cluster->cores[c]);
if (ret)
goto unroll_core_run;
}
} else {
dev_err(dev, "Invalid op: Trying to start secondary core %d in lockstep mode\n",
core->tsp.proc_id);
ret = -EINVAL;
goto proc_release;
}
} else {
ret = k3_r5f_core_run(core);
if (ret)
goto proc_release;
}
core->in_use = true;
k3_r5f_proc_release(core);
return 0;
unroll_core_run:
while (c < NR_CORES) {
k3_r5f_core_halt(cluster->cores[c]);
c++;
}
proc_release:
k3_r5f_proc_release(core);
return ret;
}
static int k3_r5f_split_reset(struct k3_r5f_core *core)
{
int ret;
dev_dbg(dev, "%s\n", __func__);
if (reset_assert(&core->reset))
ret = -EINVAL;
if (ti_sci_proc_power_domain_off(&core->tsp))
ret = -EINVAL;
return ret;
}
static int k3_r5f_lockstep_reset(struct k3_r5f_cluster *cluster)
{
int ret = 0, c;
dev_dbg(dev, "%s\n", __func__);
for (c = 0; c < NR_CORES; c++)
if (reset_assert(&cluster->cores[c]->reset))
ret = -EINVAL;
/* disable PSC modules on all applicable cores */
for (c = 0; c < NR_CORES; c++)
if (ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp))
ret = -EINVAL;
return ret;
}
static int k3_r5f_unprepare(struct udevice *dev)
{
struct k3_r5f_core *core = dev_get_priv(dev);
struct k3_r5f_cluster *cluster = core->cluster;
int ret;
dev_dbg(dev, "%s\n", __func__);
if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
if (is_primary_core(core))
ret = k3_r5f_lockstep_reset(cluster);
} else {
ret = k3_r5f_split_reset(core);
}
if (ret)
dev_warn(dev, "Unable to enable cores for TCM loading %d\n",
ret);
return 0;
}
static int k3_r5f_stop(struct udevice *dev)
{
struct k3_r5f_core *core = dev_get_priv(dev);
struct k3_r5f_cluster *cluster = core->cluster;
int c, ret;
dev_dbg(dev, "%s\n", __func__);
ret = k3_r5f_proc_request(core);
if (ret)
return ret;
core->in_use = false;
if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
if (is_primary_core(core)) {
for (c = 0; c < NR_CORES; c++)
k3_r5f_core_halt(cluster->cores[c]);
} else {
dev_err(dev, "Invalid op: Trying to stop secondary core in lockstep mode\n");
ret = -EINVAL;
goto proc_release;
}
} else {
k3_r5f_core_halt(core);
}
ret = k3_r5f_unprepare(dev);
proc_release:
k3_r5f_proc_release(core);
return ret;
}
static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size)
{
struct k3_r5f_core *core = dev_get_priv(dev);
void __iomem *va = NULL;
phys_addr_t bus_addr;
u32 dev_addr, offset;
ulong mem_size;
int i;
dev_dbg(dev, "%s\n", __func__);
if (size <= 0)
return NULL;
for (i = 0; i < core->num_mems; i++) {
bus_addr = core->mem[i].bus_addr;
dev_addr = core->mem[i].dev_addr;
mem_size = core->mem[i].size;
if (da >= bus_addr && (da + size) <= (bus_addr + mem_size)) {
offset = da - bus_addr;
va = core->mem[i].cpu_addr + offset;
return (__force void *)va;
}
if (da >= dev_addr && (da + size) <= (dev_addr + mem_size)) {
offset = da - dev_addr;
va = core->mem[i].cpu_addr + offset;
return (__force void *)va;
}
}
/* Assume it is DDR region and return da */
return map_physmem(da, size, MAP_NOCACHE);
}
static int k3_r5f_init(struct udevice *dev)
{
return 0;
}
static int k3_r5f_reset(struct udevice *dev)
{
return 0;
}
static const struct dm_rproc_ops k3_r5f_rproc_ops = {
.init = k3_r5f_init,
.reset = k3_r5f_reset,
.start = k3_r5f_start,
.stop = k3_r5f_stop,
.load = k3_r5f_load,
.device_to_virt = k3_r5f_da_to_va,
};
static int k3_r5f_rproc_configure(struct k3_r5f_core *core)
{
struct k3_r5f_cluster *cluster = core->cluster;
u32 set_cfg = 0, clr_cfg = 0, cfg, ctrl, sts;
u64 boot_vec = 0;
int ret;
dev_dbg(dev, "%s\n", __func__);
ret = ti_sci_proc_request(&core->tsp);
if (ret < 0)
return ret;
/* Do not touch boot vector now. Load will take care of it. */
clr_cfg |= PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR;
ret = ti_sci_proc_get_status(&core->tsp, &boot_vec, &cfg, &ctrl, &sts);
if (ret)
goto out;
/* Sanity check for Lockstep mode */
if (cluster->mode && is_primary_core(core) &&
!(sts & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED)) {
dev_err(core->dev, "LockStep mode not permitted on this device\n");
ret = -EINVAL;
goto out;
}
/* Primary core only configuration */
if (is_primary_core(core)) {
/* always enable ARM mode */
clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TEINIT;
if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
set_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
else
clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
}
if (core->atcm_enable)
set_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
else
clr_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
if (core->btcm_enable)
set_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
else
clr_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
if (core->loczrama)
set_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
else
clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
ret = k3_r5f_core_halt(core);
if (ret)
goto out;
ret = ti_sci_proc_set_config(&core->tsp, boot_vec, set_cfg, clr_cfg);
out:
ti_sci_proc_release(&core->tsp);
return ret;
}
static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
{
u32 ids[2];
int ret;
dev_dbg(dev, "%s\n", __func__);
tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(tsp->sci)) {
dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
return PTR_ERR(tsp->sci);
}
ret = dev_read_u32_array(dev, "ti,sci-proc-ids", ids, 2);
if (ret) {
dev_err(dev, "Proc IDs not populated %d\n", ret);
return ret;
}
tsp->ops = &tsp->sci->ops.proc_ops;
tsp->proc_id = ids[0];
tsp->host_id = ids[1];
tsp->dev_id = dev_read_u32_default(dev, "ti,sci-dev-id",
TI_SCI_RESOURCE_NULL);
if (tsp->dev_id == TI_SCI_RESOURCE_NULL) {
dev_err(dev, "Device ID not populated %d\n", ret);
return -ENODEV;
}
return 0;
}
static int k3_r5f_of_to_priv(struct k3_r5f_core *core)
{
int ret;
dev_dbg(dev, "%s\n", __func__);
core->atcm_enable = dev_read_u32_default(core->dev, "atcm-enable", 0);
core->btcm_enable = dev_read_u32_default(core->dev, "btcm-enable", 1);
core->loczrama = dev_read_u32_default(core->dev, "loczrama", 1);
ret = ti_sci_proc_of_to_priv(core->dev, &core->tsp);
if (ret)
return ret;
ret = reset_get_by_index(core->dev, 0, &core->reset);
if (ret) {
dev_err(core->dev, "Reset lines not available: %d\n", ret);
return ret;
}
return 0;
}
static int k3_r5f_core_of_get_memories(struct k3_r5f_core *core)
{
static const char * const mem_names[] = {"atcm", "btcm"};
struct udevice *dev = core->dev;
int i;
dev_dbg(dev, "%s\n", __func__);
core->num_mems = ARRAY_SIZE(mem_names);
core->mem = calloc(core->num_mems, sizeof(*core->mem));
if (!core->mem)
return -ENOMEM;
for (i = 0; i < core->num_mems; i++) {
core->mem[i].bus_addr = dev_read_addr_size_name(dev,
mem_names[i],
(fdt_addr_t *)&core->mem[i].size);
if (core->mem[i].bus_addr == FDT_ADDR_T_NONE) {
dev_err(dev, "%s bus address not found\n",
mem_names[i]);
return -EINVAL;
}
core->mem[i].cpu_addr = map_physmem(core->mem[i].bus_addr,
core->mem[i].size,
MAP_NOCACHE);
if (!strcmp(mem_names[i], "atcm")) {
core->mem[i].dev_addr = core->loczrama ?
0 : K3_R5_TCM_DEV_ADDR;
} else {
core->mem[i].dev_addr = core->loczrama ?
K3_R5_TCM_DEV_ADDR : 0;
}
dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da 0x%x\n",
mem_names[i], &core->mem[i].bus_addr,
core->mem[i].size, core->mem[i].cpu_addr,
core->mem[i].dev_addr);
}
return 0;
}
/**
* k3_r5f_probe() - Basic probe
* @dev: corresponding k3 remote processor device
*
* Return: 0 if all goes good, else appropriate error message.
*/
static int k3_r5f_probe(struct udevice *dev)
{
struct k3_r5f_cluster *cluster = dev_get_priv(dev->parent);
struct k3_r5f_core *core = dev_get_priv(dev);
bool r_state;
int ret;
dev_dbg(dev, "%s\n", __func__);
core->dev = dev;
ret = k3_r5f_of_to_priv(core);
if (ret)
return ret;
core->cluster = cluster;
/* Assume Primary core gets probed first */
if (!cluster->cores[0])
cluster->cores[0] = core;
else
cluster->cores[1] = core;
ret = k3_r5f_core_of_get_memories(core);
if (ret) {
dev_err(dev, "Rproc getting internal memories failed\n");
return ret;
}
ret = core->tsp.sci->ops.dev_ops.is_on(core->tsp.sci, core->tsp.dev_id,
&r_state, &core->in_use);
if (ret)
return ret;
if (core->in_use) {
dev_info(dev, "Core %d is already in use. No rproc commands work\n",
core->tsp.proc_id);
return 0;
}
/* Make sure Local reset is asserted. Redundant? */
reset_assert(&core->reset);
ret = k3_r5f_rproc_configure(core);
if (ret) {
dev_err(dev, "rproc configure failed %d\n", ret);
return ret;
}
dev_dbg(dev, "Remoteproc successfully probed\n");
return 0;
}
static int k3_r5f_remove(struct udevice *dev)
{
struct k3_r5f_core *core = dev_get_priv(dev);
free(core->mem);
ti_sci_proc_release(&core->tsp);
return 0;
}
static const struct udevice_id k3_r5f_rproc_ids[] = {
{ .compatible = "ti,am654-r5f"},
{ .compatible = "ti,j721e-r5f"},
{}
};
U_BOOT_DRIVER(k3_r5f_rproc) = {
.name = "k3_r5f_rproc",
.of_match = k3_r5f_rproc_ids,
.id = UCLASS_REMOTEPROC,
.ops = &k3_r5f_rproc_ops,
.probe = k3_r5f_probe,
.remove = k3_r5f_remove,
.priv_auto_alloc_size = sizeof(struct k3_r5f_core),
};
static int k3_r5f_cluster_probe(struct udevice *dev)
{
struct k3_r5f_cluster *cluster = dev_get_priv(dev);
dev_dbg(dev, "%s\n", __func__);
cluster->mode = dev_read_u32_default(dev, "lockstep-mode",
CLUSTER_MODE_LOCKSTEP);
if (device_get_child_count(dev) != 2) {
dev_err(dev, "Invalid number of R5 cores");
return -EINVAL;
}
dev_dbg(dev, "%s: Cluster successfully probed in %s mode\n",
__func__, cluster->mode ? "lockstep" : "split");
return 0;
}
static const struct udevice_id k3_r5fss_ids[] = {
{ .compatible = "ti,am654-r5fss"},
{ .compatible = "ti,j721e-r5fss"},
{}
};
U_BOOT_DRIVER(k3_r5fss) = {
.name = "k3_r5fss",
.of_match = k3_r5fss_ids,
.id = UCLASS_MISC,
.probe = k3_r5f_cluster_probe,
.priv_auto_alloc_size = sizeof(struct k3_r5f_cluster),
};

View file

@ -19,12 +19,14 @@
* @proc_id: processor id for the consumer remoteproc device * @proc_id: processor id for the consumer remoteproc device
* @host_id: host id to pass the control over for this consumer remoteproc * @host_id: host id to pass the control over for this consumer remoteproc
* device * device
* @dev_id: Device ID as identified by system controller.
*/ */
struct ti_sci_proc { struct ti_sci_proc {
const struct ti_sci_handle *sci; const struct ti_sci_handle *sci;
const struct ti_sci_proc_ops *ops; const struct ti_sci_proc_ops *ops;
u8 proc_id; u8 proc_id;
u8 host_id; u8 host_id;
u16 dev_id;
}; };
static inline int ti_sci_proc_request(struct ti_sci_proc *tsp) static inline int ti_sci_proc_request(struct ti_sci_proc *tsp)
@ -118,4 +120,29 @@ static inline int ti_sci_proc_set_control(struct ti_sci_proc *tsp,
return ret; return ret;
} }
static inline int ti_sci_proc_power_domain_on(struct ti_sci_proc *tsp)
{
int ret;
debug("%s: dev_id = %d\n", __func__, tsp->dev_id);
ret = tsp->sci->ops.dev_ops.get_device_exclusive(tsp->sci, tsp->dev_id);
if (ret)
pr_err("Power-domain on failed for dev = %d\n", tsp->dev_id);
return ret;
}
static inline int ti_sci_proc_power_domain_off(struct ti_sci_proc *tsp)
{
int ret;
debug("%s: dev_id = %d\n", __func__, tsp->dev_id);
ret = tsp->sci->ops.dev_ops.put_device(tsp->sci, tsp->dev_id);
if (ret)
pr_err("Power-domain off failed for dev = %d\n", tsp->dev_id);
return ret;
}
#endif /* REMOTEPROC_TI_SCI_PROC_H */ #endif /* REMOTEPROC_TI_SCI_PROC_H */

View file

@ -16,10 +16,14 @@
#define CONFIG_TIMESTAMP #define CONFIG_TIMESTAMP
#endif #endif
#define CONFIG_SYS_BOOTM_LEN (16 << 20)
/* Clock Defines */ /* Clock Defines */
#define V_OSCK 24000000 /* Clock output from T2 */ #define V_OSCK 24000000 /* Clock output from T2 */
#define V_SCLK (V_OSCK) #define V_SCLK (V_OSCK)
#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
#ifndef CONFIG_SPL_BUILD #ifndef CONFIG_SPL_BUILD
#define MEM_LAYOUT_ENV_SETTINGS \ #define MEM_LAYOUT_ENV_SETTINGS \
@ -30,7 +34,6 @@
"ramdisk_addr_r=0x88080000\0" \ "ramdisk_addr_r=0x88080000\0" \
#define BOOT_TARGET_DEVICES(func) \ #define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 0) \
func(UBIFS, ubifs, 0) \ func(UBIFS, ubifs, 0) \
func(PXE, pxe, na) \ func(PXE, pxe, na) \
func(DHCP, dhcp, na) func(DHCP, dhcp, na)
@ -44,11 +47,12 @@
MEM_LAYOUT_ENV_SETTINGS \ MEM_LAYOUT_ENV_SETTINGS \
BOOTENV \ BOOTENV \
"bootlimit=3\0" \ "bootlimit=3\0" \
"bootubivol=rootfs\0" \
"altbootcmd=" \ "altbootcmd=" \
"setenv boot_config \"extlinux-rollback.conf\"; " \ "setenv boot_config \"extlinux-rollback.conf\"; " \
"run distro_bootcmd\0" "run distro_bootcmd\0"
#endif /* CONFIG_SPL_BUILD */ #endif /* ! CONFIG_SPL_BUILD */
/* NS16550 Configuration */ /* NS16550 Configuration */
#define CONFIG_SYS_NS16550_COM1 0x44e09000 /* UART0 */ #define CONFIG_SYS_NS16550_COM1 0x44e09000 /* UART0 */
@ -65,9 +69,6 @@
#define CONFIG_SYS_BOOTCOUNT_LE #define CONFIG_SYS_BOOTCOUNT_LE
#ifdef CONFIG_NAND #ifdef CONFIG_NAND
#define CONFIG_ENV_OFFSET 0x300000
#define CONFIG_ENV_OFFSET_REDUND 0x340000
#define CONFIG_ENV_SIZE 0x040000
#define CONFIG_SYS_NAND_5_ADDR_CYCLE #define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \ #define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \

View file

@ -12,6 +12,7 @@
#include <linux/sizes.h> #include <linux/sizes.h>
#include <config_distro_bootcmd.h> #include <config_distro_bootcmd.h>
#include <environment/ti/mmc.h> #include <environment/ti/mmc.h>
#include <environment/ti/k3_rproc.h>
#define CONFIG_ENV_SIZE (128 << 10) #define CONFIG_ENV_SIZE (128 << 10)
@ -98,12 +99,20 @@
"${bootdir}/${name_fit}\0" \ "${bootdir}/${name_fit}\0" \
"partitions=" PARTS_DEFAULT "partitions=" PARTS_DEFAULT
#ifdef DEFAULT_RPROCS
#undef DEFAULT_RPROCS
#endif
#define DEFAULT_RPROCS "" \
"0 /lib/firmware/am65x-mcu-r5f0_0-fw " \
"1 /lib/firmware/am65x-mcu-r5f0_1-fw "
/* Incorporate settings into the U-Boot environment */ /* Incorporate settings into the U-Boot environment */
#define CONFIG_EXTRA_ENV_SETTINGS \ #define CONFIG_EXTRA_ENV_SETTINGS \
DEFAULT_MMC_TI_ARGS \ DEFAULT_MMC_TI_ARGS \
DEFAULT_FIT_TI_ARGS \ DEFAULT_FIT_TI_ARGS \
EXTRA_ENV_AM65X_BOARD_SETTINGS \ EXTRA_ENV_AM65X_BOARD_SETTINGS \
EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC \
EXTRA_ENV_RPROC_SETTINGS
/* MMC ENV related defines */ /* MMC ENV related defines */
#ifdef CONFIG_ENV_IS_IN_MMC #ifdef CONFIG_ENV_IS_IN_MMC

View file

@ -12,6 +12,7 @@
#include <linux/sizes.h> #include <linux/sizes.h>
#include <config_distro_bootcmd.h> #include <config_distro_bootcmd.h>
#include <environment/ti/mmc.h> #include <environment/ti/mmc.h>
#include <environment/ti/k3_rproc.h>
#define CONFIG_ENV_SIZE (128 << 10) #define CONFIG_ENV_SIZE (128 << 10)
@ -87,11 +88,22 @@
"get_kern_mmc=load mmc ${bootpart} ${loadaddr} " \ "get_kern_mmc=load mmc ${bootpart} ${loadaddr} " \
"${bootdir}/${name_kern}\0" "${bootdir}/${name_kern}\0"
#ifdef DEFAULT_RPROCS
#undef DEFAULT_RPROCS
#endif
#define DEFAULT_RPROCS "" \
"3 /lib/firmware/j7-main-r5f0_1-fw " \
"4 /lib/firmware/j7-main-r5f1_0-fw " \
"6 /lib/firmware/j7-c66_0-fw " \
"7 /lib/firmware/j7-c66_1-fw " \
"8 /lib/firmware/j7-c71_0-fw "
/* Incorporate settings into the U-Boot environment */ /* Incorporate settings into the U-Boot environment */
#define CONFIG_EXTRA_ENV_SETTINGS \ #define CONFIG_EXTRA_ENV_SETTINGS \
DEFAULT_MMC_TI_ARGS \ DEFAULT_MMC_TI_ARGS \
EXTRA_ENV_J721E_BOARD_SETTINGS \ EXTRA_ENV_J721E_BOARD_SETTINGS \
EXTRA_ENV_J721E_BOARD_SETTINGS_MMC EXTRA_ENV_J721E_BOARD_SETTINGS_MMC \
EXTRA_ENV_RPROC_SETTINGS
/* Now for the remaining common defines */ /* Now for the remaining common defines */
#include <configs/ti_armv7_common.h> #include <configs/ti_armv7_common.h>

View file

@ -114,7 +114,7 @@
"bootm ${loadaddr}\0" \ "bootm ${loadaddr}\0" \
#define CONFIG_BOOTCOMMAND \ #define CONFIG_BOOTCOMMAND \
"if mmc rescan ${mmcdev}; then " \ "mmc dev ${mmcdev}; if mmc rescan; then " \
"if run loadbootscript; then " \ "if run loadbootscript; then " \
"run bootscript; " \ "run bootscript; " \
"else " \ "else " \

View file

@ -60,7 +60,7 @@
"do;" \ "do;" \
"setenv overlaystring ${overlaystring}'#'${overlay};" \ "setenv overlaystring ${overlaystring}'#'${overlay};" \
"done;\0" \ "done;\0" \
"run_fit=bootm ${loadaddr}#${fdtfile}${overlaystring}\0" \ "run_fit=bootm ${addr_fit}#${fdtfile}${overlaystring}\0" \
"loadfit=run args_mmc; run run_fit;\0" \ "loadfit=run args_mmc; run run_fit;\0" \
/* /*

View file

@ -404,6 +404,15 @@ const char *dev_get_uclass_name(const struct udevice *dev);
*/ */
int device_get_child(struct udevice *parent, int index, struct udevice **devp); int device_get_child(struct udevice *parent, int index, struct udevice **devp);
/**
* device_get_child_count() - Get the available child count of a device
*
* Returns the number of children to a device.
*
* @parent: Parent device to check
*/
int device_get_child_count(struct udevice *parent);
/** /**
* device_find_child_by_seq() - Find a child device based on a sequence * device_find_child_by_seq() - Find a child device based on a sequence
* *

View file

@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
*
* rproc environment variable definitions for various TI K3 SoCs.
*/
#ifndef __TI_RPROC_H
#define __TI_RPROC_H
/*
* should contain a list of <rproc_id fw_name> tuplies,
* override in board config files with the actual list
*/
#define DEFAULT_RPROCS ""
#ifdef CONFIG_CMD_REMOTEPROC
#define EXTRA_ENV_RPROC_SETTINGS \
"dorprocboot=0\0" \
"boot_rprocs=" \
"if test ${dorprocboot} -eq 1 && test ${boot} = mmc; then "\
"rproc init;" \
"run boot_rprocs_mmc;" \
"fi;\0" \
"rproc_load_and_boot_one=" \
"if load mmc ${bootpart} $loadaddr ${rproc_fw}; then " \
"if rproc load ${rproc_id} ${loadaddr} ${filesize}; then "\
"rproc start ${rproc_id};" \
"fi;" \
"fi\0" \
"boot_rprocs_mmc=" \
"env set rproc_id;" \
"env set rproc_fw;" \
"for i in ${rproc_fw_binaries} ; do " \
"if test -z \"${rproc_id}\" ; then " \
"env set rproc_id $i;" \
"else " \
"env set rproc_fw $i;" \
"run rproc_load_and_boot_one;" \
"env set rproc_id;" \
"env set rproc_fw;" \
"fi;" \
"done\0" \
"rproc_fw_binaries=" \
DEFAULT_RPROCS \
"\0"
#else
#define EXTRA_ENV_RPROC_SETTINGS \
"boot_rprocs= \0"
#endif /* CONFIG_CMD_REMOTEPROC */
#endif /* __TI_RPROC_H */

View file

@ -122,9 +122,10 @@ struct dm_rproc_ops {
* *
* @dev: Remote proc device * @dev: Remote proc device
* @da: Device address * @da: Device address
* @size: Size of the memory region @da is pointing to
* @return virtual address. * @return virtual address.
*/ */
void * (*device_to_virt)(struct udevice *dev, ulong da); void * (*device_to_virt)(struct udevice *dev, ulong da, ulong size);
}; };
/* Accessor */ /* Accessor */
@ -213,13 +214,69 @@ int rproc_is_running(int id);
*/ */
int rproc_elf32_sanity_check(ulong addr, ulong size); int rproc_elf32_sanity_check(ulong addr, ulong size);
/**
* rproc_elf64_sanity_check() - Verify if an image is a valid ELF32 one
*
* Check if a valid ELF64 image exists at the given memory location. Verify
* basic ELF64 format requirements like magic number and sections size.
*
* @addr: address of the image to verify
* @size: size of the image
* @return 0 if the image looks good, else appropriate error value.
*/
int rproc_elf64_sanity_check(ulong addr, ulong size);
/**
* rproc_elf_sanity_check() - Verify if an image is a valid ELF one
*
* Check if a valid ELF image exists at the given memory location. Auto
* detects ELF32/ELF64 and verifies basic ELF64/ELF32 format requirements
* like magic number and sections size.
*
* @addr: address of the image to verify
* @size: size of the image
* @return 0 if the image looks good, else appropriate error value.
*/
int rproc_elf_sanity_check(ulong addr, ulong size);
/** /**
* rproc_elf32_load_image() - load an ELF32 image * rproc_elf32_load_image() - load an ELF32 image
* @dev: device loading the ELF32 image * @dev: device loading the ELF32 image
* @addr: valid ELF32 image address * @addr: valid ELF32 image address
* @size: size of the image
* @return 0 if the image is successfully loaded, else appropriate error value. * @return 0 if the image is successfully loaded, else appropriate error value.
*/ */
int rproc_elf32_load_image(struct udevice *dev, unsigned long addr); int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size);
/**
* rproc_elf64_load_image() - load an ELF64 image
* @dev: device loading the ELF64 image
* @addr: valid ELF64 image address
* @size: size of the image
* @return 0 if the image is successfully loaded, else appropriate error value.
*/
int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size);
/**
* rproc_elf_load_image() - load an ELF image
* @dev: device loading the ELF image
* @addr: valid ELF image address
* @size: size of the image
*
* Auto detects if the image is ELF32 or ELF64 image and load accordingly.
* @return 0 if the image is successfully loaded, else appropriate error value.
*/
int rproc_elf_load_image(struct udevice *dev, unsigned long addr, ulong size);
/**
* rproc_elf_get_boot_addr() - Get rproc's boot address.
* @dev: device loading the ELF image
* @addr: valid ELF image address
*
* This function returns the entry point address of the ELF
* image.
*/
ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr);
#else #else
static inline int rproc_init(void) { return -ENOSYS; } static inline int rproc_init(void) { return -ENOSYS; }
static inline int rproc_dev_init(int id) { return -ENOSYS; } static inline int rproc_dev_init(int id) { return -ENOSYS; }
@ -232,8 +289,21 @@ static inline int rproc_ping(int id) { return -ENOSYS; }
static inline int rproc_is_running(int id) { return -ENOSYS; } static inline int rproc_is_running(int id) { return -ENOSYS; }
static inline int rproc_elf32_sanity_check(ulong addr, static inline int rproc_elf32_sanity_check(ulong addr,
ulong size) { return -ENOSYS; } ulong size) { return -ENOSYS; }
static inline int rproc_elf64_sanity_check(ulong addr,
ulong size) { return -ENOSYS; }
static inline int rproc_elf_sanity_check(ulong addr,
ulong size) { return -ENOSYS; }
static inline int rproc_elf32_load_image(struct udevice *dev, static inline int rproc_elf32_load_image(struct udevice *dev,
unsigned long addr) { return -ENOSYS; } unsigned long addr, ulong size)
{ return -ENOSYS; }
static inline int rproc_elf64_load_image(struct udevice *dev, ulong addr,
ulong size)
{ return -ENOSYS; }
static inline int rproc_elf_load_image(struct udevice *dev, ulong addr,
ulong size)
{ return -ENOSYS; }
static inline ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
{ return 0; }
#endif #endif
#endif /* _RPROC_H_ */ #endif /* _RPROC_H_ */

View file

@ -434,6 +434,9 @@ int spl_mmc_load(struct spl_image_info *spl_image,
int raw_part, int raw_part,
unsigned long raw_sect); unsigned long raw_sect);
int spl_ymodem_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev);
/** /**
* spl_invoke_atf - boot using an ARM trusted firmware image * spl_invoke_atf - boot using an ARM trusted firmware image
*/ */

View file

@ -8,6 +8,7 @@
#include <os.h> #include <os.h>
#endif #endif
#include <dm.h> #include <dm.h>
#include <dm/device.h>
#include <dm/device-internal.h> #include <dm/device-internal.h>
#include <dm/test.h> #include <dm/test.h>
#include <dm/uclass-internal.h> #include <dm/uclass-internal.h>
@ -371,7 +372,6 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
{ {
struct dm_test_parent_platdata *plat; struct dm_test_parent_platdata *plat;
struct udevice *bus, *dev; struct udevice *bus, *dev;
int child_count;
/* Check that the bus has no children */ /* Check that the bus has no children */
ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
@ -380,7 +380,7 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
for (device_find_first_child(bus, &dev), child_count = 0; for (device_find_first_child(bus, &dev);
dev; dev;
device_find_next_child(&dev)) { device_find_next_child(&dev)) {
/* Check that platform data is allocated */ /* Check that platform data is allocated */
@ -399,22 +399,20 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
ut_asserteq_ptr(plat, dev_get_parent_platdata(dev)); ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
ut_asserteq(1, plat->count); ut_asserteq(1, plat->count);
ut_assertok(device_probe(dev)); ut_assertok(device_probe(dev));
child_count++;
} }
ut_asserteq(3, child_count); ut_asserteq(3, device_get_child_count(bus));
/* Removing the bus should also have no effect (it is still bound) */ /* Removing the bus should also have no effect (it is still bound) */
device_remove(bus, DM_REMOVE_NORMAL); device_remove(bus, DM_REMOVE_NORMAL);
for (device_find_first_child(bus, &dev), child_count = 0; for (device_find_first_child(bus, &dev);
dev; dev;
device_find_next_child(&dev)) { device_find_next_child(&dev)) {
/* Check that platform data is allocated */ /* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev); plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL); ut_assert(plat != NULL);
ut_asserteq(1, plat->count); ut_asserteq(1, plat->count);
child_count++;
} }
ut_asserteq(3, child_count); ut_asserteq(3, device_get_child_count(bus));
/* Unbind all the children */ /* Unbind all the children */
do { do {
@ -425,16 +423,15 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
/* Now the child platdata should be removed and re-added */ /* Now the child platdata should be removed and re-added */
device_probe(bus); device_probe(bus);
for (device_find_first_child(bus, &dev), child_count = 0; for (device_find_first_child(bus, &dev);
dev; dev;
device_find_next_child(&dev)) { device_find_next_child(&dev)) {
/* Check that platform data is allocated */ /* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev); plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL); ut_assert(plat != NULL);
ut_asserteq(0, plat->count); ut_asserteq(0, plat->count);
child_count++;
} }
ut_asserteq(3, child_count); ut_asserteq(3, device_get_child_count(bus));
return 0; return 0;
} }
@ -480,19 +477,17 @@ static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
{ {
struct dm_test_parent_platdata *plat; struct dm_test_parent_platdata *plat;
struct udevice *bus, *dev; struct udevice *bus, *dev;
int child_count;
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
for (device_find_first_child(bus, &dev), child_count = 0; for (device_find_first_child(bus, &dev);
dev; dev;
device_find_next_child(&dev)) { device_find_next_child(&dev)) {
/* Check that platform data is allocated */ /* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev); plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL); ut_assert(plat != NULL);
ut_asserteq(1, plat->bind_flag); ut_asserteq(1, plat->bind_flag);
child_count++;
} }
ut_asserteq(3, child_count); ut_asserteq(3, device_get_child_count(bus));
return 0; return 0;
} }
@ -503,19 +498,17 @@ static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
{ {
struct dm_test_parent_platdata *plat; struct dm_test_parent_platdata *plat;
struct udevice *bus, *dev; struct udevice *bus, *dev;
int child_count;
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
for (device_find_first_child(bus, &dev), child_count = 0; for (device_find_first_child(bus, &dev);
dev; dev;
device_find_next_child(&dev)) { device_find_next_child(&dev)) {
/* Check that platform data is allocated */ /* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev); plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL); ut_assert(plat != NULL);
ut_asserteq(2, plat->uclass_bind_flag); ut_asserteq(2, plat->uclass_bind_flag);
child_count++;
} }
ut_asserteq(3, child_count); ut_asserteq(3, device_get_child_count(bus));
return 0; return 0;
} }
@ -529,14 +522,13 @@ DM_TEST(dm_test_bus_child_post_bind_uclass,
static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts) static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
{ {
struct udevice *bus, *dev; struct udevice *bus, *dev;
int child_count;
/* /*
* See testfdt_drv_probe() which effectively checks that the uclass * See testfdt_drv_probe() which effectively checks that the uclass
* flag is set before that method is called * flag is set before that method is called
*/ */
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
for (device_find_first_child(bus, &dev), child_count = 0; for (device_find_first_child(bus, &dev);
dev; dev;
device_find_next_child(&dev)) { device_find_next_child(&dev)) {
struct dm_test_priv *priv = dev_get_priv(dev); struct dm_test_priv *priv = dev_get_priv(dev);
@ -549,9 +541,8 @@ static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
ut_assert(priv != NULL); ut_assert(priv != NULL);
ut_asserteq(1, priv->uclass_flag); ut_asserteq(1, priv->uclass_flag);
ut_asserteq(1, priv->uclass_total); ut_asserteq(1, priv->uclass_total);
child_count++;
} }
ut_asserteq(3, child_count); ut_asserteq(3, device_get_child_count(bus));
return 0; return 0;
} }
@ -565,14 +556,13 @@ DM_TEST(dm_test_bus_child_pre_probe_uclass,
static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts) static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
{ {
struct udevice *bus, *dev; struct udevice *bus, *dev;
int child_count;
/* /*
* See testfdt_drv_probe() which effectively initializes that * See testfdt_drv_probe() which effectively initializes that
* the uclass postp flag is set to a value * the uclass postp flag is set to a value
*/ */
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
for (device_find_first_child(bus, &dev), child_count = 0; for (device_find_first_child(bus, &dev);
dev; dev;
device_find_next_child(&dev)) { device_find_next_child(&dev)) {
struct dm_test_priv *priv = dev_get_priv(dev); struct dm_test_priv *priv = dev_get_priv(dev);
@ -584,9 +574,8 @@ static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
priv = dev_get_priv(dev); priv = dev_get_priv(dev);
ut_assert(priv != NULL); ut_assert(priv != NULL);
ut_asserteq(0, priv->uclass_postp); ut_asserteq(0, priv->uclass_postp);
child_count++;
} }
ut_asserteq(3, child_count); ut_asserteq(3, device_get_child_count(bus));
return 0; return 0;
} }

View file

@ -171,12 +171,11 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts)
ut_assertnonnull(loaded_firmware); ut_assertnonnull(loaded_firmware);
memset(loaded_firmware, 0, loaded_firmware_size); memset(loaded_firmware, 0, loaded_firmware_size);
/* Verify valid ELF format */
ut_assertok(rproc_elf32_sanity_check((ulong)valid_elf32, size));
/* Load firmware in loaded_firmware, and verify it */ /* Load firmware in loaded_firmware, and verify it */
ut_assertok(rproc_elf32_load_image(dev, (unsigned long)valid_elf32)); ut_assertok(rproc_elf32_load_image(dev, (ulong)valid_elf32, size));
ut_assertok(memcmp(loaded_firmware, valid_elf32, loaded_firmware_size)); ut_assertok(memcmp(loaded_firmware, valid_elf32, loaded_firmware_size));
ut_asserteq(rproc_elf_get_boot_addr(dev, (unsigned long)valid_elf32),
0x08000000);
unmap_physmem(loaded_firmware, MAP_NOCACHE); unmap_physmem(loaded_firmware, MAP_NOCACHE);
/* Invalid ELF Magic */ /* Invalid ELF Magic */