[PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5

Amit Kucheria amit.kucheria at canonical.com
Wed Feb 3 08:38:40 EST 2010


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 at pengutronix.de>
> Date:   Tue Nov 17 16:23:24 2009 +0100
> 
>     MXC tzic support
>     
>     Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> 
> 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 at canonical.com
----------------------------------------------------------------------



More information about the linux-arm-kernel mailing list