Commit 59162c93 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'renesas-soc-for-v4.17' of...

Merge tag 'renesas-soc-for-v4.17' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/soc

Pull "Renesas ARM Based SoC Updates for v4.17" from Simon Horman:

01d675f1 ARM: shmobile: rcar-gen2: Add watchdog support
58adf1ba ARM: shmobile: Add watchdog support

* SoC
  - Identify R-Car V3H (r8a77980) and M3N (r8a77965)

  - Enable R-Car Gen2 regulator quirk for Stout board with H3 (r8a7790) SoC

    Marek Vaust says "Regulator setup is suboptimal on H2 Stout too. The
    Stout newly has two DA9210 regulators, so the quirk is extended to
    handle another DA9210 at i2c address 0x70."

  - Add watchdog support

    This is the SoC portion of the following solution. It is not yet
    enabled in DT as it is not functional without clock dependencies
    in place.

    Fabrizio Castro says "this series has been around for some time as RFC,
    and it has collected useful comments from the community along the way.
    The solution proposed by this patch set works for most R-Car Gen2 and
    RZ/G1 devices, but not all of them. We now know that for some R-Car
    Gen2 early revisions there is no proper software fix. Anyway, no
    product has been built around early revisions, but development boards
    mounting early revisions (basically prototypes) are still out there.
    As a result, this series isn't enabling the internal watchdog on R-Car
    Gen2 boards, developers may enable it in board specific device trees if
    needed.  This series has been tested by me on the iwg20d, iwg22d,
    Lager, Alt, and Koelsch boards.

   The problem
   ===========
   To deal with SMP on R-Car Gen2 and RZ/G1, we install a reset vector to
   ICRAM1 and we program the [S]BAR registers so that when we turn ON the
   non-boot CPUs they are redirected to the reset vector installed by Linux
   in ICRAM1, and eventually they continue the execution to RAM, where the
   SMP bring-up code will take care of the rest.  The content of the [S]BAR
   registers survives a watchdog triggered reset, and as such after the
   watchdog fires the boot core will try and execute the SMP bring-up code
   instead of jumping to the bootrom code.

   The fix
   =======
   The main strategy for the solution is to let the reset vector decide if
   it needs to jump to shmobile_boot_fn or to the bootrom code.  In a
   watchdog triggered reset scenario, since the [S]BAR registers keep their
   values, the boot CPU will jump into the newly designed reset vector, the
   assembly routine will eventually test WOVF (a bit in register RWTCSRA
   that indicates if the watchdog counter has overflown, the value of this
   bit gets retained in this scenario), and jump to the bootrom code which
   will in turn load up the bootloader, etc.  When bringing up SMP or using
   CPU hotplug, the reset vector will jump to shmobile_boot_fn instead."

* R-Car Rst
  - Add support for R-Car V3H (r8a77980) and V3H (r8a77980)

* R-Car SYSC
  - Mark rcar_sysc_matches[] __initconst

   Geert Uytterhoeven says "This frees another 1764 bytes
   (arm32/shmobile_defconfig) or 1000 bytes (arm64/renesas_defconfig) of
   memory after kernel init."

  - Fix power area parents

    Sergei Shtylyov says "According to the figure 9.2(b) of the R-Car
    Series, 3rd Generation User’s Manual: Hardware Rev. 0.80 the A2IRn and
    A2SCn power areas in R8A77970 have the A3IR area as a parent, thus the
    SYSC driver has those parents wrong.."

  - Add support for R-Car V3H (r8a77980) and V3H (r8a77980)

* tag 'renesas-soc-for-v4.17' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
  ARM: shmobile: rcar-gen2: Add watchdog support
  ARM: shmobile: Add watchdog support
  ARM: shmobile: rcar-gen2: Fix error check in regulator quirk
  soc: renesas: rcar-rst: Add support for R-Car M3-N
  ARM: shmobile: stout: enable R-Car Gen2 regulator quirk
  soc: renesas: rcar-sysc: Add R-Car M3-N support
  soc: renesas: Identify R-Car M3-N
  soc: renesas: rcar-sysc: add R8A77980 support
  dt-bindings: power: add R8A77980 SYSC power domain definitions
  soc: renesas: r8a77970-sysc: fix power area parents
  soc: renesas: rcar-rst: Enable watchdog as reset trigger for Gen2
  soc: renesas: rcar-rst: add R8A77980 support
  soc: renesas: identify R-Car V3H
  soc: renesas: rcar-sysc: Mark rcar_sysc_matches[] __initconst
