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

versatile.c (5078B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Versatile board support using the device tree
      4 *
      5 *  Copyright (C) 2010 Secret Lab Technologies Ltd.
      6 *  Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com>
      7 *  Copyright (C) 2004 ARM Limited
      8 *  Copyright (C) 2000 Deep Blue Solutions Ltd
      9 */
     10
     11#include <linux/init.h>
     12#include <linux/io.h>
     13#include <linux/of.h>
     14#include <linux/of_address.h>
     15#include <linux/of_irq.h>
     16#include <linux/of_platform.h>
     17#include <linux/slab.h>
     18#include <linux/amba/bus.h>
     19#include <linux/amba/mmci.h>
     20#include <asm/mach-types.h>
     21#include <asm/mach/arch.h>
     22#include <asm/mach/map.h>
     23
     24/* macro to get at MMIO space when running virtually */
     25#define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
     26#define __io_address(n)		((void __iomem __force *)IO_ADDRESS(n))
     27
     28/*
     29 * ------------------------------------------------------------------------
     30 *  Versatile Registers
     31 * ------------------------------------------------------------------------
     32 */
     33#define VERSATILE_SYS_PCICTL_OFFSET           0x44
     34#define VERSATILE_SYS_MCI_OFFSET              0x48
     35
     36/*
     37 * VERSATILE peripheral addresses
     38 */
     39#define VERSATILE_MMCI0_BASE           0x10005000	/* MMC interface */
     40#define VERSATILE_MMCI1_BASE           0x1000B000	/* MMC Interface */
     41#define VERSATILE_SCTL_BASE            0x101E0000	/* System controller */
     42
     43/*
     44 * System controller bit assignment
     45 */
     46#define VERSATILE_REFCLK	0
     47#define VERSATILE_TIMCLK	1
     48
     49#define VERSATILE_TIMER1_EnSel	15
     50#define VERSATILE_TIMER2_EnSel	17
     51#define VERSATILE_TIMER3_EnSel	19
     52#define VERSATILE_TIMER4_EnSel	21
     53
     54static void __iomem *versatile_sys_base;
     55
     56unsigned int mmc_status(struct device *dev)
     57{
     58	struct amba_device *adev = container_of(dev, struct amba_device, dev);
     59	u32 mask;
     60
     61	if (adev->res.start == VERSATILE_MMCI0_BASE)
     62		mask = 1;
     63	else
     64		mask = 2;
     65
     66	return readl(versatile_sys_base + VERSATILE_SYS_MCI_OFFSET) & mask;
     67}
     68
     69static struct mmci_platform_data mmc0_plat_data = {
     70	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
     71	.status		= mmc_status,
     72};
     73
     74static struct mmci_platform_data mmc1_plat_data = {
     75	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
     76	.status		= mmc_status,
     77};
     78
     79/*
     80 * Lookup table for attaching a specific name and platform_data pointer to
     81 * devices as they get created by of_platform_populate().  Ideally this table
     82 * would not exist, but the current clock implementation depends on some devices
     83 * having a specific name.
     84 */
     85struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
     86	OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data),
     87	OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", &mmc1_plat_data),
     88	{}
     89};
     90
     91static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
     92	{
     93		.virtual	=  IO_ADDRESS(VERSATILE_SCTL_BASE),
     94		.pfn		= __phys_to_pfn(VERSATILE_SCTL_BASE),
     95		.length		= SZ_4K * 9,
     96		.type		= MT_DEVICE
     97	}
     98};
     99
    100static void __init versatile_map_io(void)
    101{
    102	debug_ll_io_init();
    103	iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
    104}
    105
    106static void __init versatile_init_early(void)
    107{
    108	u32 val;
    109
    110	/*
    111	 * set clock frequency:
    112	 *	VERSATILE_REFCLK is 32KHz
    113	 *	VERSATILE_TIMCLK is 1MHz
    114	 */
    115	val = readl(__io_address(VERSATILE_SCTL_BASE));
    116	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
    117	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
    118	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
    119	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
    120	       __io_address(VERSATILE_SCTL_BASE));
    121}
    122
    123static void __init versatile_dt_pci_init(void)
    124{
    125	u32 val;
    126	struct device_node *np;
    127	struct property *newprop;
    128
    129	np = of_find_compatible_node(NULL, NULL, "arm,versatile-pci");
    130	if (!np)
    131		return;
    132
    133	/* Check if PCI backplane is detected */
    134	val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
    135	if (val & 1) {
    136		/*
    137		 * Enable PCI accesses. Note that the documentaton is
    138		 * inconsistent whether or not this is needed, but the old
    139		 * driver had it so we will keep it.
    140		 */
    141		writel(1, versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
    142		goto out_put_node;
    143	}
    144
    145	newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
    146	if (!newprop)
    147		goto out_put_node;
    148
    149	newprop->name = kstrdup("status", GFP_KERNEL);
    150	newprop->value = kstrdup("disabled", GFP_KERNEL);
    151	newprop->length = sizeof("disabled");
    152	of_update_property(np, newprop);
    153
    154	pr_info("Not plugged into PCI backplane!\n");
    155
    156out_put_node:
    157	of_node_put(np);
    158}
    159
    160static void __init versatile_dt_init(void)
    161{
    162	struct device_node *np;
    163
    164	np = of_find_compatible_node(NULL, NULL, "arm,core-module-versatile");
    165	if (np)
    166		versatile_sys_base = of_iomap(np, 0);
    167	WARN_ON(!versatile_sys_base);
    168
    169	versatile_dt_pci_init();
    170
    171	of_platform_default_populate(NULL, versatile_auxdata_lookup, NULL);
    172}
    173
    174static const char *const versatile_dt_match[] __initconst = {
    175	"arm,versatile-ab",
    176	"arm,versatile-pb",
    177	NULL,
    178};
    179
    180DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
    181	.map_io		= versatile_map_io,
    182	.init_early	= versatile_init_early,
    183	.init_machine	= versatile_dt_init,
    184	.dt_compat	= versatile_dt_match,
    185MACHINE_END