aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Wang <jason77.wang@gmail.com>2010-06-24 09:11:28 -0400
committerSascha Hauer <s.hauer@pengutronix.de>2010-07-26 08:29:19 -0400
commitfa94f8dce1459eef1f0f8d5b1e4f26c3f058dec2 (patch)
treec6ef4962d52dbbbf876c80c055d05cb0c65d4c29
parent2dcf78c0eeae3bd07082821557014f25f02ca2e9 (diff)
mxc: add common debug board for 3-stack platforms
The debug board is little different for all mxc 3-stack(PDK) platforms, it is possible here to add a common implementation to support this board. Signed-off-by: Jason Wang <jason77.wang@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/arm/plat-mxc/3ds_debugboard.c202
-rw-r--r--arch/arm/plat-mxc/Kconfig11
-rw-r--r--arch/arm/plat-mxc/Makefile1
-rw-r--r--arch/arm/plat-mxc/include/mach/3ds_debugboard.h18
4 files changed, 232 insertions, 0 deletions
diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c
new file mode 100644
index 000000000000..639c54a07992
--- /dev/null
+++ b/arch/arm/plat-mxc/3ds_debugboard.c
@@ -0,0 +1,202 @@
1/*
2 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com>
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/io.h>
16#include <linux/platform_device.h>
17#include <linux/gpio.h>
18#include <linux/smsc911x.h>
19
20#include <mach/hardware.h>
21
22/* LAN9217 ethernet base address */
23#define LAN9217_BASE_ADDR(n) (n + 0x0)
24/* External UART */
25#define UARTA_BASE_ADDR(n) (n + 0x8000)
26#define UARTB_BASE_ADDR(n) (n + 0x10000)
27
28#define BOARD_IO_ADDR(n) (n + 0x20000)
29/* LED switchs */
30#define LED_SWITCH_REG 0x00
31/* buttons */
32#define SWITCH_BUTTONS_REG 0x08
33/* status, interrupt */
34#define INTR_STATUS_REG 0x10
35#define INTR_MASK_REG 0x38
36#define INTR_RESET_REG 0x20
37/* magic word for debug CPLD */
38#define MAGIC_NUMBER1_REG 0x40
39#define MAGIC_NUMBER2_REG 0x48
40/* CPLD code version */
41#define CPLD_CODE_VER_REG 0x50
42/* magic word for debug CPLD */
43#define MAGIC_NUMBER3_REG 0x58
44/* module reset register*/
45#define MODULE_RESET_REG 0x60
46/* CPU ID and Personality ID */
47#define MCU_BOARD_ID_REG 0x68
48
49#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_BOARD_IRQ_START)
50#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_INTERNAL_IRQS)
51
52#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
53#define MXC_MAX_EXP_IO_LINES 16
54
55/* interrupts like external uart , external ethernet etc*/
56#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0)
57#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1)
58#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2)
59#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3)
60#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4)
61
62static void __iomem *brd_io;
63static void expio_ack_irq(u32 irq);
64
65static struct resource smsc911x_resources[] = {
66 {
67 .flags = IORESOURCE_MEM,
68 } , {
69 .start = EXPIO_INT_ENET,
70 .end = EXPIO_INT_ENET,
71 .flags = IORESOURCE_IRQ,
72 },
73};
74
75static struct smsc911x_platform_config smsc911x_config = {
76 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
77 .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
78};
79
80static struct platform_device smsc_lan9217_device = {
81 .name = "smsc911x",
82 .id = 0,
83 .dev = {
84 .platform_data = &smsc911x_config,
85 },
86 .num_resources = ARRAY_SIZE(smsc911x_resources),
87 .resource = smsc911x_resources,
88};
89
90static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
91{
92 u32 imr_val;
93 u32 int_valid;
94 u32 expio_irq;
95
96 desc->chip->mask(irq); /* irq = gpio irq number */
97
98 imr_val = __raw_readw(brd_io + INTR_MASK_REG);
99 int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val;
100
101 expio_irq = MXC_BOARD_IRQ_START;
102 for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
103 struct irq_desc *d;
104 if ((int_valid & 1) == 0)
105 continue;
106 d = irq_desc + expio_irq;
107 if (unlikely(!(d->handle_irq)))
108 pr_err("\nEXPIO irq: %d unhandled\n", expio_irq);
109 else
110 d->handle_irq(expio_irq, d);
111 }
112
113 desc->chip->ack(irq);
114 desc->chip->unmask(irq);
115}
116
117/*
118 * Disable an expio pin's interrupt by setting the bit in the imr.
119 * Irq is an expio virtual irq number
120 */
121static void expio_mask_irq(u32 irq)
122{
123 u16 reg;
124 u32 expio = MXC_IRQ_TO_EXPIO(irq);
125
126 reg = __raw_readw(brd_io + INTR_MASK_REG);
127 reg |= (1 << expio);
128 __raw_writew(reg, brd_io + INTR_MASK_REG);
129}
130
131static void expio_ack_irq(u32 irq)
132{
133 u32 expio = MXC_IRQ_TO_EXPIO(irq);
134
135 __raw_writew(1 << expio, brd_io + INTR_RESET_REG);
136 __raw_writew(0, brd_io + INTR_RESET_REG);
137 expio_mask_irq(irq);
138}
139
140static void expio_unmask_irq(u32 irq)
141{
142 u16 reg;
143 u32 expio = MXC_IRQ_TO_EXPIO(irq);
144
145 reg = __raw_readw(brd_io + INTR_MASK_REG);
146 reg &= ~(1 << expio);
147 __raw_writew(reg, brd_io + INTR_MASK_REG);
148}
149
150static struct irq_chip expio_irq_chip = {
151 .ack = expio_ack_irq,
152 .mask = expio_mask_irq,
153 .unmask = expio_unmask_irq,
154};
155
156int __init mxc_expio_init(u32 base, u32 p_irq)
157{
158 int i;
159
160 brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K);
161 if (brd_io == NULL)
162 return -ENOMEM;
163
164 if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) ||
165 (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) ||
166 (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) {
167 pr_info("3-Stack Debug board not detected\n");
168 iounmap(brd_io);
169 brd_io = NULL;
170 return -ENODEV;
171 }
172
173 pr_info("3-Stack Debug board detected, rev = 0x%04X\n",
174 readw(brd_io + CPLD_CODE_VER_REG));
175
176 /*
177 * Configure INT line as GPIO input
178 */
179 gpio_request(MXC_IRQ_TO_GPIO(p_irq), "expio_pirq");
180 gpio_direction_input(MXC_IRQ_TO_GPIO(p_irq));
181
182 /* disable the interrupt and clear the status */
183 __raw_writew(0, brd_io + INTR_MASK_REG);
184 __raw_writew(0xFFFF, brd_io + INTR_RESET_REG);
185 __raw_writew(0, brd_io + INTR_RESET_REG);
186 __raw_writew(0x1F, brd_io + INTR_MASK_REG);
187 for (i = MXC_EXP_IO_BASE;
188 i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) {
189 set_irq_chip(i, &expio_irq_chip);
190 set_irq_handler(i, handle_level_irq);
191 set_irq_flags(i, IRQF_VALID);
192 }
193 set_irq_type(p_irq, IRQF_TRIGGER_LOW);
194 set_irq_chained_handler(p_irq, mxc_expio_irq_handler);
195
196 /* Register Lan device on the debugboard */
197 smsc911x_resources[0].start = LAN9217_BASE_ADDR(base);
198 smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1;
199 platform_device_register(&smsc_lan9217_device);
200
201 return 0;
202}
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 20b2e79e54f2..0527e65318f4 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -80,6 +80,17 @@ config MXC_PWM
80 help 80 help
81 Enable support for the i.MX PWM controller(s). 81 Enable support for the i.MX PWM controller(s).
82 82
83config MXC_DEBUG_BOARD
84 bool "Enable MXC debug board(for 3-stack)"
85 help
86 The debug board is an integral part of the MXC 3-stack(PDK)
87 platforms, it can be attached or removed from the peripheral
88 board. On debug board, several debug devices(ethernet, UART,
89 buttons, LEDs and JTAG) are implemented. Between the MCU and
90 these devices, a CPLD is added as a bridge which performs
91 data/address de-multiplexing and decode, signal level shift,
92 interrupt control and various board functions.
93
83config MXC_ULPI 94config MXC_ULPI
84 bool 95 bool
85 96
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index c7506a80eb31..78d405ed8616 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
15obj-$(CONFIG_MXC_ULPI) += ulpi.o 15obj-$(CONFIG_MXC_ULPI) += ulpi.o
16obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o 16obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
17obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o 17obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
18obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
18ifdef CONFIG_SND_IMX_SOC 19ifdef CONFIG_SND_IMX_SOC
19obj-y += ssi-fiq.o 20obj-y += ssi-fiq.o
20obj-y += ssi-fiq-ksym.o 21obj-y += ssi-fiq-ksym.o
diff --git a/arch/arm/plat-mxc/include/mach/3ds_debugboard.h b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h
new file mode 100644
index 000000000000..a384fdd49c62
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h
@@ -0,0 +1,18 @@
1/*
2 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#ifndef __ASM_ARCH_MXC_3DS_DB_H__
14#define __ASM_ARCH_MXC_3DS_DB_H__
15
16extern int __init mxc_expio_init(u32 base, u32 p_irq);
17
18#endif /* __ASM_ARCH_MXC_3DS_DB_H__ */