* [PATCH v2 1/9] lpc2k: Core support
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 15:27 ` Russell King - ARM Linux
2011-03-18 15:11 ` [PATCH v2 2/9] lpc2k: Exception vector handling Ithamar R. Adema
` (7 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Core files (including IRQ handling) for NXP LPC2K architecture.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v1:
* implement arch_idle() using PCON register.
* implement arch_reset() using WDT block.
* Fix PLL 'N' mask in regs-scb.h
---
arch/arm/Kconfig | 14 ++++++
arch/arm/Makefile | 1 +
arch/arm/mach-lpc2k/Kconfig | 5 ++
arch/arm/mach-lpc2k/Makefile | 1 +
arch/arm/mach-lpc2k/Makefile.boot | 3 +
arch/arm/mach-lpc2k/include/mach/debug-macro.S | 19 +++++++++
arch/arm/mach-lpc2k/include/mach/entry-macro.S | 33 +++++++++++++++
arch/arm/mach-lpc2k/include/mach/hardware.h | 25 ++++++++++++
arch/arm/mach-lpc2k/include/mach/io.h | 18 ++++++++
arch/arm/mach-lpc2k/include/mach/irqs.h | 49 +++++++++++++++++++++++
arch/arm/mach-lpc2k/include/mach/memory.h | 15 +++++++
arch/arm/mach-lpc2k/include/mach/regs-scb.h | 42 +++++++++++++++++++
arch/arm/mach-lpc2k/include/mach/regs-wdt.h | 26 ++++++++++++
arch/arm/mach-lpc2k/include/mach/system.h | 51 ++++++++++++++++++++++++
arch/arm/mach-lpc2k/include/mach/timex.h | 15 +++++++
arch/arm/mach-lpc2k/include/mach/uncompress.h | 50 +++++++++++++++++++++++
arch/arm/mach-lpc2k/irq.c | 17 ++++++++
17 files changed, 384 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-lpc2k/Kconfig
create mode 100644 arch/arm/mach-lpc2k/Makefile
create mode 100644 arch/arm/mach-lpc2k/Makefile.boot
create mode 100644 arch/arm/mach-lpc2k/include/mach/debug-macro.S
create mode 100644 arch/arm/mach-lpc2k/include/mach/entry-macro.S
create mode 100644 arch/arm/mach-lpc2k/include/mach/hardware.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/io.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/irqs.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/memory.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/regs-scb.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/regs-wdt.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/system.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/timex.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/uncompress.h
create mode 100644 arch/arm/mach-lpc2k/irq.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 599e163..8129cbc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -490,6 +490,18 @@ config ARCH_LOKI
help
Support for the Marvell Loki (88RC8480) SoC.
+config ARCH_LPC2K
+ bool "NXP LPC2K Family"
+ depends on !MMU
+ select CPU_ARM7TDMI
+ select ARM_VIC
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for NXP LPC2K family of SoCs. These SoCs are based on
+ an ARM7TDMI-S core, and have optional on-chip flash and SRAM,
+ also UART, I2C, SPI, SSP, CAN, RTC, and other peripherals.
+
config ARCH_LPC32XX
bool "NXP LPC32XX"
select CPU_ARM926T
@@ -931,6 +943,8 @@ source "arch/arm/mach-ks8695/Kconfig"
source "arch/arm/mach-loki/Kconfig"
+source "arch/arm/mach-lpc2k/Kconfig"
+
source "arch/arm/mach-lpc32xx/Kconfig"
source "arch/arm/mach-msm/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c7d321a..9bf8421 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -151,6 +151,7 @@ machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
machine-$(CONFIG_ARCH_KS8695) := ks8695
machine-$(CONFIG_ARCH_LOKI) := loki
+machine-$(CONFIG_ARCH_LPC2K) := lpc2k
machine-$(CONFIG_ARCH_LPC32XX) := lpc32xx
machine-$(CONFIG_ARCH_MMP) := mmp
machine-$(CONFIG_ARCH_MSM) := msm
diff --git a/arch/arm/mach-lpc2k/Kconfig b/arch/arm/mach-lpc2k/Kconfig
new file mode 100644
index 0000000..fad47b8
--- /dev/null
+++ b/arch/arm/mach-lpc2k/Kconfig
@@ -0,0 +1,5 @@
+if ARCH_LPC2K
+
+comment "LPC2K machines"
+
+endif
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
new file mode 100644
index 0000000..546666b
--- /dev/null
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -0,0 +1 @@
+obj-y := irq.o
diff --git a/arch/arm/mach-lpc2k/Makefile.boot b/arch/arm/mach-lpc2k/Makefile.boot
new file mode 100644
index 0000000..8b6b745
--- /dev/null
+++ b/arch/arm/mach-lpc2k/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0xa0008000
+params_phys-y := 0xa0000100
+initrd_phys-y := 0xa1800000
diff --git a/arch/arm/mach-lpc2k/include/mach/debug-macro.S b/arch/arm/mach-lpc2k/include/mach/debug-macro.S
new file mode 100644
index 0000000..0f581d3
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+
+#include <mach/hardware.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =APB_UART0_BASE
+ ldr \rv, =APB_UART0_BASE
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-lpc2k/include/mach/entry-macro.S b/arch/arm/mach-lpc2k/include/mach/entry-macro.S
new file mode 100644
index 0000000..f6c7a46
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <mach/hardware.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =APH_VIC_BASE
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #0]
+ mov \irqnr, #0
+1001:
+ tst \irqstat, #1
+ bne 1002f
+ add \irqnr, \irqnr, #1
+ mov \irqstat, \irqstat, lsr #1
+ cmp \irqnr, #32
+ bcc 1001b
+1002:
+ .endm
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
new file mode 100644
index 0000000..3463b47
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_HARDWARE_H
+#define MACH_LPC2K_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* Default memory size if no ATAGS found */
+#define MEM_SIZE (SZ_32M)
+
+#define APB_WDT_BASE 0xe0000000
+#define APB_TIMER0_BASE 0xe0004000
+#define APB_TIMER1_BASE 0xe0008000
+#define APB_UART0_BASE 0xe000c000
+#define APB_SCB_BASE 0xe01fc000
+#define APH_VIC_BASE 0xfffff000
+
+#endif /* MACH_LPC2K_HARDWARE_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/io.h b/arch/arm/mach-lpc2k/include/mach/io.h
new file mode 100644
index 0000000..e1a2b7f
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/io.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_IO_H
+#define MACH_LPC2K_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __mem_pci(a) (a)
+#define __io(a) __typesafe_io(a)
+
+#endif /* MACH_LPC2K_IO_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/irqs.h b/arch/arm/mach-lpc2k/include/mach/irqs.h
new file mode 100644
index 0000000..87b80dd
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/irqs.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_IRQS_H
+#define MACH_LPC2K_IRQS_H
+
+/* VIC */
+#define IRQ_LPC2K_WDINT 0
+#define IRQ_LPC2K_RSV0 1
+#define IRQ_LPC2K_DBGRX 2
+#define IRQ_LPC2K_DBGTX 3
+#define IRQ_LPC2K_TIMER0 4
+#define IRQ_LPC2K_TIMER1 5
+#define IRQ_LPC2K_UART0 6
+#define IRQ_LPC2K_UART1 7
+#define IRQ_LPC2K_PWM0 8
+#define IRQ_LPC2K_I2C0 9
+#define IRQ_LPC2K_SPI0 10
+#define IRQ_LPC2K_SPI1 11
+#define IRQ_LPC2K_PLL 12
+#define IRQ_LPC2K_RTC 13
+#define IRQ_LPC2K_EINT0 14
+#define IRQ_LPC2K_EINT1 15
+#define IRQ_LPC2K_EINT2 16
+#define IRQ_LPC2K_EINT3 17
+#define IRQ_LPC2K_ADC 18
+#define IRQ_LPC2K_I2C1 19
+#define IRQ_LPC2K_BOD 20
+#define IRQ_LPC2K_ETH 21
+#define IRQ_LPC2K_USB 22
+#define IRQ_LPC2K_CAN 23
+#define IRQ_LPC2K_MCI 24
+#define IRQ_LPC2K_DMA 25
+#define IRQ_LPC2K_TIMER2 26
+#define IRQ_LPC2K_TIMER3 27
+#define IRQ_LPC2K_UART2 28
+#define IRQ_LPC2K_UART3 29
+#define IRQ_LPC2K_I2C2 30
+#define IRQ_LPC2K_I2S 31
+
+#define NR_IRQS 32
+
+#endif /* MACH_LPC2K_IRQS_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/memory.h b/arch/arm/mach-lpc2k/include/mach/memory.h
new file mode 100644
index 0000000..6432147
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/memory.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_MEMORY_H
+#define MACH_LPC2K_MEMORY_H
+
+#define PHYS_OFFSET 0xa0000000
+
+#endif /* MACH_LPC2K_MEMORY_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/regs-scb.h b/arch/arm/mach-lpc2k/include/mach/regs-scb.h
new file mode 100644
index 0000000..d914de9
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/regs-scb.h
@@ -0,0 +1,42 @@
+/*
+ * System Control Block register definitions
+ *
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_REGS_SCB_H
+#define MACH_LPC2K_REGS_SCB_H
+
+#define CLKSRCSEL 0x10c
+#define CLKSRC(x) ((x) & 3)
+#define PLLCON 0x080
+#define PLLCFG 0x084
+#define PLLSTAT 0x088
+#define M(x) (((x) & 0x7fff) + 1)
+#define N(x) ((((x) >> 16) & 0xff) + 1)
+#define PLLE (1 << 24)
+#define PLLC (1 << 25)
+#define PLLFEED 0x08c
+
+#define CCLKCFG 0x104
+#define CCLKSEL(x) ((x) & 0xff)
+#define USBCLKCFG 0x108
+#define USBSEL(x) ((x) & 0xf)
+#define IRCTRIM 0x1a4
+#define PCLKSEL0 0x1a8
+#define PCLKSEL1 0x1ac
+
+#define PCON 0x0c0
+#define PCON_PM0 (1 << 0)
+#define PCON_PM1 (1 << 1)
+#define PCON_PM2 (1 << 7)
+#define PCON_PMMASK (PCON_PM0 | PCON_PM1 | PCON_PM2)
+#define INTWAKE 0x144
+#define PCONP 0x0c4
+
+#endif /* MACH_LPC2K_REGS_SCB_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/regs-wdt.h b/arch/arm/mach-lpc2k/include/mach/regs-wdt.h
new file mode 100644
index 0000000..eb6ab91
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/regs-wdt.h
@@ -0,0 +1,26 @@
+/*
+ * Watchdog Timer register definitions
+ *
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_REGS_WDT_H
+#define MACH_LPC2K_REGS_WDT_H
+
+#define WDMOD 0x0000
+#define WDTC 0x0004
+#define WDFEED 0x0008
+#define WDTV 0x000a
+#define WDCLKSEL 0x0010
+
+#define WDMOD_WDEN (1 << 0)
+#define WDMOD_WDRESET (1 << 1)
+#define WDMOD_WDTOF (1 << 2)
+#define WDMOD_WDINT (1 << 3)
+
+#endif /* MACH_LPC2K_REGS_WDT_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/system.h b/arch/arm/mach-lpc2k/include/mach/system.h
new file mode 100644
index 0000000..48209e1
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/system.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_SYSTEM_H
+#define MACH_LPC2K_SYSTEM_H
+
+#include <mach/regs-scb.h>
+#include <mach/regs-wdt.h>
+#include <mach/hardware.h>
+
+static void arch_idle(void)
+{
+ /* Set PM0, IDL: idle mode */
+ iowrite32((ioread32(APB_SCB_BASE + PCON) & ~PCON_PMMASK) | PCON_PM0,
+ APB_SCB_BASE + PCON);
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ switch (mode) {
+ case 's':
+ case 'h':
+ printk(KERN_CRIT "RESET: Rebooting system\n");
+
+ /* Disable interrupts */
+ local_irq_disable();
+
+ /* Setup WDT to fire on shortest allowed time */
+ iowrite32(0xff, APB_WDT_BASE + WDTC);
+ iowrite32(WDMOD_WDEN | WDMOD_WDRESET, APB_WDT_BASE + WDMOD);
+ iowrite32(0xaa, APB_WDT_BASE + WDFEED);
+ iowrite32(0x55, APB_WDT_BASE + WDFEED);
+ break;
+
+ default:
+ /* Do nothing */
+ break;
+ }
+
+ /* Wait for watchdog to reset system */
+ while (1)
+ ;
+}
+
+#endif /* MACH_LPC2K_SYSTEM_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/timex.h b/arch/arm/mach-lpc2k/include/mach/timex.h
new file mode 100644
index 0000000..ba7c8dc
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/timex.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_TIMEX_H
+#define MACH_LPC2K_TIMEX_H
+
+#define CLOCK_TICK_RATE (HZ * 100UL)
+
+#endif /* MACH_LPC2K_TIMEX_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/uncompress.h b/arch/arm/mach-lpc2k/include/mach/uncompress.h
new file mode 100644
index 0000000..1724d72
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/uncompress.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * based on uncompress.h from mach-loki.
+ *
+ * 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.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+#define SERIAL_BASE ((unsigned char *)APB_UART0_BASE)
+
+static void putc(const char c)
+{
+ unsigned char *base = SERIAL_BASE;
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ if (base[UART_LSR << 2] & UART_LSR_THRE)
+ break;
+ barrier();
+ }
+
+ base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+ unsigned char *base = SERIAL_BASE;
+ unsigned char mask;
+ int i;
+
+ mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+ for (i = 0; i < 0x1000; i++) {
+ if ((base[UART_LSR << 2] & mask) == mask)
+ break;
+ barrier();
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-lpc2k/irq.c b/arch/arm/mach-lpc2k/irq.c
new file mode 100644
index 0000000..58d291d
--- /dev/null
+++ b/arch/arm/mach-lpc2k/irq.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <asm/hardware/vic.h>
+#include <mach/hardware.h>
+
+void __init lpc2k_init_irq(void)
+{
+ vic_init((void __iomem *)APH_VIC_BASE, 0, ~0, 0);
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 2/9] lpc2k: Exception vector handling
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
2011-03-18 15:11 ` [PATCH v2 1/9] lpc2k: Core support Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 15:16 ` Russell King - ARM Linux
2011-03-18 15:11 ` [PATCH v2 3/9] lpc2k: clk API Ithamar R. Adema
` (6 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Since the LPC2K does not have an MMU (ARM7TDMI based), it expects the vectors to be
stored in on-chip SRAM. However, this moves the vectors too far away from the stubs
page, requiring the vector jumps to be indirect.
Since now VECTOR_BASE is below PHYS_OFFSET, do not try to reserve the vector
page, as it will fail (and prevent the kernel from booting).
Also, commit 247055aa (6384/1: Remove the domain switching on ARMv6k/v7 CPUs) broke
the placement of vectors in the !MMU case, so fix this too.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v1:
* added comment to entry-armv.S vector #ifdef.
---
arch/arm/Kconfig | 1 +
arch/arm/kernel/entry-armv.S | 24 ++++++++++++++++++++++++
arch/arm/kernel/traps.c | 2 +-
arch/arm/mm/nommu.c | 2 ++
4 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8129cbc..99afdeb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -186,6 +186,7 @@ config VECTORS_BASE
hex
default 0xffff0000 if MMU || CPU_HIGH_VECTOR
default DRAM_BASE if REMAP_VECTORS_TO_RAM
+ default 0x40000000 if ARCH_LPC2K
default 0x00000000
help
The base address of exception vectors.
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index e8d8856..44686b0 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -1208,6 +1208,7 @@ __stubs_end:
.globl __vectors_start
__vectors_start:
+#ifndef CONFIG_ARCH_LPC2K
ARM( swi SYS_ERROR0 )
THUMB( svc #0 )
THUMB( nop )
@@ -1218,6 +1219,29 @@ __vectors_start:
W(b) vector_addrexcptn + stubs_offset
W(b) vector_irq + stubs_offset
W(b) vector_fiq + stubs_offset
+#else /* CONFIG_ARCH_LPC2K */
+ /*
+ * The LPC2K does not have an MMU (ARM7TDMI based), it expects
+ * the vectors to be stored in on-chip SRAM. This moves the
+ * vectors too far away from the stubs page, so requiring the
+ * vector jumps to be indirect.
+ */
+ swi SYS_ERROR0
+ ldr pc, .vector_und
+ ldr pc, .vector_swi
+ ldr pc, .vector_pabt
+ ldr pc, .vector_dabt
+ ldr pc, .vector_addrexcptn
+ ldr pc, .vector_irq
+ ldr pc, .vector_fiq
+.vector_und: .word vector_und
+.vector_swi: .word vector_swi
+.vector_pabt: .word vector_pabt
+.vector_dabt: .word vector_dabt
+.vector_addrexcptn: .word vector_addrexcptn
+.vector_irq: .word vector_irq
+.vector_fiq: .word vector_fiq
+#endif
.globl __vectors_end
__vectors_end:
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 21ac43f..639c4c8 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -758,7 +758,7 @@ static void __init kuser_get_tls_init(unsigned long vectors)
void __init early_trap_init(void)
{
-#if defined(CONFIG_CPU_USE_DOMAINS)
+#if defined(CONFIG_CPU_USE_DOMAINS) || !defined(CONFIG_MMU)
unsigned long vectors = CONFIG_VECTORS_BASE;
#else
unsigned long vectors = (unsigned long)vectors_page;
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 687d023..e3bec02 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -24,7 +24,9 @@ void __init arm_mm_memblock_reserve(void)
* some architectures which the DRAM is the exception vector to trap,
* alloc_page breaks with error, although it is not NULL, but "0."
*/
+#if PHYS_OFFSET <= CONFIG_VECTORS_BASE
memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
+#endif
}
/*
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 2/9] lpc2k: Exception vector handling
2011-03-18 15:11 ` [PATCH v2 2/9] lpc2k: Exception vector handling Ithamar R. Adema
@ 2011-03-18 15:16 ` Russell King - ARM Linux
2011-03-18 17:06 ` Ithamar R. Adema
0 siblings, 1 reply; 22+ messages in thread
From: Russell King - ARM Linux @ 2011-03-18 15:16 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Mar 18, 2011 at 04:11:49PM +0100, Ithamar R. Adema wrote:
> Since the LPC2K does not have an MMU (ARM7TDMI based), it expects the vectors to be
> stored in on-chip SRAM. However, this moves the vectors too far away from the stubs
> page, requiring the vector jumps to be indirect.
Why not copy the vectors and stubs just like we do for MMU-based kernels?
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 2/9] lpc2k: Exception vector handling
2011-03-18 15:16 ` Russell King - ARM Linux
@ 2011-03-18 17:06 ` Ithamar R. Adema
0 siblings, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 17:06 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2011-03-18 at 15:16 +0000, Russell King - ARM Linux wrote:
> On Fri, Mar 18, 2011 at 04:11:49PM +0100, Ithamar R. Adema wrote:
> > Since the LPC2K does not have an MMU (ARM7TDMI based), it expects the vectors to be
> > stored in on-chip SRAM. However, this moves the vectors too far away from the stubs
> > page, requiring the vector jumps to be indirect.
>
> Why not copy the vectors and stubs just like we do for MMU-based kernels?
The problem here is the remapping of the low vectors that the LPC2K SoC
does. Although we store the vectors (and stubs) @ 0x40000000 (SRAM) the
SoC remaps only the first 64 bytes of that to address 0x00000000 (low
vectors).
This means that although the vectors are accessible, the stubs are not.
The 64 bytes cover the vectors itself, and the 1-word per vector address
variable stored directly after the vectors.
I'll update the commit log to be a bit more clear on this.
Regards,
Ithamar.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 3/9] lpc2k: clk API
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
2011-03-18 15:11 ` [PATCH v2 1/9] lpc2k: Core support Ithamar R. Adema
2011-03-18 15:11 ` [PATCH v2 2/9] lpc2k: Exception vector handling Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 15:11 ` [PATCH v2 4/9] lpc2k: generic time and clockevents Ithamar R. Adema
` (5 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Implements clock API using the CLKDEV_LOOKUP common code.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v1:
* changed mutex into spinlock
* simplified clk_readl/clk_writel macros
---
arch/arm/Kconfig | 1 +
arch/arm/mach-lpc2k/Makefile | 2 +-
arch/arm/mach-lpc2k/clock.c | 360 +++++++++++++++++++++++++++++
arch/arm/mach-lpc2k/include/mach/clkdev.h | 17 ++
4 files changed, 379 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-lpc2k/clock.c
create mode 100644 arch/arm/mach-lpc2k/include/mach/clkdev.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 99afdeb..ddec518 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -496,6 +496,7 @@ config ARCH_LPC2K
depends on !MMU
select CPU_ARM7TDMI
select ARM_VIC
+ select CLKDEV_LOOKUP
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 546666b..9eb0a6a 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y := irq.o
+obj-y := clock.o irq.o
diff --git a/arch/arm/mach-lpc2k/clock.c b/arch/arm/mach-lpc2k/clock.c
new file mode 100644
index 0000000..7631c89
--- /dev/null
+++ b/arch/arm/mach-lpc2k/clock.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-scb.h>
+
+#define clk_readl(a) \
+ ioread32(APB_SCB_BASE + (a))
+#define clk_writel(v, a) \
+ iowrite32(v, APB_SCB_BASE + (a))
+
+struct clk {
+ int refcount;
+ struct clk *parent;
+ unsigned long rate;
+
+ u32 enable_mask;
+
+ long (*round_rate)(struct clk *clk, unsigned long rate);
+ int (*set_rate)(struct clk *clk, unsigned long rate);
+ unsigned long (*get_rate)(struct clk *clk);
+ int (*set_parent)(struct clk *clk, struct clk *parent);
+};
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ BUG_ON(clk->refcount == 0);
+
+ if (!(--clk->refcount)) {
+ if (clk->parent)
+ __clk_disable(clk->parent);
+
+ if (clk->enable_mask) {
+ /* Unconditionally disable the clock in hardware */
+ u32 value = clk_readl(PCONP);
+ clk_writel(value & ~clk->enable_mask, PCONP);
+ }
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk->refcount++ == 0) {
+ if (clk->parent)
+ ret = __clk_enable(clk->parent);
+ if (ret)
+ return ret;
+ else if (clk->enable_mask) {
+ u32 value = clk_readl(PCONP);
+ clk_writel(value | clk->enable_mask, PCONP);
+ }
+ }
+
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (!clk)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ ret = __clk_enable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (!clk)
+ return;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (!clk)
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ if (clk->parent)
+ return clk_get_rate(clk->parent);
+
+ return clk->rate;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!clk)
+ return 0;
+ if (!clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_rate || !rate)
+ return ret;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ ret = clk->set_rate(clk, rate);
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+ struct clk *old;
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_parent || !parent)
+ return ret;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ old = clk->parent;
+ if (clk->refcount)
+ __clk_enable(parent);
+ ret = clk->set_parent(clk, parent);
+ if (ret)
+ old = parent;
+ if (clk->refcount)
+ __clk_disable(old);
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (!clk)
+ return NULL;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
+
+static struct clk clk_irc = {
+ .rate = 4000000
+};
+
+static struct clk clk_xtal;
+static struct clk clk_xrtc;
+
+static unsigned long pll_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 pll_stat = clk_readl(PLLSTAT);
+
+ if (pll_stat & PLLE && pll_stat & PLLC)
+ rate = (2 * M(pll_stat) * rate) / N(pll_stat);
+
+ return rate;
+}
+
+static struct clk clk_pll = {
+ .parent = NULL,
+ .get_rate = pll_get_rate,
+};
+
+static unsigned long cpu_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ return rate / (CCLKSEL(clk_readl(CCLKCFG)) + 1);
+}
+
+static struct clk clk_cpu = {
+ .parent = &clk_pll,
+ .get_rate = cpu_get_rate,
+};
+
+static unsigned long usb_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ return rate / (USBSEL(clk_readl(USBCLKCFG)) + 1);
+}
+
+static struct clk clk_usb = {
+ .enable_mask = (1 << 31),
+ .parent = &clk_pll,
+ .get_rate = usb_get_rate,
+};
+
+static struct clk clk_apbpclk;
+
+static unsigned long pclkdiv[] = { 4, 1, 2, 8 };
+
+#define PERCLK(name, pnum) \
+ static unsigned long name ## _get_rate(struct clk *clk) \
+ { \
+ unsigned long rate = clk_get_rate(clk->parent); \
+ u32 val = clk_readl((pnum < 16) ? PCLKSEL0 : PCLKSEL1); \
+ val >>= (pnum < 16) ? pnum * 2 : (pnum - 16) * 2; \
+ return rate / pclkdiv[val & 3]; \
+ } \
+ struct clk clk_ ## name = { \
+ .parent = &clk_cpu, \
+ .enable_mask = (1 << pnum), \
+ .get_rate = name ## _get_rate, \
+ }
+
+PERCLK(timer0, 1);
+PERCLK(timer1, 2);
+PERCLK(uart0, 3);
+PERCLK(uart1, 4);
+PERCLK(pwm0, 5);
+PERCLK(pwm1, 6);
+PERCLK(i2c0, 7);
+PERCLK(spi, 8);
+PERCLK(prtc, 9);
+PERCLK(ssp1, 10);
+PERCLK(emc, 11);
+PERCLK(adc, 12);
+PERCLK(can1, 13);
+PERCLK(can2, 14);
+PERCLK(i2c1, 19);
+PERCLK(lcd, 20);
+PERCLK(ssp0, 21);
+PERCLK(timer2, 22);
+PERCLK(timer3, 23);
+PERCLK(uart2, 24);
+PERCLK(uart3, 25);
+PERCLK(i2c2, 26);
+PERCLK(i2s, 27);
+PERCLK(mci, 28);
+PERCLK(dma, 29);
+PERCLK(eth, 30);
+
+#define INIT_CK(dev, con, ck) \
+ { .dev_id = dev, .con_id = con, .clk = ck }
+
+
+/* clk_rtc is a virtual clock used as glue to adjust at runtime
+ * if we're using the normal peripheral clock or an extern osc.
+ */
+static struct clk clk_rtc;
+
+static struct clk_lookup clocks[] = {
+ INIT_CK(NULL, "apb_pclk", &clk_apbpclk),
+ INIT_CK(NULL, "irc", &clk_irc),
+ INIT_CK(NULL, "xtal", &clk_xtal),
+ INIT_CK(NULL, "pll", &clk_pll),
+ INIT_CK(NULL, "cpu", &clk_cpu),
+ INIT_CK(NULL, "usb", &clk_usb),
+ INIT_CK(NULL, "timer0", &clk_timer0),
+ INIT_CK(NULL, "timer1", &clk_timer1),
+ INIT_CK(NULL, "timer2", &clk_timer2),
+ INIT_CK(NULL, "timer3", &clk_timer3),
+ INIT_CK("lpc2k-pwm.0", NULL, &clk_pwm0),
+ INIT_CK("lpc2k-pwm.1", NULL, &clk_pwm1),
+ INIT_CK("lpc2k-adc", NULL, &clk_adc),
+ INIT_CK("lpc2k-i2c.0", NULL, &clk_i2c0),
+ INIT_CK("lpc2k-i2c.1", NULL, &clk_i2c1),
+ INIT_CK("lpc2k-i2c.2", NULL, &clk_i2c2),
+ INIT_CK("serial8250.0", NULL, &clk_uart0),
+ INIT_CK("serial8250.1", NULL, &clk_uart1),
+ INIT_CK("serial8250.2", NULL, &clk_uart2),
+ INIT_CK("serial8250.3", NULL, &clk_uart3),
+ INIT_CK("lpc2k-ohci", NULL, &clk_usb),
+ INIT_CK("lpc2k-spi.0", NULL, &clk_ssp0),
+ INIT_CK("lpc2k-spi.1", NULL, &clk_ssp1),
+ INIT_CK("lpc2k-eth", NULL, &clk_eth),
+ INIT_CK("lpc2k-rtc", NULL, &clk_rtc),
+ INIT_CK("ssp0", NULL, &clk_ssp0),
+ INIT_CK("ssp1", NULL, &clk_ssp1),
+ INIT_CK("mci", NULL, &clk_mci),
+ INIT_CK("lcd", NULL, &clk_lcd),
+ INIT_CK("dma", NULL, &clk_dma),
+};
+
+void __init lpc2k_init_clocks(unsigned long xtal, unsigned long rtc)
+{
+ struct clk *pll_src_clk[] = { &clk_irc, &clk_xtal, &clk_xrtc };
+ int i;
+
+ clk_xtal.rate = xtal;
+
+ clk_pll.parent = pll_src_clk[CLKSRC(clk_readl(CLKSRCSEL))];
+ clk_xrtc.rate = rtc;
+ /* If no external RTC osc. is specified, make RTC clock child
+ of peripheral RTC (CPU) clock */
+ clk_rtc.parent = rtc ? &clk_xrtc : &clk_prtc;
+
+ for (i = 0; i < ARRAY_SIZE(clocks); i++) {
+ pr_debug("clock '%s', rate %luHz\n",
+ clocks[i].con_id ? clocks[i].con_id : clocks[i].dev_id,
+ clk_get_rate(clocks[i].clk));
+
+ clkdev_add(&clocks[i]);
+ }
+}
diff --git a/arch/arm/mach-lpc2k/include/mach/clkdev.h b/arch/arm/mach-lpc2k/include/mach/clkdev.h
new file mode 100644
index 0000000..92267cc
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/clkdev.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#ifndef MACH_LPC2K_CLKDEV_H
+#define MACH_LPC2K_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif /* MACH_LPC2K_CLKDEV_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 4/9] lpc2k: generic time and clockevents
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
` (2 preceding siblings ...)
2011-03-18 15:11 ` [PATCH v2 3/9] lpc2k: clk API Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 15:20 ` Russell King - ARM Linux
2011-03-18 15:11 ` [PATCH v2 5/9] lpc2k: gpiolib Ithamar R. Adema
` (4 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
This code was mostly "borrowed" form the lpc32xx implementation.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v1:
* make use of clockevents_calc_mult_shift.
---
arch/arm/mach-lpc2k/Makefile | 2 +-
arch/arm/mach-lpc2k/time.c | 173 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 174 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-lpc2k/time.c
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 9eb0a6a..267432c 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y := clock.o irq.o
+obj-y := clock.o irq.o time.o
diff --git a/arch/arm/mach-lpc2k/time.c b/arch/arm/mach-lpc2k/time.c
new file mode 100644
index 0000000..67abf2b
--- /dev/null
+++ b/arch/arm/mach-lpc2k/time.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ * Copyright (C) 2009 - 2010 NXP Semiconductors
+ * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven
+ * Ed Schouten <e.schouten@fontys.nl>
+ * Laurens Timmermans <l.timmermans@fontys.nl>
+ *
+ * Based on timer code from plat-lpc32xx.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <linux/err.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+
+#define IR 0x00
+#define TCR 0x04
+#define TC 0x08
+#define PR 0x0c
+#define PC 0x10
+#define MCR 0x14
+#define MR0 0x18
+#define MR1 0x1c
+#define MR2 0x20
+#define CCR 0x28
+#define CR0 0x2c
+#define CR1 0x30
+#define CR2 0x34
+#define CR3 0x38
+#define EMR 0x3c
+#define CTCR 0x70
+
+#define IR_MR_SHIFT 0
+#define IR_CR_SHIFT 4
+
+#define TCR_EN (1 << 0)
+#define TCR_RESET (1 << 1)
+
+
+static void __iomem *timer0 = (void __iomem *)APB_TIMER0_BASE;
+static void __iomem *timer1 = (void __iomem *)APB_TIMER1_BASE;
+
+static cycle_t lpc2k_clksrc_read(struct clocksource *cs)
+{
+ return __raw_readl(timer1 + TC);
+}
+
+static struct clocksource lpc2k_clksrc = {
+ .name = "lpc2k_clksrc",
+ .rating = 300,
+ .read = lpc2k_clksrc_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int lpc2k_clkevt_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ __raw_writel(TCR_RESET, timer0 + TCR);
+ __raw_writel(delta, timer0 + PR);
+ __raw_writel(TCR_EN, timer0 + TCR);
+
+ return 0;
+}
+
+static void lpc2k_clkevt_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ BUG();
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /*
+ * Disable the timer. When using oneshot, we must also
+ * disable the timer to wait for the first call to
+ * set_next_event().
+ */
+ __raw_writel(0, timer0 + TCR);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device lpc2k_clkevt = {
+ .name = "lpc2k_clkevt",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 300,
+ .set_next_event = lpc2k_clkevt_next_event,
+ .set_mode = lpc2k_clkevt_mode,
+};
+
+static irqreturn_t lpc2k_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &lpc2k_clkevt;
+
+ /* Clear match */
+ __raw_writel((1 << IR_MR_SHIFT), timer0 + IR);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction lpc2k_timer_irq = {
+ .name = "LPC2K Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = lpc2k_timer_interrupt,
+};
+
+/*
+ * The clock management driver isn't initialized at this point, so the
+ * clocks need to be enabled here manually and then tagged as used in
+ * the clock driver initialization
+ */
+static void __init lpc2k_timer_init(void)
+{
+ unsigned long rate;
+ struct clk *clk;
+
+ clk = clk_get(NULL, "timer1");
+ BUG_ON(IS_ERR(clk));
+
+ clk_enable(clk);
+ rate = clk_get_rate(clk);
+ clk_put(clk);
+
+ /* Initial timer setup */
+ __raw_writel(0, timer0 + TCR);
+ __raw_writel(1 << IR_MR_SHIFT, timer0 + IR);
+ __raw_writel(1, timer0 + MR0);
+ __raw_writel(3 << 0, timer0 + MCR);
+
+ /* Setup tick interrupt */
+ setup_irq(IRQ_LPC2K_TIMER0, &lpc2k_timer_irq);
+
+ /* Setup the clockevent structure. */
+ clockevents_calc_mult_shift(&lpc2k_clkevt, rate, 5);
+ lpc2k_clkevt.max_delta_ns = clockevent_delta2ns(-1,
+ &lpc2k_clkevt);
+ lpc2k_clkevt.min_delta_ns = clockevent_delta2ns(1,
+ &lpc2k_clkevt) + 1;
+ lpc2k_clkevt.cpumask = cpumask_of(0);
+ clockevents_register_device(&lpc2k_clkevt);
+
+ /* Use timer1 as clock source. */
+ __raw_writel(TCR_RESET, timer1 + TCR);
+ __raw_writel(0, timer1 + PR);
+ __raw_writel(0, timer1 + MCR);
+ __raw_writel(TCR_EN, timer1 + TCR);
+ clocksource_register_hz(&lpc2k_clksrc, rate);
+}
+
+struct sys_timer lpc2k_timer = {
+ .init = &lpc2k_timer_init,
+};
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 4/9] lpc2k: generic time and clockevents
2011-03-18 15:11 ` [PATCH v2 4/9] lpc2k: generic time and clockevents Ithamar R. Adema
@ 2011-03-18 15:20 ` Russell King - ARM Linux
2011-03-18 15:44 ` Ithamar R. Adema
2011-03-18 17:15 ` Kevin Wells
0 siblings, 2 replies; 22+ messages in thread
From: Russell King - ARM Linux @ 2011-03-18 15:20 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Mar 18, 2011 at 04:11:51PM +0100, Ithamar R. Adema wrote:
> + clk = clk_get(NULL, "timer1");
> + BUG_ON(IS_ERR(clk));
> +
> + clk_enable(clk);
> + rate = clk_get_rate(clk);
> + clk_put(clk);
Don't put a clock that you continue to use.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 4/9] lpc2k: generic time and clockevents
2011-03-18 15:20 ` Russell King - ARM Linux
@ 2011-03-18 15:44 ` Ithamar R. Adema
2011-03-18 17:15 ` Kevin Wells
1 sibling, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:44 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2011-03-18 at 15:20 +0000, Russell King - ARM Linux wrote:
> On Fri, Mar 18, 2011 at 04:11:51PM +0100, Ithamar R. Adema wrote:
> > + clk = clk_get(NULL, "timer1");
> > + BUG_ON(IS_ERR(clk));
> > +
> > + clk_enable(clk);
> > + rate = clk_get_rate(clk);
> > + clk_put(clk);
>
> Don't put a clock that you continue to use.
Ok, will remove the clk_put() here then.
Regards,
Ithamar.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 4/9] lpc2k: generic time and clockevents
2011-03-18 15:20 ` Russell King - ARM Linux
2011-03-18 15:44 ` Ithamar R. Adema
@ 2011-03-18 17:15 ` Kevin Wells
2011-03-18 18:32 ` Ithamar R. Adema
1 sibling, 1 reply; 22+ messages in thread
From: Kevin Wells @ 2011-03-18 17:15 UTC (permalink / raw)
To: linux-arm-kernel
>
> On Fri, Mar 18, 2011 at 04:11:51PM +0100, Ithamar R. Adema wrote:
> > + clk = clk_get(NULL, "timer1");
> > + BUG_ON(IS_ERR(clk));
I didn't see a specific enable for timer0, it seems to work for me
because my boot loader leaves it on when booting the kernel, but
maybe it's also needed.
> > +
> > + clk_enable(clk);
> > + rate = clk_get_rate(clk);
> > + clk_put(clk);
>
> Don't put a clock that you continue to use.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 5/9] lpc2k: gpiolib
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
` (3 preceding siblings ...)
2011-03-18 15:11 ` [PATCH v2 4/9] lpc2k: generic time and clockevents Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 15:11 ` [PATCH v2 6/9] lpc2k: multifunction pin configuration Ithamar R. Adema
` (3 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
gpiolib support, including gpio interrupts.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
no changes since v1.
---
arch/arm/Kconfig | 1 +
arch/arm/mach-lpc2k/Makefile | 2 +-
arch/arm/mach-lpc2k/gpio.c | 265 +++++++++++++++++++++++++++
arch/arm/mach-lpc2k/include/mach/gpio.h | 22 +++
arch/arm/mach-lpc2k/include/mach/hardware.h | 2 +
arch/arm/mach-lpc2k/include/mach/irqs.h | 69 +++++++-
6 files changed, 359 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/mach-lpc2k/gpio.c
create mode 100644 arch/arm/mach-lpc2k/include/mach/gpio.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ddec518..de826e9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -499,6 +499,7 @@ config ARCH_LPC2K
select CLKDEV_LOOKUP
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
help
Support for NXP LPC2K family of SoCs. These SoCs are based on
an ARM7TDMI-S core, and have optional on-chip flash and SRAM,
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 267432c..89596a7 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y := clock.o irq.o time.o
+obj-y := clock.o irq.o gpio.o time.o
diff --git a/arch/arm/mach-lpc2k/gpio.c b/arch/arm/mach-lpc2k/gpio.c
new file mode 100644
index 0000000..44f0eb9
--- /dev/null
+++ b/arch/arm/mach-lpc2k/gpio.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#define LPC2K_GPIO_CHIP(name, base_gpio, nr_gpio, irqbase) \
+ { \
+ .chip = { \
+ .label = name, \
+ .direction_input = lpc2k_dir_input, \
+ .direction_output = lpc2k_dir_output, \
+ .to_irq = lpc2k_to_irq, \
+ .get = lpc2k_gpio_get, \
+ .set = lpc2k_gpio_set, \
+ .base = base_gpio, \
+ .ngpio = nr_gpio, \
+ }, \
+ .irq_base = irqbase, \
+ }
+
+#define to_lpc2k_gpio_chip(c) container_of(c, struct lpc2k_gpio_chip, chip)
+
+#define FIODIR 0x00
+#define FIOMASK 0x10
+#define FIOPIN 0x14
+#define FIOSET 0x18
+#define FIOCLR 0x1c
+
+struct lpc2k_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *regbase;
+ int irq_base;
+ spinlock_t gpio_lock;
+};
+
+static int lpc2k_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+ if (lpc2k_gpio->irq_base < 0)
+ return -EINVAL;
+
+ return lpc2k_gpio->irq_base + offset;
+}
+
+static int lpc2k_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+
+ return !!(readl(lpc2k_gpio->regbase + FIOPIN) & (1 << offset));
+}
+
+static void lpc2k_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+
+ writel(1 << offset, lpc2k_gpio->regbase + (val ? FIOSET : FIOCLR));
+}
+
+static int lpc2k_dir_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+ void __iomem *pio = lpc2k_gpio->regbase + FIODIR;
+ unsigned int regval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lpc2k_gpio->gpio_lock, flags);
+
+ regval = readl(pio);
+ regval &= ~(1 << offset);
+ writel(regval, pio);
+
+ spin_unlock_irqrestore(&lpc2k_gpio->gpio_lock, flags);
+
+ return 0;
+}
+
+static int lpc2k_dir_output(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+ unsigned int regval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lpc2k_gpio->gpio_lock, flags);
+
+ regval = readl(lpc2k_gpio->regbase + FIODIR);
+ regval |= (1 << offset);
+ writel(regval, lpc2k_gpio->regbase + FIODIR);
+
+ writel(1 << offset, lpc2k_gpio->regbase + (val ? FIOSET : FIOCLR));
+
+ spin_unlock_irqrestore(&lpc2k_gpio->gpio_lock, flags);
+
+ return 0;
+}
+
+static struct lpc2k_gpio_chip lpc2k_gpio[] = {
+ LPC2K_GPIO_CHIP("P0", 0, 32, IRQ_LPC2K_GPIO0),
+ LPC2K_GPIO_CHIP("P1", 32, 32, -1),
+ LPC2K_GPIO_CHIP("P2", 64, 32, IRQ_LPC2K_GPIO64),
+ LPC2K_GPIO_CHIP("P3", 96, 32, -1),
+ LPC2K_GPIO_CHIP("P4", 128, 32, -1),
+};
+
+#define IOINTSTAT 0x0080
+#define IO0INT 0x0084
+#define IO2INT 0x00a4
+
+#define IOINTSTATR 0x0000
+#define IOINTSTATF 0x0004
+#define IOINTCLR 0x0008
+#define IOINTENR 0x000c
+#define IOINTENF 0x0010
+
+static void lpc2k_gpio_enable_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned irq = d->irq & 31;
+ unsigned status = irq_to_desc(d->irq)->status;
+
+ status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+ if (!status)
+ status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+
+ if (status & IRQ_TYPE_EDGE_RISING)
+ writel(readl(base + IOINTENR) | (1 << irq), base + IOINTENR);
+ else
+ writel(readl(base + IOINTENR) & ~(1 << irq), base + IOINTENR);
+
+ if (status & IRQ_TYPE_EDGE_FALLING)
+ writel(readl(base + IOINTENF) | (1 << irq), base + IOINTENF);
+ else
+ writel(readl(base + IOINTENF) & ~(1 << irq), base + IOINTENF);
+}
+
+static void lpc2k_gpio_disable_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned irq = d->irq & 31;
+
+ writel(readl(base + IOINTENR) & ~(1 << irq), base + IOINTENR);
+ writel(readl(base + IOINTENF) & ~(1 << irq), base + IOINTENF);
+}
+
+static int lpc2k_gpio_set_type(struct irq_data *d, unsigned trigger)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ struct irq_desc *desc = irq_to_desc(d->irq);
+ unsigned irq = d->irq & 31;
+
+ if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ return -EINVAL;
+
+ desc->status &= ~IRQ_TYPE_SENSE_MASK;
+ desc->status |= trigger;
+
+ /* don't enable the IRQ if it's currently disabled */
+ if (desc->depth == 0) {
+ if (trigger & IRQ_TYPE_EDGE_RISING)
+ writel(readl(base + IOINTENR) | (1 << irq),
+ base + IOINTENR);
+ else
+ writel(readl(base + IOINTENR) & ~(1 << irq),
+ base + IOINTENR);
+
+ if (trigger & IRQ_TYPE_EDGE_FALLING)
+ writel(readl(base + IOINTENF) | (1 << irq),
+ base + IOINTENF);
+ else
+ writel(readl(base + IOINTENF) & ~(1 << irq),
+ base + IOINTENF);
+ }
+
+ return 0;
+}
+
+struct irq_chip gpio_irq_chip_p0 = {
+ .name = "GPIO-P0",
+ .irq_enable = lpc2k_gpio_enable_irq,
+ .irq_disable = lpc2k_gpio_disable_irq,
+ .irq_set_type = lpc2k_gpio_set_type,
+};
+
+struct irq_chip gpio_irq_chip_p2 = {
+ .name = "GPIO-P2",
+ .irq_enable = lpc2k_gpio_enable_irq,
+ .irq_disable = lpc2k_gpio_disable_irq,
+ .irq_set_type = lpc2k_gpio_set_type,
+};
+
+static void lpc2k_demux_gpio_irq(unsigned int irq, struct irq_desc *desc)
+{
+ u32 status = readl(APB_GPIO_BASE + IOINTSTAT);
+ if (status & 1) {
+ int i, stat = readl(APB_GPIO_BASE + IO0INT + IOINTSTATR) |
+ readl(APB_GPIO_BASE + IO0INT + IOINTSTATF);
+
+ writel(stat, APB_GPIO_BASE + IO0INT + IOINTCLR);
+
+ for (i = 0; i < 32; i++)
+ if (stat & (1 << i))
+ generic_handle_irq(IRQ_LPC2K_GPIO0 + i);
+ }
+
+ if (status & 4) {
+ int i, stat = readl(APB_GPIO_BASE + IO2INT + IOINTSTATR) |
+ readl(APB_GPIO_BASE + IO2INT + IOINTSTATF);
+
+ writel(stat, APB_GPIO_BASE + IO2INT + IOINTCLR);
+
+ for (i = 0; i < 32; i++)
+ if (stat & (1 << i))
+ generic_handle_irq(IRQ_LPC2K_GPIO64 + i);
+ }
+}
+
+static int __init lpc2k_init_gpio(void)
+{
+ struct lpc2k_gpio_chip *gpio_chip;
+ void __iomem *base;
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(lpc2k_gpio); i++) {
+ gpio_chip = &lpc2k_gpio[i];
+ spin_lock_init(&gpio_chip->gpio_lock);
+ gpio_chip->regbase =
+ (void __iomem *)(FAST_GPIO_BASE + i * 0x20);
+ gpiochip_add(&gpio_chip->chip);
+
+ writel(0, gpio_chip->regbase + FIOMASK);
+ }
+
+ base = (void __iomem *)(APB_GPIO_BASE + IO0INT);
+ for (i = IRQ_LPC2K_GPIO0; i <= IRQ_LPC2K_GPIO31; i++) {
+ set_irq_chip(i, &gpio_irq_chip_p0);
+ set_irq_chip_data(i, base);
+ set_irq_handler(i, handle_simple_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+
+ base = (void __iomem *)(APB_GPIO_BASE + IO2INT);
+ for (i = IRQ_LPC2K_GPIO64; i <= IRQ_LPC2K_GPIO95; i++) {
+ set_irq_chip(i, &gpio_irq_chip_p2);
+ set_irq_chip_data(i, base);
+ set_irq_handler(i, handle_simple_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+
+ set_irq_chained_handler(IRQ_LPC2K_EINT3, lpc2k_demux_gpio_irq);
+
+ return 0;
+}
+
+postcore_initcall(lpc2k_init_gpio);
diff --git a/arch/arm/mach-lpc2k/include/mach/gpio.h b/arch/arm/mach-lpc2k/include/mach/gpio.h
new file mode 100644
index 0000000..efa970a
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/gpio.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ *
+ */
+
+#ifndef MACH_LPC2K_GPIO_H
+#define MACH_LPC2K_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+#endif /* MACH_LPC2K_GPIO_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
index 3463b47..b8c471b 100644
--- a/arch/arm/mach-lpc2k/include/mach/hardware.h
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -15,10 +15,12 @@
/* Default memory size if no ATAGS found */
#define MEM_SIZE (SZ_32M)
+#define FAST_GPIO_BASE 0x3fffc000
#define APB_WDT_BASE 0xe0000000
#define APB_TIMER0_BASE 0xe0004000
#define APB_TIMER1_BASE 0xe0008000
#define APB_UART0_BASE 0xe000c000
+#define APB_GPIO_BASE 0xe0028000
#define APB_SCB_BASE 0xe01fc000
#define APH_VIC_BASE 0xfffff000
diff --git a/arch/arm/mach-lpc2k/include/mach/irqs.h b/arch/arm/mach-lpc2k/include/mach/irqs.h
index 87b80dd..b7b2410 100644
--- a/arch/arm/mach-lpc2k/include/mach/irqs.h
+++ b/arch/arm/mach-lpc2k/include/mach/irqs.h
@@ -44,6 +44,73 @@
#define IRQ_LPC2K_I2C2 30
#define IRQ_LPC2K_I2S 31
-#define NR_IRQS 32
+#define IRQ_LPC2K_GPIO0 32
+#define IRQ_LPC2K_GPIO1 33
+#define IRQ_LPC2K_GPIO2 34
+#define IRQ_LPC2K_GPIO3 35
+#define IRQ_LPC2K_GPIO4 36
+#define IRQ_LPC2K_GPIO5 37
+#define IRQ_LPC2K_GPIO6 38
+#define IRQ_LPC2K_GPIO7 39
+#define IRQ_LPC2K_GPIO8 40
+#define IRQ_LPC2K_GPIO9 41
+#define IRQ_LPC2K_GPIO10 42
+#define IRQ_LPC2K_GPIO11 43
+#define IRQ_LPC2K_GPIO12 44
+#define IRQ_LPC2K_GPIO13 45
+#define IRQ_LPC2K_GPIO14 46
+#define IRQ_LPC2K_GPIO15 47
+#define IRQ_LPC2K_GPIO16 48
+#define IRQ_LPC2K_GPIO17 49
+#define IRQ_LPC2K_GPIO18 50
+#define IRQ_LPC2K_GPIO19 51
+#define IRQ_LPC2K_GPIO20 52
+#define IRQ_LPC2K_GPIO21 53
+#define IRQ_LPC2K_GPIO22 54
+#define IRQ_LPC2K_GPIO23 55
+#define IRQ_LPC2K_GPIO24 56
+#define IRQ_LPC2K_GPIO25 57
+#define IRQ_LPC2K_GPIO26 58
+#define IRQ_LPC2K_GPIO27 59
+#define IRQ_LPC2K_GPIO28 60
+#define IRQ_LPC2K_GPIO29 61
+#define IRQ_LPC2K_GPIO30 62
+#define IRQ_LPC2K_GPIO31 63
+
+/* GPIO P2 */
+#define IRQ_LPC2K_GPIO64 64
+#define IRQ_LPC2K_GPIO65 65
+#define IRQ_LPC2K_GPIO66 66
+#define IRQ_LPC2K_GPIO67 67
+#define IRQ_LPC2K_GPIO68 68
+#define IRQ_LPC2K_GPIO69 69
+#define IRQ_LPC2K_GPIO70 70
+#define IRQ_LPC2K_GPIO71 71
+#define IRQ_LPC2K_GPIO72 72
+#define IRQ_LPC2K_GPIO73 73
+#define IRQ_LPC2K_GPIO74 74
+#define IRQ_LPC2K_GPIO75 75
+#define IRQ_LPC2K_GPIO76 76
+#define IRQ_LPC2K_GPIO77 77
+#define IRQ_LPC2K_GPIO78 78
+#define IRQ_LPC2K_GPIO79 79
+#define IRQ_LPC2K_GPIO80 80
+#define IRQ_LPC2K_GPIO81 81
+#define IRQ_LPC2K_GPIO82 82
+#define IRQ_LPC2K_GPIO83 83
+#define IRQ_LPC2K_GPIO84 84
+#define IRQ_LPC2K_GPIO85 85
+#define IRQ_LPC2K_GPIO86 86
+#define IRQ_LPC2K_GPIO87 87
+#define IRQ_LPC2K_GPIO88 88
+#define IRQ_LPC2K_GPIO89 89
+#define IRQ_LPC2K_GPIO90 90
+#define IRQ_LPC2K_GPIO91 91
+#define IRQ_LPC2K_GPIO92 92
+#define IRQ_LPC2K_GPIO93 93
+#define IRQ_LPC2K_GPIO94 94
+#define IRQ_LPC2K_GPIO95 95
+
+#define NR_IRQS 96
#endif /* MACH_LPC2K_IRQS_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 6/9] lpc2k: multifunction pin configuration
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
` (4 preceding siblings ...)
2011-03-18 15:11 ` [PATCH v2 5/9] lpc2k: gpiolib Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 17:42 ` Kevin Wells
2011-03-18 15:11 ` [PATCH v2 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board Ithamar R. Adema
` (2 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Inspired by the mfp support in PXA. Includes definition of pins
for NXP LPC2468/78.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
no changes since v1.
---
arch/arm/mach-lpc2k/Makefile | 2 +-
arch/arm/mach-lpc2k/include/mach/hardware.h | 1 +
arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h | 98 +++++++++++
arch/arm/mach-lpc2k/include/mach/mfp.h | 209 ++++++++++++++++++++++++
arch/arm/mach-lpc2k/mfp.c | 99 +++++++++++
5 files changed, 408 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
create mode 100644 arch/arm/mach-lpc2k/include/mach/mfp.h
create mode 100644 arch/arm/mach-lpc2k/mfp.c
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 89596a7..2c50bb9 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y := clock.o irq.o gpio.o time.o
+obj-y := clock.o irq.o gpio.o mfp.o time.o
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
index b8c471b..1a20126 100644
--- a/arch/arm/mach-lpc2k/include/mach/hardware.h
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -21,6 +21,7 @@
#define APB_TIMER1_BASE 0xe0008000
#define APB_UART0_BASE 0xe000c000
#define APB_GPIO_BASE 0xe0028000
+#define APB_PINSEL_BASE 0xe002c000
#define APB_SCB_BASE 0xe01fc000
#define APH_VIC_BASE 0xfffff000
diff --git a/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h b/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
new file mode 100644
index 0000000..9b6bec4
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_MFP_LPC24XX_H
+#define MACH_LPC2K_MFP_LPC24XX_H
+
+#include <mach/mfp.h>
+
+#define GPIO0_RD1 MFP_CFG(GPIO0, AF1)
+#define GPIO0_TXD3 MFP_CFG(GPIO0, AF2)
+#define GPIO0_SDA1 MFP_CFG(GPIO0, AF3)
+#define GPIO1_TD1 MFP_CFG(GPIO1, AF1)
+#define GPIO1_RXD3 MFP_CFG(GPIO1, AF2)
+#define GPIO1_SCL1 MFP_CFG(GPIO1, AF3)
+#define GPIO2_TXD0 MFP_CFG(GPIO2, AF1)
+#define GPIO3_RXD0 MFP_CFG(GPIO3, AF1)
+#define GPIO4_LCDVD0 MFP_CFG(GPIO4, AF1)
+#define GPIO5_LCDVD1 MFP_CFG(GPIO5, AF1)
+#define GPIO6_LCDVD8 MFP_CFG(GPIO6, AF1)
+#define GPIO7_LCDVD9 MFP_CFG(GPIO7, AF1)
+#define GPIO8_LCDVD16 MFP_CFG(GPIO8, AF1)
+#define GPIO9_LCDVD17 MFP_CFG(GPIO9, AF1)
+#define GPIO10_TXD2 MFP_CFG(GPIO10, AF1)
+#define GPIO11_RXD2 MFP_CFG(GPIO11, AF1)
+#define GPIO12_USB_PPWR2 MFP_CFG(GPIO12, AF1)
+#define GPIO13_USB_UP_LED2 MFP_CFG(GPIO13, AF1)
+#define GPIO15_SCK MFP_CFG(GPIO15, AF3)
+#define GPIO17_MISO MFP_CFG(GPIO17, AF3)
+#define GPIO18_MOSI MFP_CFG(GPIO18, AF3)
+#define GPIO27_SDA0 MFP_CFG(GPIO27, AF1)
+#define GPIO28_SCL0 MFP_CFG(GPIO28, AF1)
+#define GPIO29_USB_Dp1 MFP_CFG(GPIO29, AF1)
+#define GPIO30_USB_Dn1 MFP_CFG(GPIO30, AF1)
+#define GPIO31_USB_Dp2 MFP_CFG(GPIO31, AF1)
+#define GPIO32_ENET_TXD0 MFP_CFG(GPIO32, AF1)
+#define GPIO33_ENET_TXD1 MFP_CFG(GPIO33, AF1)
+#define GPIO34_MCICLK MFP_CFG(GPIO34, AF2)
+#define GPIO35_MCICMD MFP_CFG(GPIO35, AF2)
+#define GPIO36_ENET_TX_EN MFP_CFG(GPIO36, AF1)
+#define GPIO37_MCIPWR MFP_CFG(GPIO37, AF2)
+#define GPIO38_ENET_TX_CLK MFP_CFG(GPIO38, AF1)
+#define GPIO38_MCIDAT0 MFP_CFG(GPIO38, AF2)
+#define GPIO39_MCIDAT1 MFP_CFG(GPIO39, AF2)
+#define GPIO40_ENET_CRS MFP_CFG(GPIO40, AF1)
+#define GPIO41_ENET_RXD0 MFP_CFG(GPIO41, AF1)
+#define GPIO42_ENET_RXD1 MFP_CFG(GPIO42, AF1)
+#define GPIO43_MCIDAT2 MFP_CFG(GPIO43, AF2)
+#define GPIO44_MCIDAT3 MFP_CFG(GPIO44, AF2)
+#define GPIO46_ENET_RX_ERR MFP_CFG(GPIO46, AF1)
+#define GPIO47_ENET_REF_CLK MFP_CFG(GPIO47, AF1)
+#define GPIO48_ENET_MDC MFP_CFG(GPIO48, AF1)
+#define GPIO49_ENET_MDIO MFP_CFG(GPIO49, AF1)
+#define GPIO50_PWM1 MFP_CFG(GPIO50, AF2)
+#define GPIO52_LCDVD10 MFP_CFG(GPIO52, AF1)
+#define GPIO53_LCDVD11 MFP_CFG(GPIO53, AF1)
+#define GPIO54_LCDVD12 MFP_CFG(GPIO54, AF1)
+#define GPIO55_LCDVD13 MFP_CFG(GPIO55, AF1)
+#define GPIO56_LCDVD14 MFP_CFG(GPIO56, AF1)
+#define GPIO57_LCDVD15 MFP_CFG(GPIO57, AF1)
+#define GPIO58_LCDVD20 MFP_CFG(GPIO58, AF1)
+#define GPIO59_LCDVD21 MFP_CFG(GPIO59, AF1)
+#define GPIO60_LCDVD22 MFP_CFG(GPIO60, AF1)
+#define GPIO61_LCDVD23 MFP_CFG(GPIO61, AF1)
+#define GPIO62_VBUS MFP_CFG(GPIO62, AF2)
+#define GPIO63_USB_OVRCR2 MFP_CFG(GPIO63, AF1)
+#define GPIO64_LCDPWR MFP_CFG(GPIO64, AF3)
+#define GPIO65_LCDLE MFP_CFG(GPIO65, AF3)
+#define GPIO66_LCDDCLK MFP_CFG(GPIO66, AF3)
+#define GPIO67_LCDFP MFP_CFG(GPIO67, AF3)
+#define GPIO68_LCDM MFP_CFG(GPIO68, AF3)
+#define GPIO69_LCDLP MFP_CFG(GPIO69, AF3)
+#define GPIO70_LCDVP4 MFP_CFG(GPIO70, AF3)
+#define GPIO71_LCDVP5 MFP_CFG(GPIO71, AF3)
+#define GPIO72_LCDVP6 MFP_CFG(GPIO72, AF3)
+#define GPIO73_LCDVP7 MFP_CFG(GPIO73, AF3)
+#define GPIO75_LCDCLKIN MFP_CFG(GPIO75, AF1)
+#define GPIO76_LCDVP18 MFP_CFG(GPIO76, AF1)
+#define GPIO77_LCDVP19 MFP_CFG(GPIO77, AF1)
+#define GPIO112_TXD1 MFP_CFG(GPIO112, AF3)
+#define GPIO113_RXD1 MFP_CFG(GPIO113, AF3)
+#define GPIO114_CTS1 MFP_CFG(GPIO114, AF3)
+#define GPIO115_DCD1 MFP_CFG(GPIO115, AF3)
+#define GPIO116_DSR1 MFP_CFG(GPIO116, AF3)
+#define GPIO117_DR1 MFP_CFG(GPIO117, AF3)
+#define GPIO118_RI1 MFP_CFG(GPIO118, AF3)
+#define GPIO126_RTS1 MFP_CFG(GPIO126, AF3)
+#define GPIO156_TXD3 MFP_CFG(GPIO156, AF3)
+#define GPIO156_LCDVP2 MFP_CFG(GPIO156, AF2)
+#define GPIO157_RXD3 MFP_CFG(GPIO157, AF3)
+#define GPIO157_LCDVP3 MFP_CFG(GPIO157, AF2)
+
+#endif /* MACH_LPC2K_MFP_LPC24XX_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/mfp.h b/arch/arm/mach-lpc2k/include/mach/mfp.h
new file mode 100644
index 0000000..3c919c8
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/mfp.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 ARCH_LPC2K_MFP_H
+#define ARCH_LPC2K_MFP_H
+
+#define mfp_to_gpio(m) ((m) % 160)
+
+/* list of all the configurable MFP pins */
+enum {
+ MFP_PIN_INVALID = -1,
+
+ MFP_PIN_GPIO0 = 0,
+ MFP_PIN_GPIO1,
+ MFP_PIN_GPIO2,
+ MFP_PIN_GPIO3,
+ MFP_PIN_GPIO4,
+ MFP_PIN_GPIO5,
+ MFP_PIN_GPIO6,
+ MFP_PIN_GPIO7,
+ MFP_PIN_GPIO8,
+ MFP_PIN_GPIO9,
+ MFP_PIN_GPIO10,
+ MFP_PIN_GPIO11,
+ MFP_PIN_GPIO12,
+ MFP_PIN_GPIO13,
+ MFP_PIN_GPIO14,
+ MFP_PIN_GPIO15,
+ MFP_PIN_GPIO16,
+ MFP_PIN_GPIO17,
+ MFP_PIN_GPIO18,
+ MFP_PIN_GPIO19,
+ MFP_PIN_GPIO20,
+ MFP_PIN_GPIO21,
+ MFP_PIN_GPIO22,
+ MFP_PIN_GPIO23,
+ MFP_PIN_GPIO24,
+ MFP_PIN_GPIO25,
+ MFP_PIN_GPIO26,
+ MFP_PIN_GPIO27,
+ MFP_PIN_GPIO28,
+ MFP_PIN_GPIO29,
+ MFP_PIN_GPIO30,
+ MFP_PIN_GPIO31,
+ MFP_PIN_GPIO32,
+ MFP_PIN_GPIO33,
+ MFP_PIN_GPIO34,
+ MFP_PIN_GPIO35,
+ MFP_PIN_GPIO36,
+ MFP_PIN_GPIO37,
+ MFP_PIN_GPIO38,
+ MFP_PIN_GPIO39,
+ MFP_PIN_GPIO40,
+ MFP_PIN_GPIO41,
+ MFP_PIN_GPIO42,
+ MFP_PIN_GPIO43,
+ MFP_PIN_GPIO44,
+ MFP_PIN_GPIO45,
+ MFP_PIN_GPIO46,
+ MFP_PIN_GPIO47,
+ MFP_PIN_GPIO48,
+ MFP_PIN_GPIO49,
+ MFP_PIN_GPIO50,
+ MFP_PIN_GPIO51,
+ MFP_PIN_GPIO52,
+ MFP_PIN_GPIO53,
+ MFP_PIN_GPIO54,
+ MFP_PIN_GPIO55,
+ MFP_PIN_GPIO56,
+ MFP_PIN_GPIO57,
+ MFP_PIN_GPIO58,
+ MFP_PIN_GPIO59,
+ MFP_PIN_GPIO60,
+ MFP_PIN_GPIO61,
+ MFP_PIN_GPIO62,
+ MFP_PIN_GPIO63,
+ MFP_PIN_GPIO64,
+ MFP_PIN_GPIO65,
+ MFP_PIN_GPIO66,
+ MFP_PIN_GPIO67,
+ MFP_PIN_GPIO68,
+ MFP_PIN_GPIO69,
+ MFP_PIN_GPIO70,
+ MFP_PIN_GPIO71,
+ MFP_PIN_GPIO72,
+ MFP_PIN_GPIO73,
+ MFP_PIN_GPIO74,
+ MFP_PIN_GPIO75,
+ MFP_PIN_GPIO76,
+ MFP_PIN_GPIO77,
+ MFP_PIN_GPIO78,
+ MFP_PIN_GPIO79,
+ MFP_PIN_GPIO80,
+ MFP_PIN_GPIO81,
+ MFP_PIN_GPIO82,
+ MFP_PIN_GPIO83,
+ MFP_PIN_GPIO84,
+ MFP_PIN_GPIO85,
+ MFP_PIN_GPIO86,
+ MFP_PIN_GPIO87,
+ MFP_PIN_GPIO88,
+ MFP_PIN_GPIO89,
+ MFP_PIN_GPIO90,
+ MFP_PIN_GPIO91,
+ MFP_PIN_GPIO92,
+ MFP_PIN_GPIO93,
+ MFP_PIN_GPIO94,
+ MFP_PIN_GPIO95,
+ MFP_PIN_GPIO96,
+ MFP_PIN_GPIO97,
+ MFP_PIN_GPIO98,
+ MFP_PIN_GPIO99,
+ MFP_PIN_GPIO100,
+ MFP_PIN_GPIO101,
+ MFP_PIN_GPIO102,
+ MFP_PIN_GPIO103,
+ MFP_PIN_GPIO104,
+ MFP_PIN_GPIO105,
+ MFP_PIN_GPIO106,
+ MFP_PIN_GPIO107,
+ MFP_PIN_GPIO108,
+ MFP_PIN_GPIO109,
+ MFP_PIN_GPIO110,
+ MFP_PIN_GPIO111,
+ MFP_PIN_GPIO112,
+ MFP_PIN_GPIO113,
+ MFP_PIN_GPIO114,
+ MFP_PIN_GPIO115,
+ MFP_PIN_GPIO116,
+ MFP_PIN_GPIO117,
+ MFP_PIN_GPIO118,
+ MFP_PIN_GPIO119,
+ MFP_PIN_GPIO120,
+ MFP_PIN_GPIO121,
+ MFP_PIN_GPIO122,
+ MFP_PIN_GPIO123,
+ MFP_PIN_GPIO124,
+ MFP_PIN_GPIO125,
+ MFP_PIN_GPIO126,
+ MFP_PIN_GPIO127,
+ MFP_PIN_GPIO128,
+ MFP_PIN_GPIO129,
+ MFP_PIN_GPIO130,
+ MFP_PIN_GPIO131,
+ MFP_PIN_GPIO132,
+ MFP_PIN_GPIO133,
+ MFP_PIN_GPIO134,
+ MFP_PIN_GPIO135,
+ MFP_PIN_GPIO136,
+ MFP_PIN_GPIO137,
+ MFP_PIN_GPIO138,
+ MFP_PIN_GPIO139,
+ MFP_PIN_GPIO140,
+ MFP_PIN_GPIO141,
+ MFP_PIN_GPIO142,
+ MFP_PIN_GPIO143,
+ MFP_PIN_GPIO144,
+ MFP_PIN_GPIO145,
+ MFP_PIN_GPIO146,
+ MFP_PIN_GPIO147,
+ MFP_PIN_GPIO148,
+ MFP_PIN_GPIO149,
+ MFP_PIN_GPIO150,
+ MFP_PIN_GPIO151,
+ MFP_PIN_GPIO152,
+ MFP_PIN_GPIO153,
+ MFP_PIN_GPIO154,
+ MFP_PIN_GPIO155,
+ MFP_PIN_GPIO156,
+ MFP_PIN_GPIO157,
+ MFP_PIN_GPIO158,
+ MFP_PIN_GPIO159,
+};
+
+/* pin number; currently only 0-159 are used */
+#define MFP_PIN(x) ((x) & 0x3ff)
+
+/* Alternate functions, currently only 0-3 are used */
+#define MFP_AF0 (0x0 << 10)
+#define MFP_AF1 (0x1 << 10)
+#define MFP_AF2 (0x2 << 10)
+#define MFP_AF3 (0x3 << 10)
+#define MFP_AF_MASK (0x3 << 10)
+#define MFP_AF(x) (((x) >> 10) & 0x3)
+
+/* Pullup/down configuration, currently only none/high/low are used */
+#define MFP_PULL_NONE (0x2 << 21)
+#define MFP_PULL_LOW (0x3 << 21)
+#define MFP_PULL_HIGH (0x0 << 21)
+#define MFP_PULL_MASK (0x3 << 21)
+#define MFP_PULL(x) (((x) >> 21) & 0x3)
+
+#define MFP_CFG_DEFAULT (MFP_PULL_HIGH | MFP_AF0)
+
+#define MFP_CFG(pin, af) \
+ ((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
+
+#define MFP_CFG_PULL(pin, af, pull) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_PULL_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##pull))
+
+#endif /* ARCH_LPC2K_MFP_H */
diff --git a/arch/arm/mach-lpc2k/mfp.c b/arch/arm/mach-lpc2k/mfp.c
new file mode 100644
index 0000000..6e4779d
--- /dev/null
+++ b/arch/arm/mach-lpc2k/mfp.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * Based on MFP code from mach-pxa.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+
+#define PINSEL(bank) (0x00 + (bank)*4)
+#define PINMODE(bank) (0x40 + (bank)*4)
+
+struct gpio_desc {
+ unsigned valid:1;
+ unsigned long config;
+};
+
+static struct gpio_desc gpio_desc[MFP_PIN_GPIO159 + 1];
+
+static int __mfp_config_gpio(unsigned gpio, unsigned long c)
+{
+ unsigned bank = gpio >> 4;
+ unsigned shift = (gpio & 0xf) * 2;
+ unsigned val;
+
+ /* Configure alternate function */
+ val = __raw_readl(APB_PINSEL_BASE + PINSEL(bank));
+ if ((val & (3 << shift)) &&
+ (val & (3 << shift)) != (MFP_AF(c) << shift))
+ pr_warning
+ ("GPIO%d is already configured (%x), not reconfigured!\n",
+ gpio, (val & (3 << shift)) >> shift);
+ else {
+ val &= ~(0x3 << shift);
+ val |= MFP_AF(c) << shift;
+ __raw_writel(val, APB_PINSEL_BASE + PINSEL(bank));
+ }
+
+ /* Configuration pullup/dn */
+ val = __raw_readl(APB_PINSEL_BASE + PINMODE(bank));
+ val &= ~(0x3 << shift);
+ val |= MFP_PULL(c) << shift;
+ __raw_writel(val, APB_PINSEL_BASE + PINMODE(bank));
+
+ return 0;
+}
+
+static inline int __mfp_validate(int mfp)
+{
+ int gpio = mfp_to_gpio(mfp);
+
+ if (!gpio_desc[gpio].valid) {
+ pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
+ return -1;
+ }
+
+ return gpio;
+}
+
+void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num)
+{
+ unsigned long flags;
+ unsigned long *c;
+ int i, gpio;
+
+ for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
+
+ gpio = __mfp_validate(MFP_PIN(*c));
+ if (gpio < 0)
+ continue;
+
+ local_irq_save(flags);
+
+ gpio_desc[gpio].config = *c;
+ __mfp_config_gpio(gpio, *c);
+
+ local_irq_restore(flags);
+ }
+}
+
+static int __init lpc2k_mfp_init(void)
+{
+ int i;
+
+ for (i = MFP_PIN_GPIO0; i <= MFP_PIN_GPIO159; i++)
+ gpio_desc[i].valid = 1;
+
+ return 0;
+}
+
+postcore_initcall(lpc2k_mfp_init);
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 6/9] lpc2k: multifunction pin configuration
2011-03-18 15:11 ` [PATCH v2 6/9] lpc2k: multifunction pin configuration Ithamar R. Adema
@ 2011-03-18 17:42 ` Kevin Wells
2011-03-18 19:55 ` Ithamar R. Adema
0 siblings, 1 reply; 22+ messages in thread
From: Kevin Wells @ 2011-03-18 17:42 UTC (permalink / raw)
To: linux-arm-kernel
> +
> +#ifndef MACH_LPC2K_MFP_LPC24XX_H
> +#define MACH_LPC2K_MFP_LPC24XX_H
> +
> +#include <mach/mfp.h>
> +
> +#define GPIO0_RD1 MFP_CFG(GPIO0, AF1)
> +#define GPIO0_TXD3 MFP_CFG(GPIO0, AF2)
> +#define GPIO0_SDA1 MFP_CFG(GPIO0, AF3)
> +#define GPIO1_TD1 MFP_CFG(GPIO1, AF1)
> +#define GPIO1_RXD3 MFP_CFG(GPIO1, AF2)
> +#define GPIO1_SCL1 MFP_CFG(GPIO1, AF3)
> +#define GPIO2_TXD0 MFP_CFG(GPIO2, AF1)
> +#define GPIO3_RXD0 MFP_CFG(GPIO3, AF1)
> +#define GPIO4_LCDVD0 MFP_CFG(GPIO4, AF1)
> +#define GPIO5_LCDVD1 MFP_CFG(GPIO5, AF1)
> +#define GPIO6_LCDVD8 MFP_CFG(GPIO6, AF1)
> +#define GPIO7_LCDVD9 MFP_CFG(GPIO7, AF1)
> +#define GPIO8_LCDVD16 MFP_CFG(GPIO8, AF1)
> +#define GPIO9_LCDVD17 MFP_CFG(GPIO9, AF1)
> +#define GPIO10_TXD2 MFP_CFG(GPIO10, AF1)
> +#define GPIO11_RXD2 MFP_CFG(GPIO11, AF1)
> +#define GPIO12_USB_PPWR2 MFP_CFG(GPIO12, AF1)
> +#define GPIO13_USB_UP_LED2 MFP_CFG(GPIO13, AF1)
> +#define GPIO15_SCK MFP_CFG(GPIO15, AF3)
> +#define GPIO17_MISO MFP_CFG(GPIO17, AF3)
> +#define GPIO18_MOSI MFP_CFG(GPIO18, AF3)
> +#define GPIO27_SDA0 MFP_CFG(GPIO27, AF1)
> +#define GPIO28_SCL0 MFP_CFG(GPIO28, AF1)
> +#define GPIO29_USB_Dp1 MFP_CFG(GPIO29, AF1)
> +#define GPIO30_USB_Dn1 MFP_CFG(GPIO30, AF1)
> +#define GPIO31_USB_Dp2 MFP_CFG(GPIO31, AF1)
> +#define GPIO32_ENET_TXD0 MFP_CFG(GPIO32, AF1)
> +#define GPIO33_ENET_TXD1 MFP_CFG(GPIO33, AF1)
> +#define GPIO34_MCICLK MFP_CFG(GPIO34, AF2)
> +#define GPIO35_MCICMD MFP_CFG(GPIO35, AF2)
> +#define GPIO36_ENET_TX_EN MFP_CFG(GPIO36, AF1)
> +#define GPIO37_MCIPWR MFP_CFG(GPIO37, AF2)
> +#define GPIO38_ENET_TX_CLK MFP_CFG(GPIO38, AF1)
> +#define GPIO38_MCIDAT0 MFP_CFG(GPIO38, AF2)
> +#define GPIO39_MCIDAT1 MFP_CFG(GPIO39, AF2)
> +#define GPIO40_ENET_CRS MFP_CFG(GPIO40, AF1)
> +#define GPIO41_ENET_RXD0 MFP_CFG(GPIO41, AF1)
> +#define GPIO42_ENET_RXD1 MFP_CFG(GPIO42, AF1)
> +#define GPIO43_MCIDAT2 MFP_CFG(GPIO43, AF2)
> +#define GPIO44_MCIDAT3 MFP_CFG(GPIO44, AF2)
> +#define GPIO46_ENET_RX_ERR MFP_CFG(GPIO46, AF1)
> +#define GPIO47_ENET_REF_CLK MFP_CFG(GPIO47, AF1)
> +#define GPIO48_ENET_MDC MFP_CFG(GPIO48, AF1)
> +#define GPIO49_ENET_MDIO MFP_CFG(GPIO49, AF1)
> +#define GPIO50_PWM1 MFP_CFG(GPIO50, AF2)
> +#define GPIO52_LCDVD10 MFP_CFG(GPIO52, AF1)
> +#define GPIO53_LCDVD11 MFP_CFG(GPIO53, AF1)
> +#define GPIO54_LCDVD12 MFP_CFG(GPIO54, AF1)
> +#define GPIO55_LCDVD13 MFP_CFG(GPIO55, AF1)
> +#define GPIO56_LCDVD14 MFP_CFG(GPIO56, AF1)
> +#define GPIO57_LCDVD15 MFP_CFG(GPIO57, AF1)
> +#define GPIO58_LCDVD20 MFP_CFG(GPIO58, AF1)
> +#define GPIO59_LCDVD21 MFP_CFG(GPIO59, AF1)
> +#define GPIO60_LCDVD22 MFP_CFG(GPIO60, AF1)
> +#define GPIO61_LCDVD23 MFP_CFG(GPIO61, AF1)
> +#define GPIO62_VBUS MFP_CFG(GPIO62, AF2)
> +#define GPIO63_USB_OVRCR2 MFP_CFG(GPIO63, AF1)
> +#define GPIO64_LCDPWR MFP_CFG(GPIO64, AF3)
> +#define GPIO65_LCDLE MFP_CFG(GPIO65, AF3)
> +#define GPIO66_LCDDCLK MFP_CFG(GPIO66, AF3)
> +#define GPIO67_LCDFP MFP_CFG(GPIO67, AF3)
> +#define GPIO68_LCDM MFP_CFG(GPIO68, AF3)
> +#define GPIO69_LCDLP MFP_CFG(GPIO69, AF3)
> +#define GPIO70_LCDVP4 MFP_CFG(GPIO70, AF3)
> +#define GPIO71_LCDVP5 MFP_CFG(GPIO71, AF3)
> +#define GPIO72_LCDVP6 MFP_CFG(GPIO72, AF3)
> +#define GPIO73_LCDVP7 MFP_CFG(GPIO73, AF3)
> +#define GPIO75_LCDCLKIN MFP_CFG(GPIO75, AF1)
> +#define GPIO76_LCDVP18 MFP_CFG(GPIO76, AF1)
> +#define GPIO77_LCDVP19 MFP_CFG(GPIO77, AF1)
> +#define GPIO112_TXD1 MFP_CFG(GPIO112, AF3)
> +#define GPIO113_RXD1 MFP_CFG(GPIO113, AF3)
> +#define GPIO114_CTS1 MFP_CFG(GPIO114, AF3)
> +#define GPIO115_DCD1 MFP_CFG(GPIO115, AF3)
> +#define GPIO116_DSR1 MFP_CFG(GPIO116, AF3)
> +#define GPIO117_DR1 MFP_CFG(GPIO117, AF3)
> +#define GPIO118_RI1 MFP_CFG(GPIO118, AF3)
> +#define GPIO126_RTS1 MFP_CFG(GPIO126, AF3)
> +#define GPIO156_TXD3 MFP_CFG(GPIO156, AF3)
> +#define GPIO156_LCDVP2 MFP_CFG(GPIO156, AF2)
> +#define GPIO157_RXD3 MFP_CFG(GPIO157, AF3)
> +#define GPIO157_LCDVP3 MFP_CFG(GPIO157, AF2)
> +
> +#endif /* MACH_LPC2K_MFP_LPC24XX_H */
> diff --git a/arch/arm/mach-lpc2k/include/mach/mfp.h b/arch/arm/mach-
> lpc2k/include/mach/mfp.h
> new file mode 100644
> index 0000000..3c919c8
> --- /dev/null
> +++ b/arch/arm/mach-lpc2k/include/mach/mfp.h
> @@ -0,0 +1,209 @@
> +/*
> + * Copyright 2011 Team Embedded VOF
> + * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
> + *
> + * 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 ARCH_LPC2K_MFP_H
> +#define ARCH_LPC2K_MFP_H
> +
> +#define mfp_to_gpio(m) ((m) % 160)
> +
> +/* list of all the configurable MFP pins */
> +enum {
> + MFP_PIN_INVALID = -1,
> +
> + MFP_PIN_GPIO0 = 0,
> + MFP_PIN_GPIO1,
> + MFP_PIN_GPIO2,
> + MFP_PIN_GPIO3,
> + MFP_PIN_GPIO4,
> + MFP_PIN_GPIO5,
> + MFP_PIN_GPIO6,
> + MFP_PIN_GPIO7,
> + MFP_PIN_GPIO8,
> + MFP_PIN_GPIO9,
> + MFP_PIN_GPIO10,
> + MFP_PIN_GPIO11,
> + MFP_PIN_GPIO12,
> + MFP_PIN_GPIO13,
> + MFP_PIN_GPIO14,
> + MFP_PIN_GPIO15,
> + MFP_PIN_GPIO16,
> + MFP_PIN_GPIO17,
> + MFP_PIN_GPIO18,
> + MFP_PIN_GPIO19,
> + MFP_PIN_GPIO20,
> + MFP_PIN_GPIO21,
> + MFP_PIN_GPIO22,
> + MFP_PIN_GPIO23,
> + MFP_PIN_GPIO24,
> + MFP_PIN_GPIO25,
> + MFP_PIN_GPIO26,
> + MFP_PIN_GPIO27,
> + MFP_PIN_GPIO28,
> + MFP_PIN_GPIO29,
> + MFP_PIN_GPIO30,
> + MFP_PIN_GPIO31,
> + MFP_PIN_GPIO32,
> + MFP_PIN_GPIO33,
> + MFP_PIN_GPIO34,
> + MFP_PIN_GPIO35,
> + MFP_PIN_GPIO36,
> + MFP_PIN_GPIO37,
> + MFP_PIN_GPIO38,
> + MFP_PIN_GPIO39,
> + MFP_PIN_GPIO40,
> + MFP_PIN_GPIO41,
> + MFP_PIN_GPIO42,
> + MFP_PIN_GPIO43,
> + MFP_PIN_GPIO44,
> + MFP_PIN_GPIO45,
> + MFP_PIN_GPIO46,
> + MFP_PIN_GPIO47,
> + MFP_PIN_GPIO48,
> + MFP_PIN_GPIO49,
> + MFP_PIN_GPIO50,
> + MFP_PIN_GPIO51,
> + MFP_PIN_GPIO52,
> + MFP_PIN_GPIO53,
> + MFP_PIN_GPIO54,
> + MFP_PIN_GPIO55,
> + MFP_PIN_GPIO56,
> + MFP_PIN_GPIO57,
> + MFP_PIN_GPIO58,
> + MFP_PIN_GPIO59,
> + MFP_PIN_GPIO60,
> + MFP_PIN_GPIO61,
> + MFP_PIN_GPIO62,
> + MFP_PIN_GPIO63,
> + MFP_PIN_GPIO64,
> + MFP_PIN_GPIO65,
> + MFP_PIN_GPIO66,
> + MFP_PIN_GPIO67,
> + MFP_PIN_GPIO68,
> + MFP_PIN_GPIO69,
> + MFP_PIN_GPIO70,
> + MFP_PIN_GPIO71,
> + MFP_PIN_GPIO72,
> + MFP_PIN_GPIO73,
> + MFP_PIN_GPIO74,
> + MFP_PIN_GPIO75,
> + MFP_PIN_GPIO76,
> + MFP_PIN_GPIO77,
> + MFP_PIN_GPIO78,
> + MFP_PIN_GPIO79,
> + MFP_PIN_GPIO80,
> + MFP_PIN_GPIO81,
> + MFP_PIN_GPIO82,
> + MFP_PIN_GPIO83,
> + MFP_PIN_GPIO84,
> + MFP_PIN_GPIO85,
> + MFP_PIN_GPIO86,
> + MFP_PIN_GPIO87,
> + MFP_PIN_GPIO88,
> + MFP_PIN_GPIO89,
> + MFP_PIN_GPIO90,
> + MFP_PIN_GPIO91,
> + MFP_PIN_GPIO92,
> + MFP_PIN_GPIO93,
> + MFP_PIN_GPIO94,
> + MFP_PIN_GPIO95,
> + MFP_PIN_GPIO96,
> + MFP_PIN_GPIO97,
> + MFP_PIN_GPIO98,
> + MFP_PIN_GPIO99,
> + MFP_PIN_GPIO100,
> + MFP_PIN_GPIO101,
> + MFP_PIN_GPIO102,
> + MFP_PIN_GPIO103,
> + MFP_PIN_GPIO104,
> + MFP_PIN_GPIO105,
> + MFP_PIN_GPIO106,
> + MFP_PIN_GPIO107,
> + MFP_PIN_GPIO108,
> + MFP_PIN_GPIO109,
> + MFP_PIN_GPIO110,
> + MFP_PIN_GPIO111,
> + MFP_PIN_GPIO112,
> + MFP_PIN_GPIO113,
> + MFP_PIN_GPIO114,
> + MFP_PIN_GPIO115,
> + MFP_PIN_GPIO116,
> + MFP_PIN_GPIO117,
> + MFP_PIN_GPIO118,
> + MFP_PIN_GPIO119,
> + MFP_PIN_GPIO120,
> + MFP_PIN_GPIO121,
> + MFP_PIN_GPIO122,
> + MFP_PIN_GPIO123,
> + MFP_PIN_GPIO124,
> + MFP_PIN_GPIO125,
> + MFP_PIN_GPIO126,
> + MFP_PIN_GPIO127,
> + MFP_PIN_GPIO128,
> + MFP_PIN_GPIO129,
> + MFP_PIN_GPIO130,
> + MFP_PIN_GPIO131,
> + MFP_PIN_GPIO132,
> + MFP_PIN_GPIO133,
> + MFP_PIN_GPIO134,
> + MFP_PIN_GPIO135,
> + MFP_PIN_GPIO136,
> + MFP_PIN_GPIO137,
> + MFP_PIN_GPIO138,
> + MFP_PIN_GPIO139,
> + MFP_PIN_GPIO140,
> + MFP_PIN_GPIO141,
> + MFP_PIN_GPIO142,
> + MFP_PIN_GPIO143,
> + MFP_PIN_GPIO144,
> + MFP_PIN_GPIO145,
> + MFP_PIN_GPIO146,
> + MFP_PIN_GPIO147,
> + MFP_PIN_GPIO148,
> + MFP_PIN_GPIO149,
> + MFP_PIN_GPIO150,
> + MFP_PIN_GPIO151,
> + MFP_PIN_GPIO152,
> + MFP_PIN_GPIO153,
> + MFP_PIN_GPIO154,
> + MFP_PIN_GPIO155,
> + MFP_PIN_GPIO156,
> + MFP_PIN_GPIO157,
> + MFP_PIN_GPIO158,
> + MFP_PIN_GPIO159,
> +};
> +
A small nit here..
You can replace this enum with a single macro, but it might be
a little easier all around to use the Px.y names for the GPIOs
instead of a just mapping the GPIO numbers linearly. This
follows the convention used in the LPC24XX User's guides,
EA schematics (at least 2468), and pin designations.
So..
MFP_PIN_GPIO0 maps to P0_0, MFP_PIN_GPIO32 maps to P1_0,
MFP_PIN_GPIO63 maps to P1_31, MFP_PIN_GPIO64 maps to P2_0, etc.
If this designation is used, you can see the mapping of a GPIO,
GPIO IRQ, or multi-function pin directly from the name and save
a little mental calculation converting the GPIOx numbers to Px_y
numbers when cross checking pin muxing and mapping.
This would affect GPIO_IRQ names, GPIOLIB names, and MFP names.
So something like..
> +#define GPIO0_RD1 MFP_CFG(GPIO0, AF1)
> +#define GPIO33_ENET_TXD1 MFP_CFG(GPIO33, AF1)
would be something like:
#define PGPIO(x, y) (((x) * 32) + (y))
#define GPIO0_RD1 MFP_CFG(PGPIO(0, 0), AF1)
#define GPIO33_ENET_TXD1 MFP_CFG(PGPIO(1, 1), AF1)
Likewise, with IRQ number mapping, you could used a single macro
definition for both P0[0, 31] and P2[0, 31] ranges. It would help
save some space.
> +/* pin number; currently only 0-159 are used */
> +#define MFP_PIN(x) ((x) & 0x3ff)
> +
> +/* Alternate functions, currently only 0-3 are used */
> +#define MFP_AF0 (0x0 << 10)
> +#define MFP_AF1 (0x1 << 10)
> +#define MFP_AF2 (0x2 << 10)
> +#define MFP_AF3 (0x3 << 10)
> +#define MFP_AF_MASK (0x3 << 10)
> +#define MFP_AF(x) (((x) >> 10) & 0x3)
> +
> +/* Pullup/down configuration, currently only none/high/low are used */
> +#define MFP_PULL_NONE (0x2 << 21)
> +#define MFP_PULL_LOW (0x3 << 21)
> +#define MFP_PULL_HIGH (0x0 << 21)
> +#define MFP_PULL_MASK (0x3 << 21)
> +#define MFP_PULL(x) (((x) >> 21) & 0x3)
> +
> +#define MFP_CFG_DEFAULT (MFP_PULL_HIGH | MFP_AF0)
> +
> +#define MFP_CFG(pin, af) \
> + ((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
> + (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
> +
> +#define MFP_CFG_PULL(pin, af, pull) \
> + ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_PULL_MASK)) |\
> + (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##pull))
> +
> +#endif /* ARCH_LPC2K_MFP_H */
> diff --git a/arch/arm/mach-lpc2k/mfp.c b/arch/arm/mach-lpc2k/mfp.c
> new file mode 100644
> index 0000000..6e4779d
> --- /dev/null
> +++ b/arch/arm/mach-lpc2k/mfp.c
> @@ -0,0 +1,99 @@
> +/*
> + * Copyright (C) 2011 Team Embeded VOF
> + * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
> + *
> + * Based on MFP code from mach-pxa.
> + *
> + * 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.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/io.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/mfp.h>
> +
> +#define PINSEL(bank) (0x00 + (bank)*4)
> +#define PINMODE(bank) (0x40 + (bank)*4)
> +
> +struct gpio_desc {
> + unsigned valid:1;
> + unsigned long config;
> +};
> +
> +static struct gpio_desc gpio_desc[MFP_PIN_GPIO159 + 1];
> +
> +static int __mfp_config_gpio(unsigned gpio, unsigned long c)
> +{
> + unsigned bank = gpio >> 4;
> + unsigned shift = (gpio & 0xf) * 2;
> + unsigned val;
> +
> + /* Configure alternate function */
> + val = __raw_readl(APB_PINSEL_BASE + PINSEL(bank));
> + if ((val & (3 << shift)) &&
> + (val & (3 << shift)) != (MFP_AF(c) << shift))
> + pr_warning
> + ("GPIO%d is already configured (%x), not reconfigured!\n",
> + gpio, (val & (3 << shift)) >> shift);
> + else {
> + val &= ~(0x3 << shift);
> + val |= MFP_AF(c) << shift;
> + __raw_writel(val, APB_PINSEL_BASE + PINSEL(bank));
> + }
> +
> + /* Configuration pullup/dn */
> + val = __raw_readl(APB_PINSEL_BASE + PINMODE(bank));
> + val &= ~(0x3 << shift);
> + val |= MFP_PULL(c) << shift;
> + __raw_writel(val, APB_PINSEL_BASE + PINMODE(bank));
> +
> + return 0;
> +}
> +
> +static inline int __mfp_validate(int mfp)
> +{
> + int gpio = mfp_to_gpio(mfp);
> +
> + if (!gpio_desc[gpio].valid) {
> + pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
> + return -1;
> + }
> +
> + return gpio;
> +}
> +
> +void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num)
> +{
> + unsigned long flags;
> + unsigned long *c;
> + int i, gpio;
> +
> + for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
> +
> + gpio = __mfp_validate(MFP_PIN(*c));
> + if (gpio < 0)
> + continue;
> +
> + local_irq_save(flags);
> +
> + gpio_desc[gpio].config = *c;
> + __mfp_config_gpio(gpio, *c);
> +
> + local_irq_restore(flags);
> + }
> +}
> +
> +static int __init lpc2k_mfp_init(void)
> +{
> + int i;
> +
> + for (i = MFP_PIN_GPIO0; i <= MFP_PIN_GPIO159; i++)
> + gpio_desc[i].valid = 1;
> +
> + return 0;
> +}
> +
> +postcore_initcall(lpc2k_mfp_init);
> --
> 1.7.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 6/9] lpc2k: multifunction pin configuration
2011-03-18 17:42 ` Kevin Wells
@ 2011-03-18 19:55 ` Ithamar R. Adema
0 siblings, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 19:55 UTC (permalink / raw)
To: linux-arm-kernel
Hi Kevin,
On Fri, 2011-03-18 at 18:42 +0100, Kevin Wells wrote:
[...]
> would be something like:
> #define PGPIO(x, y) (((x) * 32) + (y))
> #define GPIO0_RD1 MFP_CFG(PGPIO(0, 0), AF1)
> #define GPIO33_ENET_TXD1 MFP_CFG(PGPIO(1, 1), AF1)
I've introduced an LPC2K_GPIO(port,pin) macro for that, and already use
it for the IRQs too. I like your suggestion!
However, since now we're not using explicit GPIO numbers anymore,
wouldn't you agree it would be better to make the above:
#define P0_0_RD1 MFP_CFG(LPC2K_GPIO(0, 0), AF1)
instead of still using the GPIOx prefix?
Regards,
Ithamar.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
` (5 preceding siblings ...)
2011-03-18 15:11 ` [PATCH v2 6/9] lpc2k: multifunction pin configuration Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 15:21 ` Russell King - ARM Linux
2011-03-18 15:11 ` [PATCH v2 8/9] lpc2k: Add UART, SSP, and MCI devices Ithamar R. Adema
2011-03-18 15:11 ` [PATCH v2 9/9] lpc2k: defconfig for NXP LPC2K platform Ithamar R. Adema
8 siblings, 1 reply; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Add support for EmbeddedArtists LPC2478 Developer's Kit, consisting
of the LPC2478OEM board, with QVGA base board. For details, see:
http://www.embeddedartists.com/products/kits/lpc2478_kit.php
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v1:
* Fixed RTC clock rate
* Marked mfp_cfgs as __initdata.
* renamed LPC2478OEM to more appropriate EA2478DEVKIT.
since the machine ID was not used anywhere yet, this rename is
harmless.
---
arch/arm/mach-lpc2k/Kconfig | 7 ++
arch/arm/mach-lpc2k/Makefile | 2 +
arch/arm/mach-lpc2k/common.h | 21 ++++++
arch/arm/mach-lpc2k/mach-ea2478devkit.c | 121 +++++++++++++++++++++++++++++++
arch/arm/tools/mach-types | 2 +-
5 files changed, 152 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-lpc2k/common.h
create mode 100644 arch/arm/mach-lpc2k/mach-ea2478devkit.c
diff --git a/arch/arm/mach-lpc2k/Kconfig b/arch/arm/mach-lpc2k/Kconfig
index fad47b8..210b641 100644
--- a/arch/arm/mach-lpc2k/Kconfig
+++ b/arch/arm/mach-lpc2k/Kconfig
@@ -2,4 +2,11 @@ if ARCH_LPC2K
comment "LPC2K machines"
+config MACH_EA2478DEVKIT
+ bool "Embedded Artists LPC2478 Developer's Kit"
+ help
+ Say Y if you want the kernel to support the EmbeddedArtists
+ LPC2478 Developer's Kit. For more hardware details, see:
+ http://www.embeddedartists.com/products/kits/lpc2478_kit.php
+
endif
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 2c50bb9..93e27fb 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1,3 @@
obj-y := clock.o irq.o gpio.o mfp.o time.o
+
+obj-$(CONFIG_MACH_EA2478DEVKIT) += mach-ea2478devkit.o
diff --git a/arch/arm/mach-lpc2k/common.h b/arch/arm/mach-lpc2k/common.h
new file mode 100644
index 0000000..6b775d9
--- /dev/null
+++ b/arch/arm/mach-lpc2k/common.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 LPC2K_COMMON_H
+#define LPC2K_COMMON_H
+
+struct sys_timer;
+
+extern void lpc2k_init_clocks(unsigned long xtal, unsigned long rtc);
+extern void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num);
+extern void lpc2k_init_irq(void);
+
+extern struct sys_timer lpc2k_timer;
+
+#endif /* LPC2K_COMMON_H */
diff --git a/arch/arm/mach-lpc2k/mach-ea2478devkit.c b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
new file mode 100644
index 0000000..bc9c980
--- /dev/null
+++ b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/mfp-lpc24xx.h>
+#include <mach/hardware.h>
+
+#include "common.h"
+
+#define EXTPOLAR 0x14c
+
+static unsigned long mfp_cfgs[] __initdata = {
+ /* UART0 */
+ GPIO2_TXD0,
+ GPIO3_RXD0,
+ /* USB Host */
+ GPIO12_USB_PPWR2,
+ GPIO13_USB_UP_LED2,
+ GPIO31_USB_Dp2,
+ GPIO62_VBUS,
+ GPIO63_USB_OVRCR2,
+ /* USB Gadget */
+ GPIO29_USB_Dp1,
+ GPIO30_USB_Dn1,
+ /* Ethernet */
+ GPIO32_ENET_TXD0,
+ GPIO33_ENET_TXD1,
+ GPIO36_ENET_TX_EN,
+ GPIO40_ENET_CRS,
+ GPIO41_ENET_RXD0,
+ GPIO42_ENET_RXD1,
+ GPIO46_ENET_RX_ERR,
+ GPIO47_ENET_REF_CLK,
+ GPIO48_ENET_MDC,
+ GPIO49_ENET_MDIO,
+ /* I2C0 */
+ GPIO27_SDA0,
+ GPIO28_SCL0,
+ /* SPI */
+ GPIO15_SCK,
+ GPIO17_MISO,
+ GPIO18_MOSI,
+ /* LCD */
+ GPIO4_LCDVD0,
+ GPIO5_LCDVD1,
+ GPIO6_LCDVD8,
+ GPIO7_LCDVD9,
+ GPIO8_LCDVD16,
+ GPIO9_LCDVD17,
+ GPIO52_LCDVD10,
+ GPIO53_LCDVD11,
+ GPIO54_LCDVD12,
+ GPIO55_LCDVD13,
+ GPIO56_LCDVD14,
+ GPIO57_LCDVD15,
+ GPIO58_LCDVD20,
+ GPIO59_LCDVD21,
+ GPIO60_LCDVD22,
+ GPIO61_LCDVD23,
+ GPIO64_LCDPWR,
+ GPIO65_LCDLE,
+ GPIO66_LCDDCLK,
+ GPIO67_LCDFP,
+ GPIO68_LCDM,
+ GPIO69_LCDLP,
+ GPIO70_LCDVP4,
+ GPIO71_LCDVP5,
+ GPIO72_LCDVP6,
+ GPIO73_LCDVP7,
+ GPIO75_LCDCLKIN,
+ GPIO76_LCDVP18,
+ GPIO77_LCDVP19,
+ GPIO156_LCDVP2,
+ GPIO157_LCDVP3,
+ /* Backlight */
+ GPIO50_PWM1,
+ /* MMC/SD */
+ GPIO34_MCICLK,
+ GPIO35_MCICMD,
+ GPIO37_MCIPWR,
+ GPIO38_MCIDAT0,
+ GPIO39_MCIDAT1,
+ GPIO43_MCIDAT2,
+ GPIO44_MCIDAT3,
+};
+
+void __init ea2478devkit_init_machine(void)
+{
+ lpc2k_mfp_config(mfp_cfgs, ARRAY_SIZE(mfp_cfgs));
+}
+
+static void __init ea2478devkit_init_irq(void)
+{
+ /* XXX workaround for the fact that EINT3 is connected to high-active
+ * signal, but can't be disabled. As the EINT3 interrupt is also used
+ * for GPIO interrupts, this will cause an interrupt storm without
+ * this setting.
+ */
+ iowrite32(ioread32(APB_SCB_BASE + EXTPOLAR) | (1 << 3),
+ APB_SCB_BASE + EXTPOLAR);
+
+ lpc2k_init_irq();
+ lpc2k_init_clocks(12000000UL, 32768UL);
+}
+
+MACHINE_START(EA2478DEVKIT, "Embedded Artists LPC2478 Developer's Kit")
+ .init_irq = ea2478devkit_init_irq,
+ .timer = &lpc2k_timer,
+ .init_machine = ea2478devkit_init_machine,
+MACHINE_END
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 9d6feaa..570a990 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -2667,7 +2667,7 @@ msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
micro2440 MACH_MICRO2440 MICRO2440 2680
am2440 MACH_AM2440 AM2440 2681
tq2440 MACH_TQ2440 TQ2440 2682
-lpc2478oem MACH_LPC2478OEM LPC2478OEM 2683
+ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683
ak880x MACH_AK880X AK880X 2684
cobra3530 MACH_COBRA3530 COBRA3530 2685
pmppb MACH_PMPPB PMPPB 2686
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board
2011-03-18 15:11 ` [PATCH v2 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board Ithamar R. Adema
@ 2011-03-18 15:21 ` Russell King - ARM Linux
2011-03-18 15:54 ` Ithamar R. Adema
0 siblings, 1 reply; 22+ messages in thread
From: Russell King - ARM Linux @ 2011-03-18 15:21 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Mar 18, 2011 at 04:11:54PM +0100, Ithamar R. Adema wrote:
> diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
> index 9d6feaa..570a990 100644
> --- a/arch/arm/tools/mach-types
> +++ b/arch/arm/tools/mach-types
> @@ -2667,7 +2667,7 @@ msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
> micro2440 MACH_MICRO2440 MICRO2440 2680
> am2440 MACH_AM2440 AM2440 2681
> tq2440 MACH_TQ2440 TQ2440 2682
> -lpc2478oem MACH_LPC2478OEM LPC2478OEM 2683
> +ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683
> ak880x MACH_AK880X AK880X 2684
> cobra3530 MACH_COBRA3530 COBRA3530 2685
> pmppb MACH_PMPPB PMPPB 2686
NAK. When I or anyone else updates this file this change wil get reverted.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board
2011-03-18 15:21 ` Russell King - ARM Linux
@ 2011-03-18 15:54 ` Ithamar R. Adema
0 siblings, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:54 UTC (permalink / raw)
To: linux-arm-kernel
Dear Russell,
On Fri, 2011-03-18 at 15:21 +0000, Russell King - ARM Linux wrote:
> On Fri, Mar 18, 2011 at 04:11:54PM +0100, Ithamar R. Adema wrote:
> > diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
> > index 9d6feaa..570a990 100644
> > --- a/arch/arm/tools/mach-types
> > +++ b/arch/arm/tools/mach-types
> > @@ -2667,7 +2667,7 @@
[...]
> NAK. When I or anyone else updates this file this change wil get
> reverted.
Ok, I've updated the machine definitions @
http://www.arm.linux.org.uk/developer/machines/ , but can I post an
updated arch/arm/tools/mach-types (downloaded from your site) with the
next patch set version just so reviewers can actually build the patch
set?
Regards,
Ithamar.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 8/9] lpc2k: Add UART, SSP, and MCI devices
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
` (6 preceding siblings ...)
2011-03-18 15:11 ` [PATCH v2 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
2011-03-18 15:11 ` [PATCH v2 9/9] lpc2k: defconfig for NXP LPC2K platform Ithamar R. Adema
8 siblings, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Adds devices for which the drivers are already in the tree. For
the relevant devices, let the ea2478devkit board set them up.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
no changes since v1.
---
arch/arm/Kconfig | 1 +
arch/arm/mach-lpc2k/Makefile | 2 +-
arch/arm/mach-lpc2k/common.h | 4 +
arch/arm/mach-lpc2k/devices.c | 174 +++++++++++++++++++++++++++
arch/arm/mach-lpc2k/include/mach/hardware.h | 6 +
arch/arm/mach-lpc2k/mach-ea2478devkit.c | 20 +++
6 files changed, 206 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-lpc2k/devices.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index de826e9..603839f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -496,6 +496,7 @@ config ARCH_LPC2K
depends on !MMU
select CPU_ARM7TDMI
select ARM_VIC
+ select ARM_AMBA
select CLKDEV_LOOKUP
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 93e27fb..aa2b353 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1,3 +1,3 @@
obj-y := clock.o irq.o gpio.o mfp.o time.o
-obj-$(CONFIG_MACH_EA2478DEVKIT) += mach-ea2478devkit.o
+obj-$(CONFIG_MACH_EA2478DEVKIT) += mach-ea2478devkit.o devices.o
diff --git a/arch/arm/mach-lpc2k/common.h b/arch/arm/mach-lpc2k/common.h
index 6b775d9..1d4c21e 100644
--- a/arch/arm/mach-lpc2k/common.h
+++ b/arch/arm/mach-lpc2k/common.h
@@ -16,6 +16,10 @@ extern void lpc2k_init_clocks(unsigned long xtal, unsigned long rtc);
extern void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num);
extern void lpc2k_init_irq(void);
+extern void lpc2k_add_uart(int nr);
+extern void lpc2k_add_ssp(int nr, void *platform_data);
+extern void lpc2k_add_mci(void *platform_data, int pwr_high);
+
extern struct sys_timer lpc2k_timer;
#endif /* LPC2K_COMMON_H */
diff --git a/arch/arm/mach-lpc2k/devices.c b/arch/arm/mach-lpc2k/devices.c
new file mode 100644
index 0000000..8855e8a
--- /dev/null
+++ b/arch/arm/mach-lpc2k/devices.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ * Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+
+#include <mach/hardware.h>
+
+/* System Control Block - System Controls and Status register */
+#define SCS 0x1a0
+
+#define __IORESOURCE_MEM_16K(x) { \
+ .start = x, \
+ .end = x + SZ_16K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }
+
+#define __IORESOURCE_IRQ(x) { \
+ .start = x, \
+ . end = x, \
+ }
+
+/* UARTs
+ * 0/1 are available on all LPC2Ks
+ * 2/3 are available on LPC23XX and up.
+ *
+ * NOTE: the dev.init_name assignment is there so we can use the clk API to
+ * retrieve and enable the clock, since dev_name() is called from
+ * the clk_get implementation before the platform device is registered.
+ */
+
+#define LPC2K_UART(uartnum) \
+ static struct plat_serial8250_port lpc2k_pdata_uart##uartnum[] = { \
+ { \
+ .mapbase = APB_UART##uartnum##_BASE, \
+ .membase = (void __iomem *) \
+ APB_UART##uartnum##_BASE, \
+ .irq = IRQ_LPC2K_UART##uartnum, \
+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, \
+ .iotype = UPIO_MEM, \
+ .regshift = 2, \
+ .uartclk = 0, \
+ }, \
+ { }, \
+ }; \
+ static struct resource lpc2k_resources_uart##uartnum[] = { \
+ [0] = __IORESOURCE_MEM_16K(APB_UART##uartnum##_BASE), \
+ [1] = __IORESOURCE_IRQ(IRQ_LPC2K_UART##uartnum), \
+ }; \
+ static struct platform_device lpc2k_device_uart##uartnum = { \
+ .dev = { \
+ .init_name = "serial8250." __stringify(uartnum), \
+ .platform_data = lpc2k_pdata_uart##uartnum, \
+ }, \
+ .name = "serial8250", \
+ .id = uartnum, \
+ .resource = lpc2k_resources_uart##uartnum, \
+ .num_resources = ARRAY_SIZE(lpc2k_resources_uart##uartnum), \
+ }
+
+
+LPC2K_UART(0);
+LPC2K_UART(1);
+LPC2K_UART(2);
+LPC2K_UART(3);
+
+static struct platform_device *uarts[] __initdata = {
+ &lpc2k_device_uart0,
+ &lpc2k_device_uart1,
+ &lpc2k_device_uart2,
+ &lpc2k_device_uart3,
+};
+
+void __init lpc2k_add_uart(int nr)
+{
+ struct platform_device *pdev;
+ struct clk *clk;
+ int res;
+
+ BUG_ON(nr < 0 || nr > ARRAY_SIZE(uarts));
+ pdev = uarts[nr];
+
+ clk = clk_get(&pdev->dev, NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+ ((struct plat_serial8250_port *)pdev->dev.platform_data)->uartclk =
+ clk_get_rate(clk);
+ clk_put(clk);
+
+ res = platform_device_register(pdev);
+ if (res)
+ dev_err(&pdev->dev, "Unable to register: %d\n", res);
+}
+
+/* SSP, aka pl022
+ *
+ * 1-only available on enhanced LPC21XX and LPC22XX.
+ * 0/1 available on LPC23XX and up.
+ */
+
+static struct amba_device lpc2k_device_ssp0 = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "ssp0",
+ },
+ .res = __IORESOURCE_MEM_16K(APB_SSP0_BASE),
+ .irq = { IRQ_LPC2K_SPI0, NO_IRQ },
+};
+
+static struct amba_device lpc2k_device_ssp1 = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "ssp1",
+ },
+ .res = __IORESOURCE_MEM_16K(APB_SSP1_BASE),
+ .irq = { IRQ_LPC2K_SPI1, NO_IRQ },
+};
+
+void __init lpc2k_add_ssp(int nr, void *platform_data)
+{
+ struct amba_device *adev;
+ int res;
+
+ BUG_ON(nr < 0 || nr > 1);
+ adev = nr ? &lpc2k_device_ssp1 : &lpc2k_device_ssp0;
+ adev->dev.platform_data = platform_data;
+
+ res = amba_device_register(adev, &iomem_resource);
+ if (res)
+ dev_err(&adev->dev, "Unable to register: %d\n", res);
+}
+
+/* SD/MMC, aka pl180/1
+ *
+ * Available on LPC23XX and up.
+ */
+
+static struct amba_device lpc2k_device_mci = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "mci",
+ },
+ .res = __IORESOURCE_MEM_16K(APB_MCI_BASE),
+ .irq = { IRQ_LPC2K_MCI, NO_IRQ },
+};
+
+void __init lpc2k_add_mci(void *platform_data, int pwr_high)
+{
+ int res;
+ u32 scs;
+
+ /* Set MCIPWR pin to be active high or low */
+ scs = ioread32(APB_SCB_BASE + SCS);
+ scs = pwr_high ? scs | (1 << 3) : scs & ~(1 << 3);
+ iowrite32(scs, APB_SCB_BASE + SCS);
+
+ lpc2k_device_mci.dev.platform_data = platform_data;
+ res = amba_device_register(&lpc2k_device_mci, &iomem_resource);
+ if (res)
+ dev_err(&lpc2k_device_mci.dev, "Unable to register: %d\n", res);
+}
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
index 1a20126..b2e3a18 100644
--- a/arch/arm/mach-lpc2k/include/mach/hardware.h
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -20,8 +20,14 @@
#define APB_TIMER0_BASE 0xe0004000
#define APB_TIMER1_BASE 0xe0008000
#define APB_UART0_BASE 0xe000c000
+#define APB_UART1_BASE 0xe0010000
#define APB_GPIO_BASE 0xe0028000
#define APB_PINSEL_BASE 0xe002c000
+#define APB_SSP1_BASE 0xe0030000
+#define APB_SSP0_BASE 0xe0068000
+#define APB_UART2_BASE 0xe0078000
+#define APB_UART3_BASE 0xe007c000
+#define APB_MCI_BASE 0xe008c000
#define APB_SCB_BASE 0xe01fc000
#define APH_VIC_BASE 0xfffff000
diff --git a/arch/arm/mach-lpc2k/mach-ea2478devkit.c b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
index bc9c980..3685eb2 100644
--- a/arch/arm/mach-lpc2k/mach-ea2478devkit.c
+++ b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
@@ -8,6 +8,8 @@
*/
#include <linux/module.h>
+#include <linux/amba/pl022.h>
+#include <linux/amba/mmci.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
@@ -95,9 +97,27 @@ static unsigned long mfp_cfgs[] __initdata = {
GPIO44_MCIDAT3,
};
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+static struct mmci_platform_data mci_plat_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .capabilities = MMC_CAP_4_BIT_DATA,
+ .f_max = 200000,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+};
+
void __init ea2478devkit_init_machine(void)
{
lpc2k_mfp_config(mfp_cfgs, ARRAY_SIZE(mfp_cfgs));
+
+ lpc2k_add_uart(0);
+ lpc2k_add_ssp(0, &ssp0_plat_data);
+ lpc2k_add_mci(&mci_plat_data, 0 /* active low */);
}
static void __init ea2478devkit_init_irq(void)
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 9/9] lpc2k: defconfig for NXP LPC2K platform
2011-03-18 15:11 [PATCH v2 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
` (7 preceding siblings ...)
2011-03-18 15:11 ` [PATCH v2 8/9] lpc2k: Add UART, SSP, and MCI devices Ithamar R. Adema
@ 2011-03-18 15:11 ` Ithamar R. Adema
8 siblings, 0 replies; 22+ messages in thread
From: Ithamar R. Adema @ 2011-03-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Add a defconfig that is setup to support booting a uClinux based
system. This enables ROMFS/CRAMFS, initrd, and FLAT binaries besides
the drivers for the devices added in the previous patch.
Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v1:
* enabled CONFIG_MAGIC_SYSRQ for testing arch_reset.
---
arch/arm/configs/lpc2k_defconfig | 57 ++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/configs/lpc2k_defconfig
diff --git a/arch/arm/configs/lpc2k_defconfig b/arch/arm/configs/lpc2k_defconfig
new file mode 100644
index 0000000..47a7bcf
--- /dev/null
+++ b/arch/arm/configs/lpc2k_defconfig
@@ -0,0 +1,57 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_TINY_RCU=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_MMU is not set
+CONFIG_ARCH_LPC2K=y
+CONFIG_MACH_EA2478DEVKIT=y
+CONFIG_PROCESSOR_ID=0x41007700
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=/dev/ram initrd=0xa1a00000,4000k console=ttyS0,115200N8 debug rw earlyprintk"
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_SUSPEND is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread