mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 15:37:23 +00:00
Merge branch '2019-10-11-ti-imports'
- Various improvements to dra7xx, keystone 3, am65x SoCs - Platform updates - remoteproc improvements
This commit is contained in:
commit
36317705cb
67 changed files with 3142 additions and 200 deletions
|
@ -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)
|
||||||
|
|
21
arch/arm/dts/am335x-icev2-u-boot.dtsi
Normal file
21
arch/arm/dts/am335x-icev2-u-boot.dtsi
Normal 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>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -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 {
|
||||||
|
|
5
arch/arm/dts/am571x-idk-u-boot.dtsi
Normal file
5
arch/arm/dts/am571x-idk-u-boot.dtsi
Normal 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"
|
5
arch/arm/dts/am572x-idk-u-boot.dtsi
Normal file
5
arch/arm/dts/am572x-idk-u-boot.dtsi
Normal 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"
|
5
arch/arm/dts/am574x-idk-u-boot.dtsi
Normal file
5
arch/arm/dts/am574x-idk-u-boot.dtsi
Normal 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"
|
23
arch/arm/dts/am57xx-idk-common-u-boot.dtsi
Normal file
23
arch/arm/dts/am57xx-idk-common-u-boot.dtsi
Normal 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>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}, {
|
}, {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
227
board/ti/j721e/README
Normal 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 | |
|
||||||
|
| +-------------------+ |
|
||||||
|
+-----------------------+
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
49
doc/device-tree-bindings/clock/ti,cdce9xx.txt
Normal file
49
doc/device-tree-bindings/clock/ti,cdce9xx.txt
Normal 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;
|
||||||
|
};
|
||||||
|
};
|
101
doc/device-tree-bindings/remoteproc/ti,k3-dsp-rproc.txt
Normal file
101
doc/device-tree-bindings/remoteproc/ti,k3-dsp-rproc.txt
Normal 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>;
|
||||||
|
};
|
||||||
|
};
|
164
doc/device-tree-bindings/remoteproc/ti,k3-r5f-rproc.txt
Normal file
164
doc/device-tree-bindings/remoteproc/ti,k3-r5f-rproc.txt
Normal 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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -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"
|
||||||
|
|
|
@ -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
254
drivers/clk/clk-cdce9xx.c
Normal 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,
|
||||||
|
};
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
354
drivers/remoteproc/ti_k3_dsp_rproc.c
Normal file
354
drivers/remoteproc/ti_k3_dsp_rproc.c
Normal 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),
|
||||||
|
};
|
816
drivers/remoteproc/ti_k3_r5f_rproc.c
Normal file
816
drivers/remoteproc/ti_k3_r5f_rproc.c
Normal 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),
|
||||||
|
};
|
|
@ -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 */
|
||||||
|
|
|
@ -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 / \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 " \
|
||||||
|
|
|
@ -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" \
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
52
include/environment/ti/k3_rproc.h
Normal file
52
include/environment/ti/k3_rproc.h
Normal 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 */
|
|
@ -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_ */
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue