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, ®); 155 size = dt_mem_next_cell(dt_root_size_cells, ®); 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