ARM: 32-bit SoC platform updates

Most of the SoC updates in this cycle are cleanups and moves to more
 modern infrastructure:
  - Davinci was moved to common clock framework
  - OMAP1-based Amstrad E3 "Superphone" saw a bunch of cleanups to the
    keyboard interface (bitbanged AT keyboard via GPIO).
  - Removal of some stale code for Renesas platforms
  - Power management improvements for i.MX6LL
 -----BEGIN PGP SIGNATURE-----
 
 iQJDBAABCAAtFiEElf+HevZ4QCAJmMQ+jBrnPN6EHHcFAlt+Lh0PHG9sb2ZAbGl4
 b20ubmV0AAoJEIwa5zzehBx3Y+YP/2QVT1T1/Fz3WsuLg7BYa6r51BDxvr/pSQKh
 eqLhZCcI5RpOlW4noWgJXWqnX2AlR1vX6xe0W0ebj177ttUHmidUQUJCpwP39AGE
 LrVC2+mlFb3uPx0HlpHsx3zFZdNFfrhl5mN3JbZfnLv0fUibVEhR+K8ii7MV1/Fk
 Lbo9sVPT8GIJuU6uyTTUnsCufwCkARMhrYbO6cbtS0FCO77a5aHp7btvHZ2ykxwh
 hG9CI3FhfAP3Tkpm+IbHkC5jYQNRewQoqthzJ4WJbRrcdA/vaArBTOUoZG4NFMOM
 M3B4jd1x26llmQhUqH4kGeOZiQ714GPrKcGS+8w7Twj5sIRGDxpif2Ac0kKL2B8X
 Ps6UTM0cb63W9I+TphjLysKSarNjR2lVVhNVoJ8P47MSyDGIRpSR7+IWvlJ7U8vz
 1yMWCguwrwZH3DnQb8UINTfI1Y1RstmtO5v8paSqfJyFX5r64x6VfYso1fRzxyFE
 4r2TS0HRv117aKkHwY8smjielZ0CpGnyEDQgq9Z72V4FueIqsJQrA3oGYXgTArFl
 mLL+fJUdwPv00nWuAZ8q0wIj1NvJvksJy+cObZXL6HK9m3cSdYwOHipdG86k20S5
 6/KMPmgrMbV9YO3lVtfJZjdu2QTBiYVBPGfsiSo5lVL5Q5rDYV9QBijnE+9W9/yT
 tJ038MhK
 =ACVk
 -----END PGP SIGNATURE-----

Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM 32-bit SoC platform updates from Olof Johansson:
 "Most of the SoC updates in this cycle are cleanups and moves to more
  modern infrastructure:

   - Davinci was moved to common clock framework

   - OMAP1-based Amstrad E3 "Superphone" saw a bunch of cleanups to the
     keyboard interface (bitbanged AT keyboard via GPIO).

   - Removal of some stale code for Renesas platforms

   - Power management improvements for i.MX6LL"

* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (112 commits)
  ARM: uniphier: select RESET_CONTROLLER
  arm64: uniphier: select RESET_CONTROLLER
  ARM: uniphier: remove empty Makefile
  ARM: exynos: Clear global variable on init error path
  ARM: exynos: Remove outdated maintainer information
  ARM: shmobile: Always enable ARCH_TIMER on SoCs with A7 and/or A15
  ARM: shmobile: r8a7779: hide unused r8a7779_platform_cpu_kill
  soc: r9a06g032: don't build SMP files for non-SMP config
  ARM: shmobile: Add the R9A06G032 SMP enabler driver
  ARM: at91: pm: configure wakeup sources for ULP1 mode
  ARM: at91: pm: add PMC fast startup registers defines
  ARM: at91: pm: Add ULP1 mode support
  ARM: at91: pm: Use ULP0 naming instead of slow clock
  ARM: hisi: handle of_iomap and fix missing of_node_put
  ARM: hisi: check of_iomap and fix missing of_node_put
  ARM: hisi: fix error handling and missing of_node_put
  ARM: mx5: Set the DBGEN bit in ARM_GPC register
  ARM: imx51: Configure M4IF to avoid visual artifacts
  ARM: imx: call imx6sx_cpuidle_init() conditionally for 6sll
  ARM: imx: fix i.MX6SLL build
  ...
