| 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);
 
 
  |