[PATCH 02/10] ARM: Add support for IXP4xx CPU

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Mon Apr 23 03:02:11 EDT 2012


From: Krzysztof Hałasa <khc at pm.waw.pl>

Signed-off-by: Krzysztof Hałasa <khc at pm.waw.pl>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 arch/arm/Kconfig                                |    8 +
 arch/arm/Makefile                               |    1 +
 arch/arm/mach-ixp4xx/Kconfig                    |    8 +
 arch/arm/mach-ixp4xx/Makefile                   |    4 +
 arch/arm/mach-ixp4xx/devices.c                  |   60 ++++
 arch/arm/mach-ixp4xx/include/mach/cpu.h         |   70 +++++
 arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h |  365 +++++++++++++++++++++++
 arch/arm/mach-ixp4xx/include/mach/platform.h    |   24 ++
 arch/arm/mach-ixp4xx/lowlevel_init.S            |   25 ++
 arch/arm/mach-ixp4xx/reset.c                    |   15 +
 arch/arm/mach-ixp4xx/timer.c                    |   42 +++
 drivers/serial/serial_ns16550.c                 |    6 +-
 drivers/serial/serial_ns16550.h                 |    2 +
 13 files changed, 629 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-ixp4xx/Kconfig
 create mode 100644 arch/arm/mach-ixp4xx/Makefile
 create mode 100644 arch/arm/mach-ixp4xx/devices.c
 create mode 100644 arch/arm/mach-ixp4xx/include/mach/cpu.h
 create mode 100644 arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
 create mode 100644 arch/arm/mach-ixp4xx/include/mach/platform.h
 create mode 100644 arch/arm/mach-ixp4xx/lowlevel_init.S
 create mode 100644 arch/arm/mach-ixp4xx/reset.c
 create mode 100644 arch/arm/mach-ixp4xx/timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8a4e1a2..2cc3f2d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -49,6 +49,13 @@ config ARCH_MXS
 	bool "Freescale i.MX23/28 (mxs) based"
 	select GENERIC_GPIO
 
+config ARCH_IXP4XX
+	bool "Intel IXP4xx-based"
+	select CPU_XSCALE
+	select ARCH_SUPPORTS_BIG_ENDIAN
+	select CPU_BIG_ENDIAN
+	select ARCH_HAS_LOWLEVEL_INIT
+
 config ARCH_NETX
 	bool "Hilscher NetX based"
 	select CPU_ARM926T
@@ -84,6 +91,7 @@ source arch/arm/mach-at91/Kconfig
 source arch/arm/mach-ep93xx/Kconfig
 source arch/arm/mach-imx/Kconfig
 source arch/arm/mach-mxs/Kconfig
+source arch/arm/mach-ixp4xx/Kconfig
 source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c6444bb..cc5223e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -55,6 +55,7 @@ machine-$(CONFIG_ARCH_AT91)		:= at91
 machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_IMX)		:= imx
 machine-$(CONFIG_ARCH_MXS)		:= mxs
+machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
new file mode 100644
index 0000000..65778ab
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -0,0 +1,8 @@
+if ARCH_IXP4XX
+
+choice
+	prompt "IXP4xx Board Type"
+
+endchoice
+
+endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
new file mode 100644
index 0000000..6e57c91
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -0,0 +1,4 @@
+obj-y += lowlevel_init.o
+obj-y += devices.o
+obj-y += timer.o
+obj-y += reset.o
diff --git a/arch/arm/mach-ixp4xx/devices.c b/arch/arm/mach-ixp4xx/devices.c
new file mode 100644
index 0000000..8a496d1
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/devices.c
@@ -0,0 +1,60 @@
+#include <common.h>
+#include <init.h>
+#include <ns16550.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <mach/ixp4xx-regs.h>
+
+#ifdef CONFIG_DRIVER_SERIAL_NS16550
+/**
+ * @brief UART port register read function for IXP4XX
+ *
+ * @param base base address of UART
+ * @param reg_idx register index
+ *
+ * @return character read from register
+ */
+static unsigned int ixp4xx_uart_read(unsigned long base, unsigned char reg_idx)
+{
+	return readb(reg_idx + REG_OFFSET + (uint8_t *)base);
+}
+
+/**
+ * @brief UART port register write function for IXP4XX
+ *
+ * @param val value to write
+ * @param base base address of UART
+ * @param reg_idx register index
+ *
+ * @return void
+ */
+static void ixp4xx_uart_write(unsigned int val, unsigned long base,
+			      unsigned char reg_idx)
+{
+	writeb(val, reg_idx + REG_OFFSET + (uint8_t *)base);
+}
+
+static struct NS16550_plat serial_plat = {
+	.clock = 14745600,
+	.shift = 2,
+	.reg_read = ixp4xx_uart_read,
+	.reg_write = ixp4xx_uart_write,
+};
+
+/**
+ * @brief UART serial port initialization
+ *
+ * @return result of device registration
+ */
+struct device_d* ixp4xx_add_uart(int id, u32 base)
+{
+	/* Register the serial port */
+	return add_generic_device("serial_ns16550", id, NULL, base, 0xfff,
+			   IORESOURCE_MEM, &serial_plat);
+}
+#else
+struct device_d* ixp4xx_add_uart(int id, u32 base)
+{
+	return NULL;
+}
+#endif /* CONFIG_DRIVER_SERIAL_NS16550 */
diff --git a/arch/arm/mach-ixp4xx/include/mach/cpu.h b/arch/arm/mach-ixp4xx/include/mach/cpu.h
new file mode 100644
index 0000000..3de021e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/cpu.h
+ *
+ * IXP4XX cpu type detection
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_CPU_H__
+#define __ASM_ARCH_CPU_H__
+
+#include <linux/types.h>
+
+/* Processor id value in CP15 Register 0 */
+#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
+#define IXP42X_PROCESSOR_ID_MASK  0xffffffc0
+
+#define IXP43X_PROCESSOR_ID_VALUE 0x69054040
+#define IXP43X_PROCESSOR_ID_MASK  0xfffffff0
+
+#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
+#define IXP46X_PROCESSOR_ID_MASK  0xfffffff0
+
+#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \
+				IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
+			 IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
+			 IXP43X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
+			 IXP46X_PROCESSOR_ID_VALUE)
+
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant.  Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline u32 __attribute_const__ read_cpuid_id(void)
+{
+	u32 val;
+	asm("mrc p15, 0, %0, c0, c0, 0" : "=r" (val) : : "cc");
+
+	return val;
+}
+
+static inline u32 ixp4xx_read_feature_bits(void)
+{
+	u32 val = ~IXP4XX_EXP_CFG2;
+
+	if (cpu_is_ixp42x_rev_a0())
+		return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
+					       IXP4XX_FEATURE_AES);
+	if (cpu_is_ixp42x())
+		return val & IXP42X_FEATURE_MASK;
+	if (cpu_is_ixp43x())
+		return val & IXP43X_FEATURE_MASK;
+	return val & IXP46X_FEATURE_MASK;
+}
+
+static inline void ixp4xx_write_feature_bits(u32 value)
+{
+	IXP4XX_EXP_CFG2 = ~value;
+}
+
+#endif  /* _ASM_ARCH_CPU_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
new file mode 100644
index 0000000..da4dc8a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -0,0 +1,365 @@
+/*
+ * Register definitions for IXP4xx chipset.
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _ASM_ARM_IXP4XX_H_
+#define _ASM_ARM_IXP4XX_H_
+
+#ifdef __ASSEMBLER__
+#define IXP4XX_REG(reg)  (reg)
+#else
+#define IXP4XX_REG(reg)  (*(volatile u32 *)(reg))
+#define IXP4XX_BASE(reg) ((u32*)(reg))
+#endif
+
+/* Expansion Bus region */
+
+/* Queue Manager */
+#define IXP4XX_QMGR_BASE              (0x60000000)
+#define IXP4XX_QMGR_REGION_SIZE       (0x00004000)
+
+
+/* PCI Config registers */
+#define IXP4XX_PCI_CFG_BASE           (0xC0000000)
+#define IXP4XX_PCI_CFG_REGION_SIZE    (0x00001000)
+
+/* Peripheral space */
+#define IXP4XX_PERIPHERAL_BASE        (0xC8000000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
+
+/*
+ * Debug UART
+ *
+ * This is basically a remap of UART1 into a region that is section
+ * aligned so that it can be used with the low-level debug code.
+ */
+#define IXP4XX_DEBUG_UART_BASE        (0xC8000000)
+#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
+
+/* Expansion Bus Controller registers. */
+#define IXP4XX_EXP_CS0       IXP4XX_REG(0xC4000000)
+#define IXP4XX_EXP_CS1       IXP4XX_REG(0xC4000004)
+#define IXP4XX_EXP_CS2       IXP4XX_REG(0xC4000008)
+#define IXP4XX_EXP_CS3       IXP4XX_REG(0xC400000C)
+#define IXP4XX_EXP_CS4       IXP4XX_REG(0xC4000010)
+#define IXP4XX_EXP_CS5       IXP4XX_REG(0xC4000014)
+#define IXP4XX_EXP_CS6       IXP4XX_REG(0xC4000018)
+#define IXP4XX_EXP_CS7       IXP4XX_REG(0xC400001C)
+
+#define IXP4XX_EXP_BASE(n)  (0x50000000 + (n) * 1000000)
+
+#define IXP4XX_EXP_EN        0x80000000
+#define IXP4XX_EXP_T1(n)    (0x10000000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T2(n)    (0x04000000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T3(n)    (0x00400000 * (n)) /* valid: 0 - 15 */
+#define IXP4XX_EXP_T4(n)    (0x00100000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T5(n)    (0x00010000 * (n)) /* valid: 0 - 15 */
+#define IXP4XX_EXP_INTEL     0x00000000
+#define IXP4XX_EXP_MOTO      0x00004000
+#define IXP4XX_EXP_HPI       0x00008000
+#define IXP4XX_EXP_BITS(n)  (0x00000400 * ((n) - 9)) /* valid: 9 - 24 */
+#define IXP4XX_EXP_BYTE_RD16 0x00000040
+#define IXP4XX_EXP_HRDY_POL  0x00000020
+#define IXP4XX_EXP_MUX_EN    0x00000010
+#define IXP4XX_EXP_SPLT_EN   0x00000008
+#define IXP4XX_EXP_WR_EN     0x00000002
+#define IXP4XX_EXP_BYTE_EN   0x00000001
+
+#define IXP4XX_EXP_CFG0      IXP4XX_REG(0xC4000020)
+#define IXP4XX_EXP_CFG1      IXP4XX_REG(0xC4000024)
+#define IXP4XX_EXP_CFG2      IXP4XX_REG(0xC4000028)
+#define IXP4XX_EXP_CFG3      IXP4XX_REG(0xC400002C)
+
+
+/* Peripheral Space Register Region Base Addresses */
+#define IXP4XX_UART1_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x0000)
+#define IXP4XX_UART2_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x1000)
+#define IXP4XX_PMU_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x2000)
+#define IXP4XX_INTC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x3000)
+#define IXP4XX_GPIO_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x4000)
+#define IXP4XX_NPEA_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x6000)
+#define IXP4XX_NPEB_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x7000)
+#define IXP4XX_NPEC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x8000)
+#define IXP4XX_EthB_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x9000)
+#define IXP4XX_EthC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xA000)
+#define IXP4XX_USB_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xB000)
+/* IXP46x only */
+#define IXP4XX_EthA_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xC000)
+#define IXP4XX_EthB1_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xD000)
+#define IXP4XX_EthB2_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xE000)
+#define IXP4XX_EthB3_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xF000)
+#define IXP4XX_TIMESYNC_BASE IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x10000)
+#define IXP4XX_I2C_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x11000)
+#define IXP4XX_SSP_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x12000)
+
+/*
+  Constants to make it easy to access Interrupt Controller registers
+ */
+#define IXP4XX_ICPR_OFFSET   0x00 /* Interrupt Status */
+#define IXP4XX_ICMR_OFFSET   0x04 /* Interrupt Enable */
+#define IXP4XX_ICLR_OFFSET   0x08 /* Interrupt IRQ/FIQ Select */
+#define IXP4XX_ICIP_OFFSET   0x0C /* IRQ Status */
+#define IXP4XX_ICFP_OFFSET   0x10 /* FIQ Status */
+#define IXP4XX_ICHR_OFFSET   0x14 /* Interrupt Priority */
+#define IXP4XX_ICIH_OFFSET   0x18 /* IRQ Highest Pri Int */
+#define IXP4XX_ICFH_OFFSET   0x1C /* FIQ Highest Pri Int */
+
+/* IXP465-only */
+#define IXP4XX_ICPR2_OFFSET  0x20 /* Interrupt Status 2 */
+#define IXP4XX_ICMR2_OFFSET  0x24 /* Interrupt Enable 2 */
+#define IXP4XX_ICLR2_OFFSET  0x28 /* Interrupt IRQ/FIQ Select 2 */
+#define IXP4XX_ICIP2_OFFSET  0x2C /* IRQ Status */
+#define IXP4XX_ICFP2_OFFSET  0x30 /* FIQ Status */
+#define IXP4XX_ICEEN_OFFSET  0x34 /* Error High Pri Enable */
+
+
+/* Interrupt Controller Register Definitions. */
+#define IXP4XX_INTC_REG(x)   ((volatile u32 *)(IXP4XX_INTC_BASE + (x)))
+
+#define IXP4XX_ICPR          IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET)
+#define IXP4XX_ICMR          IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET)
+#define IXP4XX_ICLR          IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET)
+#define IXP4XX_ICIP          IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET)
+#define IXP4XX_ICFP          IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET)
+#define IXP4XX_ICHR          IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
+#define IXP4XX_ICIH          IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET)
+#define IXP4XX_ICFH          IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
+#define IXP4XX_ICPR2         IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
+#define IXP4XX_ICMR2         IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
+#define IXP4XX_ICLR2         IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
+#define IXP4XX_ICIP2         IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
+#define IXP4XX_ICFP2         IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
+#define IXP4XX_ICEEN         IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
+
+/* Constants to make it easy to access GPIO registers */
+#define IXP4XX_GPIO_GPOUTR_OFFSET   0x00
+#define IXP4XX_GPIO_GPOER_OFFSET    0x04
+#define IXP4XX_GPIO_GPINR_OFFSET    0x08
+#define IXP4XX_GPIO_GPISR_OFFSET    0x0C
+#define IXP4XX_GPIO_GPIT1R_OFFSET   0x10
+#define IXP4XX_GPIO_GPIT2R_OFFSET   0x14
+#define IXP4XX_GPIO_GPCLKR_OFFSET   0x18
+#define IXP4XX_GPIO_GPDBSELR_OFFSET 0x1C
+
+/* GPIO Register Definitions - perform only 32-bit reads/writes */
+#define IXP4XX_GPIO_REG(x)   ((volatile u32 *)(IXP4XX_GPIO_BASE + (x)))
+
+#define IXP4XX_GPIO_GPOUTR   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET)
+#define IXP4XX_GPIO_GPOER    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET)
+#define IXP4XX_GPIO_GPINR    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET)
+#define IXP4XX_GPIO_GPISR    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET)
+#define IXP4XX_GPIO_GPIT1R   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET)
+#define IXP4XX_GPIO_GPIT2R   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET)
+#define IXP4XX_GPIO_GPCLKR   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET)
+#define IXP4XX_GPIO_GPDBSELR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET)
+
+/* GPIO register bit definitions */
+
+/* Interrupt styles */
+#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH  0x0
+#define IXP4XX_GPIO_STYLE_ACTIVE_LOW   0x1
+#define IXP4XX_GPIO_STYLE_RISING_EDGE  0x2
+#define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3
+#define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4
+
+/* Mask used to clear interrupt styles */
+#define IXP4XX_GPIO_STYLE_CLEAR        0x7
+#define IXP4XX_GPIO_STYLE_SIZE         3
+
+/* Operating System Timer Register Definitions. */
+#define IXP4XX_OSTS          IXP4XX_REG(0xC8005000) /* Continious TimeStamp */
+#define IXP4XX_OST1          IXP4XX_REG(0xC8005004) /* Timer 1 Timestamp */
+#define IXP4XX_OSRT1         IXP4XX_REG(0xC8005008) /* Timer 1 Reload */
+#define IXP4XX_OST2          IXP4XX_REG(0xC800500C) /* Timer 2 Timestamp */
+#define IXP4XX_OSRT2         IXP4XX_REG(0xC8005010) /* Timer 2 Reload */
+#define IXP4XX_OSWT          IXP4XX_REG(0xC8005014) /* Watchdog Timer */
+#define IXP4XX_OSWE          IXP4XX_REG(0xC8005018) /* Watchdog Enable */
+#define IXP4XX_OSWK          IXP4XX_REG(0xC800501C) /* Watchdog Key */
+#define IXP4XX_OSST          IXP4XX_REG(0xC8005020) /* Timer Status */
+
+/* Timer register values and bit definitions */
+#define IXP4XX_OST_ENABLE            0x00000001
+#define IXP4XX_OST_ONE_SHOT          0x00000002
+/* Low order bits of reload value ignored */
+#define IXP4XX_OST_RELOAD_MASK       0x00000003
+#define IXP4XX_OST_DISABLED          0x00000000
+#define IXP4XX_OSST_TIMER_1_PEND     0x00000001
+#define IXP4XX_OSST_TIMER_2_PEND     0x00000002
+#define IXP4XX_OSST_TIMER_TS_PEND    0x00000004
+#define IXP4XX_OSST_TIMER_WDOG_PEND  0x00000008
+#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
+
+#define IXP4XX_WDT_KEY               0x0000482E
+
+#define IXP4XX_WDT_RESET_ENABLE      0x00000001
+#define IXP4XX_WDT_IRQ_ENABLE        0x00000002
+#define IXP4XX_WDT_COUNT_ENABLE      0x00000004
+
+
+/* Constants to make it easy to access PCI Control/Status registers */
+#define PCI_NP_AD_OFFSET           0x00
+#define PCI_NP_CBE_OFFSET          0x04
+#define PCI_NP_WDATA_OFFSET        0x08
+#define PCI_NP_RDATA_OFFSET        0x0c
+#define PCI_CRP_AD_CBE_OFFSET      0x10
+#define PCI_CRP_WDATA_OFFSET       0x14
+#define PCI_CRP_RDATA_OFFSET       0x18
+#define PCI_CSR_OFFSET             0x1c
+#define PCI_ISR_OFFSET             0x20
+#define PCI_INTEN_OFFSET           0x24
+#define PCI_DMACTRL_OFFSET         0x28
+#define PCI_AHBMEMBASE_OFFSET      0x2c
+#define PCI_AHBIOBASE_OFFSET       0x30
+#define PCI_PCIMEMBASE_OFFSET      0x34
+#define PCI_AHBDOORBELL_OFFSET     0x38
+#define PCI_PCIDOORBELL_OFFSET     0x3C
+#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
+#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
+#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
+#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
+#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
+#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
+
+/* PCI Control/Status Registers */
+#define IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE + (x)))
+
+#define PCI_NP_AD            IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
+#define PCI_NP_CBE           IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
+#define PCI_NP_WDATA         IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
+#define PCI_NP_RDATA         IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
+#define PCI_CRP_AD_CBE       IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
+#define PCI_CRP_WDATA        IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
+#define PCI_CRP_RDATA        IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
+#define PCI_CSR              IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
+#define PCI_ISR              IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
+#define PCI_INTEN            IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
+#define PCI_DMACTRL          IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
+#define PCI_AHBMEMBASE       IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
+#define PCI_AHBIOBASE        IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
+#define PCI_PCIMEMBASE       IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
+#define PCI_AHBDOORBELL      IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
+#define PCI_PCIDOORBELL      IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
+#define PCI_ATPDMA0_AHBADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
+#define PCI_ATPDMA0_PCIADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
+#define PCI_ATPDMA0_LENADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
+#define PCI_ATPDMA1_AHBADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
+#define PCI_ATPDMA1_PCIADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
+#define PCI_ATPDMA1_LENADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
+
+/* PCI register values and bit definitions */
+
+/* CSR bit definitions */
+#define PCI_CSR_HOST         0x00000001
+#define PCI_CSR_ARBEN        0x00000002
+#define PCI_CSR_ADS          0x00000004
+#define PCI_CSR_PDS          0x00000008
+#define PCI_CSR_ABE          0x00000010
+#define PCI_CSR_DBT          0x00000020
+#define PCI_CSR_ASE          0x00000100
+#define PCI_CSR_IC           0x00008000
+
+/* ISR (Interrupt status) Register bit definitions */
+#define PCI_ISR_PSE          0x00000001
+#define PCI_ISR_PFE          0x00000002
+#define PCI_ISR_PPE          0x00000004
+#define PCI_ISR_AHBE         0x00000008
+#define PCI_ISR_APDC         0x00000010
+#define PCI_ISR_PADC         0x00000020
+#define PCI_ISR_ADB          0x00000040
+#define PCI_ISR_PDB          0x00000080
+
+/* INTEN (Interrupt Enable) Register bit definitions */
+#define PCI_INTEN_PSE        0x00000001
+#define PCI_INTEN_PFE        0x00000002
+#define PCI_INTEN_PPE        0x00000004
+#define PCI_INTEN_AHBE       0x00000008
+#define PCI_INTEN_APDC       0x00000010
+#define PCI_INTEN_PADC       0x00000020
+#define PCI_INTEN_ADB        0x00000040
+#define PCI_INTEN_PDB        0x00000080
+
+/* Shift value for byte enable on NP cmd/byte enable register */
+#define IXP4XX_PCI_NP_CBE_BESL 4
+
+/* PCI commands supported by NP access unit */
+#define NP_CMD_IOREAD        0x2
+#define NP_CMD_IOWRITE       0x3
+#define NP_CMD_CONFIGREAD    0xA
+#define NP_CMD_CONFIGWRITE   0xB
+#define NP_CMD_MEMREAD       0x6
+#define NP_CMD_MEMWRITE      0x7
+
+/* Constants for CRP access into local config space */
+#define CRP_AD_CBE_BESL      20
+#define CRP_AD_CBE_WRITE     0x00010000
+
+/* USB Device Controller */
+# define IXP4XX_USB_REG(x)   (*((volatile u32 *)(x)))
+
+/* SDRAM Controller registers. */
+#define IXP4XX_SDRAM_CONFIG  IXP4XX_REG(0xCC000000)
+#define IXP4XX_SDRAM_REFRESH IXP4XX_REG(0xCC000004)
+#define IXP4XX_SDRAM_IR      IXP4XX_REG(0xCC000008)
+
+/* "fuse" bits of IXP_EXP_CFG2 */
+/* All IXP4xx CPUs */
+#define IXP4XX_FEATURE_RCOMP            (1 << 0)
+#define IXP4XX_FEATURE_USB_DEVICE       (1 << 1)
+#define IXP4XX_FEATURE_HASH             (1 << 2)
+#define IXP4XX_FEATURE_AES              (1 << 3)
+#define IXP4XX_FEATURE_DES              (1 << 4)
+#define IXP4XX_FEATURE_HDLC             (1 << 5)
+#define IXP4XX_FEATURE_AAL              (1 << 6)
+#define IXP4XX_FEATURE_HSS              (1 << 7)
+#define IXP4XX_FEATURE_UTOPIA           (1 << 8)
+#define IXP4XX_FEATURE_NPEB_ETH0        (1 << 9)
+#define IXP4XX_FEATURE_NPEC_ETH         (1 << 10)
+#define IXP4XX_FEATURE_RESET_NPEA       (1 << 11)
+#define IXP4XX_FEATURE_RESET_NPEB       (1 << 12)
+#define IXP4XX_FEATURE_RESET_NPEC       (1 << 13)
+#define IXP4XX_FEATURE_PCI              (1 << 14)
+#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
+#define IXP4XX_FEATURE_XSCALE_MAX_FREQ  (3 << 22)
+#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP            | \
+			     IXP4XX_FEATURE_USB_DEVICE       | \
+			     IXP4XX_FEATURE_HASH             | \
+			     IXP4XX_FEATURE_AES              | \
+			     IXP4XX_FEATURE_DES              | \
+			     IXP4XX_FEATURE_HDLC             | \
+			     IXP4XX_FEATURE_AAL              | \
+			     IXP4XX_FEATURE_HSS              | \
+			     IXP4XX_FEATURE_UTOPIA           | \
+			     IXP4XX_FEATURE_NPEB_ETH0        | \
+			     IXP4XX_FEATURE_NPEC_ETH         | \
+			     IXP4XX_FEATURE_RESET_NPEA       | \
+			     IXP4XX_FEATURE_RESET_NPEB       | \
+			     IXP4XX_FEATURE_RESET_NPEC       | \
+			     IXP4XX_FEATURE_PCI              | \
+			     IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
+			     IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+
+/* IXP43x/46x CPUs */
+#define IXP4XX_FEATURE_ECC_TIMESYNC     (1 << 15)
+#define IXP4XX_FEATURE_USB_HOST         (1 << 18)
+#define IXP4XX_FEATURE_NPEA_ETH         (1 << 19)
+#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK             | \
+			     IXP4XX_FEATURE_ECC_TIMESYNC     | \
+			     IXP4XX_FEATURE_USB_HOST         | \
+			     IXP4XX_FEATURE_NPEA_ETH)
+
+/* IXP46x CPU (including IXP455) only */
+#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3  (1 << 20)
+#define IXP4XX_FEATURE_RSA              (1 << 21)
+#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK             | \
+			     IXP4XX_FEATURE_NPEB_ETH_1_TO_3  | \
+			     IXP4XX_FEATURE_RSA)
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
new file mode 100644
index 0000000..ae4b767
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
@@ -0,0 +1,24 @@
+#ifndef __MACH_PLATFORM__
+#define __MACH_PLATFORM__
+
+#include <asm/types.h>
+
+#ifndef	__ARMEB__
+#define	REG_OFFSET	0
+#else
+#define	REG_OFFSET	3
+#endif
+
+struct device_d* ixp4xx_add_uart(int id, u32 base);
+
+static inline struct device_d* ixp4xx_add_uart1(void)
+{
+	return ixp4xx_add_uart(0, (u32)IXP4XX_UART1_BASE);
+}
+
+static inline struct device_d* ixp4xx_add_uart2(void)
+{
+	return ixp4xx_add_uart(1, (u32)IXP4XX_UART2_BASE);
+}
+
+#endif /* __MACH_PLATFORM__ */
diff --git a/arch/arm/mach-ixp4xx/lowlevel_init.S b/arch/arm/mach-ixp4xx/lowlevel_init.S
new file mode 100644
index 0000000..e5d4802
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/lowlevel_init.S
@@ -0,0 +1,25 @@
+#include <mach/ixp4xx-regs.h>
+
+	.section ".text_bare_init", "ax"
+
+	.globl arch_init_lowlevel
+arch_init_lowlevel:
+	ldr	r0, cfg
+	ldr	r1, [r0]
+	/*
+	 * check if EXP bus already unmap from 0x0
+	 * as example we run from ram
+	 */
+	and	r2, r1, #IXP4XX_EXP_EN
+	cmp	r2, #0
+	beq	10f
+	bic	r1, r1, #IXP4XX_EXP_EN /* unmap EXP bus from 0x0 */
+	str	r1, [r0]
+
+	/* return to ROM */
+	orr lr, #0x50000000
+10:
+	mov pc, lr
+
+cfg:
+	.word IXP4XX_EXP_CFG0
diff --git a/arch/arm/mach-ixp4xx/reset.c b/arch/arm/mach-ixp4xx/reset.c
new file mode 100644
index 0000000..d0d3894
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/reset.c
@@ -0,0 +1,15 @@
+#include <common.h>
+#include <asm/io.h>
+#include <mach/ixp4xx-regs.h>
+
+void reset_cpu(ulong addr)
+{
+	/* Use on-chip reset capability */
+	/* This may not work on IXP425 rev. A0 */
+
+	IXP4XX_OSWK = IXP4XX_WDT_KEY;
+	IXP4XX_OSWT = 0; /* request immediate reset */
+	IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
+	while (1)
+		;
+}
diff --git a/arch/arm/mach-ixp4xx/timer.c b/arch/arm/mach-ixp4xx/timer.c
new file mode 100644
index 0000000..722d1e2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/timer.c
@@ -0,0 +1,42 @@
+#include <common.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <mach/ixp4xx-regs.h>
+#include <clock.h>
+
+#define OSTS_FREQUENCY 66666000
+
+/**
+ * @brief Provide a simple clock read
+ *
+ * Nothing is simpler.. read direct from clock and provide it
+ * to the caller.
+ *
+ * @return clock counter
+ */
+static uint64_t ixp4xx_clocksource_read(void)
+{
+	return IXP4XX_OSTS;
+}
+
+static struct clocksource cs = {
+	.read = ixp4xx_clocksource_read,
+	.mask = 0xffffffff,
+	.shift = 10,
+};
+
+/**
+ * @brief Initialize the Clock
+ *
+ * We use the Time-Stamp Timer
+ *
+ * @return result of @ref init_clock
+ */
+static int ixp4xx_clocksource_init(void)
+{
+	cs.mult = clocksource_hz2mult(OSTS_FREQUENCY, cs.shift);
+
+	return init_clock(&cs);
+}
+core_initcall(ixp4xx_clocksource_init);
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 820aac5..f1f7595 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -141,8 +141,12 @@ static void ns16550_serial_init_port(struct console_device *cdev)
 {
 	/* initializing the device for the first time */
 	ns16550_write(cdev, 0x00, lcr); /* select ier reg */
-	ns16550_write(cdev, 0x00, ier);
 
+#ifdef CONFIG_ARCH_IXP4XX
+	ns16550_write(cdev, IER_UUE, ier); /* Enable UART operation */
+#else
+	ns16550_write(cdev, 0x00, ier);
+#endif
 #ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
 	ns16550_write(cdev, 0x07, mdr1);	/* Disable */
 #endif
diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h
index db8fe64..132f46e 100644
--- a/drivers/serial/serial_ns16550.h
+++ b/drivers/serial/serial_ns16550.h
@@ -50,6 +50,8 @@
 #define dll		rbr
 #define dlm		ier
 
+#define IER_UUE		0x40	/* UART Unit Enable (XScale) */
+
 #define FCR_FIFO_EN     0x01	/* Fifo enable */
 #define FCR_RXSR        0x02	/* Receiver soft reset */
 #define FCR_TXSR        0x04	/* Transmitter soft reset */
-- 
1.7.9.1




More information about the barebox mailing list