This commit is contained in:
Linus Torvalds 2018-08-23 13:44:43 -07:00
commit 9e259f9352
133 changed files with 2432 additions and 5307 deletions

View file

@ -18,6 +18,9 @@ obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o
obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o
obj-$(CONFIG_SYSC_R8A77990) += r8a77990-sysc.o
obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o
ifdef CONFIG_SMP
obj-$(CONFIG_ARCH_R9A06G032) += r9a06g032-smp.o
endif
# Family
obj-$(CONFIG_RST_RCAR) += rcar-rst.o

View file

@ -0,0 +1,96 @@
// SPDX-License-Identifier: GPL-2.0
/*
* R9A06G032 Second CA7 enabler.
*
* Copyright (C) 2018 Renesas Electronics Europe Limited
*
* Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>
* Derived from actions,s500-smp
*/
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/smp.h>
/*
* The second CPU is parked in ROM at boot time. It requires waking it after
* writing an address into the BOOTADDR register of sysctrl.
*
* So the default value of the "cpu-release-addr" corresponds to BOOTADDR...
*
* *However* the BOOTADDR register is not available when the kernel
* starts in NONSEC mode.
*
* So for NONSEC mode, the bootloader re-parks the second CPU into a pen
* in SRAM, and changes the "cpu-release-addr" of linux's DT to a SRAM address,
* which is not restricted.
*/
static void __iomem *cpu_bootaddr;
static DEFINE_SPINLOCK(cpu_lock);
static int
r9a06g032_smp_boot_secondary(unsigned int cpu,
struct task_struct *idle)
{
if (!cpu_bootaddr)
return -ENODEV;
spin_lock(&cpu_lock);
writel(__pa_symbol(secondary_startup), cpu_bootaddr);
arch_send_wakeup_ipi_mask(cpumask_of(cpu));
spin_unlock(&cpu_lock);
return 0;
}
static void __init r9a06g032_smp_prepare_cpus(unsigned int max_cpus)
{
struct device_node *dn;
int ret = -EINVAL, dns;
u32 bootaddr;
dn = of_get_cpu_node(1, NULL);
if (!dn) {
pr_err("CPU#1: missing device tree node\n");
return;
}
/*
* Determine the address from which the CPU is polling.
* The bootloader *does* change this property.
* Note: The property can be either 64 or 32 bits, so handle both cases
*/
if (of_find_property(dn, "cpu-release-addr", &dns)) {
if (dns == sizeof(u64)) {
u64 temp;
ret = of_property_read_u64(dn,
"cpu-release-addr", &temp);
bootaddr = temp;
} else {
ret = of_property_read_u32(dn,
"cpu-release-addr",
&bootaddr);
}
}
of_node_put(dn);
if (ret) {
pr_err("CPU#1: invalid cpu-release-addr property\n");
return;
}
pr_info("CPU#1: cpu-release-addr %08x\n", bootaddr);
cpu_bootaddr = ioremap(bootaddr, sizeof(bootaddr));
}
static const struct smp_operations r9a06g032_smp_ops __initconst = {
.smp_prepare_cpus = r9a06g032_smp_prepare_cpus,
.smp_boot_secondary = r9a06g032_smp_boot_secondary,
};
CPU_METHOD_OF_DECLARE(r9a06g032_smp,
"renesas,r9a06g032-smp", &r9a06g032_smp_ops);

View file

