Re: [PATCHv2 04/11] mxc: changes to common plat-mxc code to addsupport for i.MX5
From: Amit Kucheria
Date: Wed Feb 03 2010 - 08:42:02 EST
On 10 Feb 03, Sascha Hauer wrote:
> On Tue, Feb 02, 2010 at 10:43:33PM -0800, Eric Miao wrote:
> >
> > Mmm.... this should be something that we really need to get rid of, it just
> > makes a single kernel for both TZIC and AVIC together impossible, if that's
> > so designed by HW, I'm thinking about keeping this into plat-mxc/ is a good
> > way to go ...
> >
> > Sascha, you have any better idea? Provided the other file debug-macro.S in
> > the same directory already seems to break the support for multiple arches?
> >
>
> I have the following patch which I'm not sure I like better. It can
> support both irq controller types and does not add overhead if only one
> of them is compiled in. It might need some refactoring to fit into Amits
> patch stack.
Is co-existence of TZIC and AVIC a blocker to merging i.MX5 code? I've
already made changes so that i.MX5 doesn't explode if AVIC is compiled in.
Admittedly the assembly is a bit hard to rid, but we can fix in another set
of patches geared towards unification of an i.MX kernel. IMHO, making these
changes along with introducing a new SoC will make things a bit hard to
follow/merge.
Regards,
Amit
> Sascha
>
>
> commit c30ed01dcd257bba813b27a423bc54d5f32fc878
> Author: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
> Date: Tue Nov 17 16:23:24 2009 +0100
>
> MXC tzic support
>
> Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
>
> diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> index ebe4b8c..377f792 100644
> --- a/arch/arm/plat-mxc/Kconfig
> +++ b/arch/arm/plat-mxc/Kconfig
> @@ -84,4 +84,7 @@ config ARCH_MXC_IOMUX_V3
> config ARCH_MXC_AVIC
> bool
>
> +config ARCH_MXC_TZIC
> + bool
> +
> endif
> diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
> index 325d9da..37ce6ec 100644
> --- a/arch/arm/plat-mxc/Makefile
> +++ b/arch/arm/plat-mxc/Makefile
> @@ -9,4 +9,5 @@ obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
> obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
> obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
> obj-$(CONFIG_MXC_PWM) += pwm.o
> +obj-$(CONFIG_ARCH_MXC_TZIC) += tzic.o
> obj-$(CONFIG_ARCH_MXC_AVIC) += irq.o
> diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c
> index b073b7d..d46325e 100644
> --- a/arch/arm/plat-mxc/cpu.c
> +++ b/arch/arm/plat-mxc/cpu.c
> @@ -11,4 +11,5 @@ void mxc_set_cpu_type(unsigned int type)
> }
>
> void __iomem *mxc_irq_base;
> +int mxc_irq_controller_type;
>
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 286cb9b..d395763 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -44,5 +44,5 @@ extern void mxc_arch_reset_init(void __iomem *);
> extern void mxc91231_power_off(void);
> extern void mxc91231_arch_reset(int, const char *);
> extern void mxc91231_prepare_idle(void);
> -
> +extern void tzic_init_irq(void __iomem *);
> #endif
> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> index 55375df..049f740 100644
> --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> @@ -13,6 +13,9 @@
>
> #define AVIC_NIMASK 0x04
>
> +#define TZIC_HIPND0 0xd80
> +
> +
> @ this macro disables fast irq (not implemented)
> .macro disable_fiq
> .endm
> @@ -28,10 +31,35 @@
> .macro arch_ret_to_user, tmp1, tmp2
> .endm
>
> - @ this macro checks which interrupt occured
> - @ and returns its number in irqnr
> - @ and returns if an interrupt occured in irqstat
> - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> + .macro tzic_get_irqnr_and_base, irqnr, irqstat, base, tmp
> +
> + @ Load offset & priority of the highest priority
> + @ interrupt pending.
> + ldr \irqnr, =0
> + ldr \irqstat, =TZIC_HIPND0
> +1000:
> + ldr \tmp, [\base, \irqstat]
> + cmp \tmp, #0
> + bne 1001f
> + addeq \irqnr, \irqnr, #32
> + addeq \irqstat, \irqstat, #4
> + cmp \irqnr, #128
> + blo 1000b
> + b 2001f
> +1001: ldr \irqstat, =1
> +1002: tst \tmp, \irqstat
> + bne 2002f
> + movs \irqstat, \irqstat, lsl #1
> + addne \irqnr, \irqnr, #1
> + bne 1002b
> +2001:
> + ldr \irqnr, =0
> +2002:
> + movs \irqnr, \irqnr
> + .endm
> +
> + .macro avic_get_irqnr_and_base, irqnr, irqstat, base, tmp
> +
> @ Load offset & priority of the highest priority
> @ interrupt pending from AVIC_NIVECSR
> ldr \irqstat, [\base, #0x40]
> @@ -47,6 +75,28 @@
> #endif
> .endm
>
> + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> +#if defined CONFIG_ARCH_MXC_TZIC && defined CONFIG_ARCH_MXC_AVIC
> + ldr \tmp, =mxc_irq_controller_type
> + ldr \tmp, [\tmp]
> + cmp \tmp, #MXC_IRQ_TYPE_AVIC
> + beq 3001f
> +
> + tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> + b 3002f
> +3001:
> + avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +3002:
> +
> +#elif defined CONFIG_ARCH_MXC_TZIC
> + tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +#elif defined CONFIG_ARCH_MXC_AVIC
> + avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +#else
> +#error no tzic and no avic?
> +#endif
> + .endm
> +
> @ irq priority table (not used)
> .macro irq_prio_table
> .endm
> diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
> index b64a269..6cf0f98 100644
> --- a/arch/arm/plat-mxc/include/mach/mxc.h
> +++ b/arch/arm/plat-mxc/include/mach/mxc.h
> @@ -129,8 +129,12 @@ extern unsigned int __mxc_cpu_type;
> #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
> #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
>
> +#define MXC_IRQ_TYPE_AVIC 1
> +#define MXC_IRQ_TYPE_TZIC 2
> +
> #ifndef __ASSEMBLY__
> extern void __iomem *mxc_irq_base;
> +extern int mxc_irq_controller_type;
> #endif
>
> #endif /* __ASM_ARCH_MXC_H__ */
> diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
> index 4855a65..3e7ac84 100644
> --- a/arch/arm/plat-mxc/irq.c
> +++ b/arch/arm/plat-mxc/irq.c
> @@ -116,6 +116,7 @@ void __init mxc_init_irq(void __iomem *irqbase)
> int i;
>
> mxc_irq_base = irqbase;
> + mxc_irq_controller_type = MXC_IRQ_TYPE_AVIC;
>
> /* put the AVIC into the reset value with
> * all interrupts disabled
> diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
> new file mode 100644
> index 0000000..2d14af4
> --- /dev/null
> +++ b/arch/arm/plat-mxc/tzic.c
> @@ -0,0 +1,104 @@
> +/*
> + * Copyright 2004-2008 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
> + */
> +
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/io.h>
> +#include <asm/irq.h>
> +#include <asm/mach/irq.h>
> +#include <mach/common.h>
> +#include <mach/hardware.h>
> +
> +extern void __iomem *mxc_irq_base;
> +extern int mxc_irq_controller_type;
> +
> +#define TZIC_INTCNTL 0x0000 /* control register */
> +#define TZIC_INTTYPE 0x0004 /* Controller type register */
> +#define TZIC_IMPID 0x0008 /* Distributor Implementer Identification Register */
> +#define TZIC_PRIOMASK 0x000c /* Priority Mask Reg */
> +#define TZIC_SYNCCTRL 0x0010 /* Synchronizer Control register */
> +#define TZIC_DSMINT 0x0014 /* DSM interrupt Holdoffregister */
> +#define TZIC_INTSEC0 0x0080 /* interrupt security register 0 */
> +#define TZIC_ENSET0 0x0100 /* Enable Set Register 0 */
> +#define TZIC_ENCLEAR0 0x0180 /* Enable Clear Register 0 */
> +#define TZIC_SRCSET0 0x0200 /* Source Set Register 0 */
> +#define TZIC_SRCCLAR0 0x0280 /* Source Clear Register 0 */
> +#define TZIC_PRIORITY0 0x0400 /* Priority Register 0 */
> +#define TZIC_PND0 0x0d00 /* Pending Register 0 */
> +#define TZIC_HIPND0 0x0d80 /* High Priority Pending Register */
> +#define TZIC_WAKEUP0 0x0e00 /* Wakeup Config Register */
> +#define TZIC_SWINT 0x0f00 /* Software Interrupt Rigger Register */
> +#define TZIC_ID0 0x0fd0 /* Indentification Register 0 */
> +
> +static void mxc_mask_irq(unsigned int irq)
> +{
> + int index, off;
> +
> + index = irq >> 5;
> + off = irq & 0x1F;
> + __raw_writel(1 << off, mxc_irq_base + TZIC_ENCLEAR0 + (index << 2));
> +}
> +
> +static void mxc_unmask_irq(unsigned int irq)
> +{
> + int index, off;
> +
> + index = irq >> 5;
> + off = irq & 0x1F;
> + __raw_writel(1 << off, mxc_irq_base + TZIC_ENSET0 + (index << 2));
> +}
> +
> +static struct irq_chip mxc_tzic_chip = {
> + .name = "MXC_TZIC",
> + .ack = mxc_mask_irq,
> + .mask = mxc_mask_irq,
> + .unmask = mxc_unmask_irq,
> +};
> +
> +void __init tzic_init_irq(void __iomem *base)
> +{
> + int i;
> +
> + mxc_irq_base = base;
> + mxc_irq_controller_type = MXC_IRQ_TYPE_TZIC;
> +
> + /* put the TZIC into the reset value with
> + * all interrupts disabled
> + */
> + __raw_readl(mxc_irq_base + TZIC_INTCNTL);
> +
> + __raw_writel(0x80010001, mxc_irq_base + TZIC_INTCNTL);
> + __raw_readl(mxc_irq_base + TZIC_INTCNTL);
> + __raw_writel(0x1f, mxc_irq_base + TZIC_PRIOMASK);
> + __raw_readl(mxc_irq_base + TZIC_PRIOMASK);
> + __raw_writel(0x02, mxc_irq_base + TZIC_SYNCCTRL);
> + __raw_readl(mxc_irq_base + TZIC_SYNCCTRL);
> +
> + for (i = 0; i < 4; i++)
> + __raw_writel(0xffffffff, mxc_irq_base + TZIC_INTSEC0 + i * 4);
> +
> + /* disable all interrupts */
> + for (i = 0; i < 4; i++)
> + __raw_writel(0xffffffff, mxc_irq_base + TZIC_ENCLEAR0 + i * 4);
> +
> + for (i = 0; i < 128; i++) {
> + set_irq_chip(i, &mxc_tzic_chip);
> + set_irq_handler(i, handle_level_irq);
> + set_irq_flags(i, IRQF_VALID);
> + }
> +
> + printk(KERN_INFO "MXC IRQ initialized\n");
> +}
> --
> 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 |
--
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || amit.kucheria@xxxxxxxxxxxxx
----------------------------------------------------------------------
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/