[PATCH 1/2] mxc: add common debug board for 3-stack platforms
Sascha Hauer
s.hauer at pengutronix.de
Wed Jun 16 02:55:40 EDT 2010
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 <jason77.wang at gmail.com>
> ---
> 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 <jason77.wang at gmail.com>
> + *
> + * 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 <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/smsc911x.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/cpld_debugboard.h>
> +
> +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 |
More information about the linux-arm-kernel
mailing list