soc: renesas: rcar-rst: Add support to set rproc boot address

R-Car Gen3 SoC series has a realtime processor, the boot
address of this processor can be set thanks to CR7BAR register
of the reset module.

Export this function so that it's possible to set the boot
address from a remoteproc driver.

Also drop the __initdata qualifier on rcar_rst_base,
since we will use this address later than init time.

Signed-off-by: Julien Massot <julien.massot@iot.bzh>
Link: https://lore.kernel.org/r/20211022122101.66998-1-julien.massot@iot.bzh
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
This commit is contained in:
Julien Massot 2021-10-22 14:21:01 +02:00 committed by Geert Uytterhoeven
parent fa55b7dcdc
commit 4c7924fb90
2 changed files with 42 additions and 3 deletions

View file

@ -13,15 +13,43 @@
#define WDTRSTCR_RESET 0xA55A0002
#define WDTRSTCR 0x0054
#define CR7BAR 0x0070
#define CR7BAREN BIT(4)
#define CR7BAR_MASK 0xFFFC0000
static void __iomem *rcar_rst_base;
static u32 saved_mode __initdata;
static int (*rcar_rst_set_rproc_boot_addr_func)(u64 boot_addr);
static int rcar_rst_enable_wdt_reset(void __iomem *base)
{
iowrite32(WDTRSTCR_RESET, base + WDTRSTCR);
return 0;
}
/*
* Most of the R-Car Gen3 SoCs have an ARM Realtime Core.
* Firmware boot address has to be set in CR7BAR before
* starting the realtime core.
* Boot address must be aligned on a 256k boundary.
*/
static int rcar_rst_set_gen3_rproc_boot_addr(u64 boot_addr)
{
if (boot_addr & ~(u64)CR7BAR_MASK) {
pr_err("Invalid boot address got %llx\n", boot_addr);
return -EINVAL;
}
iowrite32(boot_addr, rcar_rst_base + CR7BAR);
iowrite32(boot_addr | CR7BAREN, rcar_rst_base + CR7BAR);
return 0;
}
struct rst_config {
unsigned int modemr; /* Mode Monitoring Register Offset */
int (*configure)(void __iomem *base); /* Platform specific config */
int (*set_rproc_boot_addr)(u64 boot_addr);
};
static const struct rst_config rcar_rst_gen1 __initconst = {
@ -35,6 +63,7 @@ static const struct rst_config rcar_rst_gen2 __initconst = {
static const struct rst_config rcar_rst_gen3 __initconst = {
.modemr = 0x60,
.set_rproc_boot_addr = rcar_rst_set_gen3_rproc_boot_addr,
};
static const struct rst_config rcar_rst_r8a779a0 __initconst = {
@ -76,9 +105,6 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
{ /* sentinel */ }
};
static void __iomem *rcar_rst_base __initdata;
static u32 saved_mode __initdata;
static int __init rcar_rst_init(void)
{
const struct of_device_id *match;
@ -100,6 +126,8 @@ static int __init rcar_rst_init(void)
rcar_rst_base = base;
cfg = match->data;
rcar_rst_set_rproc_boot_addr_func = cfg->set_rproc_boot_addr;
saved_mode = ioread32(base + cfg->modemr);
if (cfg->configure) {
error = cfg->configure(base);
@ -130,3 +158,12 @@ int __init rcar_rst_read_mode_pins(u32 *mode)
*mode = saved_mode;
return 0;
}
int rcar_rst_set_rproc_boot_addr(u64 boot_addr)
{
if (!rcar_rst_set_rproc_boot_addr_func)
return -EIO;
return rcar_rst_set_rproc_boot_addr_func(boot_addr);
}
EXPORT_SYMBOL_GPL(rcar_rst_set_rproc_boot_addr);

View file

@ -4,8 +4,10 @@
#ifdef CONFIG_RST_RCAR
int rcar_rst_read_mode_pins(u32 *mode);
int rcar_rst_set_rproc_boot_addr(u64 boot_addr);
#else
static inline int rcar_rst_read_mode_pins(u32 *mode) { return -ENODEV; }
static inline int rcar_rst_set_rproc_boot_addr(u64 boot_addr) { return -ENODEV; }
#endif
#endif /* __LINUX_SOC_RENESAS_RCAR_RST_H__ */