diff options
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r-- | arch/arm/mach-integrator/Kconfig | 160 | ||||
-rw-r--r-- | arch/arm/mach-integrator/Makefile | 10 | ||||
-rw-r--r-- | arch/arm/mach-integrator/cm.h | 41 | ||||
-rw-r--r-- | arch/arm/mach-integrator/common.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-integrator/core.c | 96 | ||||
-rw-r--r-- | arch/arm/mach-integrator/hardware.h | 341 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 202 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 147 |
8 files changed, 1004 insertions, 0 deletions
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig new file mode 100644 index 000000000..7a9808b01 --- /dev/null +++ b/arch/arm/mach-integrator/Kconfig @@ -0,0 +1,160 @@ +# SPDX-License-Identifier: GPL-2.0-only +menuconfig ARCH_INTEGRATOR + bool "ARM Ltd. Integrator family" + depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6 + select ARM_AMBA + select CMA + select DMA_CMA + select HAVE_TCM + select ICST + select MFD_SYSCON + select PLAT_VERSATILE + select POWER_RESET + select POWER_RESET_VERSATILE + select POWER_SUPPLY + select SOC_INTEGRATOR_CM + select VERSATILE_FPGA_IRQ + help + Support for ARM's Integrator platform. + +if ARCH_INTEGRATOR + +config ARCH_INTEGRATOR_AP + bool "Support Integrator/AP and Integrator/PP2 platforms" + select INTEGRATOR_AP_TIMER + select SERIAL_AMBA_PL010 if TTY + select SERIAL_AMBA_PL010_CONSOLE if TTY + select SOC_BUS + help + Include support for the ARM(R) Integrator/AP and + Integrator/PP2 platforms. + +config INTEGRATOR_IMPD1 + bool "Include support for Integrator/IM-PD1" + depends on ARCH_INTEGRATOR_AP + select ARM_VIC + select GPIO_PL061 + select GPIOLIB + select REGULATOR + select REGULATOR_FIXED_VOLTAGE + help + The IM-PD1 is an add-on logic module for the Integrator which + allows ARM(R) Ltd PrimeCells to be developed and evaluated. + The IM-PD1 can be found on the Integrator/PP2 platform. + +config INTEGRATOR_CM7TDMI + bool "Integrator/CM7TDMI core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V4 && !MMU + select CPU_ARM7TDMI + +config INTEGRATOR_CM720T + bool "Integrator/CM720T core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V4T + select CPU_ARM720T + +config INTEGRATOR_CM740T + bool "Integrator/CM740T core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V4T && !MMU + select CPU_ARM740T + +config INTEGRATOR_CM920T + bool "Integrator/CM920T core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V4T + select CPU_ARM920T + +config INTEGRATOR_CM922T_XA10 + bool "Integrator/CM922T-XA10 core module" + depends on ARCH_MULTI_V4T + depends on ARCH_INTEGRATOR_AP + select CPU_ARM922T + +config INTEGRATOR_CM926EJS + bool "Integrator/CM926EJ-S core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V5 + select CPU_ARM926T + +config INTEGRATOR_CM940T + bool "Integrator/CM940T core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V4T && !MMU + select CPU_ARM940T + +config INTEGRATOR_CM946ES + bool "Integrator/CM946E-S core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V5 && !MMU + select CPU_ARM946E + +config INTEGRATOR_CM966ES + bool "Integrator/CM966E-S core module" + depends on ARCH_INTEGRATOR_AP + depends on BROKEN # no kernel support + +config INTEGRATOR_CM10200E_REV0 + bool "Integrator/CM10200E rev.0 core module" + depends on ARCH_INTEGRATOR_AP && n + depends on ARCH_MULTI_V5 + select CPU_ARM1020 + +config INTEGRATOR_CM10200E + bool "Integrator/CM10200E core module" + depends on ARCH_INTEGRATOR_AP && n + depends on ARCH_MULTI_V5 + select CPU_ARM1020E + +config INTEGRATOR_CM10220E + bool "Integrator/CM10220E core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V5 + select CPU_ARM1022 + +config INTEGRATOR_CM1026EJS + bool "Integrator/CM1026EJ-S core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V5 + select CPU_ARM1026 + +config INTEGRATOR_CM1136JFS + bool "Integrator/CM1136JF-S core module" + depends on ARCH_INTEGRATOR_AP + depends on ARCH_MULTI_V6 + select CPU_V6 + +config ARCH_INTEGRATOR_CP + bool "Support Integrator/CP platform" + depends on (!MMU || ARCH_MULTI_V5 || ARCH_MULTI_V6) + select ARM_TIMER_SP804 + select SERIAL_AMBA_PL011 if TTY + select SERIAL_AMBA_PL011_CONSOLE if TTY + select SOC_BUS + help + Include support for the ARM(R) Integrator CP platform. + +config INTEGRATOR_CT7T + bool "Integrator/CT7TD (ARM7TDMI) core tile" + depends on ARCH_INTEGRATOR_CP + depends on ARCH_MULTI_V4T && !MMU + select CPU_ARM7TDMI + +config INTEGRATOR_CT926 + bool "Integrator/CT926 (ARM926EJ-S) core tile" + depends on ARCH_INTEGRATOR_CP + depends on ARCH_MULTI_V5 + select CPU_ARM926T + +config INTEGRATOR_CTB36 + bool "Integrator/CTB36 (ARM1136JF-S) core tile" + depends on ARCH_INTEGRATOR_CP + depends on ARCH_MULTI_V6 + select CPU_V6 + +config ARCH_CINTEGRATOR + depends on ARCH_INTEGRATOR_CP + def_bool y + +endif diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile new file mode 100644 index 000000000..7857a55c9 --- /dev/null +++ b/arch/arm/mach-integrator/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := core.o +obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o +obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o diff --git a/arch/arm/mach-integrator/cm.h b/arch/arm/mach-integrator/cm.h new file mode 100644 index 000000000..f09ea18a5 --- /dev/null +++ b/arch/arm/mach-integrator/cm.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * access the core module control register. + */ +u32 cm_get(void); +void cm_control(u32, u32); + +struct device_node; +void cm_init(void); +void cm_clear_irqs(void); + +#define CM_CTRL_LED (1 << 0) +#define CM_CTRL_nMBDET (1 << 1) +#define CM_CTRL_REMAP (1 << 2) + +/* + * Integrator/AP,PP2 specific + */ +#define CM_CTRL_HIGHVECTORS (1 << 4) +#define CM_CTRL_BIGENDIAN (1 << 5) +#define CM_CTRL_FASTBUS (1 << 6) +#define CM_CTRL_SYNC (1 << 7) + +/* + * ARM926/946/966 Integrator/CP specific + */ +#define CM_CTRL_LCDBIASEN (1 << 8) +#define CM_CTRL_LCDBIASUP (1 << 9) +#define CM_CTRL_LCDBIASDN (1 << 10) +#define CM_CTRL_LCDMUXSEL_MASK (7 << 11) +#define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11) +#define CM_CTRL_LCDMUXSEL_VGA565_TFT555 (2 << 11) +#define CM_CTRL_LCDMUXSEL_SHARPLCD (3 << 11) +#define CM_CTRL_LCDMUXSEL_VGA555_TFT555 (4 << 11) +#define CM_CTRL_LCDEN0 (1 << 14) +#define CM_CTRL_LCDEN1 (1 << 15) +#define CM_CTRL_STATIC1 (1 << 16) +#define CM_CTRL_STATIC2 (1 << 17) +#define CM_CTRL_STATIC (1 << 18) +#define CM_CTRL_n24BITEN (1 << 19) +#define CM_CTRL_EBIWP (1 << 20) diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h new file mode 100644 index 000000000..f053aeebe --- /dev/null +++ b/arch/arm/mach-integrator/common.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include <linux/reboot.h> +#include <linux/amba/serial.h> +extern struct amba_pl010_data ap_uart_data; +void integrator_init_early(void); +int integrator_init(bool is_cp); +void integrator_reserve(void); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c new file mode 100644 index 000000000..0fe5e1dc9 --- /dev/null +++ b/arch/arm/mach-integrator/core.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * linux/arch/arm/mach-integrator/core.c + * + * Copyright (C) 2000-2003 Deep Blue Solutions Ltd + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/export.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/memblock.h> +#include <linux/sched.h> +#include <linux/smp.h> +#include <linux/amba/bus.h> +#include <linux/amba/serial.h> +#include <linux/io.h> +#include <linux/stat.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/pgtable.h> + +#include <asm/mach-types.h> +#include <asm/mach/time.h> + +#include "hardware.h" +#include "cm.h" +#include "common.h" + +static DEFINE_RAW_SPINLOCK(cm_lock); +static void __iomem *cm_base; + +/** + * cm_get - get the value from the CM_CTRL register + */ +u32 cm_get(void) +{ + return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET); +} + +/** + * cm_control - update the CM_CTRL register. + * @mask: bits to change + * @set: bits to set + */ +void cm_control(u32 mask, u32 set) +{ + unsigned long flags; + u32 val; + + raw_spin_lock_irqsave(&cm_lock, flags); + val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask; + writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET); + raw_spin_unlock_irqrestore(&cm_lock, flags); +} + +void cm_clear_irqs(void) +{ + /* disable core module IRQs */ + writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET + + IRQ_ENABLE_CLEAR); +} + +static const struct of_device_id cm_match[] = { + { .compatible = "arm,core-module-integrator"}, + { }, +}; + +void cm_init(void) +{ + struct device_node *cm = of_find_matching_node(NULL, cm_match); + + if (!cm) { + pr_crit("no core module node found in device tree\n"); + return; + } + cm_base = of_iomap(cm, 0); + if (!cm_base) { + pr_crit("could not remap core module\n"); + return; + } + cm_clear_irqs(); +} + +/* + * We need to stop things allocating the low memory; ideally we need a + * better implementation of GFP_DMA which does not assume that DMA-able + * memory starts at zero. + */ +void __init integrator_reserve(void) +{ + memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET); +} diff --git a/arch/arm/mach-integrator/hardware.h b/arch/arm/mach-integrator/hardware.h new file mode 100644 index 000000000..4d6ade3dd --- /dev/null +++ b/arch/arm/mach-integrator/hardware.h @@ -0,0 +1,341 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * This file contains the hardware definitions of the Integrator. + * + * Copyright (C) 1998-1999 ARM Limited. + */ +#ifndef INTEGRATOR_HARDWARE_H +#define INTEGRATOR_HARDWARE_H + +/* + * Where in virtual memory the IO devices (timers, system controllers + * and so on) + */ +#define IO_BASE 0xF0000000 // VA of IO +#define IO_SIZE 0x0B000000 // How much? +#define IO_START INTEGRATOR_HDR_BASE // PA of IO + +/* macro to get at IO space when running virtually */ +#ifdef CONFIG_MMU +#define IO_ADDRESS(x) (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE) +#else +#define IO_ADDRESS(x) (x) +#endif + +#define __io_address(n) ((void __iomem *)IO_ADDRESS(n)) + +/* + * Integrator memory map + */ +#define INTEGRATOR_BOOT_ROM_LO 0x00000000 +#define INTEGRATOR_BOOT_ROM_HI 0x20000000 +#define INTEGRATOR_BOOT_ROM_BASE INTEGRATOR_BOOT_ROM_HI /* Normal position */ +#define INTEGRATOR_BOOT_ROM_SIZE SZ_512K + +/* + * New Core Modules have different amounts of SSRAM, the amount of SSRAM + * fitted can be found in HDR_STAT. + * + * The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to + * the minimum amount of SSRAM fitted on any core module. + * + * New Core Modules also alias the SSRAM. + * + */ +#define INTEGRATOR_SSRAM_BASE 0x00000000 +#define INTEGRATOR_SSRAM_ALIAS_BASE 0x10800000 +#define INTEGRATOR_SSRAM_SIZE SZ_256K + +#define INTEGRATOR_FLASH_BASE 0x24000000 +#define INTEGRATOR_FLASH_SIZE SZ_32M + +#define INTEGRATOR_MBRD_SSRAM_BASE 0x28000000 +#define INTEGRATOR_MBRD_SSRAM_SIZE SZ_512K + +/* + * SDRAM is a SIMM therefore the size is not known. + */ +#define INTEGRATOR_SDRAM_BASE 0x00040000 + +#define INTEGRATOR_SDRAM_ALIAS_BASE 0x80000000 +#define INTEGRATOR_HDR0_SDRAM_BASE 0x80000000 +#define INTEGRATOR_HDR1_SDRAM_BASE 0x90000000 +#define INTEGRATOR_HDR2_SDRAM_BASE 0xA0000000 +#define INTEGRATOR_HDR3_SDRAM_BASE 0xB0000000 + +/* + * Logic expansion modules + * + */ +#define INTEGRATOR_LOGIC_MODULES_BASE 0xC0000000 +#define INTEGRATOR_LOGIC_MODULE0_BASE 0xC0000000 +#define INTEGRATOR_LOGIC_MODULE1_BASE 0xD0000000 +#define INTEGRATOR_LOGIC_MODULE2_BASE 0xE0000000 +#define INTEGRATOR_LOGIC_MODULE3_BASE 0xF0000000 + +/* + * Integrator header card registers + */ +#define INTEGRATOR_HDR_ID_OFFSET 0x00 +#define INTEGRATOR_HDR_PROC_OFFSET 0x04 +#define INTEGRATOR_HDR_OSC_OFFSET 0x08 +#define INTEGRATOR_HDR_CTRL_OFFSET 0x0C +#define INTEGRATOR_HDR_STAT_OFFSET 0x10 +#define INTEGRATOR_HDR_LOCK_OFFSET 0x14 +#define INTEGRATOR_HDR_SDRAM_OFFSET 0x20 +#define INTEGRATOR_HDR_INIT_OFFSET 0x24 /* CM9x6 */ +#define INTEGRATOR_HDR_IC_OFFSET 0x40 +#define INTEGRATOR_HDR_SPDBASE_OFFSET 0x100 +#define INTEGRATOR_HDR_SPDTOP_OFFSET 0x200 + +#define INTEGRATOR_HDR_BASE 0x10000000 +#define INTEGRATOR_HDR_ID (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_ID_OFFSET) +#define INTEGRATOR_HDR_PROC (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_PROC_OFFSET) +#define INTEGRATOR_HDR_OSC (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_OSC_OFFSET) +#define INTEGRATOR_HDR_CTRL (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_CTRL_OFFSET) +#define INTEGRATOR_HDR_STAT (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET) +#define INTEGRATOR_HDR_LOCK (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_LOCK_OFFSET) +#define INTEGRATOR_HDR_SDRAM (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SDRAM_OFFSET) +#define INTEGRATOR_HDR_INIT (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_INIT_OFFSET) +#define INTEGRATOR_HDR_IC (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_IC_OFFSET) +#define INTEGRATOR_HDR_SPDBASE (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDBASE_OFFSET) +#define INTEGRATOR_HDR_SPDTOP (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDTOP_OFFSET) + +#define INTEGRATOR_HDR_CTRL_LED 0x01 +#define INTEGRATOR_HDR_CTRL_MBRD_DETECH 0x02 +#define INTEGRATOR_HDR_CTRL_REMAP 0x04 +#define INTEGRATOR_HDR_CTRL_RESET 0x08 +#define INTEGRATOR_HDR_CTRL_HIGHVECTORS 0x10 +#define INTEGRATOR_HDR_CTRL_BIG_ENDIAN 0x20 +#define INTEGRATOR_HDR_CTRL_FASTBUS 0x40 +#define INTEGRATOR_HDR_CTRL_SYNC 0x80 + +#define INTEGRATOR_HDR_OSC_CORE_10MHz 0x102 +#define INTEGRATOR_HDR_OSC_CORE_15MHz 0x107 +#define INTEGRATOR_HDR_OSC_CORE_20MHz 0x10C +#define INTEGRATOR_HDR_OSC_CORE_25MHz 0x111 +#define INTEGRATOR_HDR_OSC_CORE_30MHz 0x116 +#define INTEGRATOR_HDR_OSC_CORE_35MHz 0x11B +#define INTEGRATOR_HDR_OSC_CORE_40MHz 0x120 +#define INTEGRATOR_HDR_OSC_CORE_45MHz 0x125 +#define INTEGRATOR_HDR_OSC_CORE_50MHz 0x12A +#define INTEGRATOR_HDR_OSC_CORE_55MHz 0x12F +#define INTEGRATOR_HDR_OSC_CORE_60MHz 0x134 +#define INTEGRATOR_HDR_OSC_CORE_65MHz 0x139 +#define INTEGRATOR_HDR_OSC_CORE_70MHz 0x13E +#define INTEGRATOR_HDR_OSC_CORE_75MHz 0x143 +#define INTEGRATOR_HDR_OSC_CORE_80MHz 0x148 +#define INTEGRATOR_HDR_OSC_CORE_85MHz 0x14D +#define INTEGRATOR_HDR_OSC_CORE_90MHz 0x152 +#define INTEGRATOR_HDR_OSC_CORE_95MHz 0x157 +#define INTEGRATOR_HDR_OSC_CORE_100MHz 0x15C +#define INTEGRATOR_HDR_OSC_CORE_105MHz 0x161 +#define INTEGRATOR_HDR_OSC_CORE_110MHz 0x166 +#define INTEGRATOR_HDR_OSC_CORE_115MHz 0x16B +#define INTEGRATOR_HDR_OSC_CORE_120MHz 0x170 +#define INTEGRATOR_HDR_OSC_CORE_125MHz 0x175 +#define INTEGRATOR_HDR_OSC_CORE_130MHz 0x17A +#define INTEGRATOR_HDR_OSC_CORE_135MHz 0x17F +#define INTEGRATOR_HDR_OSC_CORE_140MHz 0x184 +#define INTEGRATOR_HDR_OSC_CORE_145MHz 0x189 +#define INTEGRATOR_HDR_OSC_CORE_150MHz 0x18E +#define INTEGRATOR_HDR_OSC_CORE_155MHz 0x193 +#define INTEGRATOR_HDR_OSC_CORE_160MHz 0x198 +#define INTEGRATOR_HDR_OSC_CORE_MASK 0x7FF + +#define INTEGRATOR_HDR_OSC_MEM_10MHz 0x10C000 +#define INTEGRATOR_HDR_OSC_MEM_15MHz 0x116000 +#define INTEGRATOR_HDR_OSC_MEM_20MHz 0x120000 +#define INTEGRATOR_HDR_OSC_MEM_25MHz 0x12A000 +#define INTEGRATOR_HDR_OSC_MEM_30MHz 0x134000 +#define INTEGRATOR_HDR_OSC_MEM_33MHz 0x13A000 +#define INTEGRATOR_HDR_OSC_MEM_40MHz 0x148000 +#define INTEGRATOR_HDR_OSC_MEM_50MHz 0x15C000 +#define INTEGRATOR_HDR_OSC_MEM_60MHz 0x170000 +#define INTEGRATOR_HDR_OSC_MEM_66MHz 0x17C000 +#define INTEGRATOR_HDR_OSC_MEM_MASK 0x7FF000 + +#define INTEGRATOR_HDR_OSC_BUS_MODE_CM7x0 0x0 +#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x0 0x0800000 +#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x6 0x1000000 +#define INTEGRATOR_HDR_OSC_BUS_MODE_CM10x00 0x1800000 +#define INTEGRATOR_HDR_OSC_BUS_MODE_MASK 0x1800000 + +#define INTEGRATOR_HDR_SDRAM_SPD_OK (1 << 5) + +/* + * Integrator system registers + */ + +/* + * System Controller + */ +#define INTEGRATOR_SC_ID_OFFSET 0x00 +#define INTEGRATOR_SC_OSC_OFFSET 0x04 +#define INTEGRATOR_SC_CTRLS_OFFSET 0x08 +#define INTEGRATOR_SC_CTRLC_OFFSET 0x0C +#define INTEGRATOR_SC_DEC_OFFSET 0x10 +#define INTEGRATOR_SC_ARB_OFFSET 0x14 +#define INTEGRATOR_SC_LOCK_OFFSET 0x1C + +#define INTEGRATOR_SC_BASE 0x11000000 +#define INTEGRATOR_SC_ID (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ID_OFFSET) +#define INTEGRATOR_SC_OSC (INTEGRATOR_SC_BASE + INTEGRATOR_SC_OSC_OFFSET) +#define INTEGRATOR_SC_CTRLS (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET) +#define INTEGRATOR_SC_CTRLC (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET) +#define INTEGRATOR_SC_DEC (INTEGRATOR_SC_BASE + INTEGRATOR_SC_DEC_OFFSET) +#define INTEGRATOR_SC_ARB (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ARB_OFFSET) +#define INTEGRATOR_SC_PCIENABLE (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET) +#define INTEGRATOR_SC_LOCK (INTEGRATOR_SC_BASE + INTEGRATOR_SC_LOCK_OFFSET) + +#define INTEGRATOR_SC_OSC_SYS_10MHz 0x20 +#define INTEGRATOR_SC_OSC_SYS_15MHz 0x34 +#define INTEGRATOR_SC_OSC_SYS_20MHz 0x48 +#define INTEGRATOR_SC_OSC_SYS_25MHz 0x5C +#define INTEGRATOR_SC_OSC_SYS_33MHz 0x7C +#define INTEGRATOR_SC_OSC_SYS_MASK 0xFF + +#define INTEGRATOR_SC_OSC_PCI_25MHz 0x100 +#define INTEGRATOR_SC_OSC_PCI_33MHz 0x0 +#define INTEGRATOR_SC_OSC_PCI_MASK 0x100 + +#define INTEGRATOR_SC_CTRL_SOFTRST (1 << 0) +#define INTEGRATOR_SC_CTRL_nFLVPPEN (1 << 1) +#define INTEGRATOR_SC_CTRL_nFLWP (1 << 2) +#define INTEGRATOR_SC_CTRL_URTS0 (1 << 4) +#define INTEGRATOR_SC_CTRL_UDTR0 (1 << 5) +#define INTEGRATOR_SC_CTRL_URTS1 (1 << 6) +#define INTEGRATOR_SC_CTRL_UDTR1 (1 << 7) + +/* + * External Bus Interface + */ +#define INTEGRATOR_EBI_BASE 0x12000000 + +#define INTEGRATOR_EBI_CSR0_OFFSET 0x00 +#define INTEGRATOR_EBI_CSR1_OFFSET 0x04 +#define INTEGRATOR_EBI_CSR2_OFFSET 0x08 +#define INTEGRATOR_EBI_CSR3_OFFSET 0x0C +#define INTEGRATOR_EBI_LOCK_OFFSET 0x20 + +#define INTEGRATOR_EBI_CSR0 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET) +#define INTEGRATOR_EBI_CSR1 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET) +#define INTEGRATOR_EBI_CSR2 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET) +#define INTEGRATOR_EBI_CSR3 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET) +#define INTEGRATOR_EBI_LOCK (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET) + +#define INTEGRATOR_EBI_8_BIT 0x00 +#define INTEGRATOR_EBI_16_BIT 0x01 +#define INTEGRATOR_EBI_32_BIT 0x02 +#define INTEGRATOR_EBI_WRITE_ENABLE 0x04 +#define INTEGRATOR_EBI_SYNC 0x08 +#define INTEGRATOR_EBI_WS_2 0x00 +#define INTEGRATOR_EBI_WS_3 0x10 +#define INTEGRATOR_EBI_WS_4 0x20 +#define INTEGRATOR_EBI_WS_5 0x30 +#define INTEGRATOR_EBI_WS_6 0x40 +#define INTEGRATOR_EBI_WS_7 0x50 +#define INTEGRATOR_EBI_WS_8 0x60 +#define INTEGRATOR_EBI_WS_9 0x70 +#define INTEGRATOR_EBI_WS_10 0x80 +#define INTEGRATOR_EBI_WS_11 0x90 +#define INTEGRATOR_EBI_WS_12 0xA0 +#define INTEGRATOR_EBI_WS_13 0xB0 +#define INTEGRATOR_EBI_WS_14 0xC0 +#define INTEGRATOR_EBI_WS_15 0xD0 +#define INTEGRATOR_EBI_WS_16 0xE0 +#define INTEGRATOR_EBI_WS_17 0xF0 + + +#define INTEGRATOR_CT_BASE 0x13000000 /* Counter/Timers */ +#define INTEGRATOR_IC_BASE 0x14000000 /* Interrupt Controller */ +#define INTEGRATOR_RTC_BASE 0x15000000 /* Real Time Clock */ +#define INTEGRATOR_UART0_BASE 0x16000000 /* UART 0 */ +#define INTEGRATOR_UART1_BASE 0x17000000 /* UART 1 */ +#define INTEGRATOR_KBD_BASE 0x18000000 /* Keyboard */ +#define INTEGRATOR_MOUSE_BASE 0x19000000 /* Mouse */ + +/* + * LED's & Switches + */ +#define INTEGRATOR_DBG_ALPHA_OFFSET 0x00 +#define INTEGRATOR_DBG_LEDS_OFFSET 0x04 +#define INTEGRATOR_DBG_SWITCH_OFFSET 0x08 + +#define INTEGRATOR_DBG_BASE 0x1A000000 +#define INTEGRATOR_DBG_ALPHA (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET) +#define INTEGRATOR_DBG_LEDS (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET) +#define INTEGRATOR_DBG_SWITCH (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET) + +#define INTEGRATOR_AP_GPIO_BASE 0x1B000000 /* GPIO */ + +#define INTEGRATOR_CP_MMC_BASE 0x1C000000 /* MMC */ +#define INTEGRATOR_CP_AACI_BASE 0x1D000000 /* AACI */ +#define INTEGRATOR_CP_ETH_BASE 0xC8000000 /* Ethernet */ +#define INTEGRATOR_CP_GPIO_BASE 0xC9000000 /* GPIO */ +#define INTEGRATOR_CP_SIC_BASE 0xCA000000 /* SIC */ +#define INTEGRATOR_CP_CTL_BASE 0xCB000000 /* CP system control */ + +/* PS2 Keyboard interface */ +#define KMI0_BASE INTEGRATOR_KBD_BASE + +/* PS2 Mouse interface */ +#define KMI1_BASE INTEGRATOR_MOUSE_BASE + +/* + * Integrator Interrupt Controllers + * + * + * Offsets from interrupt controller base + * + * System Controller interrupt controller base is + * + * INTEGRATOR_IC_BASE + (header_number << 6) + * + * Core Module interrupt controller base is + * + * INTEGRATOR_HDR_IC + */ +#define IRQ_STATUS 0 +#define IRQ_RAW_STATUS 0x04 +#define IRQ_ENABLE 0x08 +#define IRQ_ENABLE_SET 0x08 +#define IRQ_ENABLE_CLEAR 0x0C + +#define INT_SOFT_SET 0x10 +#define INT_SOFT_CLEAR 0x14 + +#define FIQ_STATUS 0x20 +#define FIQ_RAW_STATUS 0x24 +#define FIQ_ENABLE 0x28 +#define FIQ_ENABLE_SET 0x28 +#define FIQ_ENABLE_CLEAR 0x2C + + +/* + * LED's + */ +#define GREEN_LED 0x01 +#define YELLOW_LED 0x02 +#define RED_LED 0x04 +#define GREEN_LED_2 0x08 +#define ALL_LEDS 0x0F + +#define LED_BANK INTEGRATOR_DBG_LEDS + +/* + * Timer definitions + * + * Only use timer 1 & 2 + * (both run at 24MHz and will need the clock divider set to 16). + * + * Timer 0 runs at bus frequency + */ +#define INTEGRATOR_TIMER0_BASE INTEGRATOR_CT_BASE +#define INTEGRATOR_TIMER1_BASE (INTEGRATOR_CT_BASE + 0x100) +#define INTEGRATOR_TIMER2_BASE (INTEGRATOR_CT_BASE + 0x200) + +#define INTEGRATOR_CSR_BASE 0x10000000 +#define INTEGRATOR_CSR_SIZE 0x10000000 + +#endif /* INTEGRATOR_HARDWARE_H */ diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c new file mode 100644 index 000000000..58b02cbbe --- /dev/null +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * linux/arch/arm/mach-integrator/integrator_ap.c + * + * Copyright (C) 2000-2003 Deep Blue Solutions Ltd + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/syscore_ops.h> +#include <linux/amba/bus.h> +#include <linux/io.h> +#include <linux/irqchip.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/termios.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "hardware.h" +#include "cm.h" +#include "common.h" + +/* Regmap to the AP system controller */ +static struct regmap *ap_syscon_map; + +/* + * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx + * is the (PA >> 12). + * + * Setup a VA for the Integrator interrupt controller (for header #0, + * just for now). + */ +#define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE) + +/* + * Logical Physical + * f1400000 14000000 Interrupt controller + * f1600000 16000000 UART 0 + */ + +static struct map_desc ap_io_desc[] __initdata __maybe_unused = { + { + .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), + .length = SZ_4K, + .type = MT_DEVICE + } +}; + +static void __init ap_map_io(void) +{ + iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc)); +} + +#ifdef CONFIG_PM +static unsigned long ic_irq_enable; + +static int irq_suspend(void) +{ + ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE); + return 0; +} + +static void irq_resume(void) +{ + /* disable all irq sources */ + cm_clear_irqs(); + writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); + writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); + + writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET); +} +#else +#define irq_suspend NULL +#define irq_resume NULL +#endif + +static struct syscore_ops irq_syscore_ops = { + .suspend = irq_suspend, + .resume = irq_resume, +}; + +static int __init irq_syscore_init(void) +{ + register_syscore_ops(&irq_syscore_ops); + + return 0; +} + +device_initcall(irq_syscore_init); + +/* + * For the PL010 found in the Integrator/AP some of the UART control is + * implemented in the system controller and accessed using a callback + * from the driver. + */ +static void integrator_uart_set_mctrl(struct amba_device *dev, + void __iomem *base, unsigned int mctrl) +{ + unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask; + u32 phybase = dev->res.start; + int ret; + + if (phybase == INTEGRATOR_UART0_BASE) { + /* UART0 */ + rts_mask = 1 << 4; + dtr_mask = 1 << 5; + } else { + /* UART1 */ + rts_mask = 1 << 6; + dtr_mask = 1 << 7; + } + + if (mctrl & TIOCM_RTS) + ctrlc |= rts_mask; + else + ctrls |= rts_mask; + + if (mctrl & TIOCM_DTR) + ctrlc |= dtr_mask; + else + ctrls |= dtr_mask; + + ret = regmap_write(ap_syscon_map, + INTEGRATOR_SC_CTRLS_OFFSET, + ctrls); + if (ret) + pr_err("MODEM: unable to write PL010 UART CTRLS\n"); + + ret = regmap_write(ap_syscon_map, + INTEGRATOR_SC_CTRLC_OFFSET, + ctrlc); + if (ret) + pr_err("MODEM: unable to write PL010 UART CRTLC\n"); +} + +struct amba_pl010_data ap_uart_data = { + .set_mctrl = integrator_uart_set_mctrl, +}; + +void __init ap_init_early(void) +{ +} + +static void __init ap_init_irq_of(void) +{ + cm_init(); + irqchip_init(); +} + +/* For the Device Tree, add in the UART callbacks as AUXDATA */ +static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, + "uart0", &ap_uart_data), + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, + "uart1", &ap_uart_data), + { /* sentinel */ }, +}; + +static const struct of_device_id ap_syscon_match[] = { + { .compatible = "arm,integrator-ap-syscon"}, + { }, +}; + +static void __init ap_init_of(void) +{ + struct device_node *syscon; + + of_platform_default_populate(NULL, ap_auxdata_lookup, NULL); + + syscon = of_find_matching_node(NULL, ap_syscon_match); + if (!syscon) + return; + ap_syscon_map = syscon_node_to_regmap(syscon); + if (IS_ERR(ap_syscon_map)) { + pr_crit("could not find Integrator/AP system controller\n"); + return; + } +} + +static const char * ap_dt_board_compat[] = { + "arm,integrator-ap", + NULL, +}; + +DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)") + .reserve = integrator_reserve, + .map_io = ap_map_io, + .init_early = ap_init_early, + .init_irq = ap_init_irq_of, + .init_machine = ap_init_of, + .dt_compat = ap_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c new file mode 100644 index 000000000..b7eb40387 --- /dev/null +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * linux/arch/arm/mach-integrator/integrator_cp.c + * + * Copyright (C) 2003 Deep Blue Solutions Ltd + */ +#include <linux/kernel.h> +#include <linux/amba/mmci.h> +#include <linux/io.h> +#include <linux/irqchip.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/sched_clock.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "hardware.h" +#include "cm.h" +#include "common.h" + +/* Base address to the core module header */ +static struct regmap *cm_map; +/* Base address to the CP controller */ +static void __iomem *intcp_con_base; + +#define CM_COUNTER_OFFSET 0x28 + +/* + * Logical Physical + * f1400000 14000000 Interrupt controller + * f1600000 16000000 UART 0 + * fca00000 ca000000 SIC + */ + +static struct map_desc intcp_io_desc[] __initdata __maybe_unused = { + { + .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + } +}; + +static void __init intcp_map_io(void) +{ + iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); +} + +/* + * It seems that the card insertion interrupt remains active after + * we've acknowledged it. We therefore ignore the interrupt, and + * rely on reading it from the SIC. This also means that we must + * clear the latched interrupt. + */ +static unsigned int mmc_status(struct device *dev) +{ + unsigned int status = readl(__io_address(0xca000000 + 4)); + writel(8, intcp_con_base + 8); + + return status & 8; +} + +static struct mmci_platform_data mmc_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .status = mmc_status, +}; + +static u64 notrace intcp_read_sched_clock(void) +{ + unsigned int val; + + /* MMIO so discard return code */ + regmap_read(cm_map, CM_COUNTER_OFFSET, &val); + return val; +} + +static void __init intcp_init_early(void) +{ + cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator"); + if (IS_ERR(cm_map)) + return; + sched_clock_register(intcp_read_sched_clock, 32, 24000000); +} + +static void __init intcp_init_irq_of(void) +{ + cm_init(); + irqchip_init(); +} + +/* + * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA + * and enforce the bus names since these are used for clock lookups. + */ +static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE, + "mmci", &mmc_data), + { /* sentinel */ }, +}; + +static const struct of_device_id intcp_syscon_match[] = { + { .compatible = "arm,integrator-cp-syscon"}, + { }, +}; + +static void __init intcp_init_of(void) +{ + struct device_node *cpcon; + + cpcon = of_find_matching_node(NULL, intcp_syscon_match); + if (!cpcon) + return; + + intcp_con_base = of_iomap(cpcon, 0); + if (!intcp_con_base) + return; + + of_platform_default_populate(NULL, intcp_auxdata_lookup, NULL); +} + +static const char * intcp_dt_board_compat[] = { + "arm,integrator-cp", + NULL, +}; + +DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") + .reserve = integrator_reserve, + .map_io = intcp_map_io, + .init_early = intcp_init_early, + .init_irq = intcp_init_irq_of, + .init_machine = intcp_init_of, + .dt_compat = intcp_dt_board_compat, +MACHINE_END |