| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 | /* *  linux/arch/arm/mach-versatile/core.c * *  Copyright (C) 1999 - 2003 ARM Limited *  Copyright (C) 2000 Deep Blue Solutions Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <linux/init.h>#include <linux/device.h>#include <linux/dma-mapping.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <linux/irqdomain.h>#include <linux/of_address.h>#include <linux/of_platform.h>#include <linux/amba/bus.h>#include <linux/amba/clcd.h>#include <linux/amba/pl061.h>#include <linux/amba/mmci.h>#include <linux/amba/pl022.h>#include <linux/io.h>#include <linux/irqchip/versatile-fpga.h>#include <linux/gfp.h>#include <linux/clkdev.h>#include <linux/mtd/physmap.h>#include <linux/bitops.h>#include <asm/irq.h>#include <asm/hardware/arm_timer.h>#include <asm/hardware/icst.h>#include <asm/hardware/vic.h>#include <asm/mach-types.h>#include <asm/mach/arch.h>#include <asm/mach/irq.h>#include <asm/mach/time.h>#include <asm/mach/map.h>#include <mach/hardware.h>#include <mach/platform.h>#include <asm/hardware/timer-sp.h>#include <plat/clcd.h>#include <plat/sched_clock.h>#include "core.h"/* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx * is the (PA >> 12). * * Setup a VA for the Versatile Vectored Interrupt Controller. */#define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)#define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)/* These PIC IRQs are valid in each configuration */#define PIC_VALID_ALL	BIT(SIC_INT_KMI0) | BIT(SIC_INT_KMI1) | \			BIT(SIC_INT_SCI3) | BIT(SIC_INT_UART3) | \			BIT(SIC_INT_CLCD) | BIT(SIC_INT_TOUCH) | \			BIT(SIC_INT_KEYPAD) | BIT(SIC_INT_DoC) | \			BIT(SIC_INT_USB) | BIT(SIC_INT_PCI0) | \			BIT(SIC_INT_PCI1) | BIT(SIC_INT_PCI2) | \			BIT(SIC_INT_PCI3)#if 1#define IRQ_MMCI0A	IRQ_VICSOURCE22#define IRQ_AACI	IRQ_VICSOURCE24#define IRQ_ETH		IRQ_VICSOURCE25#define PIC_MASK	0xFFD00000#define PIC_VALID	PIC_VALID_ALL#else#define IRQ_MMCI0A	IRQ_SIC_MMCI0A#define IRQ_AACI	IRQ_SIC_AACI#define IRQ_ETH		IRQ_SIC_ETH#define PIC_MASK	0#define PIC_VALID	PIC_VALID_ALL | BIT(SIC_INT_MMCI0A) | \			BIT(SIC_INT_MMCI1A) | BIT(SIC_INT_AACI) | \			BIT(SIC_INT_ETH)#endif/* Lookup table for finding a DT node that represents the vic instance */static const struct of_device_id vic_of_match[] __initconst = {	{ .compatible = "arm,versatile-vic", },	{}};static const struct of_device_id sic_of_match[] __initconst = {	{ .compatible = "arm,versatile-sic", },	{}};void __init versatile_init_irq(void){	struct device_node *np;	np = of_find_matching_node_by_address(NULL, vic_of_match,					      VERSATILE_VIC_BASE);	__vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np);	writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);	np = of_find_matching_node_by_address(NULL, sic_of_match,					      VERSATILE_SIC_BASE);	fpga_irq_init(VA_SIC_BASE, "SIC", IRQ_SIC_START,		IRQ_VICSOURCE31, PIC_VALID, np);	/*	 * Interrupts on secondary controller from 0 to 8 are routed to	 * source 31 on PIC.	 * Interrupts from 21 to 31 are routed directly to the VIC on	 * the corresponding number on primary controller. This is controlled	 * by setting PIC_ENABLEx.	 */	writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE);}static struct map_desc versatile_io_desc[] __initdata = {	{		.virtual	=  IO_ADDRESS(VERSATILE_SYS_BASE),		.pfn		= __phys_to_pfn(VERSATILE_SYS_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  IO_ADDRESS(VERSATILE_SIC_BASE),		.pfn		= __phys_to_pfn(VERSATILE_SIC_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  IO_ADDRESS(VERSATILE_VIC_BASE),		.pfn		= __phys_to_pfn(VERSATILE_VIC_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  IO_ADDRESS(VERSATILE_SCTL_BASE),		.pfn		= __phys_to_pfn(VERSATILE_SCTL_BASE),		.length		= SZ_4K * 9,		.type		= MT_DEVICE	},#ifdef CONFIG_MACH_VERSATILE_AB 	{		.virtual	=  IO_ADDRESS(VERSATILE_IB2_BASE),		.pfn		= __phys_to_pfn(VERSATILE_IB2_BASE),		.length		= SZ_64M,		.type		= MT_DEVICE	},#endif#ifdef CONFIG_DEBUG_LL 	{		.virtual	=  IO_ADDRESS(VERSATILE_UART0_BASE),		.pfn		= __phys_to_pfn(VERSATILE_UART0_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	},#endif#ifdef CONFIG_PCI 	{		.virtual	=  IO_ADDRESS(VERSATILE_PCI_CORE_BASE),		.pfn		= __phys_to_pfn(VERSATILE_PCI_CORE_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  (unsigned long)VERSATILE_PCI_VIRT_BASE,		.pfn		= __phys_to_pfn(VERSATILE_PCI_BASE),		.length		= VERSATILE_PCI_BASE_SIZE,		.type		= MT_DEVICE	}, {		.virtual	=  (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE,		.pfn		= __phys_to_pfn(VERSATILE_PCI_CFG_BASE),		.length		= VERSATILE_PCI_CFG_BASE_SIZE,		.type		= MT_DEVICE	},#endif};void __init versatile_map_io(void){	iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));}#define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)static void versatile_flash_set_vpp(struct platform_device *pdev, int on){	u32 val;	val = __raw_readl(VERSATILE_FLASHCTRL);	if (on)		val |= VERSATILE_FLASHPROG_FLVPPEN;	else		val &= ~VERSATILE_FLASHPROG_FLVPPEN;	__raw_writel(val, VERSATILE_FLASHCTRL);
 |