0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clocksource.h>
0011 #include <linux/device.h>
0012 #include <linux/dma-map-ops.h>
0013 #include <linux/io.h>
0014 #include <linux/kernel.h>
0015 #include <linux/memblock.h>
0016 #include <linux/of.h>
0017 #include <linux/of_clk.h>
0018 #include <linux/of_fdt.h>
0019 #include <linux/of_platform.h>
0020 #include <linux/psci.h>
0021 #include <asm/mach/arch.h>
0022 #include <asm/secure_cntvoff.h>
0023 #include "common.h"
0024 #include "rcar-gen2.h"
0025
0026 static const struct of_device_id cpg_matches[] __initconst = {
0027 { .compatible = "renesas,r8a7742-cpg-mssr", .data = "extal" },
0028 { .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" },
0029 { .compatible = "renesas,r8a7744-cpg-mssr", .data = "extal" },
0030 { .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" },
0031 { .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" },
0032 { .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" },
0033 { }
0034 };
0035
0036 static unsigned int __init get_extal_freq(void)
0037 {
0038 const struct of_device_id *match;
0039 struct device_node *cpg, *extal;
0040 u32 freq = 20000000;
0041 int idx = 0;
0042
0043 cpg = of_find_matching_node_and_match(NULL, cpg_matches, &match);
0044 if (!cpg)
0045 return freq;
0046
0047 if (match->data)
0048 idx = of_property_match_string(cpg, "clock-names", match->data);
0049 extal = of_parse_phandle(cpg, "clocks", idx);
0050 of_node_put(cpg);
0051 if (!extal)
0052 return freq;
0053
0054 of_property_read_u32(extal, "clock-frequency", &freq);
0055 of_node_put(extal);
0056 return freq;
0057 }
0058
0059 #define CNTCR 0
0060 #define CNTFID0 0x20
0061
0062 static void __init rcar_gen2_timer_init(void)
0063 {
0064 bool need_update = true;
0065 void __iomem *base;
0066 u32 freq;
0067
0068
0069
0070
0071
0072
0073
0074 #ifdef CONFIG_ARM_PSCI_FW
0075 if (psci_ops.cpu_on)
0076 need_update = false;
0077 #endif
0078
0079 if (need_update == false)
0080 goto skip_update;
0081
0082 secure_cntvoff_init();
0083
0084 if (of_machine_is_compatible("renesas,r8a7745") ||
0085 of_machine_is_compatible("renesas,r8a77470") ||
0086 of_machine_is_compatible("renesas,r8a7792") ||
0087 of_machine_is_compatible("renesas,r8a7794")) {
0088 freq = 260000000 / 8;
0089 } else {
0090
0091
0092
0093
0094
0095
0096 freq = get_extal_freq() / 2;
0097 }
0098
0099
0100 base = ioremap(0xe6080000, PAGE_SIZE);
0101
0102
0103
0104
0105
0106
0107
0108
0109 if ((ioread32(base + CNTCR) & 1) == 0 ||
0110 ioread32(base + CNTFID0) != freq) {
0111
0112 iowrite32(freq, base + CNTFID0);
0113 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
0114
0115
0116 iowrite32(1, base + CNTCR);
0117 }
0118
0119 iounmap(base);
0120
0121 skip_update:
0122 of_clk_init(NULL);
0123 timer_probe();
0124 }
0125
0126 struct memory_reserve_config {
0127 u64 reserved;
0128 u64 base, size;
0129 };
0130
0131 static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname,
0132 int depth, void *data)
0133 {
0134 const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
0135 const __be32 *reg, *endp;
0136 int l;
0137 struct memory_reserve_config *mrc = data;
0138 u64 lpae_start = 1ULL << 32;
0139
0140
0141 if (type == NULL || strcmp(type, "memory"))
0142 return 0;
0143
0144 reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
0145 if (reg == NULL)
0146 reg = of_get_flat_dt_prop(node, "reg", &l);
0147 if (reg == NULL)
0148 return 0;
0149
0150 endp = reg + (l / sizeof(__be32));
0151 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
0152 u64 base, size;
0153
0154 base = dt_mem_next_cell(dt_root_addr_cells, ®);
0155 size = dt_mem_next_cell(dt_root_size_cells, ®);
0156
0157 if (base >= lpae_start)
0158 continue;
0159
0160 if ((base + size) >= lpae_start)
0161 size = lpae_start - base;
0162
0163 if (size < mrc->reserved)
0164 continue;
0165
0166 if (base < mrc->base)
0167 continue;
0168
0169
0170 mrc->base = base + size - mrc->reserved;
0171 mrc->size = mrc->reserved;
0172 }
0173
0174 return 0;
0175 }
0176
0177 static void __init rcar_gen2_reserve(void)
0178 {
0179 struct memory_reserve_config mrc;
0180
0181
0182 memset(&mrc, 0, sizeof(mrc));
0183 mrc.reserved = SZ_256M;
0184
0185 of_scan_flat_dt(rcar_gen2_scan_mem, &mrc);
0186 #ifdef CONFIG_DMA_CMA
0187 if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) {
0188 static struct cma *rcar_gen2_dma_contiguous;
0189
0190 dma_contiguous_reserve_area(mrc.size, mrc.base, 0,
0191 &rcar_gen2_dma_contiguous, true);
0192 }
0193 #endif
0194 }
0195
0196 static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
0197 "renesas,r8a7790",
0198 "renesas,r8a7791",
0199 "renesas,r8a7792",
0200 "renesas,r8a7793",
0201 "renesas,r8a7794",
0202 NULL
0203 };
0204
0205 DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
0206 .init_late = shmobile_init_late,
0207 .init_time = rcar_gen2_timer_init,
0208 .reserve = rcar_gen2_reserve,
0209 .dt_compat = rcar_gen2_boards_compat_dt,
0210 MACHINE_END
0211
0212 static const char * const rz_g1_boards_compat_dt[] __initconst = {
0213 "renesas,r8a7742",
0214 "renesas,r8a7743",
0215 "renesas,r8a7744",
0216 "renesas,r8a7745",
0217 "renesas,r8a77470",
0218 NULL
0219 };
0220
0221 DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
0222 .init_late = shmobile_init_late,
0223 .init_time = rcar_gen2_timer_init,
0224 .reserve = rcar_gen2_reserve,
0225 .dt_compat = rz_g1_boards_compat_dt,
0226 MACHINE_END