diff options
| author | Tom Rini <[email protected]> | 2026-08-20 08:46:59 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-08-20 12:15:24 -0600 |
| commit | 33472b3162ced734e1e6eadb55ed1afa7d46eb52 (patch) | |
| tree | fd1c927b3821d877b14e13a890da60860fad0c62 | |
| parent | 527115ef6783cec49e5610c523c124b399011361 (diff) | |
| parent | 3b4aa7df8071c97e621c7684b00ed6e13661c77e (diff) | |
Merge branch 'main' of https://git.u-boot-project.org/u-boot/custodians/u-boot-sh
R-Car Gen4
- PCIe driver fixes and switch to generic firmware loader
- Bootloader update and switch to distro boot command
- DT removal of duplicate nodes which are in Linux DTs node
R-Car Gen5
- RSIP CM33 remoteproc driver clean up and pending updates
| -rw-r--r-- | arch/arm/dts/r8a779g3-sparrow-hawk-u-boot.dtsi | 16 | ||||
| -rw-r--r-- | arch/arm/dts/r8a78000-ironhide-cm33-u-boot.dtsi | 1 | ||||
| -rw-r--r-- | arch/arm/dts/r8a78000-u-boot.dtsi | 8 | ||||
| -rw-r--r-- | board/renesas/common/gen5-cm33.c | 70 | ||||
| -rw-r--r-- | configs/r8a779g3_sparrowhawk_defconfig | 2 | ||||
| -rw-r--r-- | doc/board/renesas/rcar-gen4-sparrow-hawk.rst | 21 | ||||
| -rw-r--r-- | drivers/pci/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/pci/pci-rcar-gen4.c | 116 | ||||
| -rw-r--r-- | drivers/remoteproc/renesas_rsip.c | 202 | ||||
| -rw-r--r-- | include/configs/sparrowhawk.h | 121 | ||||
| -rw-r--r-- | include/dt-bindings/reset/r8a78000-reset-scmi.h | 2 |
11 files changed, 373 insertions, 187 deletions
diff --git a/arch/arm/dts/r8a779g3-sparrow-hawk-u-boot.dtsi b/arch/arm/dts/r8a779g3-sparrow-hawk-u-boot.dtsi index dff0355150d..c9f302799f1 100644 --- a/arch/arm/dts/r8a779g3-sparrow-hawk-u-boot.dtsi +++ b/arch/arm/dts/r8a779g3-sparrow-hawk-u-boot.dtsi @@ -7,13 +7,6 @@ #include "r8a779g0-u-boot.dtsi" -&avb0_pins { - pins-vddq18-25-avb { - pins = "PIN_VDDQ_AVB0", "PIN_VDDQ_AVB1", "PIN_VDDQ_AVB2", "PIN_VDDQ_TSN0"; - power-source = <1800>; - }; -}; - /* Page 31 / FAN */ &gpio1 { pwm-fan-hog { @@ -51,16 +44,7 @@ &rpc { flash@0 { - /* - * EVTA1 is populated with Spansion S25FS512S - * EVTB1 is populated with Winbond W77Q51NW - */ - compatible = "jedec,spi-nor"; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; }; }; - -&vcc_sdhi { - states = <1800000 0>, <3300000 1>; -}; diff --git a/arch/arm/dts/r8a78000-ironhide-cm33-u-boot.dtsi b/arch/arm/dts/r8a78000-ironhide-cm33-u-boot.dtsi index 872cbfdbad6..5a76d9740a0 100644 --- a/arch/arm/dts/r8a78000-ironhide-cm33-u-boot.dtsi +++ b/arch/arm/dts/r8a78000-ironhide-cm33-u-boot.dtsi @@ -90,6 +90,7 @@ scp@c1340000 { compatible = "renesas,r8a78000-rproc"; reg = <0 0xc1340000 0 0x80000>; + resets = <&mdlc_scp SCP_RESET_DOMAIN_ID_SCP>; }; ram@e9800000 { /* DBSC5 */ diff --git a/arch/arm/dts/r8a78000-u-boot.dtsi b/arch/arm/dts/r8a78000-u-boot.dtsi index df21a9e03a2..67da58f6474 100644 --- a/arch/arm/dts/r8a78000-u-boot.dtsi +++ b/arch/arm/dts/r8a78000-u-boot.dtsi @@ -170,6 +170,14 @@ bootph-all; }; + mdlc_scp: system-controller@c1330000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc1330000 0 0x1000>; + #power-domain-cells = <1>; + #reset-cells = <1>; + bootph-all; + }; + i2c0: i2c@c11d0000 { compatible = "renesas,i2c-r8a78000", "renesas,rcar-gen5-i2c"; diff --git a/board/renesas/common/gen5-cm33.c b/board/renesas/common/gen5-cm33.c index b2f6087a943..f532daa16d5 100644 --- a/board/renesas/common/gen5-cm33.c +++ b/board/renesas/common/gen5-cm33.c @@ -535,12 +535,6 @@ static void clk_control_set_pll(void) #define MDLC_HSCN_BASE 0xc9c90000 /* The addresses in range 0x08000000..0x1fffffff are incremented by 0xa0000000 */ #define MDLC_RT_BASE 0xb9440000 -#define MDLC_SCP_BASE 0xc1330000 - -#define MDLC_SCP_MSRES02 (MDLC_SCP_BASE + 0x908) -#define MDLC_SCP_MSRESS02 (MDLC_SCP_BASE + 0x968) -#define MDLC_SCP_MSRES02_SCP_MASK GENMASK(1, 0) -#define MDLC_SCP_PKCPROT1 (MDLC_SCP_BASE + 0xcf4) #define MDLC_PERW_MSRES05 (MDLC_PERW_BASE + 0x914) #define MDLC_PERW_MSRESS05 (MDLC_PERW_BASE + 0x974) @@ -669,32 +663,6 @@ static void mdlc_rmw_msres(const u32 prot, const u32 res, const u32 mask, const } /** - * mdlc_set_reset() - Set IP into reset - * @prot: Protect register - * @res: Reset register - * @stat: Reset register - * @mask: Mask in the register to clear - */ -static void mdlc_set_reset(const u32 prot, const u32 res, const u32 stat, const u32 mask) -{ - u32 status; - - mdlc_wait_for_reset(res, stat); - - status = field_get(mask, readl(stat)); - if (status == MDLC_MSRESS_STOP) { - mdlc_rmw_msres(prot, res, mask, MDLC_MSRESS_STANDBY); - mdlc_wait_for_reset(res, stat); - status = field_get(mask, readl(stat)); - } - - if (status == MDLC_MSRESS_STANDBY || status == MDLC_MSRESS_RUN) { - mdlc_rmw_msres(prot, res, mask, MDLC_MSRESS_RESET); - mdlc_wait_for_reset(res, stat); - } -} - -/** * mdlc_release_reset() - Release IP from reset * @prot: Protect register * @res: Reset register @@ -1260,41 +1228,6 @@ static void load_perm_tables(void) writel(0xffffffff, 0xe9a081fc); } -#define SCP_STCM_BASE 0xc1000000 -#define SCP_BASE 0xc1340000 -#define SCP_CFGVECTABLE (SCP_BASE + 0x0) -#define SCP_CFGNSSTCALIB (SCP_BASE + 0x10) -#define SCP_CPUWAIT (SCP_BASE + 0x30) -#define SCP_CFGNSSTCALIB_13_3MHZ 0x010040f0 -#define SCP_CPUWAIT_WAIT BIT(0) - -/** - * scp_initialize() - Initialize SCP - * - * Put SCP into reset, configure SCP entry point address and systick timer, - * release SCP from reset, and zero out SCP STCM regions. - */ -static void scp_initialize(void) -{ - u32 addr; - - mdlc_set_reset(MDLC_SCP_PKCPROT1, MDLC_SCP_MSRES02, MDLC_SCP_MSRESS02, - MDLC_SCP_MSRES02_SCP_MASK); - - writel(SCP_STCM_BASE, SCP_CFGVECTABLE); - writel(SCP_CFGNSSTCALIB_13_3MHZ, SCP_CFGNSSTCALIB); - setbits_le32(SCP_CPUWAIT, SCP_CPUWAIT_WAIT); - - mdlc_release_reset(MDLC_SCP_PKCPROT1, MDLC_SCP_MSRES02, MDLC_SCP_MSRESS02, - MDLC_SCP_MSRES02_SCP_MASK); - - /* Fill zero to SCP STCM regions 0 ... 27 */ - for (addr = SCP_STCM_BASE; addr < 0xc1061b00; addr += 8) - writeq(0, addr); - - asm volatile("dsb sy"); -} - #define GIC720AE_GICR_PWRR(cpu) \ (GICR_BASE + 0x24 + ((cpu) * 0x40000)) @@ -1362,9 +1295,6 @@ int mach_cpu_init(void) load_perm_tables(); gic720ae_init(); - /* Release SCP from reset */ - scp_initialize(); - return 0; } diff --git a/configs/r8a779g3_sparrowhawk_defconfig b/configs/r8a779g3_sparrowhawk_defconfig index e39d14df806..a36ed3ffa3a 100644 --- a/configs/r8a779g3_sparrowhawk_defconfig +++ b/configs/r8a779g3_sparrowhawk_defconfig @@ -19,7 +19,7 @@ CONFIG_SYS_BARGSIZE=2048 CONFIG_SYS_CBSIZE=2048 CONFIG_BAUDRATE=921600 CONFIG_BINMAN=y -CONFIG_BOOTCOMMAND="tftp ${loadaddr} fitImage && bootm ${loadaddr}" +CONFIG_DISTRO_DEFAULTS=y CONFIG_DEFAULT_FDT_FILE="r8a779g3-sparrow-hawk.dtb" CONFIG_CMD_REMOTEPROC=y CONFIG_GPIO_HOG=y diff --git a/doc/board/renesas/rcar-gen4-sparrow-hawk.rst b/doc/board/renesas/rcar-gen4-sparrow-hawk.rst index a1b92ecab57..7d006a3d2b1 100644 --- a/doc/board/renesas/rcar-gen4-sparrow-hawk.rst +++ b/doc/board/renesas/rcar-gen4-sparrow-hawk.rst @@ -59,6 +59,27 @@ Finally, write U-Boot into SPI NOR: => sf probe && sf update 0x50000000 0 ${filesize} +SPI NOR layout +-------------- + +The Retronix R-Car V4H Sparrow Hawk board 64 MiB SPI NOR layout is listed below. + +.. table:: Retronix R-Car Gen4 V4H Sparrow Hawk SPI NOR layout + + +----------------+----------------+-----------+---------------------------------------------------------------+ + | Start | End | Size | Content | + +================+================+===========+===============================================================+ + | ``0x000_0000`` | ``0x02f_ffff`` | 3072 kiB | U-Boot bootloader ``flash.bin`` | + +----------------+----------------+-----------+---------------------------------------------------------------+ + | ``0x030_0000`` | ``0x033_ffff`` | 256 kiB | PCIe controller firmware ``rcar_gen4_pcie.bin`` (32 kiB used) | + +----------------+----------------+-----------+---------------------------------------------------------------+ + | ``0x034_0000`` | ``0x3f7_ffff`` | 61696 kiB | UNUSED | + +----------------+----------------+-----------+---------------------------------------------------------------+ + | ``0x3f8_0000`` | ``0x3fb_ffff`` | 256 kiB | U-Boot bootloader environment copy 1 | + +----------------+----------------+-----------+---------------------------------------------------------------+ + | ``0x3fc_0000`` | ``0x3ff_ffff`` | 256 kiB | U-Boot bootloader environment copy 2 | + +----------------+----------------+-----------+---------------------------------------------------------------+ + Bundle TFA BL31 into Linux kernel fitImage ------------------------------------------ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 9ffccc3a80b..2b2ccdf4745 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -396,6 +396,7 @@ config PCI_RCAR_GEN4 depends on RCAR_GEN4 select DM_RESET select DM_GPIO + select FW_LOADER select PCIE_DW_COMMON help Say Y here if you want to enable PCIe controller support on diff --git a/drivers/pci/pci-rcar-gen4.c b/drivers/pci/pci-rcar-gen4.c index 8c5c8095c73..b1d43b2e7aa 100644 --- a/drivers/pci/pci-rcar-gen4.c +++ b/drivers/pci/pci-rcar-gen4.c @@ -19,6 +19,7 @@ #include <dm.h> #include <dm/device_compat.h> #include <env.h> +#include <fw_loader.h> #include <log.h> #include <reset.h> @@ -75,6 +76,7 @@ #define RCAR_GEN4_PCIE_FIRMWARE_NAME "rcar_gen4_pcie.bin" #define RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR 0xc000 +#define RCAR_GEN4_PCIE_FIRMWARE_SIZE 0x8000 #define PCIE_T_PVPERL_MS 100 @@ -97,17 +99,26 @@ struct rcar_gen4_pcie { /* Must be first member of the struct */ struct pcie_dw dw; - struct reset_ctl pwr_rst; + struct reset_ctl *pwr_rst; struct clk *core_clk; struct clk *ref_clk; - struct gpio_desc pe_rst; + struct gpio_desc *pe_rst; void *app_base; void *dbi2_base; void *phy_base; u32 max_link_speed; u32 num_lanes; u16 *firmware; - u32 firmware_size; + size_t firmware_size; +}; + +/** + * struct rcar_gen4_pcie_plat - Renesas R-Car Gen4 DW PCIe controller platform data + * + * @probed: Controller was started + */ +struct rcar_gen4_pcie_plat { + bool probed; }; /* Common */ @@ -302,7 +313,7 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) if (ret) return ret; - ret = reset_assert(&rcar->pwr_rst); + ret = reset_assert(rcar->pwr_rst); if (ret) goto err_unprepare; @@ -312,11 +323,11 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) DEVICE_TYPE_RC | ((rcar->num_lanes < 4) ? BIFUR_MOD_SET_ON : 0)); - ret = reset_deassert(&rcar->pwr_rst); + ret = reset_deassert(rcar->pwr_rst); if (ret) goto err_unprepare; - reset_status(&rcar->pwr_rst); + reset_status(rcar->pwr_rst); mdelay(1); rcar_gen4_pcie_additional_common_init(rcar); @@ -335,7 +346,7 @@ static int rcar_gen4_pcie_host_init(struct udevice *dev) struct rcar_gen4_pcie *rcar = dev_get_priv(dev); int ret; - dm_gpio_set_value(&rcar->pe_rst, 1); + dm_gpio_set_value(rcar->pe_rst, 1); ret = rcar_gen4_pcie_common_init(rcar); if (ret) @@ -355,63 +366,38 @@ static int rcar_gen4_pcie_host_init(struct udevice *dev) mdelay(PCIE_T_PVPERL_MS); /* pe_rst requires 100msec delay */ - dm_gpio_set_value(&rcar->pe_rst, 0); + dm_gpio_set_value(rcar->pe_rst, 0); return 0; } static int rcar_gen4_pcie_load_firmware(struct rcar_gen4_pcie *rcar) { - ulong addr, size; int ret; - /* - * Run user specified firmware loading script, which loads the - * firmware from whichever location the user decides it should - * load the firmware from, by whatever means the user decides. - */ - ret = run_command_list("run renesas_rcar_gen4_load_firmware", -1, 0); - if (ret) { - printf("Firmware loading script 'renesas_rcar_gen4_load_firmware' not defined or failed.\n"); - goto fail; - } - - /* Find out where the firmware got loaded and how long it is. */ - addr = env_get_hex("renesas_rcar_gen4_load_firmware_addr", 0); - size = env_get_hex("renesas_rcar_gen4_load_firmware_size", 0); - - /* - * Clear the variables set by the firmware loading script, as - * their content would become stale once this function exits. - */ - env_set("renesas_rcar_gen4_load_firmware_addr", NULL); - env_set("renesas_rcar_gen4_load_firmware_size", NULL); - - if (!addr || !size) { - printf("Firmware address (%lx) or size (%lx) are invalid.\n", addr, size); - goto fail; - } - - /* Create local copy of the loaded firmware. */ - rcar->firmware = (u16 *)memdup((void *)addr, size); + rcar->firmware = calloc(1, RCAR_GEN4_PCIE_FIRMWARE_SIZE); if (!rcar->firmware) return -ENOMEM; - rcar->firmware_size = size; + ret = request_firmware_into_buf_via_script(rcar->firmware, + RCAR_GEN4_PCIE_FIRMWARE_SIZE, + "renesas_rcar_gen4_load_firmware", + &rcar->firmware_size); + if (ret) { + free(rcar->firmware); - return 0; + printf("Define 'renesas_rcar_gen4_load_firmware' script which loads the R-Car\n" + "Gen4 PCIe controller firmware from storage into memory and sets these\n" + "two environment variables:\n" + " renesas_rcar_gen4_load_firmware_addr ... address of firmware in memory\n" + " renesas_rcar_gen4_load_firmware_size ... length of firmware in bytes\n" + "\n" + "Example:\n" + " => env set renesas_rcar_gen4_load_firmware 'env set renesas_rcar_gen4_load_firmware_addr 0x54000000 && load mmc 0:1 ${renesas_rcar_gen4_load_firmware_addr} lib/firmware/rcar_gen4_pcie.bin && env set renesas_rcar_gen4_load_firmware_size ${filesize}'\n" + ); + } -fail: - printf("Define 'renesas_rcar_gen4_load_firmware' script which loads the R-Car\n" - "Gen4 PCIe controller firmware from storage into memory and sets these\n" - "two environment variables:\n" - " renesas_rcar_gen4_load_firmware_addr ... address of firmware in memory\n" - " renesas_rcar_gen4_load_firmware_size ... length of firmware in bytes\n" - "\n" - "Example:\n" - " => env set renesas_rcar_gen4_load_firmware 'env set renesas_rcar_gen4_load_firmware_addr 0x54000000 && load mmc 0:1 ${renesas_rcar_gen4_load_firmware_addr} lib/firmware/rcar_gen4_pcie.bin && env set renesas_rcar_gen4_load_firmware_size ${filesize}'\n" - ); - return -EINVAL; + return ret; } /** @@ -427,10 +413,14 @@ fail: static int rcar_gen4_pcie_probe(struct udevice *dev) { struct rcar_gen4_pcie *rcar = dev_get_priv(dev); + struct rcar_gen4_pcie_plat *plat = dev_get_plat(dev); struct udevice *ctlr = pci_get_controller(dev); struct pci_controller *hose = dev_get_uclass_priv(ctlr); int ret; + if (plat->probed) + return -ENODEV; + ret = rcar_gen4_pcie_load_firmware(rcar); if (ret) return ret; @@ -438,9 +428,9 @@ static int rcar_gen4_pcie_probe(struct udevice *dev) rcar->dw.first_busno = dev_seq(dev); rcar->dw.dev = dev; - ret = reset_get_by_name(dev, "pwr", &rcar->pwr_rst); - if (ret) - return ret; + rcar->pwr_rst = devm_reset_control_get(dev, "pwr"); + if (IS_ERR(rcar->pwr_rst)) + return PTR_ERR(rcar->pwr_rst); rcar->core_clk = devm_clk_get(dev, "core"); if (IS_ERR(rcar->core_clk)) @@ -454,10 +444,10 @@ static int rcar_gen4_pcie_probe(struct udevice *dev) if (ret && ret != -ENOSYS) return ret; - ret = gpio_request_by_name(dev, "reset-gpios", 0, &rcar->pe_rst, - GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); - if (ret) - return ret; + rcar->pe_rst = devm_gpiod_get(dev, "reset", + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (IS_ERR(rcar->pe_rst)) + return PTR_ERR(rcar->pe_rst); ret = rcar_gen4_pcie_host_init(dev); if (ret) @@ -470,6 +460,7 @@ static int rcar_gen4_pcie_probe(struct udevice *dev) dw_pcie_link_set_max_link_width(&rcar->dw, rcar->num_lanes); ret = rcar_gen4_pcie_start_link(rcar); + plat->probed = true; if (ret) return ret; @@ -478,8 +469,8 @@ static int rcar_gen4_pcie_probe(struct udevice *dev) if (!rcar_gen4_pcie_link_up(rcar)) { printf("PCIE-%d: Link down\n", dev_seq(dev)); rcar_gen4_pcie_ltssm_control(rcar, false); - dm_gpio_set_value(&rcar->pe_rst, 1); - reset_assert(&rcar->pwr_rst); + dm_gpio_set_value(rcar->pe_rst, 1); + reset_assert(rcar->pwr_rst); clk_disable_unprepare(rcar->ref_clk); return -ENODEV; } @@ -510,8 +501,8 @@ static int rcar_gen4_pcie_remove(struct udevice *dev) struct rcar_gen4_pcie *rcar = dev_get_priv(dev); rcar_gen4_pcie_ltssm_control(rcar, false); - dm_gpio_set_value(&rcar->pe_rst, 1); - reset_assert(&rcar->pwr_rst); + dm_gpio_set_value(rcar->pe_rst, 1); + reset_assert(rcar->pwr_rst); clk_disable_unprepare(rcar->ref_clk); return 0; @@ -592,5 +583,6 @@ U_BOOT_DRIVER(rcar_gen4_pcie) = { .probe = rcar_gen4_pcie_probe, .remove = rcar_gen4_pcie_remove, .priv_auto = sizeof(struct rcar_gen4_pcie), + .plat_auto = sizeof(struct rcar_gen4_pcie_plat), .flags = DM_FLAG_ACTIVE_DMA, }; diff --git a/drivers/remoteproc/renesas_rsip.c b/drivers/remoteproc/renesas_rsip.c index 76ccaf93b1a..c71424a2c16 100644 --- a/drivers/remoteproc/renesas_rsip.c +++ b/drivers/remoteproc/renesas_rsip.c @@ -13,6 +13,7 @@ #include <linux/sizes.h> #include <malloc.h> #include <remoteproc.h> +#include <reset.h> /* R-Car X5H contains 1 SCP core, 6 lockstep Cortex-R52 and 32 Cortex-A720AE cores. */ #define RCAR5_SCP_CORES 1 @@ -20,6 +21,9 @@ #define RCAR5_CA720_CORES 32 #define SCP_BASE 0xc1340000 +#define SCP_CFGVECTABLE (SCP_BASE + 0x0) +#define SCP_CFGNSSTCALIB (SCP_BASE + 0x10) +#define SCP_CFGNSSTCALIB_13_3MHZ 0x010040f0 #define SCP_CPUWAIT (SCP_BASE + 0x30) #define SCP_CPUWAIT_WAIT BIT(0) #define SCP_STCM 0xc1000000 @@ -96,26 +100,59 @@ static void scp_send_interrupt(void) * This must be removed when proper upstream SCP port exists */ #define SCMI_PD_POWER_STATE_SET_BOOTADDR 0x4411 +#define SCMI_PD_POWER_STATE_SET_STATE_ON 0 +#define SCMI_PD_POWER_STATE_SET_STATE_OFF BIT(30) +#define SCMI_PD_POWER_STATE_GET 0x4405 /** - * scp_cpu_core_start() - Boot CPU core by invoking SCP via SCMI + * scp_cpu_core_id_to_domain() - Convert core ID to SCMI domain ID + * @core: CPU core + * @domain: SCMI domain + */ +static int scp_cpu_core_id_to_domain(const u32 core, u32 *domain) +{ + if (core >= RCAR5_SCP_CORES && core < RCAR5_SCP_CORES + RCAR5_CR52_CORES) { + /* CR52 */ + *domain = core - RCAR5_SCP_CORES + SCMI_PD_CORE_RT_CORE00; + return 0; + } + + if (core >= RCAR5_SCP_CORES + RCAR5_CR52_CORES && + core < RCAR5_SCP_CORES + RCAR5_CR52_CORES + RCAR5_CA720_CORES) { + /* CA720 */ + *domain = core - RCAR5_SCP_CORES - RCAR5_CR52_CORES + SCMI_PD_CORE_AP_CORE00; + return 0; + } + + return -EINVAL; +} + +/** + * scp_cpu_core_set() - Start or stop CPU core by invoking SCP via SCMI * @core: CPU core to boot * @ep: Entry point + * @state: Power state, 0: Power on, BIT(30): Power off */ -static void scp_cpu_core_start(const u32 core, const u32 ep) +static int scp_cpu_core_set(const u32 core, const u32 ep, const u32 state) { struct scp_scmi_shmem *shmem = (struct scp_scmi_shmem *)SCP_SCMI_SHMEM_AREA09; struct scp_scmi_pd_power_state_set_a2p scmi_parameter = { .flags = 1, /* Asynchronous power transition using APMU */ - .domain_id = core, - .power_state = 0, /* Power on */ + .domain_id = 0, /* Core ID */ + .power_state = state, /* 0: Power on, BIT(30): Power off */ .boot_addr = ep, }; u32 status; + int ret; + + ret = scp_cpu_core_id_to_domain(core, &scmi_parameter.domain_id); + if (ret) + return ret; /* Wait for SCP to be free, then set it busy */ scp_wait_fw_free(); shmem->status &= ~SCP_SCMI_STATUS_FREE; + shmem->flags = 0; /* Set up the message and copy it to SHMEM */ shmem->message_header = SCMI_PD_POWER_STATE_SET_BOOTADDR; @@ -128,8 +165,59 @@ static void scp_cpu_core_start(const u32 core, const u32 ep) /* Read back the result */ status = readl((uintptr_t)shmem->payload); - if (status) - printf("SCP POWER_STATE_SET failed, status=0x%x\n", status); + if (status) { + printf("SCP POWER_STATE_SET domain %d failed, status=0x%x (%d)\n", + scmi_parameter.domain_id, status, status); + return -EINVAL; + } + + return 0; +} + +/** + * scp_cpu_core_get() - Get CPU core state by invoking SCP via SCMI + * @core: CPU core to get + */ +static int scp_cpu_core_get(const u32 core) +{ + struct scp_scmi_shmem *shmem = (struct scp_scmi_shmem *)SCP_SCMI_SHMEM_AREA09; + u32 status, pwr; + u32 domain_id; /* Core ID */ + int ret; + + ret = scp_cpu_core_id_to_domain(core, &domain_id); + if (ret) + return ret; + + /* Wait for SCP to be free, then set it busy */ + scp_wait_fw_free(); + shmem->status &= ~SCP_SCMI_STATUS_FREE; + shmem->flags = 0; + + /* Set up the message and copy it to SHMEM */ + shmem->message_header = SCMI_PD_POWER_STATE_GET; + memcpy(shmem->payload, &domain_id, sizeof(domain_id)); + shmem->length = sizeof(shmem->message_header) + sizeof(domain_id); + + /* Send message to SCP and wait for completion */ + scp_send_interrupt(); + scp_wait_fw_free(); + + /* Read back the result */ + status = readl((uintptr_t)shmem->payload); + if (status) { + printf("SCP POWER_STATE_GET domain %d failed, status=0x%x (%d)\n", + domain_id, status, status); + return -EINVAL; + } + + pwr = readl((uintptr_t)(shmem->payload + 4)); + if (pwr == SCMI_PD_POWER_STATE_SET_STATE_ON) + return 0; + else if (pwr == SCMI_PD_POWER_STATE_SET_STATE_OFF) + return 1; + else + return -EINVAL; } /** @@ -163,6 +251,42 @@ static int renesas_rsip_rproc_load(struct udevice *dev, ulong addr, ulong size) } /** + * renesas_rsip_rproc_init() - Initialize the remote processor + * @dev: corresponding remote processor device + * + * Return: 0 if all went ok, else corresponding -ve error + */ +static int renesas_rsip_rproc_init(struct udevice *dev) +{ + struct renesas_rsip_rproc_privdata *priv = dev_get_priv(dev); + struct reset_ctl *rst = dev_get_priv(dev->parent); + u32 addr; + + if (priv->core_id != 0) /* No init for non-SCP cores */ + return 0; + + /* + * Put SCP into reset, configure SCP entry point address and systick + * timer, release SCP from reset, and zero out SCP STCM regions. + */ + reset_assert(rst); + + writel(SCP_STCM, SCP_CFGVECTABLE); + writel(SCP_CFGNSSTCALIB_13_3MHZ, SCP_CFGNSSTCALIB); + setbits_le32(SCP_CPUWAIT, SCP_CPUWAIT_WAIT); + + reset_deassert(rst); + + /* Fill zero to SCP STCM regions 0 ... 27 */ + for (addr = SCP_STCM; addr < 0xc1061b00; addr += 8) + writeq(0, addr); + + asm volatile("dsb sy"); + + return 0; +} + +/** * renesas_rsip_rproc_start() - Start the remote processor * @dev: corresponding remote processor device * @@ -171,27 +295,16 @@ static int renesas_rsip_rproc_load(struct udevice *dev, ulong addr, ulong size) static int renesas_rsip_rproc_start(struct udevice *dev) { struct renesas_rsip_rproc_privdata *priv = dev_get_priv(dev); - int scmi_core; if (priv->core_id == 0) { /* SCP */ clrbits_le32(SCP_CPUWAIT, SCP_CPUWAIT_WAIT); return 0; - } else if (priv->core_id >= RCAR5_SCP_CORES && - priv->core_id < RCAR5_SCP_CORES + RCAR5_CR52_CORES) { - /* CR52 */ - scmi_core = priv->core_id - RCAR5_SCP_CORES + - SCMI_PD_CORE_RT_CORE00; - } else if (priv->core_id >= RCAR5_SCP_CORES + RCAR5_CR52_CORES && - priv->core_id < RCAR5_SCP_CORES + RCAR5_CR52_CORES + RCAR5_CA720_CORES) { - /* CA720 */ - scmi_core = priv->core_id - RCAR5_SCP_CORES - RCAR5_CR52_CORES + - SCMI_PD_CORE_AP_CORE00; + } else { + /* CR52 or CA720 */ + return scp_cpu_core_set(priv->core_id, priv->ep, + SCMI_PD_POWER_STATE_SET_STATE_ON); } - - scp_cpu_core_start(scmi_core, priv->ep); - - return 0; } /** @@ -204,12 +317,14 @@ static int renesas_rsip_rproc_stop(struct udevice *dev) { struct renesas_rsip_rproc_privdata *priv = dev_get_priv(dev); - if (priv->core_id == 0) { /* SCP */ - setbits_le32(SCP_CPUWAIT, SCP_CPUWAIT_WAIT); - return 0; + if (priv->core_id == 0) { + /* SCP */ + return renesas_rsip_rproc_init(dev); + } else { + /* CR52 or CA720 */ + return scp_cpu_core_set(priv->core_id, 0, + SCMI_PD_POWER_STATE_SET_STATE_OFF); } - - return 0; } /** @@ -233,19 +348,15 @@ static int renesas_rsip_rproc_reset(struct udevice *dev) */ static int renesas_rsip_rproc_is_running(struct udevice *dev) { - /* We assume the core is stopped. */ - return 1; -} + struct renesas_rsip_rproc_privdata *priv = dev_get_priv(dev); -/** - * renesas_rsip_rproc_init() - Initialize the remote processor - * @dev: corresponding remote processor device - * - * Return: 0 if all went ok, else corresponding -ve error - */ -static int renesas_rsip_rproc_init(struct udevice *dev) -{ - return 0; + if (priv->core_id == 0) { + /* SCP */ + return readl(SCP_CPUWAIT) & SCP_CPUWAIT_WAIT; + } else { + /* CR52 or CA720 */ + return scp_cpu_core_get(priv->core_id); + } } /** @@ -297,6 +408,19 @@ U_BOOT_DRIVER(renesas_rsip_core) = { }; /** + * renesas_rsip_rproc_probe() - Common rproc driver probe + * @dev: corresponding remote processor parent device + * + * Return: 0 if all went ok, else corresponding -ve error + */ +static int renesas_rsip_rproc_probe(struct udevice *parent) +{ + struct reset_ctl *rst = dev_get_priv(parent); + + return reset_get_by_index(parent, 0, rst); +} + +/** * renesas_rsip_rproc_bind() - Bind rproc driver to each core control * @dev: corresponding remote processor parent device * @@ -355,4 +479,6 @@ U_BOOT_DRIVER(renesas_rsip_rproc) = { .of_match = renesas_rsip_rproc_ids, .id = UCLASS_NOP, .bind = renesas_rsip_rproc_bind, + .probe = renesas_rsip_rproc_probe, + .priv_auto = sizeof(struct reset_ctl), }; diff --git a/include/configs/sparrowhawk.h b/include/configs/sparrowhawk.h index 0524e39229c..a4309953433 100644 --- a/include/configs/sparrowhawk.h +++ b/include/configs/sparrowhawk.h @@ -11,4 +11,125 @@ #include "rcar-gen4-common.h" +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(NVME, nvme, 0) \ + func(USB, usb, 0) \ + func(DHCP, dhcp, na) + +#include <config_distro_bootcmd.h> + +/* + * Support for USB-ethernet and PCIe-ethernet is disabled, do not + * initialize either and directly boot via native ethernet only. + */ +#undef BOOTENV_RUN_NET_USB_START +#define BOOTENV_RUN_NET_USB_START +#undef BOOTENV_SHARED_USB +#define BOOTENV_SHARED_USB \ + "usb_boot=" \ + "run boot_pci_enum ; usb start ; " \ + BOOTENV_SHARED_BLKDEV_BODY(usb) +#undef BOOTENV_DEV_DHCP +#define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \ + "bootcmd_dhcp=" \ + "devtype=" #devtypel "; " \ + "if dhcp ${scriptaddr} ${boot_script_dhcp}; then " \ + "source ${scriptaddr}; " \ + "fi;" \ + BOOTENV_EFI_RUN_DHCP \ + "\0" + +/* Environment setting */ +#undef CFG_EXTRA_ENV_SETTINGS +#define CFG_EXTRA_ENV_SETTINGS \ + "bootm_size=0x10000000\0" \ + \ + "renesas_rcar_gen4_pcie_firmware_sf_offset=0x300000\0" \ + "renesas_rcar_gen4_pcie_firmware_sd_path=lib/firmware/rcar_gen4_pcie.bin\0" \ + "renesas_rcar_gen4_load_firmware=" \ + "env set renesas_rcar_gen4_load_firmware_addr 0x54000000 && " \ + "env set renesas_rcar_gen4_load_firmware_size 0x8000 && " \ + "sf probe && " \ + "sf read ${renesas_rcar_gen4_load_firmware_addr} " \ + "${renesas_rcar_gen4_pcie_firmware_sf_offset} " \ + "${renesas_rcar_gen4_load_firmware_size}\0" \ + "flash_pcie_fw_to_qspi_from_mmc=" \ + "load mmc 0:1 ${loadaddr} " \ + "${renesas_rcar_gen4_pcie_firmware_sd_path} && " \ + "sf probe && " \ + "sf update ${loadaddr} " \ + "${renesas_rcar_gen4_pcie_firmware_sf_offset} " \ + "${filesize}\0" \ + \ + "renesas_update_loader_iface=mmc\0" \ + "renesas_update_loader_dev=0\0" \ + "renesas_update_loader_part=1\0" \ + "renesas_update_loader_sf_offset=0x0\0" \ + "renesas_update_loader_filename=flash.bin\0" \ + "update_loader_from_blk=" \ + "load ${renesas_update_loader_iface} " \ + "${renesas_update_loader_dev}:${renesas_update_loader_part} " \ + "${loadaddr} " \ + "${renesas_update_loader_filename} && " \ + "sf probe && " \ + "sf update ${loadaddr} " \ + "${renesas_update_loader_sf_offset} " \ + "${filesize} && " \ + "reset\0" \ + "update_loader_from_blk01=" \ + "env set renesas_update_loader_dev 0 && " \ + "env set renesas_update_loader_part 1 && " \ + "run update_loader_from_blk\0" \ + "update_loader_from_mmc=" \ + "env set renesas_update_loader_iface mmc && " \ + "run update_loader_from_blk01\0" \ + "update_loader_from_nvme=" \ + "pci enum && nvme scan && " \ + "env set renesas_update_loader_iface nvme && " \ + "run update_loader_from_blk01\0" \ + "update_loader_from_usb=" \ + "pci enum && usb start && " \ + "env set renesas_update_loader_iface usb && " \ + "run update_loader_from_blk01\0" \ + \ + BOOTENV \ + "scriptaddr=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \ + "scan_dev_for_scripts=" \ + "if test -e ${devtype} ${devnum}:${distro_bootpart} " \ + "${prefix}fitImage; then " \ + "echo Found fitImage ${prefix}fitImage ; " \ + "if test ${devtype} = \"mmc\" ; then " \ + "env set bootargs \"${bootargs} " \ + "root=/dev/mmcblk0p1\" ; " \ + "elif test ${devtype} = \"nvme\" ; then " \ + "env set bootargs \"${bootargs} " \ + "root=/dev/nvme0n1p1\" ; " \ + "elif test ${devtype} = \"usb\" ; then " \ + "env set bootargs \"${bootargs} " \ + "root=/dev/sda1\" ; " \ + "else " \ + "part uuid ${devtype} " \ + "${devnum}:${distro_bootpart} " \ + "uuid ; " \ + "env set bootargs \"${bootargs} " \ + "root=PARTUUID=${uuid}\" ; " \ + "fi ; " \ + "env set bootargs \"${bootargs} rw rootwait\" ; " \ + "load ${devtype} ${devnum}:${distro_bootpart} " \ + "${scriptaddr} ${prefix}fitImage && " \ + "source ${scriptaddr}:script ; " \ + "echo fitImage script FAILED: continuing...; " \ + "fi; " \ + "for script in ${boot_scripts}; do " \ + "if test -e ${devtype} " \ + "${devnum}:${distro_bootpart} " \ + "${prefix}${script}; then " \ + "echo Found U-Boot script " \ + "${prefix}${script}; " \ + "run boot_a_script; " \ + "echo SCRIPT FAILED: continuing...; " \ + "fi; " \ + "done\0" + #endif /* __SPARROWHAWK_H */ diff --git a/include/dt-bindings/reset/r8a78000-reset-scmi.h b/include/dt-bindings/reset/r8a78000-reset-scmi.h index 3d84bfb073a..bf8c1b710f0 100644 --- a/include/dt-bindings/reset/r8a78000-reset-scmi.h +++ b/include/dt-bindings/reset/r8a78000-reset-scmi.h @@ -24,4 +24,6 @@ #define SCP_RESET_DOMAIN_ID_MPPHY31 0x67 #define SCP_RESET_DOMAIN_ID_MPPHY02 0x68 +#define SCP_RESET_DOMAIN_ID_SCP 0x20 + #endif /* __DT_BINDINGS_R8A78000_SCMI_RESET_H__ */ |