parents 8650b9fe 01d675f1
...@@ -17,7 +17,9 @@ Required properties: ...@@ -17,7 +17,9 @@ Required properties:
- "renesas,r8a7794-sysc" (R-Car E2) - "renesas,r8a7794-sysc" (R-Car E2)
- "renesas,r8a7795-sysc" (R-Car H3) - "renesas,r8a7795-sysc" (R-Car H3)
- "renesas,r8a7796-sysc" (R-Car M3-W) - "renesas,r8a7796-sysc" (R-Car M3-W)
- "renesas,r8a77965-sysc" (R-Car M3-N)
- "renesas,r8a77970-sysc" (R-Car V3M) - "renesas,r8a77970-sysc" (R-Car V3M)
- "renesas,r8a77980-sysc" (R-Car V3H)
- "renesas,r8a77995-sysc" (R-Car D3) - "renesas,r8a77995-sysc" (R-Car D3)
- reg: Address start and address range for the device. - reg: Address start and address range for the device.
- #power-domain-cells: Must be 1. - #power-domain-cells: Must be 1.
......
...@@ -26,7 +26,9 @@ Required properties: ...@@ -26,7 +26,9 @@ Required properties:
- "renesas,r8a7794-rst" (R-Car E2) - "renesas,r8a7794-rst" (R-Car E2)
- "renesas,r8a7795-rst" (R-Car H3) - "renesas,r8a7795-rst" (R-Car H3)
- "renesas,r8a7796-rst" (R-Car M3-W) - "renesas,r8a7796-rst" (R-Car M3-W)
- "renesas,r8a77965-rst" (R-Car M3-N)
- "renesas,r8a77970-rst" (R-Car V3M) - "renesas,r8a77970-rst" (R-Car V3M)
- "renesas,r8a77980-rst" (R-Car V3H)
- "renesas,r8a77995-rst" (R-Car D3) - "renesas,r8a77995-rst" (R-Car D3)
- reg: Address start and address range for the device. - reg: Address start and address range for the device.
......
...@@ -7,6 +7,10 @@ extern void shmobile_init_delay(void); ...@@ -7,6 +7,10 @@ extern void shmobile_init_delay(void);
extern void shmobile_boot_vector(void); extern void shmobile_boot_vector(void);
extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_fn;
extern unsigned long shmobile_boot_size; extern unsigned long shmobile_boot_size;
extern void shmobile_boot_vector_gen2(void);
extern unsigned long shmobile_boot_fn_gen2;
extern unsigned long shmobile_boot_cpu_gen2;
extern unsigned long shmobile_boot_size_gen2;
extern void shmobile_smp_boot(void); extern void shmobile_smp_boot(void);
extern void shmobile_smp_sleep(void); extern void shmobile_smp_sleep(void);
extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
......
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
#include <asm/assembler.h> #include <asm/assembler.h>
#include <asm/memory.h> #include <asm/memory.h>
#define SCTLR_MMU 0x01
#define BOOTROM_ADDRESS 0xE6340000
#define RWTCSRA_ADDRESS 0xE6020004
#define RWTCSRA_WOVF 0x10
/* /*
* Reset vector for secondary CPUs. * Reset vector for secondary CPUs.
* This will be mapped at address 0 by SBAR register. * This will be mapped at address 0 by SBAR register.
...@@ -37,6 +42,56 @@ shmobile_boot_fn: ...@@ -37,6 +42,56 @@ shmobile_boot_fn:
shmobile_boot_size: shmobile_boot_size:
.long . - shmobile_boot_vector .long . - shmobile_boot_vector
#ifdef CONFIG_ARCH_RCAR_GEN2
/*
* Reset vector for R-Car Gen2 and RZ/G1 secondary CPUs.
* This will be mapped at address 0 by SBAR register.
*/
ENTRY(shmobile_boot_vector_gen2)
mrc p15, 0, r0, c0, c0, 5 @ r0 = MPIDR
ldr r1, shmobile_boot_cpu_gen2
cmp r0, r1
bne shmobile_smp_continue_gen2
mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR
and r0, r1, #SCTLR_MMU
cmp r0, #SCTLR_MMU
beq shmobile_smp_continue_gen2
ldr r0, rwtcsra
mov r1, #0
ldrb r1, [r0]
and r0, r1, #RWTCSRA_WOVF
cmp r0, #RWTCSRA_WOVF
bne shmobile_smp_continue_gen2
ldr r0, bootrom
bx r0
shmobile_smp_continue_gen2:
ldr r1, shmobile_boot_fn_gen2
bx r1
ENDPROC(shmobile_boot_vector_gen2)
.align 4
rwtcsra:
.word RWTCSRA_ADDRESS
bootrom:
.word BOOTROM_ADDRESS
.globl shmobile_boot_cpu_gen2
shmobile_boot_cpu_gen2:
.word 0x00000000
.align 2
.globl shmobile_boot_fn_gen2
shmobile_boot_fn_gen2:
.space 4
.globl shmobile_boot_size_gen2
shmobile_boot_size_gen2:
.long . - shmobile_boot_vector_gen2
#endif /* CONFIG_ARCH_RCAR_GEN2 */
/* /*
* Per-CPU SMP boot function/argument selection code based on MPIDR * Per-CPU SMP boot function/argument selection code based on MPIDR
*/ */
......
...@@ -191,6 +191,7 @@ static void __init shmobile_smp_apmu_setup_boot(void) ...@@ -191,6 +191,7 @@ static void __init shmobile_smp_apmu_setup_boot(void)
{ {
/* install boot code shared by all CPUs */ /* install boot code shared by all CPUs */
shmobile_boot_fn = __pa_symbol(shmobile_smp_boot); shmobile_boot_fn = __pa_symbol(shmobile_smp_boot);
shmobile_boot_fn_gen2 = shmobile_boot_fn;
} }
void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/soc/renesas/rcar-sysc.h> #include <linux/soc/renesas/rcar-sysc.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/cputype.h>
#include "common.h" #include "common.h"
#include "rcar-gen2.h" #include "rcar-gen2.h"
...@@ -37,7 +38,6 @@ ...@@ -37,7 +38,6 @@
#define CA7RESCNT_CODE 0x5a5a0000 #define CA7RESCNT_CODE 0x5a5a0000
#define CA7RESCNT_CPUS 0xf /* CPU0-3 */ #define CA7RESCNT_CPUS 0xf /* CPU0-3 */
/* On-chip RAM */ /* On-chip RAM */
#define ICRAM1 0xe63c0000 /* Inter Connect RAM1 (4 KiB) */ #define ICRAM1 0xe63c0000 /* Inter Connect RAM1 (4 KiB) */
...@@ -119,8 +119,17 @@ void __init rcar_gen2_pm_init(void) ...@@ -119,8 +119,17 @@ void __init rcar_gen2_pm_init(void)
p = ioremap(res.start, resource_size(&res)); p = ioremap(res.start, resource_size(&res));
if (!p) if (!p)
return; return;
/*
memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); * install the reset vector, use the largest version if we have enough
* memory available
*/
if (resource_size(&res) >= shmobile_boot_size_gen2) {
shmobile_boot_cpu_gen2 = read_cpuid_mpidr();
memcpy_toio(p, shmobile_boot_vector_gen2,
shmobile_boot_size_gen2);
} else {
memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
}
iounmap(p); iounmap(p);
/* setup reset vectors */ /* setup reset vectors */
......
/* /*
* R-Car Generation 2 da9063/da9210 regulator quirk * R-Car Generation 2 da9063/da9210 regulator quirk
* *
* The r8a7790/lager and r8a7791/koelsch development boards have da9063 and * Certain Gen2 development boards have an da9063 and one or more da9210
* da9210 regulators. Both regulators have their interrupt request lines tied * regulators. All of these regulators have their interrupt request lines
* to the same interrupt pin (IRQ2) on the SoC. * tied to the same interrupt pin (IRQ2) on the SoC.
* *
* After cold boot or da9063-induced restart, both the da9063 and da9210 seem * After cold boot or da9063-induced restart, both the da9063 and da9210 seem
* to assert their interrupt request lines. Hence as soon as one driver * to assert their interrupt request lines. Hence as soon as one driver
...@@ -50,7 +50,7 @@ static void __iomem *irqc; ...@@ -50,7 +50,7 @@ static void __iomem *irqc;
static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff }; static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff };
static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff }; static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff };
static struct i2c_msg da9xxx_msgs[2] = { static struct i2c_msg da9xxx_msgs[3] = {
{ {
.addr = 0x58, .addr = 0x58,
.len = ARRAY_SIZE(da9063_irq_clr), .len = ARRAY_SIZE(da9063_irq_clr),
...@@ -59,6 +59,10 @@ static struct i2c_msg da9xxx_msgs[2] = { ...@@ -59,6 +59,10 @@ static struct i2c_msg da9xxx_msgs[2] = {
.addr = 0x68, .addr = 0x68,
.len = ARRAY_SIZE(da9210_irq_clr), .len = ARRAY_SIZE(da9210_irq_clr),
.buf = da9210_irq_clr, .buf = da9210_irq_clr,
}, {
.addr = 0x70,
.len = ARRAY_SIZE(da9210_irq_clr),
.buf = da9210_irq_clr,
}, },
}; };
...@@ -85,12 +89,16 @@ static int regulator_quirk_notify(struct notifier_block *nb, ...@@ -85,12 +89,16 @@ static int regulator_quirk_notify(struct notifier_block *nb,
dev_dbg(dev, "Detected %s\n", client->name); dev_dbg(dev, "Detected %s\n", client->name);
if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) || if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) ||
(client->addr == 0x68 && !strcmp(client->name, "da9210"))) { (client->addr == 0x68 && !strcmp(client->name, "da9210")) ||
int ret; (client->addr == 0x70 && !strcmp(client->name, "da9210"))) {
int ret, len;
/* There are two DA9210 on Stout, one on the other boards. */
len = of_machine_is_compatible("renesas,stout") ? 3 : 2;
dev_info(&client->dev, "clearing da9063/da9210 interrupts\n"); dev_info(&client->dev, "clearing da9063/da9210 interrupts\n");
ret = i2c_transfer(client->adapter, da9xxx_msgs, ARRAY_SIZE(da9xxx_msgs)); ret = i2c_transfer(client->adapter, da9xxx_msgs, len);
if (ret != ARRAY_SIZE(da9xxx_msgs)) if (ret != len)
dev_err(&client->dev, "i2c error %d\n", ret); dev_err(&client->dev, "i2c error %d\n", ret);
} }
...@@ -118,6 +126,7 @@ static int __init rcar_gen2_regulator_quirk(void) ...@@ -118,6 +126,7 @@ static int __init rcar_gen2_regulator_quirk(void)
if (!of_machine_is_compatible("renesas,koelsch") && if (!of_machine_is_compatible("renesas,koelsch") &&
!of_machine_is_compatible("renesas,lager") && !of_machine_is_compatible("renesas,lager") &&
!of_machine_is_compatible("renesas,stout") &&
!of_machine_is_compatible("renesas,gose")) !of_machine_is_compatible("renesas,gose"))
return -ENODEV; return -ENODEV;
......
...@@ -3,8 +3,8 @@ config SOC_RENESAS ...@@ -3,8 +3,8 @@ config SOC_RENESAS
default y if ARCH_RENESAS default y if ARCH_RENESAS
select SOC_BUS select SOC_BUS
select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \ select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \
ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77970 || \ ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \
ARCH_R8A77995 ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77995
select SYSC_R8A7743 if ARCH_R8A7743 select SYSC_R8A7743 if ARCH_R8A7743
select SYSC_R8A7745 if ARCH_R8A7745 select SYSC_R8A7745 if ARCH_R8A7745
select SYSC_R8A7779 if ARCH_R8A7779 select SYSC_R8A7779 if ARCH_R8A7779
...@@ -14,7 +14,9 @@ config SOC_RENESAS ...@@ -14,7 +14,9 @@ config SOC_RENESAS
select SYSC_R8A7794 if ARCH_R8A7794 select SYSC_R8A7794 if ARCH_R8A7794
select SYSC_R8A7795 if ARCH_R8A7795 select SYSC_R8A7795 if ARCH_R8A7795
select SYSC_R8A7796 if ARCH_R8A7796 select SYSC_R8A7796 if ARCH_R8A7796
select SYSC_R8A77965 if ARCH_R8A77965
select SYSC_R8A77970 if ARCH_R8A77970 select SYSC_R8A77970 if ARCH_R8A77970
select SYSC_R8A77980 if ARCH_R8A77980
select SYSC_R8A77995 if ARCH_R8A77995 select SYSC_R8A77995 if ARCH_R8A77995
if SOC_RENESAS if SOC_RENESAS
...@@ -56,10 +58,18 @@ config SYSC_R8A7796 ...@@ -56,10 +58,18 @@ config SYSC_R8A7796
bool "R-Car M3-W System Controller support" if COMPILE_TEST bool "R-Car M3-W System Controller support" if COMPILE_TEST
select SYSC_RCAR select SYSC_RCAR
config SYSC_R8A77965
bool "R-Car M3-N System Controller support" if COMPILE_TEST
select SYSC_RCAR
config SYSC_R8A77970 config SYSC_R8A77970
bool "R-Car V3M System Controller support" if COMPILE_TEST bool "R-Car V3M System Controller support" if COMPILE_TEST
select SYSC_RCAR select SYSC_RCAR
config SYSC_R8A77980
bool "R-Car V3H System Controller support" if COMPILE_TEST
select SYSC_RCAR
config SYSC_R8A77995 config SYSC_R8A77995
bool "R-Car D3 System Controller support" if COMPILE_TEST bool "R-Car D3 System Controller support" if COMPILE_TEST
select SYSC_RCAR select SYSC_RCAR
......
...@@ -12,7 +12,9 @@ obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o ...@@ -12,7 +12,9 @@ obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o
obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o
obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o
obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o
obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o
obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o
obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o
obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o
# Family # Family
......
// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car M3-N System Controller
* Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
*
* Based on Renesas R-Car M3-W System Controller
* Copyright (C) 2016 Glider bvba
*/
#include <linux/bug.h>
#include <linux/kernel.h>
#include <dt-bindings/power/r8a77965-sysc.h>
#include "rcar-sysc.h"
static const struct rcar_sysc_area r8a77965_areas[] __initconst = {
{ "always-on", 0, 0, R8A77965_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
{ "ca57-scu", 0x1c0, 0, R8A77965_PD_CA57_SCU, R8A77965_PD_ALWAYS_ON,
PD_SCU },
{ "ca57-cpu0", 0x80, 0, R8A77965_PD_CA57_CPU0, R8A77965_PD_CA57_SCU,
PD_CPU_NOCR },
{ "ca57-cpu1", 0x80, 1, R8A77965_PD_CA57_CPU1, R8A77965_PD_CA57_SCU,
PD_CPU_NOCR },
{ "cr7", 0x240, 0, R8A77965_PD_CR7, R8A77965_PD_ALWAYS_ON },
{ "a3vc", 0x380, 0, R8A77965_PD_A3VC, R8A77965_PD_ALWAYS_ON },
{ "a3vp", 0x340, 0, R8A77965_PD_A3VP, R8A77965_PD_ALWAYS_ON },
{ "a2vc1", 0x3c0, 1, R8A77965_PD_A2VC1, R8A77965_PD_A3VC },
{ "3dg-a", 0x100, 0, R8A77965_PD_3DG_A, R8A77965_PD_ALWAYS_ON },
{ "3dg-b", 0x100, 1, R8A77965_PD_3DG_B, R8A77965_PD_3DG_A },
{ "a3ir", 0x180, 0, R8A77965_PD_A3IR, R8A77965_PD_ALWAYS_ON },
};
const struct rcar_sysc_info r8a77965_sysc_info __initconst = {
.areas = r8a77965_areas,
.num_areas = ARRAY_SIZE(r8a77965_areas),
};
...@@ -25,12 +25,12 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = { ...@@ -25,12 +25,12 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = {
PD_CPU_NOCR }, PD_CPU_NOCR },
{ "cr7", 0x240, 0, R8A77970_PD_CR7, R8A77970_PD_ALWAYS_ON }, { "cr7", 0x240, 0, R8A77970_PD_CR7, R8A77970_PD_ALWAYS_ON },
{ "a3ir", 0x180, 0, R8A77970_PD_A3IR, R8A77970_PD_ALWAYS_ON }, { "a3ir", 0x180, 0, R8A77970_PD_A3IR, R8A77970_PD_ALWAYS_ON },
{ "a2ir0", 0x400, 0, R8A77970_PD_A2IR0, R8A77970_PD_ALWAYS_ON }, { "a2ir0", 0x400, 0, R8A77970_PD_A2IR0, R8A77970_PD_A3IR },
{ "a2ir1", 0x400, 1, R8A77970_PD_A2IR1, R8A77970_PD_A2IR0 }, { "a2ir1", 0x400, 1, R8A77970_PD_A2IR1, R8A77970_PD_A3IR },
{ "a2ir2", 0x400, 2, R8A77970_PD_A2IR2, R8A77970_PD_A2IR0 }, { "a2ir2", 0x400, 2, R8A77970_PD_A2IR2, R8A77970_PD_A3IR },
{ "a2ir3", 0x400, 3, R8A77970_PD_A2IR3, R8A77970_PD_A2IR0 }, { "a2ir3", 0x400, 3, R8A77970_PD_A2IR3, R8A77970_PD_A3IR },
{ "a2sc0", 0x400, 4, R8A77970_PD_A2SC0, R8A77970_PD_ALWAYS_ON }, { "a2sc0", 0x400, 4, R8A77970_PD_A2SC0, R8A77970_PD_A3IR },
{ "a2sc1", 0x400, 5, R8A77970_PD_A2SC1, R8A77970_PD_A2SC0 }, { "a2sc1", 0x400, 5, R8A77970_PD_A2SC1, R8A77970_PD_A3IR },
}; };
const struct rcar_sysc_info r8a77970_sysc_info __initconst = { const struct rcar_sysc_info r8a77970_sysc_info __initconst = {
......
// SPDX-License-Identifier: GPL-2.0
/*
* Renesas R-Car V3H System Controller
*
* Copyright (C) 2018 Renesas Electronics Corp.
* Copyright (C) 2018 Cogent Embedded, Inc.
*/
#include <linux/bug.h>
#include <linux/kernel.h>
#include <dt-bindings/power/r8a77980-sysc.h>
#include "rcar-sysc.h"
static const struct rcar_sysc_area r8a77980_areas[] __initconst = {
{ "always-on", 0, 0, R8A77980_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
{ "ca53-scu", 0x140, 0, R8A77980_PD_CA53_SCU, R8A77980_PD_ALWAYS_ON,
PD_SCU },
{ "ca53-cpu0", 0x200, 0, R8A77980_PD_CA53_CPU0, R8A77980_PD_CA53_SCU,
PD_CPU_NOCR },
{ "ca53-cpu1", 0x200, 1, R8A77980_PD_CA53_CPU1, R8A77980_PD_CA53_SCU,
PD_CPU_NOCR },
{ "ca53-cpu2", 0x200, 2, R8A77980_PD_CA53_CPU2, R8A77980_PD_CA53_SCU,
PD_CPU_NOCR },
{ "ca53-cpu3", 0x200, 3, R8A77980_PD_CA53_CPU3, R8A77980_PD_CA53_SCU,
PD_CPU_NOCR },
{ "cr7", 0x240, 0, R8A77980_PD_CR7, R8A77980_PD_ALWAYS_ON },
{ "a3ir", 0x180, 0, R8A77980_PD_A3IR, R8A77980_PD_ALWAYS_ON },
{ "a2ir0", 0x400, 0, R8A77980_PD_A2IR0, R8A77980_PD_A3IR },
{ "a2ir1", 0x400, 1, R8A77980_PD_A2IR1, R8A77980_PD_A3IR },
{ "a2ir2", 0x400, 2, R8A77980_PD_A2IR2, R8A77980_PD_A3IR },
{ "a2ir3", 0x400, 3, R8A77980_PD_A2IR3, R8A77980_PD_A3IR },
{ "a2ir4", 0x400, 4, R8A77980_PD_A2IR4, R8A77980_PD_A3IR },
{ "a2ir5", 0x400, 5, R8A77980_PD_A2IR5, R8A77980_PD_A3IR },
{ "a2sc0", 0x400, 6, R8A77980_PD_A2SC0, R8A77980_PD_A3IR },
{ "a2sc1", 0x400, 7, R8A77980_PD_A2SC1, R8A77980_PD_A3IR },
{ "a2sc2", 0x400, 8, R8A77980_PD_A2SC2, R8A77980_PD_A3IR },
{ "a2sc3", 0x400, 9, R8A77980_PD_A2SC3, R8A77980_PD_A3IR },
{ "a2sc4", 0x400, 10, R8A77980_PD_A2SC4, R8A77980_PD_A3IR },
{ "a2pd0", 0x400, 11, R8A77980_PD_A2PD0, R8A77980_PD_A3IR },
{ "a2pd1", 0x400, 12, R8A77980_PD_A2PD1, R8A77980_PD_A3IR },
{ "a2cn", 0x400, 13, R8A77980_PD_A2CN, R8A77980_PD_A3IR },
{ "a3vip", 0x2c0, 0, R8A77980_PD_A3VIP, R8A77980_PD_ALWAYS_ON },
{ "a3vip1", 0x300, 0, R8A77980_PD_A3VIP1, R8A77980_PD_A3VIP },
{ "a3vip2", 0x280, 0, R8A77980_PD_A3VIP2, R8A77980_PD_A3VIP },
};
const struct rcar_sysc_info r8a77980_sysc_info __initconst = {
.areas = r8a77980_areas,
.num_areas = ARRAY_SIZE(r8a77980_areas),
};
...@@ -13,8 +13,18 @@ ...@@ -13,8 +13,18 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/soc/renesas/rcar-rst.h> #include <linux/soc/renesas/rcar-rst.h>
#define WDTRSTCR_RESET 0xA55A0002
#define WDTRSTCR 0x0054
static int rcar_rst_enable_wdt_reset(void __iomem *base)
{
iowrite32(WDTRSTCR_RESET, base + WDTRSTCR);
return 0;
}
struct rst_config { struct rst_config {
unsigned int modemr; /* Mode Monitoring Register Offset */ unsigned int modemr; /* Mode Monitoring Register Offset */
int (*configure)(void *base); /* Platform specific configuration */
}; };
static const struct rst_config rcar_rst_gen1 __initconst = { static const struct rst_config rcar_rst_gen1 __initconst = {
...@@ -23,6 +33,11 @@ static const struct rst_config rcar_rst_gen1 __initconst = { ...@@ -23,6 +33,11 @@ static const struct rst_config rcar_rst_gen1 __initconst = {
static const struct rst_config rcar_rst_gen2 __initconst = { static const struct rst_config rcar_rst_gen2 __initconst = {
.modemr = 0x60, .modemr = 0x60,
.configure = rcar_rst_enable_wdt_reset,
};
static const struct rst_config rcar_rst_gen3 __initconst = {
.modemr = 0x60,
}; };
static const struct of_device_id rcar_rst_matches[] __initconst = { static const struct of_device_id rcar_rst_matches[] __initconst = {
...@@ -38,11 +53,13 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { ...@@ -38,11 +53,13 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
{ .compatible = "renesas,r8a7792-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7792-rst", .data = &rcar_rst_gen2 },
{ .compatible = "renesas,r8a7793-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7793-rst", .data = &rcar_rst_gen2 },
{ .compatible = "renesas,r8a7794-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7794-rst", .data = &rcar_rst_gen2 },
/* R-Car Gen3 is handled like R-Car Gen2 */ /* R-Car Gen3 */
{ .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a77980-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen3 },
{ /* sentinel */ } { /* sentinel */ }
}; };
...@@ -71,6 +88,14 @@ static int __init rcar_rst_init(void) ...@@ -71,6 +88,14 @@ static int __init rcar_rst_init(void)
rcar_rst_base = base; rcar_rst_base = base;
cfg = match->data; cfg = match->data;
saved_mode = ioread32(base + cfg->modemr); saved_mode = ioread32(base + cfg->modemr);
if (cfg->configure) {
error = cfg->configure(base);
if (error) {
pr_warn("%pOF: Cannot run SoC specific configuration\n",
np);
goto out_put;
}
}
pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode); pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode);
......
...@@ -254,7 +254,7 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd) ...@@ -254,7 +254,7 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
pm_genpd_init(genpd, gov, false); pm_genpd_init(genpd, gov, false);
} }
static const struct of_device_id rcar_sysc_matches[] = { static const struct of_device_id rcar_sysc_matches[] __initconst = {
#ifdef CONFIG_SYSC_R8A7743 #ifdef CONFIG_SYSC_R8A7743
{ .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info }, { .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info },
#endif #endif
...@@ -284,9 +284,15 @@ static const struct of_device_id rcar_sysc_matches[] = { ...@@ -284,9 +284,15 @@ static const struct of_device_id rcar_sysc_matches[] = {
#ifdef CONFIG_SYSC_R8A7796 #ifdef CONFIG_SYSC_R8A7796
{ .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info }, { .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info },
#endif #endif
#ifdef CONFIG_SYSC_R8A77965
{ .compatible = "renesas,r8a77965-sysc", .data = &r8a77965_sysc_info },
#endif
#ifdef CONFIG_SYSC_R8A77970 #ifdef CONFIG_SYSC_R8A77970
{ .compatible = "renesas,r8a77970-sysc", .data = &r8a77970_sysc_info }, { .compatible = "renesas,r8a77970-sysc", .data = &r8a77970_sysc_info },
#endif #endif
#ifdef CONFIG_SYSC_R8A77980
{ .compatible = "renesas,r8a77980-sysc", .data = &r8a77980_sysc_info },
#endif
#ifdef CONFIG_SYSC_R8A77995 #ifdef CONFIG_SYSC_R8A77995
{ .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info }, { .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info },
#endif #endif
......
...@@ -58,7 +58,9 @@ extern const struct rcar_sysc_info r8a7792_sysc_info; ...@@ -58,7 +58,9 @@ extern const struct rcar_sysc_info r8a7792_sysc_info;
extern const struct rcar_sysc_info r8a7794_sysc_info; extern const struct rcar_sysc_info r8a7794_sysc_info;
extern const struct rcar_sysc_info r8a7795_sysc_info; extern const struct rcar_sysc_info r8a7795_sysc_info;
extern const struct rcar_sysc_info r8a7796_sysc_info; extern const struct rcar_sysc_info r8a7796_sysc_info;
extern const struct rcar_sysc_info r8a77965_sysc_info;
extern const struct rcar_sysc_info r8a77970_sysc_info; extern const struct rcar_sysc_info r8a77970_sysc_info;
extern const struct rcar_sysc_info r8a77980_sysc_info;
extern const struct rcar_sysc_info r8a77995_sysc_info; extern const struct rcar_sysc_info r8a77995_sysc_info;
......
...@@ -144,11 +144,21 @@ static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = { ...@@ -144,11 +144,21 @@ static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = {
.id = 0x52, .id = 0x52,
}; };
static const struct renesas_soc soc_rcar_m3_n __initconst __maybe_unused = {
.family = &fam_rcar_gen3,
.id = 0x55,
};
static const struct renesas_soc soc_rcar_v3m __initconst __maybe_unused = { static const struct renesas_soc soc_rcar_v3m __initconst __maybe_unused = {
.family = &fam_rcar_gen3, .family = &fam_rcar_gen3,
.id = 0x54, .id = 0x54,
}; };
static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = {
.family = &fam_rcar_gen3,
.id = 0x56,
};
static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = { static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = {
.family = &fam_rcar_gen3, .family = &fam_rcar_gen3,
.id = 0x58, .id = 0x58,
...@@ -209,9 +219,15 @@ static const struct of_device_id renesas_socs[] __initconst = { ...@@ -209,9 +219,15 @@ static const struct of_device_id renesas_socs[] __initconst = {
#ifdef CONFIG_ARCH_R8A7796 #ifdef CONFIG_ARCH_R8A7796
{ .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w }, { .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w },
#endif #endif
#ifdef CONFIG_ARCH_R8A77965
{ .compatible = "renesas,r8a77965", .data = &soc_rcar_m3_n },
#endif
#ifdef CONFIG_ARCH_R8A77970 #ifdef CONFIG_ARCH_R8A77970
{ .compatible = "renesas,r8a77970", .data = &soc_rcar_v3m }, { .compatible = "renesas,r8a77970", .data = &soc_rcar_v3m },
#endif #endif
#ifdef CONFIG_ARCH_R8A77980
{ .compatible = "renesas,r8a77980", .data = &soc_rcar_v3h },
#endif
#ifdef CONFIG_ARCH_R8A77995 #ifdef CONFIG_ARCH_R8A77995
{ .compatible = "renesas,r8a77995", .data = &soc_rcar_d3 }, { .compatible = "renesas,r8a77995", .data = &soc_rcar_d3 },
#endif #endif
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
* Copyright (C) 2016 Glider bvba
*/
#ifndef __DT_BINDINGS_POWER_R8A77965_SYSC_H__
#define __DT_BINDINGS_POWER_R8A77965_SYSC_H__
/*
* These power domain indices match the numbers of the interrupt bits
* representing the power areas in the various Interrupt Registers
* (e.g. SYSCISR, Interrupt Status Register)
*/
#define R8A77965_PD_CA57_CPU0 0
#define R8A77965_PD_CA57_CPU1 1
#define R8A77965_PD_A3VP 9
#define R8A77965_PD_CA57_SCU 12
#define R8A77965_PD_CR7 13
#define R8A77965_PD_A3VC 14
#define R8A77965_PD_3DG_A 17
#define R8A77965_PD_3DG_B 18
#define R8A77965_PD_A3IR 24
#define R8A77965_PD_A2VC1 26
/* Always-on power area */
#define R8A77965_PD_ALWAYS_ON 32
#endif /* __DT_BINDINGS_POWER_R8A77965_SYSC_H__ */
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018 Renesas Electronics Corp.
* Copyright (C) 2018 Cogent Embedded, Inc.
*/
#ifndef __DT_BINDINGS_POWER_R8A77980_SYSC_H__
#define __DT_BINDINGS_POWER_R8A77980_SYSC_H__
/*
* These power domain indices match the numbers of the interrupt bits
* representing the power areas in the various Interrupt Registers
* (e.g. SYSCISR, Interrupt Status Register)
*/
#define R8A77980_PD_A2SC2 0
#define R8A77980_PD_A2SC3 1
#define R8A77980_PD_A2SC4 2
#define R8A77980_PD_A2PD0 3
#define R8A77980_PD_A2PD1 4
#define R8A77980_PD_CA53_CPU0 5
#define R8A77980_PD_CA53_CPU1 6
#define R8A77980_PD_CA53_CPU2 7
#define R8A77980_PD_CA53_CPU3 8
#define R8A77980_PD_A2CN 10
#define R8A77980_PD_A3VIP 11
#define R8A77980_PD_A2IR5 12
#define R8A77980_PD_CR7 13
#define R8A77980_PD_A2IR4 15
#define R8A77980_PD_CA53_SCU 21
#define R8A77980_PD_A2IR0 23
#define R8A77980_PD_A3IR 24
#define R8A77980_PD_A3VIP1 25
#define R8A77980_PD_A3VIP2 26
#define R8A77980_PD_A2IR1 27
#define R8A77980_PD_A2IR2 28
#define R8A77980_PD_A2IR3 29
#define R8A77980_PD_A2SC0 30
#define R8A77980_PD_A2SC1 31
/* Always-on power area */
#define R8A77980_PD_ALWAYS_ON 32
#endif /* __DT_BINDINGS_POWER_R8A77980_SYSC_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment