From mboxrd@z Thu Jan 1 00:00:00 1970 From: s.hauer@pengutronix.de (Sascha Hauer) Date: Wed, 16 Jun 2010 08:55:40 +0200 Subject: [PATCH 1/2] mxc: add common debug board for 3-stack platforms In-Reply-To: <1276352707-8199-2-git-send-email-jason77.wang@gmail.com> References: <1276352707-8199-1-git-send-email-jason77.wang@gmail.com> <1276352707-8199-2-git-send-email-jason77.wang@gmail.com> Message-ID: <20100616065540.GI20799@pengutronix.de> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Sat, Jun 12, 2010 at 10:25:06PM +0800, Jason Wang wrote: > 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. Two small things left: Could you change the name cpld_debugboard.c to something like 3ds_debugboard.c? That we are talking about the 3ds is much more interesting than that there's a cpld on the board. Also, I really prefer having no extra header file for the debug board. All information in this header file is only interesting in this single C file. Sascha > > Signed-off-by: Jason Wang > --- > arch/arm/plat-mxc/Kconfig | 11 ++ > arch/arm/plat-mxc/Makefile | 1 + > arch/arm/plat-mxc/cpld_debugboard.c | 161 ++++++++++++++++++++++ > arch/arm/plat-mxc/include/mach/cpld_debugboard.h | 60 ++++++++ > 4 files changed, 233 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/plat-mxc/cpld_debugboard.c > create mode 100644 arch/arm/plat-mxc/include/mach/cpld_debugboard.h > > diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig > index 7f7ad6f..8bf917e 100644 > --- a/arch/arm/plat-mxc/Kconfig > +++ b/arch/arm/plat-mxc/Kconfig > @@ -81,6 +81,17 @@ config MXC_PWM > help > Enable support for the i.MX PWM controller(s). > > +config MXC_DEBUG_BOARD > + bool "Enable MXC debug board(for 3-stack)" > + help > + The debug board is an integral part of the MXC 3-stack(PDK) > + platforms, it can be attached or removed from the peripheral > + board. On debug board, several debug devices(ethernet, UART, > + buttons, LEDs and JTAG) are implemented. Between the MCU and > + these devices, a CPLD is added as a bridge which performs > + data/address de-multiplexing and decode, signal level shift, > + interrupt control and various board functions. > + > config MXC_ULPI > bool > > diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile > index 895bc3c..b9e8c6f 100644 > --- a/arch/arm/plat-mxc/Makefile > +++ b/arch/arm/plat-mxc/Makefile > @@ -17,6 +17,7 @@ obj-$(CONFIG_USB_EHCI_MXC) += ehci.o > obj-$(CONFIG_MXC_ULPI) += ulpi.o > obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o > obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o > +obj-$(CONFIG_MXC_DEBUG_BOARD) += cpld_debugboard.o > ifdef CONFIG_SND_IMX_SOC > obj-y += ssi-fiq.o > obj-y += ssi-fiq-ksym.o > diff --git a/arch/arm/plat-mxc/cpld_debugboard.c b/arch/arm/plat-mxc/cpld_debugboard.c > new file mode 100644 > index 0000000..0554fa0 > --- /dev/null > +++ b/arch/arm/plat-mxc/cpld_debugboard.c > @@ -0,0 +1,161 @@ > +/* > + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. > + * Copyright (C) 2010 Jason Wang > + * > + * The code contained herein is licensed under the GNU General Public > + * License. You may obtain a copy of the GNU General Public License > + * Version 2 or later at the following locations: > + * > + * http://www.opensource.org/licenses/gpl-license.html > + * http://www.gnu.org/copyleft/gpl.html > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +static void __iomem *brd_io; > +static void expio_ack_irq(u32 irq); > + > +static struct resource smsc911x_resources[] = { > + { > + .flags = IORESOURCE_MEM, > + } , { > + .start = EXPIO_INT_ENET, > + .end = EXPIO_INT_ENET, > + .flags = IORESOURCE_IRQ, > + }, > +}; > + > +struct smsc911x_platform_config smsc911x_config = { > + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, > + .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY, > +}; > + > +struct platform_device smsc_lan9217_device = { > + .name = "smsc911x", > + .id = 0, > + .dev = { > + .platform_data = &smsc911x_config, > + }, > + .num_resources = ARRAY_SIZE(smsc911x_resources), > + .resource = smsc911x_resources, > +}; > + > +static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) > +{ > + u32 imr_val; > + u32 int_valid; > + u32 expio_irq; > + > + desc->chip->mask(irq); /* irq = gpio irq number */ > + > + imr_val = __raw_readw(brd_io + INTR_MASK_REG); > + int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; > + > + expio_irq = MXC_BOARD_IRQ_START; > + for (; int_valid != 0; int_valid >>= 1, expio_irq++) { > + struct irq_desc *d; > + if ((int_valid & 1) == 0) > + continue; > + d = irq_desc + expio_irq; > + if (unlikely(!(d->handle_irq))) > + pr_err("\nEXPIO irq: %d unhandled\n", expio_irq); > + else > + d->handle_irq(expio_irq, d); > + } > + > + desc->chip->ack(irq); > + desc->chip->unmask(irq); > +} > + > +/* > + * Disable an expio pin's interrupt by setting the bit in the imr. > + * Irq is an expio virtual irq number > + */ > +static void expio_mask_irq(u32 irq) > +{ > + u16 reg; > + u32 expio = MXC_IRQ_TO_EXPIO(irq); > + > + reg = __raw_readw(brd_io + INTR_MASK_REG); > + reg |= (1 << expio); > + __raw_writew(reg, brd_io + INTR_MASK_REG); > +} > + > +static void expio_ack_irq(u32 irq) > +{ > + u32 expio = MXC_IRQ_TO_EXPIO(irq); > + > + __raw_writew(1 << expio, brd_io + INTR_RESET_REG); > + __raw_writew(0, brd_io + INTR_RESET_REG); > + expio_mask_irq(irq); > +} > + > +static void expio_unmask_irq(u32 irq) > +{ > + u16 reg; > + u32 expio = MXC_IRQ_TO_EXPIO(irq); > + > + reg = __raw_readw(brd_io + INTR_MASK_REG); > + reg &= ~(1 << expio); > + __raw_writew(reg, brd_io + INTR_MASK_REG); > +} > + > +static struct irq_chip expio_irq_chip = { > + .ack = expio_ack_irq, > + .mask = expio_mask_irq, > + .unmask = expio_unmask_irq, > +}; > + > +int __init mxc_expio_init(u32 base, u32 p_irq) > +{ > + int i; > + > + brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K); > + if (brd_io == NULL) > + return -ENOMEM; > + > + if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || > + (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || > + (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { > + pr_info("3-Stack Debug board not detected\n"); > + iounmap(brd_io); > + brd_io = NULL; > + return -ENODEV; > + } > + > + pr_info("3-Stack Debug board detected, rev = 0x%04X\n", > + readw(brd_io + CPLD_CODE_VER_REG)); > + > + smsc911x_resources[0].start = LAN9217_BASE_ADDR(base); > + smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1; > + > + /* > + * Configure INT line as GPIO input > + */ > + gpio_request(MXC_IRQ_TO_GPIO(p_irq), "expio_pirq"); > + gpio_direction_input(MXC_IRQ_TO_GPIO(p_irq)); > + > + /* disable the interrupt and clear the status */ > + __raw_writew(0, brd_io + INTR_MASK_REG); > + __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); > + __raw_writew(0, brd_io + INTR_RESET_REG); > + __raw_writew(0x1F, brd_io + INTR_MASK_REG); > + for (i = MXC_EXP_IO_BASE; > + i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) { > + set_irq_chip(i, &expio_irq_chip); > + set_irq_handler(i, handle_level_irq); > + set_irq_flags(i, IRQF_VALID); > + } > + set_irq_type(p_irq, IRQF_TRIGGER_LOW); > + set_irq_chained_handler(p_irq, mxc_expio_irq_handler); > + > + return 0; > +} > diff --git a/arch/arm/plat-mxc/include/mach/cpld_debugboard.h b/arch/arm/plat-mxc/include/mach/cpld_debugboard.h > new file mode 100644 > index 0000000..a1422d2 > --- /dev/null > +++ b/arch/arm/plat-mxc/include/mach/cpld_debugboard.h > @@ -0,0 +1,60 @@ > +/* > + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. > + * > + * > + * The code contained herein is licensed under the GNU General Public > + * License. You may obtain a copy of the GNU General Public License > + * Version 2 or later at the following locations: > + * > + * http://www.opensource.org/licenses/gpl-license.html > + * http://www.gnu.org/copyleft/gpl.html > + */ > + > +#ifndef __ASM_ARCH_MXC_CPLD_DB_H__ > +#define __ASM_ARCH_MXC_CPLD_DB_H__ > + > +/* LAN9217 ethernet base address */ > +#define LAN9217_BASE_ADDR(n) (n + 0x0) > +/* External UART */ > +#define UARTA_BASE_ADDR(n) (n + 0x8000) > +#define UARTB_BASE_ADDR(n) (n + 0x10000) > + > +#define BOARD_IO_ADDR(n) (n + 0x20000) > +/* LED switchs */ > +#define LED_SWITCH_REG 0x00 > +/* buttons */ > +#define SWITCH_BUTTONS_REG 0x08 > +/* status, interrupt */ > +#define INTR_STATUS_REG 0x10 > +#define INTR_MASK_REG 0x38 > +#define INTR_RESET_REG 0x20 > +/* magic word for debug CPLD */ > +#define MAGIC_NUMBER1_REG 0x40 > +#define MAGIC_NUMBER2_REG 0x48 > +/* CPLD code version */ > +#define CPLD_CODE_VER_REG 0x50 > +/* magic word for debug CPLD */ > +#define MAGIC_NUMBER3_REG 0x58 > +/* module reset register*/ > +#define MODULE_RESET_REG 0x60 > +/* CPU ID and Personality ID */ > +#define MCU_BOARD_ID_REG 0x68 > + > +#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_BOARD_IRQ_START) > +#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_INTERNAL_IRQS) > + > +#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) > +#define MXC_MAX_EXP_IO_LINES 16 > + > +/* interrupts like external uart , external ethernet etc*/ > +#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0) > +#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1) > +#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2) > +#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3) > +#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4) > + > +extern struct platform_device smsc_lan9217_device; > + > +int __init mxc_expio_init(u32 base, u32 p_irq); > + > +#endif /* __ASM_ARCH_MXC_CPLD_DB_H__ */ > -- > 1.5.6.5 > > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |