linux/arch/arm/mach-shmobile/setup-rcar-gen2.c
<<
>>
Prefs
   1/*
   2 * R-Car Generation 2 support
   3 *
   4 * Copyright (C) 2013  Renesas Solutions Corp.
   5 * Copyright (C) 2013  Magnus Damm
   6 * Copyright (C) 2014  Ulrich Hecht
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; version 2 of the License.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18#include <linux/clk-provider.h>
  19#include <linux/clocksource.h>
  20#include <linux/device.h>
  21#include <linux/dma-contiguous.h>
  22#include <linux/io.h>
  23#include <linux/kernel.h>
  24#include <linux/memblock.h>
  25#include <linux/of.h>
  26#include <linux/of_fdt.h>
  27#include <linux/of_platform.h>
  28#include <asm/mach/arch.h>
  29#include "common.h"
  30#include "rcar-gen2.h"
  31
  32static unsigned int __init get_extal_freq(void)
  33{
  34        struct device_node *cpg, *extal;
  35        u32 freq = 20000000;
  36
  37        cpg = of_find_compatible_node(NULL, NULL,
  38                                      "renesas,rcar-gen2-cpg-clocks");
  39        if (!cpg)
  40                return freq;
  41
  42        extal = of_parse_phandle(cpg, "clocks", 0);
  43        of_node_put(cpg);
  44        if (!extal)
  45                return freq;
  46
  47        of_property_read_u32(extal, "clock-frequency", &freq);
  48        of_node_put(extal);
  49        return freq;
  50}
  51
  52#define CNTCR 0
  53#define CNTFID0 0x20
  54
  55void __init rcar_gen2_timer_init(void)
  56{
  57#ifdef CONFIG_ARM_ARCH_TIMER
  58        void __iomem *base;
  59        u32 freq;
  60
  61        if (of_machine_is_compatible("renesas,r8a7792") ||
  62            of_machine_is_compatible("renesas,r8a7794")) {
  63                freq = 260000000 / 8;   /* ZS / 8 */
  64                /* CNTVOFF has to be initialized either from non-secure
  65                 * Hypervisor mode or secure Monitor mode with SCR.NS==1.
  66                 * If TrustZone is enabled then it should be handled by the
  67                 * secure code.
  68                 */
  69                asm volatile(
  70                "       cps     0x16\n"
  71                "       mrc     p15, 0, r1, c1, c1, 0\n"
  72                "       orr     r0, r1, #1\n"
  73                "       mcr     p15, 0, r0, c1, c1, 0\n"
  74                "       isb\n"
  75                "       mov     r0, #0\n"
  76                "       mcrr    p15, 4, r0, r0, c14\n"
  77                "       isb\n"
  78                "       mcr     p15, 0, r1, c1, c1, 0\n"
  79                "       isb\n"
  80                "       cps     0x13\n"
  81                        : : : "r0", "r1");
  82        } else {
  83                /* At Linux boot time the r8a7790 arch timer comes up
  84                 * with the counter disabled. Moreover, it may also report
  85                 * a potentially incorrect fixed 13 MHz frequency. To be
  86                 * correct these registers need to be updated to use the
  87                 * frequency EXTAL / 2.
  88                 */
  89                freq = get_extal_freq() / 2;
  90        }
  91
  92        /* Remap "armgcnt address map" space */
  93        base = ioremap(0xe6080000, PAGE_SIZE);
  94
  95        /*
  96         * Update the timer if it is either not running, or is not at the
  97         * right frequency. The timer is only configurable in secure mode
  98         * so this avoids an abort if the loader started the timer and
  99         * entered the kernel in non-secure mode.
 100         */
 101
 102        if ((ioread32(base + CNTCR) & 1) == 0 ||
 103            ioread32(base + CNTFID0) != freq) {
 104                /* Update registers with correct frequency */
 105                iowrite32(freq, base + CNTFID0);
 106                asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
 107
 108                /* make sure arch timer is started by setting bit 0 of CNTCR */
 109                iowrite32(1, base + CNTCR);
 110        }
 111
 112        iounmap(base);
 113#endif /* CONFIG_ARM_ARCH_TIMER */
 114
 115        of_clk_init(NULL);
 116        clocksource_probe();
 117}
 118
 119struct memory_reserve_config {
 120        u64 reserved;
 121        u64 base, size;
 122};
 123
 124static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname,
 125                                     int depth, void *data)
 126{
 127        const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 128        const __be32 *reg, *endp;
 129        int l;
 130        struct memory_reserve_config *mrc = data;
 131        u64 lpae_start = 1ULL << 32;
 132
 133        /* We are scanning "memory" nodes only */
 134        if (type == NULL || strcmp(type, "memory"))
 135                return 0;
 136
 137        reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
 138        if (reg == NULL)
 139                reg = of_get_flat_dt_prop(node, "reg", &l);
 140        if (reg == NULL)
 141                return 0;
 142
 143        endp = reg + (l / sizeof(__be32));
 144        while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
 145                u64 base, size;
 146
 147                base = dt_mem_next_cell(dt_root_addr_cells, &reg);
 148                size = dt_mem_next_cell(dt_root_size_cells, &reg);
 149
 150                if (base >= lpae_start)
 151                        continue;
 152
 153                if ((base + size) >= lpae_start)
 154                        size = lpae_start - base;
 155
 156                if (size < mrc->reserved)
 157                        continue;
 158
 159                if (base < mrc->base)
 160                        continue;
 161
 162                /* keep the area at top near the 32-bit legacy limit */
 163                mrc->base = base + size - mrc->reserved;
 164                mrc->size = mrc->reserved;
 165        }
 166
 167        return 0;
 168}
 169
 170void __init rcar_gen2_reserve(void)
 171{
 172        struct memory_reserve_config mrc;
 173
 174        /* reserve 256 MiB at the top of the physical legacy 32-bit space */
 175        memset(&mrc, 0, sizeof(mrc));
 176        mrc.reserved = SZ_256M;
 177
 178        of_scan_flat_dt(rcar_gen2_scan_mem, &mrc);
 179#ifdef CONFIG_DMA_CMA
 180        if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) {
 181                static struct cma *rcar_gen2_dma_contiguous;
 182
 183                dma_contiguous_reserve_area(mrc.size, mrc.base, 0,
 184                                            &rcar_gen2_dma_contiguous, true);
 185        }
 186#endif
 187}
 188
 189static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
 190        /*
 191         * R8A7790 and R8A7791 can't be handled here as long as they need SMP
 192         * initialization fallback.
 193         */
 194        "renesas,r8a7792",
 195        "renesas,r8a7793",
 196        "renesas,r8a7794",
 197        NULL,
 198};
 199
 200DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
 201        .init_early     = shmobile_init_delay,
 202        .init_late      = shmobile_init_late,
 203        .init_time      = rcar_gen2_timer_init,
 204        .reserve        = rcar_gen2_reserve,
 205        .dt_compat      = rcar_gen2_boards_compat_dt,
 206MACHINE_END
 207
 208static const char * const rz_g1_boards_compat_dt[] __initconst = {
 209        "renesas,r8a7743",
 210        "renesas,r8a7745",
 211        NULL,
 212};
 213
 214DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
 215        .init_early     = shmobile_init_delay,
 216        .init_late      = shmobile_init_late,
 217        .init_time      = rcar_gen2_timer_init,
 218        .reserve        = rcar_gen2_reserve,
 219        .dt_compat      = rz_g1_boards_compat_dt,
 220MACHINE_END
 221