aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-integrator
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r--arch/arm/mach-integrator/Kconfig13
-rw-r--r--arch/arm/mach-integrator/Makefile3
-rw-r--r--arch/arm/mach-integrator/cm.h (renamed from arch/arm/mach-integrator/include/mach/cm.h)7
-rw-r--r--arch/arm/mach-integrator/common.h8
-rw-r--r--arch/arm/mach-integrator/core.c188
-rw-r--r--arch/arm/mach-integrator/cpu.c224
-rw-r--r--arch/arm/mach-integrator/hardware.h (renamed from arch/arm/mach-integrator/include/mach/platform.h)131
-rw-r--r--arch/arm/mach-integrator/impd1.c95
-rw-r--r--arch/arm/mach-integrator/impd1.h (renamed from arch/arm/mach-integrator/include/mach/impd1.h)4
-rw-r--r--arch/arm/mach-integrator/include/mach/debug-macro.S20
-rw-r--r--arch/arm/mach-integrator/include/mach/hardware.h45
-rw-r--r--arch/arm/mach-integrator/include/mach/irqs.h81
-rw-r--r--arch/arm/mach-integrator/include/mach/timex.h26
-rw-r--r--arch/arm/mach-integrator/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c304
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c285
-rw-r--r--arch/arm/mach-integrator/leds.c7
-rw-r--r--arch/arm/mach-integrator/lm.c2
-rw-r--r--arch/arm/mach-integrator/lm.h (renamed from arch/arm/mach-integrator/include/mach/lm.h)0
-rw-r--r--arch/arm/mach-integrator/pci.c113
-rw-r--r--arch/arm/mach-integrator/pci_v3.c485
-rw-r--r--arch/arm/mach-integrator/pci_v3.h9
22 files changed, 721 insertions, 1331 deletions
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index abeff25532a..64f8e2564a3 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -6,8 +6,8 @@ config ARCH_INTEGRATOR_AP
bool "Support Integrator/AP and Integrator/PP2 platforms"
select CLKSRC_MMIO
select MIGHT_HAVE_PCI
- select SERIAL_AMBA_PL010
- select SERIAL_AMBA_PL010_CONSOLE
+ 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
@@ -18,8 +18,8 @@ config ARCH_INTEGRATOR_CP
select ARCH_CINTEGRATOR
select ARM_TIMER_SP804
select PLAT_VERSATILE_CLCD
- select SERIAL_AMBA_PL011
- select SERIAL_AMBA_PL011_CONSOLE
+ 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.
@@ -28,8 +28,11 @@ config ARCH_CINTEGRATOR
bool
config INTEGRATOR_IMPD1
- tristate "Include support for Integrator/IM-PD1"
+ bool "Include support for Integrator/IM-PD1"
depends on ARCH_INTEGRATOR_AP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_VIC
+ select GPIO_PL061 if GPIOLIB
help
The IM-PD1 is an add-on logic module for the Integrator which
allows ARM(R) Ltd PrimeCells to be developed and evaluated.
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
index 5521d18bf19..ec759ded7b6 100644
--- a/arch/arm/mach-integrator/Makefile
+++ b/arch/arm/mach-integrator/Makefile
@@ -8,6 +8,5 @@ obj-y := core.o lm.o leds.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
-obj-$(CONFIG_PCI) += pci_v3.o pci.o
-obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o
+obj-$(CONFIG_PCI) += pci_v3.o
obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o
diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/cm.h
index 202e6a57f10..4ecff7bff48 100644
--- a/arch/arm/mach-integrator/include/mach/cm.h
+++ b/arch/arm/mach-integrator/cm.h
@@ -1,9 +1,12 @@
/*
- * update the core module control register.
+ * access the core module control register.
*/
+u32 cm_get(void);
void cm_control(u32, u32);
-#define CM_CTRL __io_address(INTEGRATOR_HDR_CTRL)
+struct device_node;
+void cm_init(void);
+void cm_clear_irqs(void);
#define CM_CTRL_LED (1 << 0)
#define CM_CTRL_nMBDET (1 << 1)
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 79197d8b34a..ad0ac5547b2 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,12 +1,8 @@
+#include <linux/reboot.h>
#include <linux/amba/serial.h>
-#ifdef CONFIG_ARCH_INTEGRATOR_AP
extern struct amba_pl010_data ap_uart_data;
-#else
-/* Not used without Integrator/AP support anyway */
-struct amba_pl010_data ap_uart_data {};
-#endif
void integrator_init_early(void);
int integrator_init(bool is_cp);
void integrator_reserve(void);
-void integrator_restart(char, const char *);
+void integrator_restart(enum reboot_mode, const char *);
void integrator_init_sysfs(struct device *parent, u32 id);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 39c060f75e4..e3f3aca43ef 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -22,77 +22,28 @@
#include <linux/amba/serial.h>
#include <linux/io.h>
#include <linux/stat.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include <mach/cm.h>
-#include <mach/irqs.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <asm/mach-types.h>
#include <asm/mach/time.h>
#include <asm/pgtable.h>
+#include "hardware.h"
+#include "cm.h"
#include "common.h"
-#ifdef CONFIG_ATAGS
-
-#define INTEGRATOR_RTC_IRQ { IRQ_RTCINT }
-#define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 }
-#define INTEGRATOR_UART1_IRQ { IRQ_UARTINT1 }
-#define KMI0_IRQ { IRQ_KMIINT0 }
-#define KMI1_IRQ { IRQ_KMIINT1 }
-
-static AMBA_APB_DEVICE(rtc, "rtc", 0,
- INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
-
-static AMBA_APB_DEVICE(uart0, "uart0", 0,
- INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL);
-
-static AMBA_APB_DEVICE(uart1, "uart1", 0,
- INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL);
-
-static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);
-static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL);
-
-static struct amba_device *amba_devs[] __initdata = {
- &rtc_device,
- &uart0_device,
- &uart1_device,
- &kmi0_device,
- &kmi1_device,
-};
+static DEFINE_RAW_SPINLOCK(cm_lock);
+static void __iomem *cm_base;
-int __init integrator_init(bool is_cp)
+/**
+ * cm_get - get the value from the CM_CTRL register
+ */
+u32 cm_get(void)
{
- int i;
-
- /*
- * The Integrator/AP lacks necessary AMBA PrimeCell IDs, so we need to
- * hard-code them. The Integator/CP and forward have proper cell IDs.
- * Else we leave them undefined to the bus driver can autoprobe them.
- */
- if (!is_cp) {
- rtc_device.periphid = 0x00041030;
- uart0_device.periphid = 0x00041010;
- uart1_device.periphid = 0x00041010;
- kmi0_device.periphid = 0x00041050;
- kmi1_device.periphid = 0x00041050;
- uart0_device.dev.platform_data = &ap_uart_data;
- uart1_device.dev.platform_data = &ap_uart_data;
- }
-
- for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
- struct amba_device *d = amba_devs[i];
- amba_device_register(d, &iomem_resource);
- }
-
- return 0;
+ return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
}
-#endif
-
-static DEFINE_RAW_SPINLOCK(cm_lock);
-
/**
* cm_control - update the CM_CTRL register.
* @mask: bits to change
@@ -104,12 +55,80 @@ void cm_control(u32 mask, u32 set)
u32 val;
raw_spin_lock_irqsave(&cm_lock, flags);
- val = readl(CM_CTRL) & ~mask;
- writel(val | set, CM_CTRL);
+ 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);
}
-EXPORT_SYMBOL(cm_control);
+static const char *integrator_arch_str(u32 id)
+{
+ switch ((id >> 16) & 0xff) {
+ case 0x00:
+ return "ASB little-endian";
+ case 0x01:
+ return "AHB little-endian";
+ case 0x03:
+ return "AHB-Lite system bus, bi-endian";
+ case 0x04:
+ return "AHB";
+ case 0x08:
+ return "AHB system bus, ASB processor bus";
+ default:
+ return "Unknown";
+ }
+}
+
+static const char *integrator_fpga_str(u32 id)
+{
+ switch ((id >> 12) & 0xf) {
+ case 0x01:
+ return "XC4062";
+ case 0x02:
+ return "XC4085";
+ case 0x03:
+ return "XVC600";
+ case 0x04:
+ return "EPM7256AE (Altera PLD)";
+ default:
+ return "Unknown";
+ }
+}
+
+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);
+ u32 val;
+
+ 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();
+ val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET);
+ pr_info("Detected ARM core module:\n");
+ pr_info(" Manufacturer: %02x\n", (val >> 24));
+ pr_info(" Architecture: %s\n", integrator_arch_str(val));
+ pr_info(" FPGA: %s\n", integrator_fpga_str(val));
+ pr_info(" Build: %02x\n", (val >> 4) & 0xFF);
+ pr_info(" Rev: %c\n", ('A' + (val & 0x03)));
+}
/*
* We need to stop things allocating the low memory; ideally we need a
@@ -124,7 +143,7 @@ void __init integrator_reserve(void)
/*
* To reset, we hit the on-board reset register in the system FPGA
*/
-void integrator_restart(char mode, const char *cmd)
+void integrator_restart(enum reboot_mode mode, const char *cmd)
{
cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
}
@@ -145,27 +164,7 @@ static ssize_t intcp_get_arch(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- const char *arch;
-
- switch ((integrator_id >> 16) & 0xff) {
- case 0x00:
- arch = "ASB little-endian";
- break;
- case 0x01:
- arch = "AHB little-endian";
- break;
- case 0x03:
- arch = "AHB-Lite system bus, bi-endian";
- break;
- case 0x04:
- arch = "AHB";
- break;
- default:
- arch = "Unknown";
- break;
- }
-
- return sprintf(buf, "%s\n", arch);
+ return sprintf(buf, "%s\n", integrator_arch_str(integrator_id));
}
static struct device_attribute intcp_arch_attr =
@@ -175,24 +174,7 @@ static ssize_t intcp_get_fpga(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- const char *fpga;
-
- switch ((integrator_id >> 12) & 0xf) {
- case 0x01:
- fpga = "XC4062";
- break;
- case 0x02:
- fpga = "XC4085";
- break;
- case 0x04:
- fpga = "EPM7256AE (Altera PLD)";
- break;
- default:
- fpga = "Unknown";
- break;
- }
-
- return sprintf(buf, "%s\n", fpga);
+ return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id));
}
static struct device_attribute intcp_fpga_attr =
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
deleted file mode 100644
index 590c192cdf4..00000000000
--- a/arch/arm/mach-integrator/cpu.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * linux/arch/arm/mach-integrator/cpu.c
- *
- * Copyright (C) 2001-2002 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * CPU support functions
- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/cpufreq.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include <asm/mach-types.h>
-#include <asm/hardware/icst.h>
-
-static struct cpufreq_driver integrator_driver;
-
-#define CM_ID __io_address(INTEGRATOR_HDR_ID)
-#define CM_OSC __io_address(INTEGRATOR_HDR_OSC)
-#define CM_STAT __io_address(INTEGRATOR_HDR_STAT)
-#define CM_LOCK __io_address(INTEGRATOR_HDR_LOCK)
-
-static const struct icst_params lclk_params = {
- .ref = 24000000,
- .vco_max = ICST525_VCO_MAX_5V,
- .vco_min = ICST525_VCO_MIN,
- .vd_min = 8,
- .vd_max = 132,
- .rd_min = 24,
- .rd_max = 24,
- .s2div = icst525_s2div,
- .idx2s = icst525_idx2s,
-};
-
-static const struct icst_params cclk_params = {
- .ref = 24000000,
- .vco_max = ICST525_VCO_MAX_5V,
- .vco_min = ICST525_VCO_MIN,
- .vd_min = 12,
- .vd_max = 160,
- .rd_min = 24,
- .rd_max = 24,
- .s2div = icst525_s2div,
- .idx2s = icst525_idx2s,
-};
-
-/*
- * Validate the speed policy.
- */
-static int integrator_verify_policy(struct cpufreq_policy *policy)
-{
- struct icst_vco vco;
-
- cpufreq_verify_within_limits(policy,
- policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- vco = icst_hz_to_vco(&cclk_params, policy->max * 1000);
- policy->max = icst_hz(&cclk_params, vco) / 1000;
-
- vco = icst_hz_to_vco(&cclk_params, policy->min * 1000);
- policy->min = icst_hz(&cclk_params, vco) / 1000;
-
- cpufreq_verify_within_limits(policy,
- policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- return 0;
-}
-
-
-static int integrator_set_target(struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- cpumask_t cpus_allowed;
- int cpu = policy->cpu;
- struct icst_vco vco;
- struct cpufreq_freqs freqs;
- u_int cm_osc;
-
- /*
- * Save this threads cpus_allowed mask.
- */
- cpus_allowed = current->cpus_allowed;
-
- /*
- * Bind to the specified CPU. When this call returns,
- * we should be running on the right CPU.
- */
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
- BUG_ON(cpu != smp_processor_id());
-
- /* get current setting */
- cm_osc = __raw_readl(CM_OSC);
-
- if (machine_is_integrator()) {
- vco.s = (cm_osc >> 8) & 7;
- } else if (machine_is_cintegrator()) {
- vco.s = 1;
- }
- vco.v = cm_osc & 255;
- vco.r = 22;
- freqs.old = icst_hz(&cclk_params, vco) / 1000;
-
- /* icst_hz_to_vco rounds down -- so we need the next
- * larger freq in case of CPUFREQ_RELATION_L.
- */
- if (relation == CPUFREQ_RELATION_L)
- target_freq += 999;
- if (target_freq > policy->max)
- target_freq = policy->max;
- vco = icst_hz_to_vco(&cclk_params, target_freq * 1000);
- freqs.new = icst_hz(&cclk_params, vco) / 1000;
-
- freqs.cpu = policy->cpu;
-
- if (freqs.old == freqs.new) {
- set_cpus_allowed(current, cpus_allowed);
- return 0;
- }
-
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
- cm_osc = __raw_readl(CM_OSC);
-
- if (machine_is_integrator()) {
- cm_osc &= 0xfffff800;
- cm_osc |= vco.s << 8;
- } else if (machine_is_cintegrator()) {
- cm_osc &= 0xffffff00;
- }
- cm_osc |= vco.v;
-
- __raw_writel(0xa05f, CM_LOCK);
- __raw_writel(cm_osc, CM_OSC);
- __raw_writel(0, CM_LOCK);
-
- /*
- * Restore the CPUs allowed mask.
- */
- set_cpus_allowed(current, cpus_allowed);
-
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
- return 0;
-}
-
-static unsigned int integrator_get(unsigned int cpu)
-{
- cpumask_t cpus_allowed;
- unsigned int current_freq;
- u_int cm_osc;
- struct icst_vco vco;
-
- cpus_allowed = current->cpus_allowed;
-
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
- BUG_ON(cpu != smp_processor_id());
-
- /* detect memory etc. */
- cm_osc = __raw_readl(CM_OSC);
-
- if (machine_is_integrator()) {
- vco.s = (cm_osc >> 8) & 7;
- } else {
- vco.s = 1;
- }
- vco.v = cm_osc & 255;
- vco.r = 22;
-
- current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */
-
- set_cpus_allowed(current, cpus_allowed);
-
- return current_freq;
-}
-
-static int integrator_cpufreq_init(struct cpufreq_policy *policy)
-{
-
- /* set default policy and cpuinfo */
- policy->cpuinfo.max_freq = 160000;
- policy->cpuinfo.min_freq = 12000;
- policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */
- policy->cur = policy->min = policy->max = integrator_get(policy->cpu);
-
- return 0;
-}
-
-static struct cpufreq_driver integrator_driver = {
- .verify = integrator_verify_policy,
- .target = integrator_set_target,
- .get = integrator_get,
- .init = integrator_cpufreq_init,
- .name = "integrator",
-};
-
-static int __init integrator_cpu_init(void)
-{
- return cpufreq_register_driver(&integrator_driver);
-}
-
-static void __exit integrator_cpu_exit(void)
-{
- cpufreq_unregister_driver(&integrator_driver);
-}
-
-MODULE_AUTHOR ("Russell M. King");
-MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs");
-MODULE_LICENSE ("GPL");
-
-module_init(integrator_cpu_init);
-module_exit(integrator_cpu_exit);
diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/hardware.h
index be5859efe10..857ca5f8b9a 100644
--- a/arch/arm/mach-integrator/include/mach/platform.h
+++ b/arch/arm/mach-integrator/hardware.h
@@ -1,4 +1,8 @@
/*
+ * This file contains the hardware definitions of the Integrator.
+ *
+ * Copyright (C) 1998-1999 ARM Limited.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -13,26 +17,28 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/**************************************************************************
- * * Copyright © ARM Limited 1998. All rights reserved.
- * ***********************************************************************/
-/* ************************************************************************
- *
- * Integrator address map
- *
- * ***********************************************************************/
+#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
-#ifndef __address_h
-#define __address_h 1
+#define __io_address(n) ((void __iomem *)IO_ADDRESS(n))
-/* ========================================================================
- * Integrator definitions
- * ========================================================================
- * ------------------------------------------------------------------------
- * Memory definitions
- * ------------------------------------------------------------------------
+/*
* Integrator memory map
- *
*/
#define INTEGRATOR_BOOT_ROM_LO 0x00000000
#define INTEGRATOR_BOOT_ROM_HI 0x20000000
@@ -40,13 +46,13 @@
#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.
+ * 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.
+ * 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.
+ * New Core Modules also alias the SSRAM.
*
*/
#define INTEGRATOR_SSRAM_BASE 0x00000000
@@ -61,7 +67,6 @@
/*
* SDRAM is a SIMM therefore the size is not known.
- *
*/
#define INTEGRATOR_SDRAM_BASE 0x00040000
@@ -81,10 +86,8 @@
#define INTEGRATOR_LOGIC_MODULE2_BASE 0xE0000000
#define INTEGRATOR_LOGIC_MODULE3_BASE 0xF0000000
-/* ------------------------------------------------------------------------
- * Integrator header card registers
- * ------------------------------------------------------------------------
- *
+/*
+ * Integrator header card registers
*/
#define INTEGRATOR_HDR_ID_OFFSET 0x00
#define INTEGRATOR_HDR_PROC_OFFSET 0x04
@@ -173,16 +176,12 @@
#define INTEGRATOR_HDR_SDRAM_SPD_OK (1 << 5)
-
-/* ------------------------------------------------------------------------
- * Integrator system registers
- * ------------------------------------------------------------------------
- *
+/*
+ * Integrator system registers
*/
/*
* System Controller
- *
*/
#define INTEGRATOR_SC_ID_OFFSET 0x00
#define INTEGRATOR_SC_OSC_OFFSET 0x04
@@ -223,7 +222,6 @@
/*
* External Bus Interface
- *
*/
#define INTEGRATOR_EBI_BASE 0x12000000
@@ -272,7 +270,6 @@
/*
* LED's & Switches
- *
*/
#define INTEGRATOR_DBG_ALPHA_OFFSET 0x00
#define INTEGRATOR_DBG_LEDS_OFFSET 0x04
@@ -292,55 +289,25 @@
#define INTEGRATOR_CP_SIC_BASE 0xCA000000 /* SIC */
#define INTEGRATOR_CP_CTL_BASE 0xCB000000 /* CP system control */
-/* ------------------------------------------------------------------------
- * KMI keyboard/mouse definitions
- * ------------------------------------------------------------------------
- */
/* PS2 Keyboard interface */
#define KMI0_BASE INTEGRATOR_KBD_BASE
/* PS2 Mouse interface */
#define KMI1_BASE INTEGRATOR_MOUSE_BASE
-/* KMI definitions are now in include/asm-arm/hardware/amba_kmi.h -- rmk */
-
-/* ------------------------------------------------------------------------
- * Where in the memory map does PCI live?
- * ------------------------------------------------------------------------
- * This represents a fairly liberal usage of address space. Even though
- * the V3 only has two windows (therefore we need to map stuff on the fly),
- * we maintain the same addresses, even if they're not mapped.
+/*
+ * Integrator Interrupt Controllers
*
- */
-#define PHYS_PCI_MEM_BASE 0x40000000 /* 512M to xxx */
-/* unused 256M from A0000000-AFFFFFFF might be used for I2O ???
- */
-#define PHYS_PCI_IO_BASE 0x60000000 /* 16M to xxx */
-/* unused (128-16)M from B1000000-B7FFFFFF
- */
-#define PHYS_PCI_CONFIG_BASE 0x61000000 /* 16M to xxx */
-/* unused ((128-16)M - 64K) from XXX
- */
-#define PHYS_PCI_V3_BASE 0x62000000
-
-#define PCI_MEMORY_VADDR IOMEM(0xe8000000)
-#define PCI_CONFIG_VADDR IOMEM(0xec000000)
-#define PCI_V3_VADDR IOMEM(0xed000000)
-
-/* ------------------------------------------------------------------------
- * Integrator Interrupt Controllers
- * ------------------------------------------------------------------------
*
- * Offsets from interrupt controller base
+ * Offsets from interrupt controller base
*
- * System Controller interrupt controller base is
+ * System Controller interrupt controller base is
*
* INTEGRATOR_IC_BASE + (header_number << 6)
*
- * Core Module interrupt controller base is
+ * Core Module interrupt controller base is
*
* INTEGRATOR_HDR_IC
- *
*/
#define IRQ_STATUS 0
#define IRQ_RAW_STATUS 0x04
@@ -358,25 +325,8 @@
#define FIQ_ENABLE_CLEAR 0x2C
-/* ------------------------------------------------------------------------
- * Interrupts
- * ------------------------------------------------------------------------
- *
- *
- * Each Core Module has two interrupts controllers, one on the core module
- * itself and one in the system controller on the motherboard. The
- * READ_INT macro in target.s reads both interrupt controllers and returns
- * a 32 bit bitmask, bits 0 to 23 are interrupts from the system controller
- * and bits 24 to 31 are from the core module.
- *
- * The following definitions relate to the bitmask returned by READ_INT.
- *
- */
-
-/* ------------------------------------------------------------------------
- * LED's
- * ------------------------------------------------------------------------
- *
+/*
+ * LED's
*/
#define GREEN_LED 0x01
#define YELLOW_LED 0x02
@@ -394,7 +344,6 @@
*
* 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)
@@ -402,4 +351,4 @@
#define INTEGRATOR_CSR_BASE 0x10000000
#define INTEGRATOR_CSR_SIZE 0x10000000
-#endif
+#endif /* INTEGRATOR_HARDWARE_H */
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 9f82f9dcbb9..3ce880729cf 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -23,10 +23,11 @@
#include <linux/io.h>
#include <linux/platform_data/clk-integrator.h>
#include <linux/slab.h>
+#include <linux/irqchip/arm-vic.h>
-#include <mach/lm.h>
-#include <mach/impd1.h>
#include <asm/sizes.h>
+#include "lm.h"
+#include "impd1.h"
static int module_id;
@@ -35,6 +36,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
struct impd1_module {
void __iomem *base;
+ void __iomem *vic_base;
};
void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
@@ -262,9 +264,6 @@ struct impd1_device {
static struct impd1_device impd1_devs[] = {
{
- .offset = 0x03000000,
- .id = 0x00041190,
- }, {
.offset = 0x00100000,
.irq = { 1 },
.id = 0x00141011,
@@ -304,46 +303,77 @@ static struct impd1_device impd1_devs[] = {
}
};
-static int impd1_probe(struct lm_device *dev)
+/*
+ * Valid IRQs: 0 thru 9 and 11, 10 unused.
+ */
+#define IMPD1_VALID_IRQS 0x00000bffU
+
+/*
+ * As this module is bool, it is OK to have this as __init_refok() - no
+ * probe calls will be done after the initial system bootup, as devices
+ * are discovered as part of the machine startup.
+ */
+static int __init_refok impd1_probe(struct lm_device *dev)
{
struct impd1_module *impd1;
- int i, ret;
+ int irq_base;
+ int i;
if (dev->id != module_id)
return -EINVAL;
- if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
+ if (!devm_request_mem_region(&dev->dev, dev->resource.start,
+ SZ_4K, "LM registers"))
return -EBUSY;
- impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL);
- if (!impd1) {
- ret = -ENOMEM;
- goto release_lm;
- }
+ impd1 = devm_kzalloc(&dev->dev, sizeof(struct impd1_module),
+ GFP_KERNEL);
+ if (!impd1)
+ return -ENOMEM;
- impd1->base = ioremap(dev->resource.start, SZ_4K);
- if (!impd1->base) {
- ret = -ENOMEM;
- goto free_impd1;
- }
+ impd1->base = devm_ioremap(&dev->dev, dev->resource.start, SZ_4K);
+ if (!impd1->base)
+ return -ENOMEM;
- lm_set_drvdata(dev, impd1);
+ integrator_impd1_clk_init(impd1->base, dev->id);
- printk("IM-PD1 found at 0x%08lx\n",
- (unsigned long)dev->resource.start);
+ if (!devm_request_mem_region(&dev->dev,
+ dev->resource.start + 0x03000000,
+ SZ_4K, "VIC"))
+ return -EBUSY;
- integrator_impd1_clk_init(impd1->base, dev->id);
+ impd1->vic_base = devm_ioremap(&dev->dev,
+ dev->resource.start + 0x03000000,
+ SZ_4K);
+ if (!impd1->vic_base)
+ return -ENOMEM;
+
+ irq_base = vic_init_cascaded(impd1->vic_base, dev->irq,
+ IMPD1_VALID_IRQS, 0);
+
+ lm_set_drvdata(dev, impd1);
+
+ dev_info(&dev->dev, "IM-PD1 found at 0x%08lx\n",
+ (unsigned long)dev->resource.start);
for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
struct impd1_device *idev = impd1_devs + i;
struct amba_device *d;
unsigned long pc_base;
char devname[32];
+ int irq1 = idev->irq[0];
+ int irq2 = idev->irq[1];
+
+ /* Translate IRQs to IM-PD1 local numberspace */
+ if (irq1)
+ irq1 += irq_base;
+ if (irq2)
+ irq2 += irq_base;
pc_base = dev->resource.start + idev->offset;
snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K,
- dev->irq, dev->irq,
+ irq1, irq2,
idev->platform_data, idev->id,
&dev->resource);
if (IS_ERR(d)) {
@@ -353,14 +383,6 @@ static int impd1_probe(struct lm_device *dev)
}
return 0;
-
- free_impd1:
- if (impd1 && impd1->base)
- iounmap(impd1->base);
- kfree(impd1);
- release_lm:
- release_mem_region(dev->resource.start, SZ_4K);
- return ret;
}
static int impd1_remove_one(struct device *dev, void *data)
@@ -371,21 +393,20 @@ static int impd1_remove_one(struct device *dev, void *data)
static void impd1_remove(struct lm_device *dev)
{
- struct impd1_module *impd1 = lm_get_drvdata(dev);
-
device_for_each_child(&dev->dev, NULL, impd1_remove_one);
integrator_impd1_clk_exit(dev->id);
lm_set_drvdata(dev, NULL);
-
- iounmap(impd1->base);
- kfree(impd1);
- release_mem_region(dev->resource.start, SZ_4K);
}
static struct lm_driver impd1_driver = {
.drv = {
.name = "impd1",
+ /*
+ * As we're dropping the probe() function, suppress driver
+ * binding from sysfs.
+ */
+ .suppress_bind_attrs = true,
},
.probe = impd1_probe,
.remove = impd1_remove,
diff --git a/arch/arm/mach-integrator/include/mach/impd1.h b/arch/arm/mach-integrator/impd1.h
index d75de4b1423..76de4dc9bee 100644
--- a/arch/arm/mach-integrator/include/mach/impd1.h
+++ b/arch/arm/mach-integrator/impd1.h
@@ -1,6 +1,3 @@
-#define IMPD1_OSC1 0x00
-#define IMPD1_OSC2 0x04
-#define IMPD1_LOCK 0x08
#define IMPD1_LEDS 0x0c
#define IMPD1_INT 0x10
#define IMPD1_SW 0x14
@@ -15,4 +12,3 @@
struct device;
void impd1_tweak_control(struct device *dev, u32 mask, u32 val);
-
diff --git a/arch/arm/mach-integrator/include/mach/debug-macro.S b/arch/arm/mach-integrator/include/mach/debug-macro.S
deleted file mode 100644
index 411b116077e..00000000000
--- a/arch/arm/mach-integrator/include/mach/debug-macro.S
+++ /dev/null
@@ -1,20 +0,0 @@
-/* arch/arm/mach-integrator/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- * Copyright (C) 1994-1999 Russell King
- * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
- .macro addruart, rp, rv, tmp
- mov \rp, #0x16000000 @ physical base address
- mov \rv, #0xf0000000 @ virtual base
- add \rv, \rv, #0x16000000 >> 4
- .endm
-
-#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h
deleted file mode 100644
index 65fed7c0eb8..00000000000
--- a/arch/arm/mach-integrator/include/mach/hardware.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * arch/arm/mach-integrator/include/mach/hardware.h
- *
- * This file contains the hardware definitions of the Integrator.
- *
- * Copyright (C) 1999 ARM Limited.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <asm/sizes.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))
-
-#endif
-
diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h
deleted file mode 100644
index eff0adad9ae..00000000000
--- a/arch/arm/mach-integrator/include/mach/irqs.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * arch/arm/mach-integrator/include/mach/irqs.h
- *
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Interrupt numbers, all of the above are just static reservations
- * used so they can be encoded into device resources. They will finally
- * be done away with when switching to device tree.
- */
-#define IRQ_PIC_START 64
-#define IRQ_SOFTINT (IRQ_PIC_START+0)
-#define IRQ_UARTINT0 (IRQ_PIC_START+1)
-#define IRQ_UARTINT1 (IRQ_PIC_START+2)
-#define IRQ_KMIINT0 (IRQ_PIC_START+3)
-#define IRQ_KMIINT1 (IRQ_PIC_START+4)
-#define IRQ_TIMERINT0 (IRQ_PIC_START+5)
-#define IRQ_TIMERINT1 (IRQ_PIC_START+6)
-#define IRQ_TIMERINT2 (IRQ_PIC_START+7)
-#define IRQ_RTCINT (IRQ_PIC_START+8)
-#define IRQ_AP_EXPINT0 (IRQ_PIC_START+9)
-#define IRQ_AP_EXPINT1 (IRQ_PIC_START+10)
-#define IRQ_AP_EXPINT2 (IRQ_PIC_START+11)
-#define IRQ_AP_EXPINT3 (IRQ_PIC_START+12)
-#define IRQ_AP_PCIINT0 (IRQ_PIC_START+13)
-#define IRQ_AP_PCIINT1 (IRQ_PIC_START+14)
-#define IRQ_AP_PCIINT2 (IRQ_PIC_START+15)
-#define IRQ_AP_PCIINT3 (IRQ_PIC_START+16)
-#define IRQ_AP_V3INT (IRQ_PIC_START+17)
-#define IRQ_AP_CPINT0 (IRQ_PIC_START+18)
-#define IRQ_AP_CPINT1 (IRQ_PIC_START+19)
-#define IRQ_AP_LBUSTIMEOUT (IRQ_PIC_START+20)
-#define IRQ_AP_APCINT (IRQ_PIC_START+21)
-#define IRQ_CP_CLCDCINT (IRQ_PIC_START+22)
-#define IRQ_CP_MMCIINT0 (IRQ_PIC_START+23)
-#define IRQ_CP_MMCIINT1 (IRQ_PIC_START+24)
-#define IRQ_CP_AACIINT (IRQ_PIC_START+25)
-#define IRQ_CP_CPPLDINT (IRQ_PIC_START+26)
-#define IRQ_CP_ETHINT (IRQ_PIC_START+27)
-#define IRQ_CP_TSPENINT (IRQ_PIC_START+28)
-#define IRQ_PIC_END (IRQ_PIC_START+28)
-
-#define IRQ_CIC_START (IRQ_PIC_END+1)
-#define IRQ_CM_SOFTINT (IRQ_CIC_START+0)
-#define IRQ_CM_COMMRX (IRQ_CIC_START+1)
-#define IRQ_CM_COMMTX (IRQ_CIC_START+2)
-#define IRQ_CIC_END (IRQ_CIC_START+2)
-
-/*
- * IntegratorCP only
- */
-#define IRQ_SIC_START (IRQ_CIC_END+1)
-#define IRQ_SIC_CP_SOFTINT (IRQ_SIC_START+0)
-#define IRQ_SIC_CP_RI0 (IRQ_SIC_START+1)
-#define IRQ_SIC_CP_RI1 (IRQ_SIC_START+2)
-#define IRQ_SIC_CP_CARDIN (IRQ_SIC_START+3)
-#define IRQ_SIC_CP_LMINT0 (IRQ_SIC_START+4)
-#define IRQ_SIC_CP_LMINT1 (IRQ_SIC_START+5)
-#define IRQ_SIC_CP_LMINT2 (IRQ_SIC_START+6)
-#define IRQ_SIC_CP_LMINT3 (IRQ_SIC_START+7)
-#define IRQ_SIC_CP_LMINT4 (IRQ_SIC_START+8)
-#define IRQ_SIC_CP_LMINT5 (IRQ_SIC_START+9)
-#define IRQ_SIC_CP_LMINT6 (IRQ_SIC_START+10)
-#define IRQ_SIC_CP_LMINT7 (IRQ_SIC_START+11)
-#define IRQ_SIC_END (IRQ_SIC_START+11)
diff --git a/arch/arm/mach-integrator/include/mach/timex.h b/arch/arm/mach-integrator/include/mach/timex.h
deleted file mode 100644
index 1dcb42028c8..00000000000
--- a/arch/arm/mach-integrator/include/mach/timex.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-integrator/include/mach/timex.h
- *
- * Integrator architecture timex specifications
- *
- * Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * ??
- */
-#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/arch/arm/mach-integrator/include/mach/uncompress.h b/arch/arm/mach-integrator/include/mach/uncompress.h
index 30452f00a16..8f3cc9954c1 100644
--- a/arch/arm/mach-integrator/include/mach/uncompress.h
+++ b/arch/arm/mach-integrator/include/mach/uncompress.h
@@ -46,5 +46,3 @@ static inline void flush(void)
* nothing to do
*/
#define arch_decomp_setup()
-
-#define arch_decomp_wdog()
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 11e2a414580..660ca6feff4 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -41,29 +41,30 @@
#include <linux/stat.h>
#include <linux/sys_soc.h>
#include <linux/termios.h>
-#include <video/vga.h>
+#include <linux/sched_clock.h>
+#include <linux/clk-provider.h>
-#include <mach/hardware.h>
-#include <mach/platform.h>
#include <asm/hardware/arm_timer.h>
#include <asm/setup.h>
#include <asm/param.h> /* HZ */
#include <asm/mach-types.h>
-#include <asm/sched_clock.h>
-
-#include <mach/lm.h>
-#include <mach/irqs.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
-#include <asm/mach/pci.h>
#include <asm/mach/time.h>
+#include "hardware.h"
+#include "cm.h"
#include "common.h"
+#include "pci_v3.h"
+#include "lm.h"
/* Base address to the AP system controller */
void __iomem *ap_syscon_base;
+/* Base address to the external bus interface */
+static void __iomem *ebi_base;
+
/*
* All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
@@ -73,19 +74,11 @@ void __iomem *ap_syscon_base;
* just for now).
*/
#define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
-#define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
-#define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
/*
* Logical Physical
- * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
- * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
- * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k)
- * fee00000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
* ef000000 Cache flush
- * f1000000 10000000 Core module registers
* f1100000 11000000 System controller registers
- * f1200000 12000000 EBI registers
* f1300000 13000000 Counter/Timer
* f1400000 14000000 Interrupt controller
* f1600000 16000000 UART 0
@@ -94,18 +87,8 @@ void __iomem *ap_syscon_base;
* f1b00000 1b000000 GPIO
*/
-static struct map_desc ap_io_desc[] __initdata = {
+static struct map_desc ap_io_desc[] __initdata __maybe_unused = {
{
- .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- }, {
- .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- }, {
.virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
.pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
.length = SZ_4K,
@@ -130,29 +113,13 @@ static struct map_desc ap_io_desc[] __initdata = {
.pfn = __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE),
.length = SZ_4K,
.type = MT_DEVICE
- }, {
- .virtual = (unsigned long)PCI_MEMORY_VADDR,
- .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE),
- .length = SZ_16M,
- .type = MT_DEVICE
- }, {
- .virtual = (unsigned long)PCI_CONFIG_VADDR,
- .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
- .length = SZ_16M,
- .type = MT_DEVICE
- }, {
- .virtual = (unsigned long)PCI_V3_VADDR,
- .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE),
- .length = SZ_64K,
- .type = MT_DEVICE
}
};
static void __init ap_map_io(void)
{
iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
- vga_base = (unsigned long)PCI_MEMORY_VADDR;
- pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
+ pci_v3_early_init();
}
#ifdef CONFIG_PM
@@ -167,7 +134,7 @@ static int irq_suspend(void)
static void irq_resume(void)
{
/* disable all irq sources */
- writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+ cm_clear_irqs();
writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
@@ -195,9 +162,6 @@ device_initcall(irq_syscore_init);
/*
* Flash handling.
*/
-#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
-#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
-
static int ap_flash_init(struct platform_device *dev)
{
u32 tmp;
@@ -205,13 +169,15 @@ static int ap_flash_init(struct platform_device *dev)
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
- tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
- writel(tmp, EBI_CSR1);
+ tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) |
+ INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
- if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
- writel(0xa05f, EBI_LOCK);
- writel(tmp, EBI_CSR1);
- writel(0, EBI_LOCK);
+ if (!(readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET)
+ & INTEGRATOR_EBI_WRITE_ENABLE)) {
+ writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+ writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
}
return 0;
}
@@ -223,13 +189,15 @@ static void ap_flash_exit(struct platform_device *dev)
writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
- tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
- writel(tmp, EBI_CSR1);
+ tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) &
+ ~INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
- if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
- writel(0xa05f, EBI_LOCK);
- writel(tmp, EBI_CSR1);
- writel(0, EBI_LOCK);
+ if (readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) &
+ INTEGRATOR_EBI_WRITE_ENABLE) {
+ writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
+ writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET);
+ writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET);
}
}
@@ -298,7 +266,7 @@ struct amba_pl010_data ap_uart_data = {
static unsigned long timer_reload;
-static u32 notrace integrator_read_sched_clock(void)
+static u64 notrace integrator_read_sched_clock(void)
{
return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
}
@@ -319,7 +287,7 @@ static void integrator_clocksource_init(unsigned long inrate,
clocksource_mmio_init(base + TIMER_VALUE, "timer2",
rate, 200, 16, clocksource_mmio_readl_down);
- setup_sched_clock(integrator_read_sched_clock, 16, rate);
+ sched_clock_register(integrator_read_sched_clock, 16, rate);
}
static void __iomem * clkevt_base;
@@ -389,7 +357,7 @@ static struct clock_event_device integrator_clockevent = {
static struct irqaction integrator_timer_irq = {
.name = "timer",
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = integrator_timer_interrupt,
.dev_id = &integrator_clockevent,
};
@@ -423,9 +391,7 @@ void __init ap_init_early(void)
{
}
-#ifdef CONFIG_OF
-
-static void __init ap_init_timer_of(void)
+static void __init ap_of_timer_init(void)
{
struct device_node *node;
const char *path;
@@ -435,10 +401,7 @@ static void __init ap_init_timer_of(void)
struct clk *clk;
unsigned long rate;
- clk = clk_get_sys("ap_timer", NULL);
- BUG_ON(IS_ERR(clk));
- clk_prepare_enable(clk);
- rate = clk_get_rate(clk);
+ of_clk_init(NULL);
err = of_property_read_string(of_aliases,
"arm,timer-primary", &path);
@@ -448,6 +411,12 @@ static void __init ap_init_timer_of(void)
base = of_iomap(node, 0);
if (WARN_ON(!base))
return;
+
+ clk = of_clk_get(node, 0);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
writel(0, base + TIMER_CTRL);
integrator_clocksource_init(rate, base);
@@ -460,14 +429,16 @@ static void __init ap_init_timer_of(void)
if (WARN_ON(!base))
return;
irq = irq_of_parse_and_map(node, 0);
+
+ clk = of_clk_get(node, 0);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
writel(0, base + TIMER_CTRL);
integrator_clockevent_init(rate, base, irq);
}
-static struct sys_timer ap_of_timer = {
- .init = ap_init_timer_of,
-};
-
static const struct of_device_id fpga_irq_of_match[] __initconst = {
{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
{ /* Sentinel */ }
@@ -475,10 +446,8 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = {
static void __init ap_init_irq_of(void)
{
- /* disable core module IRQs */
- writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+ cm_init();
of_irq_init(fpga_irq_of_match);
- integrator_clk_init(false);
}
/* For the Device Tree, add in the UART callbacks as AUXDATA */
@@ -498,29 +467,43 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
{ /* sentinel */ },
};
+static const struct of_device_id ap_syscon_match[] = {
+ { .compatible = "arm,integrator-ap-syscon"},
+ { },
+};
+
+static const struct of_device_id ebi_match[] = {
+ { .compatible = "arm,external-bus-interface"},
+ { },
+};
+
static void __init ap_init_of(void)
{
unsigned long sc_dec;
- struct device_node *root;
struct device_node *syscon;
+ struct device_node *ebi;
struct device *parent;
struct soc_device *soc_dev;
struct soc_device_attribute *soc_dev_attr;
u32 ap_sc_id;
- int err;
int i;
- /* Here we create an SoC device for the root node */
- root = of_find_node_by_path("/");
- if (!root)
- return;
- syscon = of_find_node_by_path("/syscon");
+ syscon = of_find_matching_node(NULL, ap_syscon_match);
if (!syscon)
return;
+ ebi = of_find_matching_node(NULL, ebi_match);
+ if (!ebi)
+ return;
ap_syscon_base = of_iomap(syscon, 0);
if (!ap_syscon_base)
return;
+ ebi_base = of_iomap(ebi, 0);
+ if (!ebi_base)
+ return;
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ ap_auxdata_lookup, NULL);
ap_sc_id = readl(ap_syscon_base);
@@ -528,31 +511,21 @@ static void __init ap_init_of(void)
if (!soc_dev_attr)
return;
- err = of_property_read_string(root, "compatible",
- &soc_dev_attr->soc_id);
- if (err)
- return;
- err = of_property_read_string(root, "model", &soc_dev_attr->machine);
- if (err)
- return;
+ soc_dev_attr->soc_id = "XVC";
+ soc_dev_attr->machine = "Integrator/AP";
soc_dev_attr->family = "Integrator";
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
'A' + (ap_sc_id & 0x0f));
soc_dev = soc_device_register(soc_dev_attr);
- if (IS_ERR_OR_NULL(soc_dev)) {
+ if (IS_ERR(soc_dev)) {
kfree(soc_dev_attr->revision);
kfree(soc_dev_attr);
return;
}
parent = soc_device_to_device(soc_dev);
-
- if (!IS_ERR_OR_NULL(parent))
- integrator_init_sysfs(parent, ap_sc_id);
-
- of_platform_populate(root, of_default_bus_match_table,
- ap_auxdata_lookup, parent);
+ integrator_init_sysfs(parent, ap_sc_id);
sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
for (i = 0; i < 4; i++) {
@@ -568,7 +541,7 @@ static void __init ap_init_of(void)
lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
lmdev->resource.flags = IORESOURCE_MEM;
- lmdev->irq = IRQ_AP_EXPINT0 + i;
+ lmdev->irq = irq_of_parse_and_map(syscon, i);
lmdev->id = i;
lm_device_register(lmdev);
@@ -586,139 +559,8 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
.init_early = ap_init_early,
.init_irq = ap_init_irq_of,
.handle_irq = fpga_handle_irq,
- .timer = &ap_of_timer,
+ .init_time = ap_of_timer_init,
.init_machine = ap_init_of,
.restart = integrator_restart,
.dt_compat = ap_dt_board_compat,
MACHINE_END
-
-#endif
-
-#ifdef CONFIG_ATAGS
-
-/*
- * For the ATAG boot some static mappings are needed. This will
- * go away with the ATAG support down the road.
- */
-
-static struct map_desc ap_io_desc_atag[] __initdata = {
- {
- .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- },
-};
-
-static void __init ap_map_io_atag(void)
-{
- iotable_init(ap_io_desc_atag, ARRAY_SIZE(ap_io_desc_atag));
- ap_syscon_base = __io_address(INTEGRATOR_SC_BASE);
- ap_map_io();
-}
-
-/*
- * This is where non-devicetree initialization code is collected and stashed
- * for eventual deletion.
- */
-
-static struct resource cfi_flash_resource = {
- .start = INTEGRATOR_FLASH_BASE,
- .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device cfi_flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &ap_flash_data,
- },
- .num_resources = 1,
- .resource = &cfi_flash_resource,
-};
-
-static void __init ap_init_timer(void)
-{
- struct clk *clk;
- unsigned long rate;
-
- clk = clk_get_sys("ap_timer", NULL);
- BUG_ON(IS_ERR(clk));
- clk_prepare_enable(clk);
- rate = clk_get_rate(clk);
-
- writel(0, TIMER0_VA_BASE + TIMER_CTRL);
- writel(0, TIMER1_VA_BASE + TIMER_CTRL);
- writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
- integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
- integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
- IRQ_TIMERINT1);
-}
-
-static struct sys_timer ap_timer = {
- .init = ap_init_timer,
-};
-
-#define INTEGRATOR_SC_VALID_INT 0x003fffff
-
-static void __init ap_init_irq(void)
-{
- /* Disable all interrupts initially. */
- /* Do the core module ones */
- writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
-
- /* do the header card stuff next */
- writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
- writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
-
- fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
- -1, INTEGRATOR_SC_VALID_INT, NULL);
- integrator_clk_init(false);
-}
-
-static void __init ap_init(void)
-{
- unsigned long sc_dec;
- int i;
-
- platform_device_register(&cfi_flash_device);
-
- sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
- for (i = 0; i < 4; i++) {
- struct lm_device *lmdev;
-
- if ((sc_dec & (16 << i)) == 0)
- continue;
-
- lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
- if (!lmdev)
- continue;
-
- lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
- lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
- lmdev->resource.flags = IORESOURCE_MEM;
- lmdev->irq = IRQ_AP_EXPINT0 + i;
- lmdev->id = i;
-
- lm_device_register(lmdev);
- }
-
- integrator_init(false);
-}
-
-MACHINE_START(INTEGRATOR, "ARM-Integrator")
- /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .atag_offset = 0x100,
- .reserve = integrator_reserve,
- .map_io = ap_map_io_atag,
- .init_early = ap_init_early,
- .init_irq = ap_init_irq,
- .handle_irq = fpga_handle_irq,
- .timer = &ap_timer,
- .init_machine = ap_init,
- .restart = integrator_restart,
-MACHINE_END
-
-#endif
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 7322838c044..0e57f8f820a 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -23,33 +23,23 @@
#include <linux/irqchip/versatile-fpga.h>
#include <linux/gfp.h>
#include <linux/mtd/physmap.h>
-#include <linux/platform_data/clk-integrator.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/sys_soc.h>
+#include <linux/sched_clock.h>
-#include <mach/hardware.h>
-#include <mach/platform.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst.h>
-
-#include <mach/cm.h>
-#include <mach/lm.h>
-#include <mach/irqs.h>
-
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <asm/hardware/timer-sp.h>
-
#include <plat/clcd.h>
-#include <plat/sched_clock.h>
+#include "hardware.h"
+#include "cm.h"
#include "common.h"
/* Base address to the CP controller */
@@ -66,8 +56,6 @@ static void __iomem *intcp_con_base;
/*
* Logical Physical
* f1000000 10000000 Core module registers
- * f1100000 11000000 System controller registers
- * f1200000 12000000 EBI registers
* f1300000 13000000 Counter/Timer
* f1400000 14000000 Interrupt controller
* f1600000 16000000 UART 0
@@ -75,21 +63,15 @@ static void __iomem *intcp_con_base;
* f1a00000 1a000000 Debug LEDs
* fc900000 c9000000 GPIO
* fca00000 ca000000 SIC
- * fcb00000 cb000000 CP system control
*/
-static struct map_desc intcp_io_desc[] __initdata = {
+static struct map_desc intcp_io_desc[] __initdata __maybe_unused = {
{
.virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
.pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
.length = SZ_4K,
.type = MT_DEVICE
}, {
- .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- }, {
.virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
.pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
.length = SZ_4K,
@@ -199,7 +181,8 @@ static struct mmci_platform_data mmc_data = {
static void cp_clcd_enable(struct clcd_fb *fb)
{
struct fb_var_screeninfo *var = &fb->fb.var;
- u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
+ u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2
+ | CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1;
if (var->bits_per_pixel <= 8 ||
(var->bits_per_pixel == 16 && var->green.length == 5))
@@ -242,51 +225,16 @@ static struct clcd_board clcd_data = {
#define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
-static void __init intcp_init_early(void)
+static u64 notrace intcp_read_sched_clock(void)
{
-#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
- versatile_sched_clock_init(REFCOUNTER, 24000000);
-#endif
+ return readl(REFCOUNTER);
}
-#ifdef CONFIG_OF
-
-static void __init intcp_timer_init_of(void)
+static void __init intcp_init_early(void)
{
- struct device_node *node;
- const char *path;
- void __iomem *base;
- int err;
- int irq;
-
- err = of_property_read_string(of_aliases,
- "arm,timer-primary", &path);
- if (WARN_ON(err))
- return;
- node = of_find_node_by_path(path);
- base = of_iomap(node, 0);
- if (WARN_ON(!base))
- return;
- writel(0, base + TIMER_CTRL);
- sp804_clocksource_init(base, node->name);
-
- err = of_property_read_string(of_aliases,
- "arm,timer-secondary", &path);
- if (WARN_ON(err))
- return;
- node = of_find_node_by_path(path);
- base = of_iomap(node, 0);
- if (WARN_ON(!base))
- return;
- irq = irq_of_parse_and_map(node, 0);
- writel(0, base + TIMER_CTRL);
- sp804_clockevents_init(base, irq, node->name);
+ sched_clock_register(intcp_read_sched_clock, 32, 24000000);
}
-static struct sys_timer cp_of_timer = {
- .init = intcp_timer_init_of,
-};
-
static const struct of_device_id fpga_irq_of_match[] __initconst = {
{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
{ /* Sentinel */ }
@@ -294,8 +242,8 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = {
static void __init intcp_init_irq_of(void)
{
+ cm_init();
of_irq_init(fpga_irq_of_match);
- integrator_clk_init(true);
}
/*
@@ -324,21 +272,20 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
{ /* 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 *root;
struct device_node *cpcon;
struct device *parent;
struct soc_device *soc_dev;
struct soc_device_attribute *soc_dev_attr;
u32 intcp_sc_id;
- int err;
- /* Here we create an SoC device for the root node */
- root = of_find_node_by_path("/");
- if (!root)
- return;
- cpcon = of_find_node_by_path("/cpcon");
+ cpcon = of_find_matching_node(NULL, intcp_syscon_match);
if (!cpcon)
return;
@@ -346,37 +293,30 @@ static void __init intcp_init_of(void)
if (!intcp_con_base)
return;
+ of_platform_populate(NULL, of_default_bus_match_table,
+ intcp_auxdata_lookup, NULL);
+
intcp_sc_id = readl(intcp_con_base);
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
if (!soc_dev_attr)
return;
- err = of_property_read_string(root, "compatible",
- &soc_dev_attr->soc_id);
- if (err)
- return;
- err = of_property_read_string(root, "model", &soc_dev_attr->machine);
- if (err)
- return;
+ soc_dev_attr->soc_id = "XCV";
+ soc_dev_attr->machine = "Integrator/CP";
soc_dev_attr->family = "Integrator";
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
'A' + (intcp_sc_id & 0x0f));
soc_dev = soc_device_register(soc_dev_attr);
- if (IS_ERR_OR_NULL(soc_dev)) {
+ if (IS_ERR(soc_dev)) {
kfree(soc_dev_attr->revision);
kfree(soc_dev_attr);
return;
}
parent = soc_device_to_device(soc_dev);
-
- if (!IS_ERR_OR_NULL(parent))
- integrator_init_sysfs(parent, intcp_sc_id);
-
- of_platform_populate(root, of_default_bus_match_table,
- intcp_auxdata_lookup, parent);
+ integrator_init_sysfs(parent, intcp_sc_id);
}
static const char * intcp_dt_board_compat[] = {
@@ -390,184 +330,7 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
.init_early = intcp_init_early,
.init_irq = intcp_init_irq_of,
.handle_irq = fpga_handle_irq,
- .timer = &cp_of_timer,
.init_machine = intcp_init_of,
.restart = integrator_restart,
.dt_compat = intcp_dt_board_compat,
MACHINE_END
-
-#endif
-
-#ifdef CONFIG_ATAGS
-
-/*
- * For the ATAG boot some static mappings are needed. This will
- * go away with the ATAG support down the road.
- */
-
-static struct map_desc intcp_io_desc_atag[] __initdata = {
- {
- .virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
- .pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE
- },
-};
-
-static void __init intcp_map_io_atag(void)
-{
- iotable_init(intcp_io_desc_atag, ARRAY_SIZE(intcp_io_desc_atag));
- intcp_con_base = __io_address(INTEGRATOR_CP_CTL_BASE);
- intcp_map_io();
-}
-
-
-/*
- * This is where non-devicetree initialization code is collected and stashed
- * for eventual deletion.
- */
-
-#define INTCP_FLASH_SIZE SZ_32M
-
-static struct resource intcp_flash_resource = {
- .start = INTCP_PA_FLASH_BASE,
- .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device intcp_flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &intcp_flash_data,
- },
- .num_resources = 1,
- .resource = &intcp_flash_resource,
-};
-
-#define INTCP_ETH_SIZE 0x10
-
-static struct resource smc91x_resources[] = {
- [0] = {
- .start = INTEGRATOR_CP_ETH_BASE,
- .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_CP_ETHINT,
- .end = IRQ_CP_ETHINT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device smc91x_device = {
- .name = "smc91x",
- .id = 0,
- .num_resources = ARRAY_SIZE(smc91x_resources),
- .resource = smc91x_resources,
-};
-
-static struct platform_device *intcp_devs[] __initdata = {
- &intcp_flash_device,
- &smc91x_device,
-};
-
-#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
-#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
-#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
-
-static void __init intcp_init_irq(void)
-{
- u32 pic_mask, cic_mask, sic_mask;
-
- /* These masks are for the HW IRQ registers */
- pic_mask = ~((~0u) << (11 - 0));
- pic_mask |= (~((~0u) << (29 - 22))) << 22;
- cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
- sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
-
- /*
- * Disable all interrupt sources
- */
- writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
- writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
- writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
- writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
- writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
- writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
-
- fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
- -1, pic_mask, NULL);
-
- fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
- -1, cic_mask, NULL);
-
- fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
- IRQ_CP_CPPLDINT, sic_mask, NULL);
-
- integrator_clk_init(true);
-}
-
-#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
-#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
-#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
-
-static void __init intcp_timer_init(void)
-{
- writel(0, TIMER0_VA_BASE + TIMER_CTRL);
- writel(0, TIMER1_VA_BASE + TIMER_CTRL);
- writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
- sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
- sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
-}
-
-static struct sys_timer cp_timer = {
- .init = intcp_timer_init,
-};
-
-#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
-#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT }
-
-static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
- INTEGRATOR_CP_MMC_IRQS, &mmc_data);
-
-static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE,
- INTEGRATOR_CP_AACI_IRQS, NULL);
-
-static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
- { IRQ_CP_CLCDCINT }, &clcd_data);
-
-static struct amba_device *amba_devs[] __initdata = {
- &mmc_device,
- &aaci_device,
- &clcd_device,
-};
-
-static void __init intcp_init(void)
-{
- int i;
-
- platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
-
- for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
- struct amba_device *d = amba_devs[i];
- amba_device_register(d, &iomem_resource);
- }
- integrator_init(true);
-}
-
-MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
- /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .atag_offset = 0x100,
- .reserve = integrator_reserve,
- .map_io = intcp_map_io_atag,
- .init_early = intcp_init_early,
- .init_irq = intcp_init_irq,
- .handle_irq = fpga_handle_irq,
- .timer = &cp_timer,
- .init_machine = intcp_init,
- .restart = integrator_restart,
-MACHINE_END
-
-#endif
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
index 7a7f6d3273b..f1dcb57a59e 100644
--- a/arch/arm/mach-integrator/leds.c
+++ b/arch/arm/mach-integrator/leds.c
@@ -11,9 +11,8 @@
#include <linux/slab.h>
#include <linux/leds.h>
-#include <mach/cm.h>
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include "hardware.h"
+#include "cm.h"
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
@@ -78,7 +77,7 @@ static void cm_led_set(struct led_classdev *cdev,
static enum led_brightness cm_led_get(struct led_classdev *cdev)
{
- u32 reg = readl(CM_CTRL);
+ u32 reg = cm_get();
return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
}
diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
index f52c7af31ea..3f9e9f04316 100644
--- a/arch/arm/mach-integrator/lm.c
+++ b/arch/arm/mach-integrator/lm.c
@@ -12,7 +12,7 @@
#include <linux/device.h>
#include <linux/slab.h>
-#include <mach/lm.h>
+#include "lm.h"
#define to_lm_device(d) container_of(d, struct lm_device, dev)
#define to_lm_driver(d) container_of(d, struct lm_driver, drv)
diff --git a/arch/arm/mach-integrator/include/mach/lm.h b/arch/arm/mach-integrator/lm.h
index 28186b6f2c0..28186b6f2c0 100644
--- a/arch/arm/mach-integrator/include/mach/lm.h
+++ b/arch/arm/mach-integrator/lm.h
diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
deleted file mode 100644
index 6c1667e728f..00000000000
--- a/arch/arm/mach-integrator/pci.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * linux/arch/arm/mach-integrator/pci-integrator.c
- *
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * PCI functions for Integrator
- */
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-#include <mach/irqs.h>
-
-/*
- * A small note about bridges and interrupts. The DECchip 21050 (and
- * later) adheres to the PCI-PCI bridge specification. This says that
- * the interrupts on the other side of a bridge are swizzled in the
- * following manner:
- *
- * Dev Interrupt Interrupt
- * Pin on Pin on
- * Device Connector
- *
- * 4 A A
- * B B
- * C C
- * D D
- *
- * 5 A B
- * B C
- * C D
- * D A
- *
- * 6 A C
- * B D
- * C A
- * D B
- *
- * 7 A D
- * B A
- * C B
- * D C
- *
- * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
- * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
- */
-
-/*
- * This routine handles multiple bridges.
- */
-static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp)
-{
- if (*pinp == 0)
- *pinp = 1;
-
- return pci_common_swizzle(dev, pinp);
-}
-
-static int irq_tab[4] __initdata = {
- IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3
-};
-
-/*
- * map the specified device/slot/pin to an IRQ. This works out such
- * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
- */
-static int __init integrator_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- int intnr = ((slot - 9) + (pin - 1)) & 3;
-
- return irq_tab[intnr];
-}
-
-extern void pci_v3_init(void *);
-
-static struct hw_pci integrator_pci __initdata = {
- .swizzle = integrator_swizzle,
- .map_irq = integrator_map_irq,
- .setup = pci_v3_setup,
- .nr_controllers = 1,
- .ops = &pci_v3_ops,
- .preinit = pci_v3_preinit,
- .postinit = pci_v3_postinit,
-};
-
-static int __init integrator_pci_init(void)
-{
- if (machine_is_integrator())
- pci_common_init(&integrator_pci);
- return 0;
-}
-
-subsys_initcall(integrator_pci_init);
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index e7fcea7f330..05e1f73a1e8 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -27,16 +27,196 @@
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include <mach/irqs.h>
-
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <video/vga.h>
+
+#include <asm/mach/map.h>
#include <asm/signal.h>
#include <asm/mach/pci.h>
#include <asm/irq_regs.h>
-#include <asm/hardware/pci_v3.h>
+#include "pci_v3.h"
+#include "hardware.h"
+
+/*
+ * Where in the memory map does PCI live?
+ *
+ * This represents a fairly liberal usage of address space. Even though
+ * the V3 only has two windows (therefore we need to map stuff on the fly),
+ * we maintain the same addresses, even if they're not mapped.
+ */
+#define PHYS_PCI_MEM_BASE 0x40000000 /* 256M */
+#define PHYS_PCI_PRE_BASE 0x50000000 /* 256M */
+#define PHYS_PCI_IO_BASE 0x60000000 /* 16M */
+#define PHYS_PCI_CONFIG_BASE 0x61000000 /* 16M */
+#define PHYS_PCI_V3_BASE 0x62000000 /* 64K */
+
+#define PCI_MEMORY_VADDR IOMEM(0xe8000000)
+#define PCI_CONFIG_VADDR IOMEM(0xec000000)
+
+/*
+ * V3 Local Bus to PCI Bridge definitions
+ *
+ * Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04
+ * All V3 register names are prefaced by V3_ to avoid clashing with any other
+ * PCI definitions. Their names match the user's manual.
+ *
+ * I'm assuming that I20 is disabled.
+ *
+ */
+#define V3_PCI_VENDOR 0x00000000
+#define V3_PCI_DEVICE 0x00000002
+#define V3_PCI_CMD 0x00000004
+#define V3_PCI_STAT 0x00000006
+#define V3_PCI_CC_REV 0x00000008
+#define V3_PCI_HDR_CFG 0x0000000C
+#define V3_PCI_IO_BASE 0x00000010
+#define V3_PCI_BASE0 0x00000014
+#define V3_PCI_BASE1 0x00000018
+#define V3_PCI_SUB_VENDOR 0x0000002C
+#define V3_PCI_SUB_ID 0x0000002E
+#define V3_PCI_ROM 0x00000030
+#define V3_PCI_BPARAM 0x0000003C
+#define V3_PCI_MAP0 0x00000040
+#define V3_PCI_MAP1 0x00000044
+#define V3_PCI_INT_STAT 0x00000048
+#define V3_PCI_INT_CFG 0x0000004C
+#define V3_LB_BASE0 0x00000054
+#define V3_LB_BASE1 0x00000058
+#define V3_LB_MAP0 0x0000005E
+#define V3_LB_MAP1 0x00000062
+#define V3_LB_BASE2 0x00000064
+#define V3_LB_MAP2 0x00000066
+#define V3_LB_SIZE 0x00000068
+#define V3_LB_IO_BASE 0x0000006E
+#define V3_FIFO_CFG 0x00000070
+#define V3_FIFO_PRIORITY 0x00000072
+#define V3_FIFO_STAT 0x00000074
+#define V3_LB_ISTAT 0x00000076
+#define V3_LB_IMASK 0x00000077
+#define V3_SYSTEM 0x00000078
+#define V3_LB_CFG 0x0000007A
+#define V3_PCI_CFG 0x0000007C
+#define V3_DMA_PCI_ADR0 0x00000080
+#define V3_DMA_PCI_ADR1 0x00000090
+#define V3_DMA_LOCAL_ADR0 0x00000084
+#define V3_DMA_LOCAL_ADR1 0x00000094
+#define V3_DMA_LENGTH0 0x00000088
+#define V3_DMA_LENGTH1 0x00000098
+#define V3_DMA_CSR0 0x0000008B
+#define V3_DMA_CSR1 0x0000009B
+#define V3_DMA_CTLB_ADR0 0x0000008C
+#define V3_DMA_CTLB_ADR1 0x0000009C
+#define V3_DMA_DELAY 0x000000E0
+#define V3_MAIL_DATA 0x000000C0
+#define V3_PCI_MAIL_IEWR 0x000000D0
+#define V3_PCI_MAIL_IERD 0x000000D2
+#define V3_LB_MAIL_IEWR 0x000000D4
+#define V3_LB_MAIL_IERD 0x000000D6
+#define V3_MAIL_WR_STAT 0x000000D8
+#define V3_MAIL_RD_STAT 0x000000DA
+#define V3_QBA_MAP 0x000000DC
+
+/* PCI COMMAND REGISTER bits
+ */
+#define V3_COMMAND_M_FBB_EN (1 << 9)
+#define V3_COMMAND_M_SERR_EN (1 << 8)
+#define V3_COMMAND_M_PAR_EN (1 << 6)
+#define V3_COMMAND_M_MASTER_EN (1 << 2)
+#define V3_COMMAND_M_MEM_EN (1 << 1)
+#define V3_COMMAND_M_IO_EN (1 << 0)
+
+/* SYSTEM REGISTER bits
+ */
+#define V3_SYSTEM_M_RST_OUT (1 << 15)
+#define V3_SYSTEM_M_LOCK (1 << 14)
+
+/* PCI_CFG bits
+ */
+#define V3_PCI_CFG_M_I2O_EN (1 << 15)
+#define V3_PCI_CFG_M_IO_REG_DIS (1 << 14)
+#define V3_PCI_CFG_M_IO_DIS (1 << 13)
+#define V3_PCI_CFG_M_EN3V (1 << 12)
+#define V3_PCI_CFG_M_RETRY_EN (1 << 10)
+#define V3_PCI_CFG_M_AD_LOW1 (1 << 9)
+#define V3_PCI_CFG_M_AD_LOW0 (1 << 8)
+
+/* PCI_BASE register bits (PCI -> Local Bus)
+ */
+#define V3_PCI_BASE_M_ADR_BASE 0xFFF00000
+#define V3_PCI_BASE_M_ADR_BASEL 0x000FFF00
+#define V3_PCI_BASE_M_PREFETCH (1 << 3)
+#define V3_PCI_BASE_M_TYPE (3 << 1)
+#define V3_PCI_BASE_M_IO (1 << 0)
+
+/* PCI MAP register bits (PCI -> Local bus)
+ */
+#define V3_PCI_MAP_M_MAP_ADR 0xFFF00000
+#define V3_PCI_MAP_M_RD_POST_INH (1 << 15)
+#define V3_PCI_MAP_M_ROM_SIZE (3 << 10)
+#define V3_PCI_MAP_M_SWAP (3 << 8)
+#define V3_PCI_MAP_M_ADR_SIZE 0x000000F0
+#define V3_PCI_MAP_M_REG_EN (1 << 1)
+#define V3_PCI_MAP_M_ENABLE (1 << 0)
+
+/*
+ * LB_BASE0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_BASE_ADR_BASE 0xfff00000
+#define V3_LB_BASE_SWAP (3 << 8)
+#define V3_LB_BASE_ADR_SIZE (15 << 4)
+#define V3_LB_BASE_PREFETCH (1 << 3)
+#define V3_LB_BASE_ENABLE (1 << 0)
+
+#define V3_LB_BASE_ADR_SIZE_1MB (0 << 4)
+#define V3_LB_BASE_ADR_SIZE_2MB (1 << 4)
+#define V3_LB_BASE_ADR_SIZE_4MB (2 << 4)
+#define V3_LB_BASE_ADR_SIZE_8MB (3 << 4)
+#define V3_LB_BASE_ADR_SIZE_16MB (4 << 4)
+#define V3_LB_BASE_ADR_SIZE_32MB (5 << 4)
+#define V3_LB_BASE_ADR_SIZE_64MB (6 << 4)
+#define V3_LB_BASE_ADR_SIZE_128MB (7 << 4)
+#define V3_LB_BASE_ADR_SIZE_256MB (8 << 4)
+#define V3_LB_BASE_ADR_SIZE_512MB (9 << 4)
+#define V3_LB_BASE_ADR_SIZE_1GB (10 << 4)
+#define V3_LB_BASE_ADR_SIZE_2GB (11 << 4)
+
+#define v3_addr_to_lb_base(a) ((a) & V3_LB_BASE_ADR_BASE)
+
+/*
+ * LB_MAP0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_MAP_MAP_ADR 0xfff0
+#define V3_LB_MAP_TYPE (7 << 1)
+#define V3_LB_MAP_AD_LOW_EN (1 << 0)
+
+#define V3_LB_MAP_TYPE_IACK (0 << 1)
+#define V3_LB_MAP_TYPE_IO (1 << 1)
+#define V3_LB_MAP_TYPE_MEM (3 << 1)
+#define V3_LB_MAP_TYPE_CONFIG (5 << 1)
+#define V3_LB_MAP_TYPE_MEM_MULTIPLE (6 << 1)
+
+#define v3_addr_to_lb_map(a) (((a) >> 16) & V3_LB_MAP_MAP_ADR)
+
+/*
+ * LB_BASE2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_BASE2_ADR_BASE 0xff00
+#define V3_LB_BASE2_SWAP (3 << 6)
+#define V3_LB_BASE2_ENABLE (1 << 0)
+
+#define v3_addr_to_lb_base2(a) (((a) >> 16) & V3_LB_BASE2_ADR_BASE)
+
+/*
+ * LB_MAP2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_MAP2_MAP_ADR 0xff00
+
+#define v3_addr_to_lb_map2(a) (((a) >> 16) & V3_LB_MAP2_MAP_ADR)
/*
* The V3 PCI interface chip in Integrator provides several windows from
@@ -101,15 +281,28 @@
* the mappings into PCI memory.
*/
+/* Filled in by probe */
+static void __iomem *pci_v3_base;
+/* CPU side memory ranges */
+static struct resource conf_mem; /* FIXME: remap this instead of static map */
+static struct resource io_mem;
+static struct resource non_mem;
+static struct resource pre_mem;
+/* PCI side memory ranges */
+static u64 non_mem_pci;
+static u64 non_mem_pci_sz;
+static u64 pre_mem_pci;
+static u64 pre_mem_pci_sz;
+
// V3 access routines
-#define v3_writeb(o,v) __raw_writeb(v, PCI_V3_VADDR + (unsigned int)(o))
-#define v3_readb(o) (__raw_readb(PCI_V3_VADDR + (unsigned int)(o)))
+#define v3_writeb(o,v) __raw_writeb(v, pci_v3_base + (unsigned int)(o))
+#define v3_readb(o) (__raw_readb(pci_v3_base + (unsigned int)(o)))
-#define v3_writew(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o))
-#define v3_readw(o) (__raw_readw(PCI_V3_VADDR + (unsigned int)(o)))
+#define v3_writew(o,v) __raw_writew(v, pci_v3_base + (unsigned int)(o))
+#define v3_readw(o) (__raw_readw(pci_v3_base + (unsigned int)(o)))
-#define v3_writel(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o))
-#define v3_readl(o) (__raw_readl(PCI_V3_VADDR + (unsigned int)(o)))
+#define v3_writel(o,v) __raw_writel(v, pci_v3_base + (unsigned int)(o))
+#define v3_readl(o) (__raw_readl(pci_v3_base + (unsigned int)(o)))
/*============================================================================
*
@@ -165,19 +358,6 @@
*/
static DEFINE_RAW_SPINLOCK(v3_lock);
-#define PCI_BUS_NONMEM_START 0x00000000
-#define PCI_BUS_NONMEM_SIZE SZ_256M
-
-#define PCI_BUS_PREMEM_START PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
-#define PCI_BUS_PREMEM_SIZE SZ_256M
-
-#if PCI_BUS_NONMEM_START & 0x000fffff
-#error PCI_BUS_NONMEM_START must be megabyte aligned
-#endif
-#if PCI_BUS_PREMEM_START & 0x000fffff
-#error PCI_BUS_PREMEM_START must be megabyte aligned
-#endif
-
#undef V3_LB_BASE_PREFETCH
#define V3_LB_BASE_PREFETCH 0
@@ -243,13 +423,13 @@ static void __iomem *v3_open_config_window(struct pci_bus *bus,
* prefetchable), this frees up base1 for re-use by
* configuration memory
*/
- v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) |
V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
/*
* Set up base1/map1 to point into configuration space.
*/
- v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(conf_mem.start) |
V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
v3_writew(V3_LB_MAP1, mapaddress);
@@ -261,16 +441,16 @@ static void v3_close_config_window(void)
/*
* Reassign base1 for use by prefetchable PCI memory
*/
- v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(pre_mem.start) |
V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
V3_LB_BASE_ENABLE);
- v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) |
V3_LB_MAP_TYPE_MEM_MULTIPLE);
/*
* And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
*/
- v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) |
V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
}
@@ -337,25 +517,11 @@ static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
return PCIBIOS_SUCCESSFUL;
}
-struct pci_ops pci_v3_ops = {
+static struct pci_ops pci_v3_ops = {
.read = v3_read_config,
.write = v3_write_config,
};
-static struct resource non_mem = {
- .name = "PCI non-prefetchable",
- .start = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START,
- .end = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct resource pre_mem = {
- .name = "PCI prefetchable",
- .start = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START,
- .end = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
- .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
-};
-
static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
{
if (request_resource(&iomem_resource, &non_mem)) {
@@ -436,7 +602,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
return 1;
}
-static irqreturn_t v3_irq(int dummy, void *devid)
+static irqreturn_t v3_irq(int irq, void *devid)
{
#ifdef CONFIG_DEBUG_LL
struct pt_regs *regs = get_irq_regs();
@@ -446,7 +612,7 @@ static irqreturn_t v3_irq(int dummy, void *devid)
extern void printascii(const char *);
sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
- "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
+ "ISTAT=%02x\n", irq, pc, instr,
__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
v3_readb(V3_LB_ISTAT));
@@ -471,7 +637,7 @@ static irqreturn_t v3_irq(int dummy, void *devid)
return IRQ_HANDLED;
}
-int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
+static int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
{
int ret = 0;
@@ -479,7 +645,7 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
return -EINVAL;
if (nr == 0) {
- sys->mem_offset = PHYS_PCI_MEM_BASE;
+ sys->mem_offset = non_mem.start;
ret = pci_v3_setup_resources(sys);
}
@@ -490,18 +656,10 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
* V3_LB_BASE? - local bus address
* V3_LB_MAP? - pci bus address
*/
-void __init pci_v3_preinit(void)
+static void __init pci_v3_preinit(void)
{
unsigned long flags;
unsigned int temp;
- int ret;
-
- /* Remap the Integrator system controller */
- ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
- if (!ap_syscon_base) {
- pr_err("unable to remap the AP syscon for PCIv3\n");
- return;
- }
pcibios_min_mem = 0x00100000;
@@ -525,25 +683,25 @@ void __init pci_v3_preinit(void)
* Setup window 0 - PCI non-prefetchable memory
* Local: 0x40000000 Bus: 0x00000000 Size: 256MB
*/
- v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) |
V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
- v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(PCI_BUS_NONMEM_START) |
+ v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(non_mem_pci) |
V3_LB_MAP_TYPE_MEM);
/*
* Setup window 1 - PCI prefetchable memory
* Local: 0x50000000 Bus: 0x10000000 Size: 256MB
*/
- v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(pre_mem.start) |
V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
V3_LB_BASE_ENABLE);
- v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) |
V3_LB_MAP_TYPE_MEM_MULTIPLE);
/*
* Setup window 2 - PCI IO
*/
- v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(PHYS_PCI_IO_BASE) |
+ v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
V3_LB_BASE_ENABLE);
v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
@@ -578,18 +736,10 @@ void __init pci_v3_preinit(void)
v3_writeb(V3_LB_IMASK, 0x28);
__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
- /*
- * Grab the PCI error interrupt.
- */
- ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
- if (ret)
- printk(KERN_ERR "PCI: unable to grab PCI error "
- "interrupt: %d\n", ret);
-
raw_spin_unlock_irqrestore(&v3_lock, flags);
}
-void __init pci_v3_postinit(void)
+static void __init pci_v3_postinit(void)
{
unsigned int pci_cmd;
@@ -608,5 +758,194 @@ void __init pci_v3_postinit(void)
"interrupt: %d\n", ret);
#endif
- register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
+ register_isa_ports(non_mem.start, io_mem.start, 0);
+}
+
+/*
+ * A small note about bridges and interrupts. The DECchip 21050 (and
+ * later) adheres to the PCI-PCI bridge specification. This says that
+ * the interrupts on the other side of a bridge are swizzled in the
+ * following manner:
+ *
+ * Dev Interrupt Interrupt
+ * Pin on Pin on
+ * Device Connector
+ *
+ * 4 A A
+ * B B
+ * C C
+ * D D
+ *
+ * 5 A B
+ * B C
+ * C D
+ * D A
+ *
+ * 6 A C
+ * B D
+ * C A
+ * D B
+ *
+ * 7 A D
+ * B A
+ * C B
+ * D C
+ *
+ * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
+ * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
+ */
+
+/*
+ * This routine handles multiple bridges.
+ */
+static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+ if (*pinp == 0)
+ *pinp = 1;
+
+ return pci_common_swizzle(dev, pinp);
+}
+
+static struct hw_pci pci_v3 __initdata = {
+ .swizzle = pci_v3_swizzle,
+ .setup = pci_v3_setup,
+ .nr_controllers = 1,
+ .ops = &pci_v3_ops,
+ .preinit = pci_v3_preinit,
+ .postinit = pci_v3_postinit,
+};
+
+static int __init pci_v3_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct of_pci_range_parser parser;
+ struct of_pci_range range;
+ struct resource *res;
+ int irq, ret;
+
+ /* Remap the Integrator system controller */
+ ap_syscon_base = devm_ioremap(&pdev->dev, INTEGRATOR_SC_BASE, 0x100);
+ if (!ap_syscon_base) {
+ dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
+ return -ENODEV;
+ }
+
+ /* Device tree probe path */
+ if (!np) {
+ dev_err(&pdev->dev, "no device tree node for PCIv3\n");
+ return -ENODEV;
+ }
+
+ if (of_pci_range_parser_init(&parser, np))
+ return -EINVAL;
+
+ /* Get base for bridge registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "unable to obtain PCIv3 base\n");
+ return -ENODEV;
+ }
+ pci_v3_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!pci_v3_base) {
+ dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
+ return -ENODEV;
+ }
+
+ /* Get and request error IRQ resource */
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(&pdev->dev, "unable to obtain PCIv3 error IRQ\n");
+ return -ENODEV;
+ }
+ ret = devm_request_irq(&pdev->dev, irq, v3_irq, 0,
+ "PCIv3 error", NULL);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "unable to request PCIv3 error IRQ %d (%d)\n", irq, ret);
+ return ret;
+ }
+
+ for_each_of_pci_range(&parser, &range) {
+ if (!range.flags) {
+ of_pci_range_to_resource(&range, np, &conf_mem);
+ conf_mem.name = "PCIv3 config";
+ }
+ if (range.flags & IORESOURCE_IO) {
+ of_pci_range_to_resource(&range, np, &io_mem);
+ io_mem.name = "PCIv3 I/O";
+ }
+ if ((range.flags & IORESOURCE_MEM) &&
+ !(range.flags & IORESOURCE_PREFETCH)) {
+ non_mem_pci = range.pci_addr;
+ non_mem_pci_sz = range.size;
+ of_pci_range_to_resource(&range, np, &non_mem);
+ non_mem.name = "PCIv3 non-prefetched mem";
+ }
+ if ((range.flags & IORESOURCE_MEM) &&
+ (range.flags & IORESOURCE_PREFETCH)) {
+ pre_mem_pci = range.pci_addr;
+ pre_mem_pci_sz = range.size;
+ of_pci_range_to_resource(&range, np, &pre_mem);
+ pre_mem.name = "PCIv3 prefetched mem";
+ }
+ }
+
+ if (!conf_mem.start || !io_mem.start ||
+ !non_mem.start || !pre_mem.start) {
+ dev_err(&pdev->dev, "missing ranges in device node\n");
+ return -EINVAL;
+ }
+
+ pci_v3.map_irq = of_irq_parse_and_map_pci;
+ pci_common_init_dev(&pdev->dev, &pci_v3);
+
+ return 0;
+}
+
+static const struct of_device_id pci_ids[] = {
+ { .compatible = "v3,v360epc-pci", },
+ {},
+};
+
+static struct platform_driver pci_v3_driver = {
+ .driver = {
+ .name = "pci-v3",
+ .of_match_table = pci_ids,
+ },
+};
+
+static int __init pci_v3_init(void)
+{
+ return platform_driver_probe(&pci_v3_driver, pci_v3_probe);
+}
+
+subsys_initcall(pci_v3_init);
+
+/*
+ * Static mappings for the PCIv3 bridge
+ *
+ * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
+ * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
+ * fee00000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
+ */
+static struct map_desc pci_v3_io_desc[] __initdata __maybe_unused = {
+ {
+ .virtual = (unsigned long)PCI_MEMORY_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)PCI_CONFIG_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }
+};
+
+int __init pci_v3_early_init(void)
+{
+ iotable_init(pci_v3_io_desc, ARRAY_SIZE(pci_v3_io_desc));
+ vga_base = (unsigned long)PCI_MEMORY_VADDR;
+ pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
+ return 0;
}
diff --git a/arch/arm/mach-integrator/pci_v3.h b/arch/arm/mach-integrator/pci_v3.h
new file mode 100644
index 00000000000..06a9e2e7d00
--- /dev/null
+++ b/arch/arm/mach-integrator/pci_v3.h
@@ -0,0 +1,9 @@
+/* Simple oneliner include to the PCIv3 early init */
+#ifdef CONFIG_PCI
+extern int pci_v3_early_init(void);
+#else
+static inline int pci_v3_early_init(void)
+{
+ return 0;
+}
+#endif