summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-08-20 08:46:59 -0600
committerTom Rini <[email protected]>2026-08-20 12:15:24 -0600
commit33472b3162ced734e1e6eadb55ed1afa7d46eb52 (patch)
treefd1c927b3821d877b14e13a890da60860fad0c62
parent527115ef6783cec49e5610c523c124b399011361 (diff)
parent3b4aa7df8071c97e621c7684b00ed6e13661c77e (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.dtsi16
-rw-r--r--arch/arm/dts/r8a78000-ironhide-cm33-u-boot.dtsi1
-rw-r--r--arch/arm/dts/r8a78000-u-boot.dtsi8
-rw-r--r--board/renesas/common/gen5-cm33.c70
-rw-r--r--configs/r8a779g3_sparrowhawk_defconfig2
-rw-r--r--doc/board/renesas/rcar-gen4-sparrow-hawk.rst21
-rw-r--r--drivers/pci/Kconfig1
-rw-r--r--drivers/pci/pci-rcar-gen4.c116
-rw-r--r--drivers/remoteproc/renesas_rsip.c202
-rw-r--r--include/configs/sparrowhawk.h121
-rw-r--r--include/dt-bindings/reset/r8a78000-reset-scmi.h2
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__ */