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

board-v7.c (5320B)


      1/*
      2 * Device Tree support for Armada 370 and XP platforms.
      3 *
      4 * Copyright (C) 2012 Marvell
      5 *
      6 * Lior Amsalem <alior@marvell.com>
      7 * Gregory CLEMENT <gregory.clement@free-electrons.com>
      8 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
      9 *
     10 * This file is licensed under the terms of the GNU General Public
     11 * License version 2.  This program is licensed "as is" without any
     12 * warranty of any kind, whether express or implied.
     13 */
     14
     15#include <linux/kernel.h>
     16#include <linux/init.h>
     17#include <linux/of_address.h>
     18#include <linux/of_fdt.h>
     19#include <linux/io.h>
     20#include <linux/clocksource.h>
     21#include <linux/dma-mapping.h>
     22#include <linux/memblock.h>
     23#include <linux/mbus.h>
     24#include <linux/slab.h>
     25#include <linux/irqchip.h>
     26#include <asm/hardware/cache-l2x0.h>
     27#include <asm/mach/arch.h>
     28#include <asm/mach/map.h>
     29#include <asm/mach/time.h>
     30#include <asm/smp_scu.h>
     31#include "armada-370-xp.h"
     32#include "common.h"
     33#include "coherency.h"
     34#include "mvebu-soc-id.h"
     35
     36static void __iomem *scu_base;
     37
     38/*
     39 * Enables the SCU when available. Obviously, this is only useful on
     40 * Cortex-A based SOCs, not on PJ4B based ones.
     41 */
     42static void __init mvebu_scu_enable(void)
     43{
     44	struct device_node *np =
     45		of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
     46	if (np) {
     47		scu_base = of_iomap(np, 0);
     48		scu_enable(scu_base);
     49		of_node_put(np);
     50	}
     51}
     52
     53void __iomem *mvebu_get_scu_base(void)
     54{
     55	return scu_base;
     56}
     57
     58/*
     59 * When returning from suspend, the platform goes through the
     60 * bootloader, which executes its DDR3 training code. This code has
     61 * the unfortunate idea of using the first 10 KB of each DRAM bank to
     62 * exercise the RAM and calculate the optimal timings. Therefore, this
     63 * area of RAM is overwritten, and shouldn't be used by the kernel if
     64 * suspend/resume is supported.
     65 */
     66
     67#ifdef CONFIG_SUSPEND
     68#define MVEBU_DDR_TRAINING_AREA_SZ (10 * SZ_1K)
     69static int __init mvebu_scan_mem(unsigned long node, const char *uname,
     70				 int depth, void *data)
     71{
     72	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
     73	const __be32 *reg, *endp;
     74	int l;
     75
     76	if (type == NULL || strcmp(type, "memory"))
     77		return 0;
     78
     79	reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
     80	if (reg == NULL)
     81		reg = of_get_flat_dt_prop(node, "reg", &l);
     82	if (reg == NULL)
     83		return 0;
     84
     85	endp = reg + (l / sizeof(__be32));
     86	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
     87		u64 base, size;
     88
     89		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
     90		size = dt_mem_next_cell(dt_root_size_cells, &reg);
     91
     92		memblock_reserve(base, MVEBU_DDR_TRAINING_AREA_SZ);
     93	}
     94
     95	return 0;
     96}
     97
     98static void __init mvebu_memblock_reserve(void)
     99{
    100	of_scan_flat_dt(mvebu_scan_mem, NULL);
    101}
    102#else
    103static void __init mvebu_memblock_reserve(void) {}
    104#endif
    105
    106static void __init mvebu_init_irq(void)
    107{
    108	irqchip_init();
    109	mvebu_scu_enable();
    110	coherency_init();
    111	BUG_ON(mvebu_mbus_dt_init(coherency_available()));
    112}
    113
    114static void __init i2c_quirk(void)
    115{
    116	struct device_node *np;
    117	u32 dev, rev;
    118
    119	/*
    120	 * Only revisons more recent than A0 support the offload
    121	 * mechanism. We can exit only if we are sure that we can
    122	 * get the SoC revision and it is more recent than A0.
    123	 */
    124	if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > MV78XX0_A0_REV)
    125		return;
    126
    127	for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") {
    128		struct property *new_compat;
    129
    130		new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
    131
    132		new_compat->name = kstrdup("compatible", GFP_KERNEL);
    133		new_compat->length = sizeof("marvell,mv78230-a0-i2c");
    134		new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
    135						GFP_KERNEL);
    136
    137		of_update_property(np, new_compat);
    138	}
    139}
    140
    141static void __init mvebu_dt_init(void)
    142{
    143	if (of_machine_is_compatible("marvell,armadaxp"))
    144		i2c_quirk();
    145}
    146
    147static void __init armada_370_xp_dt_fixup(void)
    148{
    149#ifdef CONFIG_SMP
    150	smp_set_ops(smp_ops(armada_xp_smp_ops));
    151#endif
    152}
    153
    154static const char * const armada_370_xp_dt_compat[] __initconst = {
    155	"marvell,armada-370-xp",
    156	NULL,
    157};
    158
    159DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
    160	.l2c_aux_val	= 0,
    161	.l2c_aux_mask	= ~0,
    162	.init_machine	= mvebu_dt_init,
    163	.init_irq       = mvebu_init_irq,
    164	.restart	= mvebu_restart,
    165	.reserve        = mvebu_memblock_reserve,
    166	.dt_compat	= armada_370_xp_dt_compat,
    167	.dt_fixup	= armada_370_xp_dt_fixup,
    168MACHINE_END
    169
    170static const char * const armada_375_dt_compat[] __initconst = {
    171	"marvell,armada375",
    172	NULL,
    173};
    174
    175DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
    176	.l2c_aux_val	= 0,
    177	.l2c_aux_mask	= ~0,
    178	.init_irq       = mvebu_init_irq,
    179	.init_machine	= mvebu_dt_init,
    180	.restart	= mvebu_restart,
    181	.dt_compat	= armada_375_dt_compat,
    182MACHINE_END
    183
    184static const char * const armada_38x_dt_compat[] __initconst = {
    185	"marvell,armada380",
    186	"marvell,armada385",
    187	NULL,
    188};
    189
    190DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
    191	.l2c_aux_val	= 0,
    192	.l2c_aux_mask	= ~0,
    193	.init_irq       = mvebu_init_irq,
    194	.restart	= mvebu_restart,
    195	.dt_compat	= armada_38x_dt_compat,
    196MACHINE_END
    197
    198static const char * const armada_39x_dt_compat[] __initconst = {
    199	"marvell,armada390",
    200	"marvell,armada398",
    201	NULL,
    202};
    203
    204DT_MACHINE_START(ARMADA_39X_DT, "Marvell Armada 39x (Device Tree)")
    205	.l2c_aux_val	= 0,
    206	.l2c_aux_mask	= ~0,
    207	.init_irq       = mvebu_init_irq,
    208	.restart	= mvebu_restart,
    209	.dt_compat	= armada_39x_dt_compat,
    210MACHINE_END