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:
Olof Johansson
2016-07-06 22:21:11 -07:00
19 changed files with 323 additions and 47 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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,

View File

@@ -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,

View 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

View File

@@ -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 */