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

integrator_cp.c (3494B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Copyright (C) 2003 Deep Blue Solutions Ltd
      4 */
      5#include <linux/kernel.h>
      6#include <linux/amba/mmci.h>
      7#include <linux/io.h>
      8#include <linux/irqchip.h>
      9#include <linux/of_irq.h>
     10#include <linux/of_address.h>
     11#include <linux/of_platform.h>
     12#include <linux/sched_clock.h>
     13#include <linux/regmap.h>
     14#include <linux/mfd/syscon.h>
     15
     16#include <asm/mach/arch.h>
     17#include <asm/mach/map.h>
     18
     19#include "integrator-hardware.h"
     20#include "integrator-cm.h"
     21#include "integrator.h"
     22
     23/* Base address to the core module header */
     24static struct regmap *cm_map;
     25/* Base address to the CP controller */
     26static void __iomem *intcp_con_base;
     27
     28#define CM_COUNTER_OFFSET 0x28
     29
     30/*
     31 * Logical      Physical
     32 * f1400000	14000000	Interrupt controller
     33 * f1600000	16000000	UART 0
     34 * fca00000	ca000000	SIC
     35 */
     36
     37static struct map_desc intcp_io_desc[] __initdata __maybe_unused = {
     38	{
     39		.virtual	= IO_ADDRESS(INTEGRATOR_IC_BASE),
     40		.pfn		= __phys_to_pfn(INTEGRATOR_IC_BASE),
     41		.length		= SZ_4K,
     42		.type		= MT_DEVICE
     43	}, {
     44		.virtual	= IO_ADDRESS(INTEGRATOR_UART0_BASE),
     45		.pfn		= __phys_to_pfn(INTEGRATOR_UART0_BASE),
     46		.length		= SZ_4K,
     47		.type		= MT_DEVICE
     48	}, {
     49		.virtual	= IO_ADDRESS(INTEGRATOR_CP_SIC_BASE),
     50		.pfn		= __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
     51		.length		= SZ_4K,
     52		.type		= MT_DEVICE
     53	}
     54};
     55
     56static void __init intcp_map_io(void)
     57{
     58	iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
     59}
     60
     61/*
     62 * It seems that the card insertion interrupt remains active after
     63 * we've acknowledged it.  We therefore ignore the interrupt, and
     64 * rely on reading it from the SIC.  This also means that we must
     65 * clear the latched interrupt.
     66 */
     67static unsigned int mmc_status(struct device *dev)
     68{
     69	unsigned int status = readl(__io_address(0xca000000 + 4));
     70	writel(8, intcp_con_base + 8);
     71
     72	return status & 8;
     73}
     74
     75static struct mmci_platform_data mmc_data = {
     76	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
     77	.status		= mmc_status,
     78};
     79
     80static u64 notrace intcp_read_sched_clock(void)
     81{
     82	unsigned int val;
     83
     84	/* MMIO so discard return code */
     85	regmap_read(cm_map, CM_COUNTER_OFFSET, &val);
     86	return val;
     87}
     88
     89static void __init intcp_init_early(void)
     90{
     91	cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator");
     92	if (IS_ERR(cm_map))
     93		return;
     94	sched_clock_register(intcp_read_sched_clock, 32, 24000000);
     95}
     96
     97static void __init intcp_init_irq_of(void)
     98{
     99	cm_init();
    100	irqchip_init();
    101}
    102
    103/*
    104 * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA
    105 * and enforce the bus names since these are used for clock lookups.
    106 */
    107static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
    108	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE,
    109		"mmci", &mmc_data),
    110	{ /* sentinel */ },
    111};
    112
    113static const struct of_device_id intcp_syscon_match[] = {
    114	{ .compatible = "arm,integrator-cp-syscon"},
    115	{ },
    116};
    117
    118static void __init intcp_init_of(void)
    119{
    120	struct device_node *cpcon;
    121
    122	cpcon = of_find_matching_node(NULL, intcp_syscon_match);
    123	if (!cpcon)
    124		return;
    125
    126	intcp_con_base = of_iomap(cpcon, 0);
    127	if (!intcp_con_base)
    128		return;
    129
    130	of_platform_default_populate(NULL, intcp_auxdata_lookup, NULL);
    131}
    132
    133static const char * intcp_dt_board_compat[] = {
    134	"arm,integrator-cp",
    135	NULL,
    136};
    137
    138DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
    139	.reserve	= integrator_reserve,
    140	.map_io		= intcp_map_io,
    141	.init_early	= intcp_init_early,
    142	.init_irq	= intcp_init_irq_of,
    143	.init_machine	= intcp_init_of,
    144	.dt_compat      = intcp_dt_board_compat,
    145MACHINE_END