linux_dsm_epyc7002/arch/arm/mach-shmobile/setup-rcar-gen2.c
Oleksandr Tyshchenko 51a0daf64d ARM: mach-shmobile: Don't init CNTVOFF/counter if PSCI is available
If PSCI is available then most likely we are running on PSCI-enabled
U-Boot which, we assume, has already taken care of resetting CNTVOFF
and updating counter module before switching to non-secure mode
and we don't need to.

As the psci_smp_available() helper always returns false if CONFIG_SMP
is disabled, it can't be used safely as an indicator of PSCI usage.
For that reason, we check for the mandatory PSCI operation to be
available.

Please note, an extra check to prevent secure_cntvoff_init() from
being called for secondary CPUs in headsmp-apmu.S is not needed,
as SMP code for APMU based system is not executed if PSCI is in use.

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
2019-05-31 11:38:01 +02:00

226 lines
5.7 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* R-Car Generation 2 support
*
* Copyright (C) 2013 Renesas Solutions Corp.
* Copyright (C) 2013 Magnus Damm
* Copyright (C) 2014 Ulrich Hecht
*/
#include <linux/clk-provider.h>
#include <linux/clocksource.h>
#include <linux/device.h>
#include <linux/dma-contiguous.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/memblock.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/psci.h>
#include <asm/mach/arch.h>
#include <asm/secure_cntvoff.h>
#include "common.h"
#include "rcar-gen2.h"
static const struct of_device_id cpg_matches[] __initconst = {
{ .compatible = "renesas,rcar-gen2-cpg-clocks", },
{ .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" },
{ .compatible = "renesas,r8a7744-cpg-mssr", .data = "extal" },
{ .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" },
{ .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" },
{ .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" },
{ /* sentinel */ }
};
static unsigned int __init get_extal_freq(void)
{
const struct of_device_id *match;
struct device_node *cpg, *extal;
u32 freq = 20000000;
int idx = 0;
cpg = of_find_matching_node_and_match(NULL, cpg_matches, &match);
if (!cpg)
return freq;
if (match->data)
idx = of_property_match_string(cpg, "clock-names", match->data);
extal = of_parse_phandle(cpg, "clocks", idx);
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
void __init rcar_gen2_timer_init(void)
{
bool need_update = true;
void __iomem *base;
u32 freq;
/*
* If PSCI is available then most likely we are running on PSCI-enabled
* U-Boot which, we assume, has already taken care of resetting CNTVOFF
* and updating counter module before switching to non-secure mode
* and we don't need to.
*/
#ifdef CONFIG_ARM_PSCI_FW
if (psci_ops.cpu_on)
need_update = false;
#endif
if (need_update == false)
goto skip_update;
secure_cntvoff_init();
if (of_machine_is_compatible("renesas,r8a7745") ||
of_machine_is_compatible("renesas,r8a77470") ||
of_machine_is_compatible("renesas,r8a7792") ||
of_machine_is_compatible("renesas,r8a7794")) {
freq = 260000000 / 8; /* ZS / 8 */
} else {
/* At Linux boot time the r8a7790 arch timer comes up
* 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.
*/
freq = get_extal_freq() / 2;
}
/* Remap "armgcnt address map" space */
base = ioremap(0xe6080000, PAGE_SIZE);
/*
* Update the timer if it is either not running, or is not at the
* right frequency. The timer is only configurable in secure mode
* so this avoids an abort if the loader started the timer and
* entered the kernel in non-secure mode.
*/
if ((ioread32(base + CNTCR) & 1) == 0 ||
ioread32(base + CNTFID0) != freq) {
/* Update registers with correct frequency */
iowrite32(freq, base + CNTFID0);
asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
/* make sure arch timer is started by setting bit 0 of CNTCR */
iowrite32(1, base + CNTCR);
}
iounmap(base);
skip_update:
of_clk_init(NULL);
timer_probe();
}
struct memory_reserve_config {
u64 reserved;
u64 base, size;
};
static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname,
int depth, void *data)
{
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
const __be32 *reg, *endp;
int l;
struct memory_reserve_config *mrc = data;
u64 lpae_start = 1ULL << 32;
/* We are scanning "memory" nodes only */
if (type == NULL || strcmp(type, "memory"))
return 0;
reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
if (reg == NULL)
reg = of_get_flat_dt_prop(node, "reg", &l);
if (reg == NULL)
return 0;
endp = reg + (l / sizeof(__be32));
while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
u64 base, size;
base = dt_mem_next_cell(dt_root_addr_cells, &reg);
size = dt_mem_next_cell(dt_root_size_cells, &reg);
if (base >= lpae_start)
continue;
if ((base + size) >= lpae_start)
size = lpae_start - base;
if (size < mrc->reserved)
continue;
if (base < mrc->base)
continue;
/* keep the area at top near the 32-bit legacy limit */
mrc->base = base + size - mrc->reserved;
mrc->size = mrc->reserved;
}
return 0;
}
void __init rcar_gen2_reserve(void)
{
struct memory_reserve_config mrc;
/* reserve 256 MiB at the top of the physical legacy 32-bit space */
memset(&mrc, 0, sizeof(mrc));
mrc.reserved = SZ_256M;
of_scan_flat_dt(rcar_gen2_scan_mem, &mrc);
#ifdef CONFIG_DMA_CMA
if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) {
static struct cma *rcar_gen2_dma_contiguous;
dma_contiguous_reserve_area(mrc.size, mrc.base, 0,
&rcar_gen2_dma_contiguous, true);
}
#endif
}
static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
"renesas,r8a7790",
"renesas,r8a7791",
"renesas,r8a7792",
"renesas,r8a7793",
"renesas,r8a7794",
NULL,
};
DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
.init_late = shmobile_init_late,
.init_time = rcar_gen2_timer_init,
.reserve = rcar_gen2_reserve,
.dt_compat = rcar_gen2_boards_compat_dt,
MACHINE_END
static const char * const rz_g1_boards_compat_dt[] __initconst = {
"renesas,r8a7743",
"renesas,r8a7744",
"renesas,r8a7745",
"renesas,r8a77470",
NULL,
};
DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
.init_late = shmobile_init_late,
.init_time = rcar_gen2_timer_init,
.reserve = rcar_gen2_reserve,
.dt_compat = rz_g1_boards_compat_dt,
MACHINE_END