cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

setup-rcar-gen2.c (5903B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * R-Car Generation 2 support
      4 *
      5 * Copyright (C) 2013  Renesas Solutions Corp.
      6 * Copyright (C) 2013  Magnus Damm
      7 * Copyright (C) 2014  Ulrich Hecht
      8 */
      9
     10#include <linux/clocksource.h>
     11#include <linux/device.h>
     12#include <linux/dma-map-ops.h>
     13#include <linux/io.h>
     14#include <linux/kernel.h>
     15#include <linux/memblock.h>
     16#include <linux/of.h>
     17#include <linux/of_clk.h>
     18#include <linux/of_fdt.h>
     19#include <linux/of_platform.h>
     20#include <linux/psci.h>
     21#include <asm/mach/arch.h>
     22#include <asm/secure_cntvoff.h>
     23#include "common.h"
     24#include "rcar-gen2.h"
     25
     26static const struct of_device_id cpg_matches[] __initconst = {
     27	{ .compatible = "renesas,r8a7742-cpg-mssr", .data = "extal" },
     28	{ .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" },
     29	{ .compatible = "renesas,r8a7744-cpg-mssr", .data = "extal" },
     30	{ .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" },
     31	{ .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" },
     32	{ .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" },
     33	{ /* sentinel */ }
     34};
     35
     36static unsigned int __init get_extal_freq(void)
     37{
     38	const struct of_device_id *match;
     39	struct device_node *cpg, *extal;
     40	u32 freq = 20000000;
     41	int idx = 0;
     42
     43	cpg = of_find_matching_node_and_match(NULL, cpg_matches, &match);
     44	if (!cpg)
     45		return freq;
     46
     47	if (match->data)
     48		idx = of_property_match_string(cpg, "clock-names", match->data);
     49	extal = of_parse_phandle(cpg, "clocks", idx);
     50	of_node_put(cpg);
     51	if (!extal)
     52		return freq;
     53
     54	of_property_read_u32(extal, "clock-frequency", &freq);
     55	of_node_put(extal);
     56	return freq;
     57}
     58
     59#define CNTCR 0
     60#define CNTFID0 0x20
     61
     62static void __init rcar_gen2_timer_init(void)
     63{
     64	bool need_update = true;
     65	void __iomem *base;
     66	u32 freq;
     67
     68	/*
     69	 * If PSCI is available then most likely we are running on PSCI-enabled
     70	 * U-Boot which, we assume, has already taken care of resetting CNTVOFF
     71	 * and updating counter module before switching to non-secure mode
     72	 * and we don't need to.
     73	 */
     74#ifdef CONFIG_ARM_PSCI_FW
     75	if (psci_ops.cpu_on)
     76		need_update = false;
     77#endif
     78
     79	if (need_update == false)
     80		goto skip_update;
     81
     82	secure_cntvoff_init();
     83
     84	if (of_machine_is_compatible("renesas,r8a7745") ||
     85	    of_machine_is_compatible("renesas,r8a77470") ||
     86	    of_machine_is_compatible("renesas,r8a7792") ||
     87	    of_machine_is_compatible("renesas,r8a7794")) {
     88		freq = 260000000 / 8;	/* ZS / 8 */
     89	} else {
     90		/* At Linux boot time the r8a7790 arch timer comes up
     91		 * with the counter disabled. Moreover, it may also report
     92		 * a potentially incorrect fixed 13 MHz frequency. To be
     93		 * correct these registers need to be updated to use the
     94		 * frequency EXTAL / 2.
     95		 */
     96		freq = get_extal_freq() / 2;
     97	}
     98
     99	/* Remap "armgcnt address map" space */
    100	base = ioremap(0xe6080000, PAGE_SIZE);
    101
    102	/*
    103	 * Update the timer if it is either not running, or is not at the
    104	 * right frequency. The timer is only configurable in secure mode
    105	 * so this avoids an abort if the loader started the timer and
    106	 * entered the kernel in non-secure mode.
    107	 */
    108
    109	if ((ioread32(base + CNTCR) & 1) == 0 ||
    110	    ioread32(base + CNTFID0) != freq) {
    111		/* Update registers with correct frequency */
    112		iowrite32(freq, base + CNTFID0);
    113		asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
    114
    115		/* make sure arch timer is started by setting bit 0 of CNTCR */
    116		iowrite32(1, base + CNTCR);
    117	}
    118
    119	iounmap(base);
    120
    121skip_update:
    122	of_clk_init(NULL);
    123	timer_probe();
    124}
    125
    126struct memory_reserve_config {
    127	u64 reserved;
    128	u64 base, size;
    129};
    130
    131static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname,
    132				     int depth, void *data)
    133{
    134	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
    135	const __be32 *reg, *endp;
    136	int l;
    137	struct memory_reserve_config *mrc = data;
    138	u64 lpae_start = 1ULL << 32;
    139
    140	/* We are scanning "memory" nodes only */
    141	if (type == NULL || strcmp(type, "memory"))
    142		return 0;
    143
    144	reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
    145	if (reg == NULL)
    146		reg = of_get_flat_dt_prop(node, "reg", &l);
    147	if (reg == NULL)
    148		return 0;
    149
    150	endp = reg + (l / sizeof(__be32));
    151	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
    152		u64 base, size;
    153
    154		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
    155		size = dt_mem_next_cell(dt_root_size_cells, &reg);
    156
    157		if (base >= lpae_start)
    158			continue;
    159
    160		if ((base + size) >= lpae_start)
    161			size = lpae_start - base;
    162
    163		if (size < mrc->reserved)
    164			continue;
    165
    166		if (base < mrc->base)
    167			continue;
    168
    169		/* keep the area at top near the 32-bit legacy limit */
    170		mrc->base = base + size - mrc->reserved;
    171		mrc->size = mrc->reserved;
    172	}
    173
    174	return 0;
    175}
    176
    177static void __init rcar_gen2_reserve(void)
    178{
    179	struct memory_reserve_config mrc;
    180
    181	/* reserve 256 MiB at the top of the physical legacy 32-bit space */
    182	memset(&mrc, 0, sizeof(mrc));
    183	mrc.reserved = SZ_256M;
    184
    185	of_scan_flat_dt(rcar_gen2_scan_mem, &mrc);
    186#ifdef CONFIG_DMA_CMA
    187	if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) {
    188		static struct cma *rcar_gen2_dma_contiguous;
    189
    190		dma_contiguous_reserve_area(mrc.size, mrc.base, 0,
    191					    &rcar_gen2_dma_contiguous, true);
    192	}
    193#endif
    194}
    195
    196static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
    197	"renesas,r8a7790",
    198	"renesas,r8a7791",
    199	"renesas,r8a7792",
    200	"renesas,r8a7793",
    201	"renesas,r8a7794",
    202	NULL
    203};
    204
    205DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
    206	.init_late	= shmobile_init_late,
    207	.init_time	= rcar_gen2_timer_init,
    208	.reserve	= rcar_gen2_reserve,
    209	.dt_compat	= rcar_gen2_boards_compat_dt,
    210MACHINE_END
    211
    212static const char * const rz_g1_boards_compat_dt[] __initconst = {
    213	"renesas,r8a7742",
    214	"renesas,r8a7743",
    215	"renesas,r8a7744",
    216	"renesas,r8a7745",
    217	"renesas,r8a77470",
    218	NULL
    219};
    220
    221DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
    222	.init_late	= shmobile_init_late,
    223	.init_time	= rcar_gen2_timer_init,
    224	.reserve	= rcar_gen2_reserve,
    225	.dt_compat	= rz_g1_boards_compat_dt,
    226MACHINE_END