Merge tag 'renesas-soc2-for-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/soc
Second Round of Renesas ARM Based SoC Updates for v4.8 * Add DT support to the APMU driver and prioritise DT APMU support * Obtain extal frequency from DT * Add support for r8a7792 * tag 'renesas-soc2-for-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: ARM: shmobile: r8a7791: Prioritize DT APMU support ARM: shmobile: r8a7790: Prioritize DT APMU support ARM: shmobile: smp: Add function to prioritize DT SMP ARM: shmobile: apmu: Add APMU DT support via Enable method ARM: shmobile: apmu: Move #ifdef CONFIG_SMP to cover more functions ARM: shmobile: rcar-gen2: Correct arch timer frequency on R-Car V2H ARM: shmobile: rcar-gen2: Obtain extal frequency from DT ARM: shmobile: r8a7792: basic SoC support soc: renesas: rcar-sysc: Improve SYSC interrupt config in legacy wrapper soc: renesas: rcar-sysc: Move SYSC interrupt config to rcar-sysc driver soc: renesas: rcar-sysc: Make rcar_sysc_init() init the PM domains soc: renesas: rcar-sysc: Fix uninitialized error code in rcar_sysc_pd_init() soc: renesas: rcar-sysc: add R8A7792 support soc: renesas: rcar-sysc: Add support for R-Car M3-W power areas soc: renesas: Add r8a7796 SYSC PM Domain Binding Definitions soc: renesas: rcar-sysc: Document r8a7796 support Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
@@ -86,6 +86,10 @@ config ARCH_R8A7791
|
||||
select ARCH_RCAR_GEN2
|
||||
select I2C
|
||||
|
||||
config ARCH_R8A7792
|
||||
bool "R-Car V2H (R8A77920)"
|
||||
select ARCH_RCAR_GEN2
|
||||
|
||||
config ARCH_R8A7793
|
||||
bool "R-Car M2-N (R8A7793)"
|
||||
select ARCH_RCAR_GEN2
|
||||
|
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o
|
||||
obj-$(CONFIG_ARCH_R8A7792) += setup-r8a7792.o
|
||||
obj-$(CONFIG_ARCH_R8A7793) += setup-r8a7793.o
|
||||
obj-$(CONFIG_ARCH_R8A7794) += setup-r8a7794.o
|
||||
obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
|
||||
|
@@ -10,6 +10,7 @@ extern void shmobile_smp_sleep(void);
|
||||
extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
|
||||
unsigned long arg);
|
||||
extern bool shmobile_smp_cpu_can_disable(unsigned int cpu);
|
||||
extern bool shmobile_smp_init_fallback_ops(void);
|
||||
extern void shmobile_boot_scu(void);
|
||||
extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys,
|
||||
unsigned int max_cpus);
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <asm/suspend.h>
|
||||
#include "common.h"
|
||||
#include "platsmp-apmu.h"
|
||||
#include "rcar-gen2.h"
|
||||
|
||||
static struct {
|
||||
void __iomem *iomem;
|
||||
@@ -74,6 +75,7 @@ static int __maybe_unused apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)
|
||||
return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static void apmu_init_cpu(struct resource *res, int cpu, int bit)
|
||||
{
|
||||
if ((cpu >= ARRAY_SIZE(apmu_cpus)) || apmu_cpus[cpu].iomem)
|
||||
@@ -117,18 +119,69 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
|
||||
}
|
||||
}
|
||||
|
||||
static const struct of_device_id apmu_ids[] = {
|
||||
{ .compatible = "renesas,apmu" },
|
||||
{ /*sentinel*/ }
|
||||
};
|
||||
|
||||
static void apmu_parse_dt(void (*fn)(struct resource *res, int cpu, int bit))
|
||||
{
|
||||
struct device_node *np_apmu, *np_cpu;
|
||||
struct resource res;
|
||||
int bit, index;
|
||||
u32 id;
|
||||
|
||||
for_each_matching_node(np_apmu, apmu_ids) {
|
||||
/* only enable the cluster that includes the boot CPU */
|
||||
bool is_allowed = false;
|
||||
|
||||
for (bit = 0; bit < CONFIG_NR_CPUS; bit++) {
|
||||
np_cpu = of_parse_phandle(np_apmu, "cpus", bit);
|
||||
if (np_cpu) {
|
||||
if (!of_property_read_u32(np_cpu, "reg", &id)) {
|
||||
if (id == cpu_logical_map(0)) {
|
||||
is_allowed = true;
|
||||
of_node_put(np_cpu);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
of_node_put(np_cpu);
|
||||
}
|
||||
}
|
||||
if (!is_allowed)
|
||||
continue;
|
||||
|
||||
for (bit = 0; bit < CONFIG_NR_CPUS; bit++) {
|
||||
np_cpu = of_parse_phandle(np_apmu, "cpus", bit);
|
||||
if (np_cpu) {
|
||||
if (!of_property_read_u32(np_cpu, "reg", &id)) {
|
||||
index = get_logical_index(id);
|
||||
if ((index >= 0) &&
|
||||
!of_address_to_resource(np_apmu,
|
||||
0, &res))
|
||||
fn(&res, index, bit);
|
||||
}
|
||||
of_node_put(np_cpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __init shmobile_smp_apmu_setup_boot(void)
|
||||
{
|
||||
/* install boot code shared by all CPUs */
|
||||
shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
|
||||
}
|
||||
|
||||
void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
|
||||
struct rcar_apmu_config *apmu_config,
|
||||
int num)
|
||||
{
|
||||
/* install boot code shared by all CPUs */
|
||||
shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
|
||||
|
||||
/* perform per-cpu setup */
|
||||
shmobile_smp_apmu_setup_boot();
|
||||
apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
/* For this particular CPU register boot vector */
|
||||
@@ -136,7 +189,38 @@ int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
|
||||
return apmu_wrap(cpu, apmu_power_on);
|
||||
}
|
||||
|
||||
static void __init shmobile_smp_apmu_prepare_cpus_dt(unsigned int max_cpus)
|
||||
{
|
||||
shmobile_smp_apmu_setup_boot();
|
||||
apmu_parse_dt(apmu_init_cpu);
|
||||
rcar_gen2_pm_init();
|
||||
}
|
||||
|
||||
static int shmobile_smp_apmu_boot_secondary_md21(unsigned int cpu,
|
||||
struct task_struct *idle)
|
||||
{
|
||||
/* Error out when hardware debug mode is enabled */
|
||||
if (rcar_gen2_read_mode_pins() & BIT(21)) {
|
||||
pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
return shmobile_smp_apmu_boot_secondary(cpu, idle);
|
||||
}
|
||||
|
||||
static struct smp_operations apmu_smp_ops __initdata = {
|
||||
.smp_prepare_cpus = shmobile_smp_apmu_prepare_cpus_dt,
|
||||
.smp_boot_secondary = shmobile_smp_apmu_boot_secondary_md21,
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
.cpu_can_disable = shmobile_smp_cpu_can_disable,
|
||||
.cpu_die = shmobile_smp_apmu_cpu_die,
|
||||
.cpu_kill = shmobile_smp_apmu_cpu_kill,
|
||||
#endif
|
||||
};
|
||||
|
||||
CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops);
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
|
||||
/* nicked from arch/arm/mach-exynos/hotplug.c */
|
||||
|
@@ -36,3 +36,9 @@ bool shmobile_smp_cpu_can_disable(unsigned int cpu)
|
||||
return true; /* Hotplug of any CPU is supported */
|
||||
}
|
||||
#endif
|
||||
|
||||
bool __init shmobile_smp_init_fallback_ops(void)
|
||||
{
|
||||
/* fallback on PSCI/smp_ops if no other DT based method is detected */
|
||||
return platform_can_secondary_boot() ? true : false;
|
||||
}
|
||||
|
@@ -23,11 +23,7 @@
|
||||
|
||||
static void __init r8a7779_sysc_init(void)
|
||||
{
|
||||
void __iomem *base = rcar_sysc_init(0xffd85000);
|
||||
|
||||
/* enable all interrupt sources, but do not use interrupt handler */
|
||||
iowrite32(0x0131000e, base + SYSCIER);
|
||||
iowrite32(0, base + SYSCIMR);
|
||||
rcar_sysc_init(0xffd85000, 0x0131000e);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PM || CONFIG_SMP */
|
||||
|
@@ -36,11 +36,7 @@
|
||||
|
||||
static void __init rcar_gen2_sysc_init(u32 syscier)
|
||||
{
|
||||
void __iomem *base = rcar_sysc_init(0xe6180000);
|
||||
|
||||
/* enable all interrupt sources, but do not use interrupt handler */
|
||||
iowrite32(syscier, base + SYSCIER);
|
||||
iowrite32(0, base + SYSCIMR);
|
||||
rcar_sysc_init(0xe6180000, syscier);
|
||||
}
|
||||
|
||||
#else /* CONFIG_SMP */
|
||||
|
@@ -28,6 +28,7 @@ static const char * const r8a7790_boards_compat_dt[] __initconst = {
|
||||
};
|
||||
|
||||
DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
|
||||
.smp_init = shmobile_smp_init_fallback_ops,
|
||||
.smp = smp_ops(r8a7790_smp_ops),
|
||||
.init_early = shmobile_init_delay,
|
||||
.init_time = rcar_gen2_timer_init,
|
||||
|
@@ -29,6 +29,7 @@ static const char *const r8a7791_boards_compat_dt[] __initconst = {
|
||||
};
|
||||
|
||||
DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)")
|
||||
.smp_init = shmobile_smp_init_fallback_ops,
|
||||
.smp = smp_ops(r8a7791_smp_ops),
|
||||
.init_early = shmobile_init_delay,
|
||||
.init_time = rcar_gen2_timer_init,
|
||||
|
35
arch/arm/mach-shmobile/setup-r8a7792.c
Normal file
35
arch/arm/mach-shmobile/setup-r8a7792.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* r8a7792 processor support
|
||||
*
|
||||
* Copyright (C) 2014 Renesas Electronics Corporation
|
||||
* Copyright (C) 2016 Cogent Embedded, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "rcar-gen2.h"
|
||||
|
||||
static const char * const r8a7792_boards_compat_dt[] __initconst = {
|
||||
"renesas,r8a7792",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(R8A7792_DT, "Generic R8A7792 (Flattened Device Tree)")
|
||||
.init_early = shmobile_init_delay,
|
||||
.init_late = shmobile_init_late,
|
||||
.init_time = rcar_gen2_timer_init,
|
||||
.reserve = rcar_gen2_reserve,
|
||||
.dt_compat = r8a7792_boards_compat_dt,
|
||||
MACHINE_END
|
@@ -46,6 +46,26 @@ u32 rcar_gen2_read_mode_pins(void)
|
||||
return mode;
|
||||
}
|
||||
|
||||
static unsigned int __init get_extal_freq(void)
|
||||
{
|
||||
struct device_node *cpg, *extal;
|
||||
u32 freq = 20000000;
|
||||
|
||||
cpg = of_find_compatible_node(NULL, NULL,
|
||||
"renesas,rcar-gen2-cpg-clocks");
|
||||
if (!cpg)
|
||||
return freq;
|
||||
|
||||
extal = of_parse_phandle(cpg, "clocks", 0);
|
||||
of_node_put(cpg);
|
||||
if (!extal)
|
||||
return freq;
|
||||
|
||||
of_property_read_u32(extal, "clock-frequency", &freq);
|
||||
of_node_put(extal);
|
||||
return freq;
|
||||
}
|
||||
|
||||
#define CNTCR 0
|
||||
#define CNTFID0 0x20
|
||||
|
||||
@@ -54,10 +74,10 @@ void __init rcar_gen2_timer_init(void)
|
||||
u32 mode = rcar_gen2_read_mode_pins();
|
||||
#ifdef CONFIG_ARM_ARCH_TIMER
|
||||
void __iomem *base;
|
||||
int extal_mhz = 0;
|
||||
u32 freq;
|
||||
|
||||
if (of_machine_is_compatible("renesas,r8a7794")) {
|
||||
if (of_machine_is_compatible("renesas,r8a7792") ||
|
||||
of_machine_is_compatible("renesas,r8a7794")) {
|
||||
freq = 260000000 / 8; /* ZS / 8 */
|
||||
/* CNTVOFF has to be initialized either from non-secure
|
||||
* Hypervisor mode or secure Monitor mode with SCR.NS==1.
|
||||
@@ -82,26 +102,9 @@ void __init rcar_gen2_timer_init(void)
|
||||
* with the counter disabled. Moreover, it may also report
|
||||
* a potentially incorrect fixed 13 MHz frequency. To be
|
||||
* correct these registers need to be updated to use the
|
||||
* frequency EXTAL / 2 which can be determined by the MD pins.
|
||||
* frequency EXTAL / 2.
|
||||
*/
|
||||
|
||||
switch (mode & (MD(14) | MD(13))) {
|
||||
case 0:
|
||||
extal_mhz = 15;
|
||||
break;
|
||||
case MD(13):
|
||||
extal_mhz = 20;
|
||||
break;
|
||||
case MD(14):
|
||||
extal_mhz = 26;
|
||||
break;
|
||||
case MD(13) | MD(14):
|
||||
extal_mhz = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
/* The arch timer frequency equals EXTAL / 2 */
|
||||
freq = extal_mhz * (1000000 / 2);
|
||||
freq = get_extal_freq() / 2;
|
||||
}
|
||||
|
||||
/* Remap "armgcnt address map" space */
|
||||
|
Reference in New Issue
Block a user