@ -58,6 +58,12 @@
#define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */
struct rcar_sysc_ch {
u16 chan_offs;
u8 chan_bit;
u8 isr_bit;
};
static void __iomem *rcar_sysc_base;
static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
@ -143,12 +149,12 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
return ret;
}
int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
static int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
{
return rcar_sysc_power(sysc_ch, false);
}
int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
static int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
{
return rcar_sysc_power(sysc_ch, true);
}
@ -315,6 +321,8 @@ struct rcar_pm_domains {
struct generic_pm_domain *domains[RCAR_PD_ALWAYS_ON + 1];
};
static struct genpd_onecell_data *rcar_sysc_onecell_data;
static int __init rcar_sysc_pd_init(void)
{
const struct rcar_sysc_info *info;
@ -326,9 +334,6 @@ static int __init rcar_sysc_pd_init(void)
unsigned int i;
int error;
if (rcar_sysc_base)
return 0;
np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match);
if (!np)
return -ENODEV;
@ -361,6 +366,7 @@ static int __init rcar_sysc_pd_init(void)
domains->onecell_data.domains = domains->domains;
domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains);
rcar_sysc_onecell_data = &domains->onecell_data;
for (i = 0, syscier = 0; i < info->num_areas; i++)
syscier |= BIT(info->areas[i].isr_bit);
@ -448,27 +454,39 @@ void __init rcar_sysc_nullify(struct rcar_sysc_area *areas,
}
}
void __init rcar_sysc_init(phys_addr_t base, u32 syscier)
#ifdef CONFIG_ARCH_R8A7779
static int rcar_sysc_power_cpu(unsigned int idx, bool on)
{
u32 syscimr;
struct generic_pm_domain *genpd;
struct rcar_sysc_pd *pd;
unsigned int i;
if (!rcar_sysc_pd_init())
return;
if (!rcar_sysc_onecell_data)
return -ENODEV;
rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
for (i = 0; i < rcar_sysc_onecell_data->num_domains; i++) {
genpd = rcar_sysc_onecell_data->domains[i];
if (!genpd)
continue;
/*
* Mask all interrupt sources to prevent the CPU from receiving them.
* Make sure not to clear reserved bits that were set before.
*/
syscimr = ioread32(rcar_sysc_base + SYSCIMR);
syscimr |= syscier;
pr_debug("%s: syscimr = 0x%08x\n", __func__, syscimr);
iowrite32(syscimr, rcar_sysc_base + SYSCIMR);
pd = to_rcar_pd(genpd);
if (!(pd->flags & PD_CPU) || pd->ch.chan_bit != idx)
continue;
/*
* SYSC needs all interrupt sources enabled to control power.
*/
pr_debug("%s: syscier = 0x%08x\n", __func__, syscier);
iowrite32(syscier, rcar_sysc_base + SYSCIER);
return on ? rcar_sysc_power_up(&pd->ch)
: rcar_sysc_power_down(&pd->ch);
}
return -ENOENT;
}
int rcar_sysc_power_down_cpu(unsigned int cpu)
{
return rcar_sysc_power_cpu(cpu, false);
}
int rcar_sysc_power_up_cpu(unsigned int cpu)
{
return rcar_sysc_power_cpu(cpu, true);
}
#endif /* CONFIG_ARCH_R8A7779 */

View file

@ -41,6 +41,8 @@ static struct am33xx_pm_sram_addr *pm_sram;
static struct device *pm33xx_dev;
static struct wkup_m3_ipc *m3_ipc;
static unsigned long suspend_wfi_flags;
static u32 sram_suspend_address(unsigned long addr)
{
return ((unsigned long)am33xx_do_wfi_sram +
@ -53,7 +55,7 @@ static int am33xx_pm_suspend(suspend_state_t suspend_state)
int i, ret = 0;
ret = pm_ops->soc_suspend((unsigned long)suspend_state,
am33xx_do_wfi_sram);
am33xx_do_wfi_sram, suspend_wfi_flags);
if (ret) {
dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");
@ -227,6 +229,7 @@ static int am33xx_push_sram_idle(void)
ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;
ro_sram_data.amx3_pm_sram_data_phys =
gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);
ro_sram_data.rtc_base_virt = pm_ops->get_rtc_base_addr();
/* Save physical address to calculate resume offset during pm init */
am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,
@ -310,6 +313,17 @@ static int am33xx_pm_probe(struct platform_device *pdev)
suspend_set_ops(&am33xx_pm_ops);
#endif /* CONFIG_SUSPEND */
/*
* For a system suspend we must flush the caches, we want
* the DDR in self-refresh, we want to save the context
* of the EMIF, and we want the wkup_m3 to handle low-power
* transition.
*/
suspend_wfi_flags |= WFI_FLAG_FLUSH_CACHE;
suspend_wfi_flags |= WFI_FLAG_SELF_REFRESH;
suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;
suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
ret = pm_ops->init();
if (ret) {
dev_err(dev, "Unable to call core pm init!\n");