diff options
Diffstat (limited to 'arch/arm/mach-versatile')
21 files changed, 408 insertions, 672 deletions
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig index c781f30c836..1dba3688275 100644 --- a/arch/arm/mach-versatile/Kconfig +++ b/arch/arm/mach-versatile/Kconfig @@ -2,16 +2,32 @@ menu "Versatile platform type"  	depends on ARCH_VERSATILE  config ARCH_VERSATILE_PB -	bool "Support Versatile/PB platform" -	select CPU_ARM926T +	bool "Support Versatile Platform Baseboard for ARM926EJ-S"  	default y +	select CPU_ARM926T +	select MIGHT_HAVE_PCI  	help -	  Include support for the ARM(R) Versatile/PB platform. +	  Include support for the ARM(R) Versatile Platform Baseboard +	  for the ARM926EJ-S.  config MACH_VERSATILE_AB -	bool "Support Versatile/AB platform" +	bool "Support Versatile Application Baseboard for ARM926EJ-S" +	select CPU_ARM926T +	help +	  Include support for the ARM(R) Versatile Application Baseboard +	  for the ARM926EJ-S. + +config MACH_VERSATILE_DT +	bool "Support Versatile platform from device tree"  	select CPU_ARM926T +	select USE_OF  	help -	  Include support for the ARM(R) Versatile/AP platform. +	  Include support for the ARM(R) Versatile/PB platform, +	  using the device tree for discovery + +config MACH_VERSATILE_AUTO +	def_bool y +	depends on !ARCH_VERSATILE_PB && !MACH_VERSATILE_AB +	select MACH_VERSATILE_DT  endmenu diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile index 97cf4d831b0..81fa3fe25e1 100644 --- a/arch/arm/mach-versatile/Makefile +++ b/arch/arm/mach-versatile/Makefile @@ -5,4 +5,5 @@  obj-y					:= core.o  obj-$(CONFIG_ARCH_VERSATILE_PB)		+= versatile_pb.o  obj-$(CONFIG_MACH_VERSATILE_AB)		+= versatile_ab.o +obj-$(CONFIG_MACH_VERSATILE_DT)		+= versatile_dt.o  obj-$(CONFIG_PCI)			+= pci.o diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot index c7e75acfe6c..ff0a4b5b0a8 100644 --- a/arch/arm/mach-versatile/Makefile.boot +++ b/arch/arm/mach-versatile/Makefile.boot @@ -1,4 +1,4 @@ -   zreladdr-y	:= 0x00008000 +   zreladdr-y	+= 0x00008000  params_phys-y	:= 0x00000100  initrd_phys-y	:= 0x00800000 diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index e38acb0f89c..be83ba25f81 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -22,34 +22,39 @@  #include <linux/device.h>  #include <linux/dma-mapping.h>  #include <linux/platform_device.h> -#include <linux/sysdev.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/arm-vic.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 <linux/reboot.h> -#include <asm/clkdev.h> -#include <asm/system.h>  #include <asm/irq.h> -#include <asm/leds.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/flash.h>  #include <asm/mach/irq.h>  #include <asm/mach/time.h>  #include <asm/mach/map.h> -#include <mach/clkdev.h>  #include <mach/hardware.h>  #include <mach/platform.h> -#include <plat/timer-sp.h> +#include <asm/hardware/timer-sp.h> + +#include <plat/clcd.h> +#include <plat/sched_clock.h>  #include "core.h" @@ -62,75 +67,56 @@  #define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)  #define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE) -static void sic_mask_irq(unsigned int irq) -{ -	irq -= IRQ_SIC_START; -	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); -} - -static void sic_unmask_irq(unsigned int irq) -{ -	irq -= IRQ_SIC_START; -	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET); -} - -static struct irq_chip sic_chip = { -	.name	= "SIC", -	.ack	= sic_mask_irq, -	.mask	= sic_mask_irq, -	.unmask	= sic_unmask_irq, -}; - -static void -sic_handle_irq(unsigned int irq, struct irq_desc *desc) -{ -	unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS); - -	if (status == 0) { -		do_bad_IRQ(irq, desc); -		return; -	} - -	do { -		irq = ffs(status) - 1; -		status &= ~(1 << irq); - -		irq += IRQ_SIC_START; - -		generic_handle_irq(irq); -	} while (status); -} - +/* 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)  { -	unsigned int i; +	struct device_node *np; -	vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0); +	np = of_find_matching_node_by_address(NULL, vic_of_match, +					      VERSATILE_VIC_BASE); +	__vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np); -	set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq); - -	/* Do second interrupt controller */  	writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); -	for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { -		if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) { -			set_irq_chip(i, &sic_chip); -			set_irq_handler(i, handle_level_irq); -			set_irq_flags(i, IRQF_VALID | IRQF_PROBE); -		} -	} +	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 @@ -142,7 +128,7 @@ void __init versatile_init_irq(void)  	writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE);  } -static struct map_desc versatile_io_desc[] __initdata = { +static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {  	{  		.virtual	=  IO_ADDRESS(VERSATILE_SYS_BASE),  		.pfn		= __phys_to_pfn(VERSATILE_SYS_BASE), @@ -166,11 +152,6 @@ static struct map_desc versatile_io_desc[] __initdata = {  	},  #ifdef CONFIG_MACH_VERSATILE_AB   	{ -		.virtual	=  IO_ADDRESS(VERSATILE_GPIO0_BASE), -		.pfn		= __phys_to_pfn(VERSATILE_GPIO0_BASE), -		.length		= SZ_4K, -		.type		= MT_DEVICE -	}, {  		.virtual	=  IO_ADDRESS(VERSATILE_IB2_BASE),  		.pfn		= __phys_to_pfn(VERSATILE_IB2_BASE),  		.length		= SZ_64M, @@ -202,24 +183,6 @@ static struct map_desc versatile_io_desc[] __initdata = {  		.length		= VERSATILE_PCI_CFG_BASE_SIZE,  		.type		= MT_DEVICE  	}, -#if 0 - 	{ -		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE0, -		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE0), -		.length		= SZ_16M, -		.type		= MT_DEVICE -	}, { -		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE1, -		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE1), -		.length		= SZ_16M, -		.type		= MT_DEVICE -	}, { -		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE2, -		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE2), -		.length		= SZ_16M, -		.type		= MT_DEVICE -	}, -#endif  #endif  }; @@ -231,27 +194,7 @@ void __init versatile_map_io(void)  #define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET) -static int versatile_flash_init(void) -{ -	u32 val; - -	val = __raw_readl(VERSATILE_FLASHCTRL); -	val &= ~VERSATILE_FLASHPROG_FLVPPEN; -	__raw_writel(val, VERSATILE_FLASHCTRL); - -	return 0; -} - -static void versatile_flash_exit(void) -{ -	u32 val; - -	val = __raw_readl(VERSATILE_FLASHCTRL); -	val &= ~VERSATILE_FLASHPROG_FLVPPEN; -	__raw_writel(val, VERSATILE_FLASHCTRL); -} - -static void versatile_flash_set_vpp(int on) +static void versatile_flash_set_vpp(struct platform_device *pdev, int on)  {  	u32 val; @@ -263,11 +206,8 @@ static void versatile_flash_set_vpp(int on)  	__raw_writel(val, VERSATILE_FLASHCTRL);  } -static struct flash_platform_data versatile_flash_data = { -	.map_name		= "cfi_probe", +static struct physmap_flash_data versatile_flash_data = {  	.width			= 4, -	.init			= versatile_flash_init, -	.exit			= versatile_flash_exit,  	.set_vpp		= versatile_flash_set_vpp,  }; @@ -278,7 +218,7 @@ static struct resource versatile_flash_resource = {  };  static struct platform_device versatile_flash_device = { -	.name			= "armflash", +	.name			= "physmap-flash",  	.id			= 0,  	.dev			= {  		.platform_data	= &versatile_flash_data, @@ -370,6 +310,21 @@ static struct platform_device char_lcd_device = {  	.resource       =       char_lcd_resources,  }; +static struct resource leds_resources[] = { +	{ +		.start	= VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET, +		.end	= VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET + 4, +		.flags	= IORESOURCE_MEM, +	}, +}; + +static struct platform_device leds_device = { +	.name		= "versatile-leds", +	.id		= -1, +	.num_resources	= ARRAY_SIZE(leds_resources), +	.resource	= leds_resources, +}; +  /*   * Clock handling   */ @@ -416,6 +371,10 @@ static struct clk ref24_clk = {  	.rate	= 24000000,  }; +static struct clk sp804_clk = { +	.rate	= 1000000, +}; +  static struct clk dummy_apb_pclk;  static struct clk_lookup lookups[] = { @@ -452,7 +411,10 @@ static struct clk_lookup lookups[] = {  	}, {	/* CLCD */  		.dev_id		= "dev:20",  		.clk		= &osc4_clk, -	} +	}, {	/* SP804 timers */ +		.dev_id		= "sp804", +		.clk		= &sp804_clk, +	},  };  /* @@ -473,127 +435,7 @@ static struct clk_lookup lookups[] = {  #define SYS_CLCD_ID_SANYO_2_5	(0x07 << 8)  #define SYS_CLCD_ID_VGA		(0x1f << 8) -static struct clcd_panel vga = { -	.mode		= { -		.name		= "VGA", -		.refresh	= 60, -		.xres		= 640, -		.yres		= 480, -		.pixclock	= 39721, -		.left_margin	= 40, -		.right_margin	= 24, -		.upper_margin	= 32, -		.lower_margin	= 11, -		.hsync_len	= 96, -		.vsync_len	= 2, -		.sync		= 0, -		.vmode		= FB_VMODE_NONINTERLACED, -	}, -	.width		= -1, -	.height		= -1, -	.tim2		= TIM2_BCD | TIM2_IPC, -	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1), -	.bpp		= 16, -}; - -static struct clcd_panel sanyo_3_8_in = { -	.mode		= { -		.name		= "Sanyo QVGA", -		.refresh	= 116, -		.xres		= 320, -		.yres		= 240, -		.pixclock	= 100000, -		.left_margin	= 6, -		.right_margin	= 6, -		.upper_margin	= 5, -		.lower_margin	= 5, -		.hsync_len	= 6, -		.vsync_len	= 6, -		.sync		= 0, -		.vmode		= FB_VMODE_NONINTERLACED, -	}, -	.width		= -1, -	.height		= -1, -	.tim2		= TIM2_BCD, -	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1), -	.bpp		= 16, -}; - -static struct clcd_panel sanyo_2_5_in = { -	.mode		= { -		.name		= "Sanyo QVGA Portrait", -		.refresh	= 116, -		.xres		= 240, -		.yres		= 320, -		.pixclock	= 100000, -		.left_margin	= 20, -		.right_margin	= 10, -		.upper_margin	= 2, -		.lower_margin	= 2, -		.hsync_len	= 10, -		.vsync_len	= 2, -		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -		.vmode		= FB_VMODE_NONINTERLACED, -	}, -	.width		= -1, -	.height		= -1, -	.tim2		= TIM2_IVS | TIM2_IHS | TIM2_IPC, -	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1), -	.bpp		= 16, -}; - -static struct clcd_panel epson_2_2_in = { -	.mode		= { -		.name		= "Epson QCIF", -		.refresh	= 390, -		.xres		= 176, -		.yres		= 220, -		.pixclock	= 62500, -		.left_margin	= 3, -		.right_margin	= 2, -		.upper_margin	= 1, -		.lower_margin	= 0, -		.hsync_len	= 3, -		.vsync_len	= 2, -		.sync		= 0, -		.vmode		= FB_VMODE_NONINTERLACED, -	}, -	.width		= -1, -	.height		= -1, -	.tim2		= TIM2_BCD | TIM2_IPC, -	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1), -	.bpp		= 16, -}; - -/* - * Detect which LCD panel is connected, and return the appropriate - * clcd_panel structure.  Note: we do not have any information on - * the required timings for the 8.4in panel, so we presently assume - * VGA timings. - */ -static struct clcd_panel *versatile_clcd_panel(void) -{ -	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; -	struct clcd_panel *panel = &vga; -	u32 val; - -	val = readl(sys_clcd) & SYS_CLCD_ID_MASK; -	if (val == SYS_CLCD_ID_SANYO_3_8) -		panel = &sanyo_3_8_in; -	else if (val == SYS_CLCD_ID_SANYO_2_5) -		panel = &sanyo_2_5_in; -	else if (val == SYS_CLCD_ID_EPSON_2_2) -		panel = &epson_2_2_in; -	else if (val == SYS_CLCD_ID_VGA) -		panel = &vga; -	else { -		printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", -			val); -		panel = &vga; -	} - -	return panel; -} +static bool is_sanyo_2_5_lcd;  /*   * Disable all display connectors on the interface module. @@ -611,7 +453,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)  	/*  	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off  	 */ -	if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { +	if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {  		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);  		unsigned long ctrl; @@ -627,18 +469,22 @@ static void versatile_clcd_disable(struct clcd_fb *fb)   */  static void versatile_clcd_enable(struct clcd_fb *fb)  { +	struct fb_var_screeninfo *var = &fb->fb.var;  	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;  	u32 val;  	val = readl(sys_clcd);  	val &= ~SYS_CLCD_MODE_MASK; -	switch (fb->fb.var.green.length) { +	switch (var->green.length) {  	case 5:  		val |= SYS_CLCD_MODE_5551;  		break;  	case 6: -		val |= SYS_CLCD_MODE_565_RLSB; +		if (var->red.offset == 0) +			val |= SYS_CLCD_MODE_565_RLSB; +		else +			val |= SYS_CLCD_MODE_565_BLSB;  		break;  	case 8:  		val |= SYS_CLCD_MODE_888; @@ -660,7 +506,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb)  	/*  	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on  	 */ -	if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { +	if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {  		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);  		unsigned long ctrl; @@ -671,50 +517,62 @@ static void versatile_clcd_enable(struct clcd_fb *fb)  #endif  } -static unsigned long framesize = SZ_1M; - +/* + * Detect which LCD panel is connected, and return the appropriate + * clcd_panel structure.  Note: we do not have any information on + * the required timings for the 8.4in panel, so we presently assume + * VGA timings. + */  static int versatile_clcd_setup(struct clcd_fb *fb)  { -	dma_addr_t dma; +	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; +	const char *panel_name; +	u32 val; -	fb->panel		= versatile_clcd_panel(); +	is_sanyo_2_5_lcd = false; -	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, -						    &dma, GFP_KERNEL); -	if (!fb->fb.screen_base) { -		printk(KERN_ERR "CLCD: unable to map framebuffer\n"); -		return -ENOMEM; +	val = readl(sys_clcd) & SYS_CLCD_ID_MASK; +	if (val == SYS_CLCD_ID_SANYO_3_8) +		panel_name = "Sanyo TM38QV67A02A"; +	else if (val == SYS_CLCD_ID_SANYO_2_5) { +		panel_name = "Sanyo QVGA Portrait"; +		is_sanyo_2_5_lcd = true; +	} else if (val == SYS_CLCD_ID_EPSON_2_2) +		panel_name = "Epson L2F50113T00"; +	else if (val == SYS_CLCD_ID_VGA) +		panel_name = "VGA"; +	else { +		printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", +			val); +		panel_name = "VGA";  	} -	fb->fb.fix.smem_start	= dma; -	fb->fb.fix.smem_len	= framesize; +	fb->panel = versatile_clcd_get_panel(panel_name); +	if (!fb->panel) +		return -EINVAL; -	return 0; +	return versatile_clcd_setup_dma(fb, SZ_1M);  } -static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)  { -	return dma_mmap_writecombine(&fb->dev->dev, vma, -				     fb->fb.screen_base, -				     fb->fb.fix.smem_start, -				     fb->fb.fix.smem_len); -} +	clcdfb_decode(fb, regs); -static void versatile_clcd_remove(struct clcd_fb *fb) -{ -	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, -			      fb->fb.screen_base, fb->fb.fix.smem_start); +	/* Always clear BGR for RGB565: we do the routing externally */ +	if (fb->fb.var.green.length == 6) +		regs->cntl &= ~CNTL_BGR;  }  static struct clcd_board clcd_plat_data = {  	.name		= "Versatile", +	.caps		= CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,  	.check		= clcdfb_check, -	.decode		= clcdfb_decode, +	.decode		= versatile_clcd_decode,  	.disable	= versatile_clcd_disable,  	.enable		= versatile_clcd_enable,  	.setup		= versatile_clcd_setup, -	.mmap		= versatile_clcd_mmap, -	.remove		= versatile_clcd_remove, +	.mmap		= versatile_clcd_mmap_dma, +	.remove		= versatile_clcd_remove_dma,  };  static struct pl061_platform_data gpio0_plat_data = { @@ -727,82 +585,78 @@ static struct pl061_platform_data gpio1_plat_data = {  	.irq_base	= IRQ_GPIO1_START,  }; +static struct pl061_platform_data gpio2_plat_data = { +	.gpio_base	= 16, +	.irq_base	= IRQ_GPIO2_START, +}; + +static struct pl061_platform_data gpio3_plat_data = { +	.gpio_base	= 24, +	.irq_base	= IRQ_GPIO3_START, +}; +  static struct pl022_ssp_controller ssp0_plat_data = {  	.bus_id = 0,  	.enable_dma = 0,  	.num_chipselect = 1,  }; -#define AACI_IRQ	{ IRQ_AACI, NO_IRQ } -#define AACI_DMA	{ 0x80, 0x81 } +#define AACI_IRQ	{ IRQ_AACI }  #define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_SIC_MMCI0B } -#define MMCI0_DMA	{ 0x84, 0 } -#define KMI0_IRQ	{ IRQ_SIC_KMI0, NO_IRQ } -#define KMI0_DMA	{ 0, 0 } -#define KMI1_IRQ	{ IRQ_SIC_KMI1, NO_IRQ } -#define KMI1_DMA	{ 0, 0 } +#define KMI0_IRQ	{ IRQ_SIC_KMI0 } +#define KMI1_IRQ	{ IRQ_SIC_KMI1 }  /*   * These devices are connected directly to the multi-layer AHB switch   */ -#define SMC_IRQ		{ NO_IRQ, NO_IRQ } -#define SMC_DMA		{ 0, 0 } -#define MPMC_IRQ	{ NO_IRQ, NO_IRQ } -#define MPMC_DMA	{ 0, 0 } -#define CLCD_IRQ	{ IRQ_CLCDINT, NO_IRQ } -#define CLCD_DMA	{ 0, 0 } -#define DMAC_IRQ	{ IRQ_DMAINT, NO_IRQ } -#define DMAC_DMA	{ 0, 0 } +#define SMC_IRQ		{ } +#define MPMC_IRQ	{ } +#define CLCD_IRQ	{ IRQ_CLCDINT } +#define DMAC_IRQ	{ IRQ_DMAINT }  /*   * These devices are connected via the core APB bridge   */ -#define SCTL_IRQ	{ NO_IRQ, NO_IRQ } -#define SCTL_DMA	{ 0, 0 } -#define WATCHDOG_IRQ	{ IRQ_WDOGINT, NO_IRQ } -#define WATCHDOG_DMA	{ 0, 0 } -#define GPIO0_IRQ	{ IRQ_GPIOINT0, NO_IRQ } -#define GPIO0_DMA	{ 0, 0 } -#define GPIO1_IRQ	{ IRQ_GPIOINT1, NO_IRQ } -#define GPIO1_DMA	{ 0, 0 } -#define RTC_IRQ		{ IRQ_RTCINT, NO_IRQ } -#define RTC_DMA		{ 0, 0 } +#define SCTL_IRQ	{ } +#define WATCHDOG_IRQ	{ IRQ_WDOGINT } +#define GPIO0_IRQ	{ IRQ_GPIOINT0 } +#define GPIO1_IRQ	{ IRQ_GPIOINT1 } +#define GPIO2_IRQ	{ IRQ_GPIOINT2 } +#define GPIO3_IRQ	{ IRQ_GPIOINT3 } +#define RTC_IRQ		{ IRQ_RTCINT }  /*   * These devices are connected via the DMA APB bridge   */ -#define SCI_IRQ		{ IRQ_SCIINT, NO_IRQ } -#define SCI_DMA		{ 7, 6 } -#define UART0_IRQ	{ IRQ_UARTINT0, NO_IRQ } -#define UART0_DMA	{ 15, 14 } -#define UART1_IRQ	{ IRQ_UARTINT1, NO_IRQ } -#define UART1_DMA	{ 13, 12 } -#define UART2_IRQ	{ IRQ_UARTINT2, NO_IRQ } -#define UART2_DMA	{ 11, 10 } -#define SSP_IRQ		{ IRQ_SSPINT, NO_IRQ } -#define SSP_DMA		{ 9, 8 } +#define SCI_IRQ		{ IRQ_SCIINT } +#define UART0_IRQ	{ IRQ_UARTINT0 } +#define UART1_IRQ	{ IRQ_UARTINT1 } +#define UART2_IRQ	{ IRQ_UARTINT2 } +#define SSP_IRQ		{ IRQ_SSPINT }  /* FPGA Primecells */ -AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL); -AMBA_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data); -AMBA_DEVICE(kmi0,  "fpga:06", KMI0,     NULL); -AMBA_DEVICE(kmi1,  "fpga:07", KMI1,     NULL); +APB_DEVICE(aaci,  "fpga:04", AACI,     NULL); +APB_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data); +APB_DEVICE(kmi0,  "fpga:06", KMI0,     NULL); +APB_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);  /* DevChip Primecells */ -AMBA_DEVICE(smc,   "dev:00",  SMC,      NULL); -AMBA_DEVICE(mpmc,  "dev:10",  MPMC,     NULL); -AMBA_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data); -AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL); -AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL); -AMBA_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data); -AMBA_DEVICE(rtc,   "dev:e8",  RTC,      NULL); -AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL); -AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL); -AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL); -AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL); -AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      &ssp0_plat_data); +AHB_DEVICE(smc,   "dev:00",  SMC,      NULL); +AHB_DEVICE(mpmc,  "dev:10",  MPMC,     NULL); +AHB_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data); +AHB_DEVICE(dmac,  "dev:30",  DMAC,     NULL); +APB_DEVICE(sctl,  "dev:e0",  SCTL,     NULL); +APB_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:e4",  GPIO0,    &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:e6",  GPIO2,    &gpio2_plat_data); +APB_DEVICE(gpio3, "dev:e7",  GPIO3,    &gpio3_plat_data); +APB_DEVICE(rtc,   "dev:e8",  RTC,      NULL); +APB_DEVICE(sci0,  "dev:f0",  SCI,      NULL); +APB_DEVICE(uart0, "dev:f1",  UART0,    NULL); +APB_DEVICE(uart1, "dev:f2",  UART1,    NULL); +APB_DEVICE(uart2, "dev:f3",  UART2,    NULL); +APB_DEVICE(ssp0,  "dev:f4",  SSP,      &ssp0_plat_data);  static struct amba_device *amba_devs[] __initdata = {  	&dmac_device, @@ -816,6 +670,8 @@ static struct amba_device *amba_devs[] __initdata = {  	&wdog_device,  	&gpio0_device,  	&gpio1_device, +	&gpio2_device, +	&gpio3_device,  	&rtc_device,  	&sci0_device,  	&ssp0_device, @@ -825,6 +681,53 @@ static struct amba_device *amba_devs[] __initdata = {  	&kmi1_device,  }; +#ifdef CONFIG_OF +/* + * Lookup table for attaching a specific name and platform_data pointer to + * devices as they get created by of_platform_populate().  Ideally this table + * would not exist, but the current clock implementation depends on some devices + * having a specific name. + */ +struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = { +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI0_BASE, "fpga:06", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI1_BASE, "fpga:07", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART3_BASE, "fpga:09", NULL), +	/* FIXME: this is buggy, the platform data is needed for this MMC instance too */ +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", NULL), + +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART0_BASE, "dev:f1", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART1_BASE, "dev:f2", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART2_BASE, "dev:f3", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", &ssp0_plat_data), + +#if 0 +	/* +	 * These entries are unnecessary because no clocks referencing +	 * them.  I've left them in for now as place holders in case +	 * any of them need to be added back, but they should be +	 * removed before actually committing this patch.  --gcl +	 */ +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_AACI_BASE, "fpga:04", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI1_BASE, "fpga:0a", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_SMC_BASE, "dev:00", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_MPMC_BASE, "dev:10", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_DMAC_BASE, "dev:30", NULL), + +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCTL_BASE, "dev:e0", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_WATCHDOG_BASE, "dev:e1", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO0_BASE, "dev:e4", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO1_BASE, "dev:e5", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO2_BASE, "dev:e6", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO3_BASE, "dev:e7", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_RTC_BASE, "dev:e8", NULL), +	OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI_BASE, "dev:f0", NULL), +#endif +	{} +}; +#endif +  #ifdef CONFIG_LEDS  #define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) @@ -862,27 +765,57 @@ static void versatile_leds_event(led_event_t ledevt)  }  #endif	/* CONFIG_LEDS */ -void __init versatile_init(void) +void versatile_restart(enum reboot_mode mode, const char *cmd)  { -	int i; +	void __iomem *sys = __io_address(VERSATILE_SYS_BASE); +	u32 val; + +	val = __raw_readl(sys + VERSATILE_SYS_RESETCTL_OFFSET); +	val |= 0x105; + +	__raw_writel(0xa05f, sys + VERSATILE_SYS_LOCK_OFFSET); +	__raw_writel(val, sys + VERSATILE_SYS_RESETCTL_OFFSET); +	__raw_writel(0, sys + VERSATILE_SYS_LOCK_OFFSET); +} -	osc4_clk.vcoreg	= __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET; +/* Early initializations */ +void __init versatile_init_early(void) +{ +	u32 val; +	void __iomem *sys = __io_address(VERSATILE_SYS_BASE); +	osc4_clk.vcoreg	= sys + VERSATILE_SYS_OSCCLCD_OFFSET;  	clkdev_add_table(lookups, ARRAY_SIZE(lookups)); +	versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000); + +	/* +	 * set clock frequency: +	 *	VERSATILE_REFCLK is 32KHz +	 *	VERSATILE_TIMCLK is 1MHz +	 */ +	val = readl(__io_address(VERSATILE_SCTL_BASE)); +	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | +	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | +	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | +	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, +	       __io_address(VERSATILE_SCTL_BASE)); +} + +void __init versatile_init(void) +{ +	int i; +  	platform_device_register(&versatile_flash_device);  	platform_device_register(&versatile_i2c_device);  	platform_device_register(&smc91x_device);  	platform_device_register(&char_lcd_device); +	platform_device_register(&leds_device);  	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {  		struct amba_device *d = amba_devs[i];  		amba_device_register(d, &iomem_resource);  	} - -#ifdef CONFIG_LEDS -	leds_event = versatile_leds_event; -#endif  }  /* @@ -896,21 +829,8 @@ void __init versatile_init(void)  /*   * Set up timer interrupt, and return the current time in seconds.   */ -static void __init versatile_timer_init(void) +void __init versatile_timer_init(void)  { -	u32 val; - -	/*  -	 * set clock frequency:  -	 *	VERSATILE_REFCLK is 32KHz -	 *	VERSATILE_TIMCLK is 1MHz -	 */ -	val = readl(__io_address(VERSATILE_SCTL_BASE)); -	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | -	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |  -	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | -	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, -	       __io_address(VERSATILE_SCTL_BASE));  	/*  	 * Initialise to a known state (all timers off) @@ -920,11 +840,6 @@ static void __init versatile_timer_init(void)  	writel(0, TIMER2_VA_BASE + TIMER_CTRL);  	writel(0, TIMER3_VA_BASE + TIMER_CTRL); -	sp804_clocksource_init(TIMER3_VA_BASE); -	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1); +	sp804_clocksource_init(TIMER3_VA_BASE, "timer3"); +	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");  } - -struct sys_timer versatile_timer = { -	.init		= versatile_timer_init, -}; - diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h index 9d39886a835..f06d5768e42 100644 --- a/arch/arm/mach-versatile/core.h +++ b/arch/arm/mach-versatile/core.h @@ -23,28 +23,24 @@  #define __ASM_ARCH_VERSATILE_H  #include <linux/amba/bus.h> +#include <linux/of_platform.h> +#include <linux/reboot.h>  extern void __init versatile_init(void); +extern void __init versatile_init_early(void);  extern void __init versatile_init_irq(void);  extern void __init versatile_map_io(void); -extern struct sys_timer versatile_timer; +extern void versatile_timer_init(void); +extern void versatile_restart(enum reboot_mode, const char *);  extern unsigned int mmc_status(struct device *dev); +#ifdef CONFIG_OF +extern struct of_dev_auxdata versatile_auxdata_lookup[]; +#endif + +#define APB_DEVICE(name, busid, base, plat)	\ +static AMBA_APB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat) -#define AMBA_DEVICE(name,busid,base,plat)			\ -static struct amba_device name##_device = {			\ -	.dev		= {					\ -		.coherent_dma_mask = ~0,			\ -		.init_name = busid,				\ -		.platform_data = plat,				\ -	},							\ -	.res		= {					\ -		.start	= VERSATILE_##base##_BASE,		\ -		.end	= (VERSATILE_##base##_BASE) + SZ_4K - 1,\ -		.flags	= IORESOURCE_MEM,			\ -	},							\ -	.dma_mask	= ~0,					\ -	.irq		= base##_IRQ,				\ -	/* .dma		= base##_DMA,*/				\ -} +#define AHB_DEVICE(name, busid, base, plat)	\ +static AMBA_AHB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)  #endif diff --git a/arch/arm/mach-versatile/include/mach/debug-macro.S b/arch/arm/mach-versatile/include/mach/debug-macro.S deleted file mode 100644 index eb2cf7dc5c4..00000000000 --- a/arch/arm/mach-versatile/include/mach/debug-macro.S +++ /dev/null @@ -1,21 +0,0 @@ -/* arch/arm/mach-versatile/include/mach/debug-macro.S - * - * Debugging macro include header - * - *  Copyright (C) 1994-1999 Russell King - *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - -		.macro	addruart, rp, rv -		mov	\rp,      #0x001F0000 -		orr	\rp, \rp, #0x00001000 -		orr	\rv, \rp, #0xf1000000	@ virtual base -		orr	\rp, \rp,  #0x10000000	@ physical base -		.endm - -#include <asm/hardware/debug-pl01x.S> diff --git a/arch/arm/mach-versatile/include/mach/entry-macro.S b/arch/arm/mach-versatile/include/mach/entry-macro.S deleted file mode 100644 index e6f7c166316..00000000000 --- a/arch/arm/mach-versatile/include/mach/entry-macro.S +++ /dev/null @@ -1,45 +0,0 @@ -/* - * arch/arm/mach-versatile/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for Versatile platforms - * - * This file is licensed under  the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#include <mach/hardware.h> -#include <mach/platform.h> -#include <asm/hardware/vic.h> - -		.macro	disable_fiq -		.endm - -		.macro  get_irqnr_preamble, base, tmp -		ldr	\base, =IO_ADDRESS(VERSATILE_VIC_BASE) -		.endm - -		.macro  arch_ret_to_user, tmp1, tmp2 -		.endm - -		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp -		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get masked status -		mov	\irqnr, #0 -		teq	\irqstat, #0 -		beq	1003f - -1001:		tst	\irqstat, #15 -		bne	1002f -		add	\irqnr, \irqnr, #4 -		movs	\irqstat, \irqstat, lsr #4 -		bne	1001b -1002:		tst	\irqstat, #1 -		bne	1003f -		add	\irqnr, \irqnr, #1 -		movs	\irqstat, \irqstat, lsr #1 -		bne	1002b -1003:		/* EQ will be set if no irqs pending */ - -@		clz	\irqnr, \irqstat -@1003:		/* EQ will be set if we reach MAXIRQNUM */ -		.endm - diff --git a/arch/arm/mach-versatile/include/mach/gpio.h b/arch/arm/mach-versatile/include/mach/gpio.h deleted file mode 100644 index 94ff27678a4..00000000000 --- a/arch/arm/mach-versatile/include/mach/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#include <asm-generic/gpio.h> - -#define gpio_get_value	__gpio_get_value -#define gpio_set_value	__gpio_set_value -#define gpio_cansleep	__gpio_cansleep -#define gpio_to_irq	__gpio_to_irq diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h index b5e75bb4496..3e5d425e2a9 100644 --- a/arch/arm/mach-versatile/include/mach/hardware.h +++ b/arch/arm/mach-versatile/include/mach/hardware.h @@ -30,15 +30,9 @@  #define VERSATILE_PCI_VIRT_BASE		(void __iomem *)0xe8000000ul  #define VERSATILE_PCI_CFG_VIRT_BASE	(void __iomem *)0xe9000000ul -/* CIK guesswork */ -#define PCIBIOS_MIN_IO			0x44000000 -#define PCIBIOS_MIN_MEM			0x50000000 - -#define pcibios_assign_all_busses()     1 - -/* macro to get at IO space when running virtually */ +/* macro to get at MMIO space when running virtually */  #define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) -#define __io_address(n)		__io(IO_ADDRESS(n)) +#define __io_address(n)		((void __iomem __force *)IO_ADDRESS(n))  #endif diff --git a/arch/arm/mach-versatile/include/mach/io.h b/arch/arm/mach-versatile/include/mach/io.h deleted file mode 100644 index f067c14c718..00000000000 --- a/arch/arm/mach-versatile/include/mach/io.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - *  arch/arm/mach-versatile/include/mach/io.h - * - *  Copyright (C) 2003 ARM Limited - * - * 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 - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a)		__typesafe_io(a) -#define __mem_pci(a)	(a) - -#endif diff --git a/arch/arm/mach-versatile/include/mach/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h index bf44c61bd1f..0fd771ca617 100644 --- a/arch/arm/mach-versatile/include/mach/irqs.h +++ b/arch/arm/mach-versatile/include/mach/irqs.h @@ -25,7 +25,7 @@   *  IRQ interrupts definitions are the same as the INT definitions   *  held within platform.h   */ -#define IRQ_VIC_START		0 +#define IRQ_VIC_START		32  #define IRQ_WDOGINT		(IRQ_VIC_START + INT_WDOGINT)  #define IRQ_SOFTINT		(IRQ_VIC_START + INT_SOFTINT)  #define IRQ_COMMRx		(IRQ_VIC_START + INT_COMMRx) @@ -100,7 +100,7 @@  /*   * Secondary interrupt controller   */ -#define IRQ_SIC_START		32 +#define IRQ_SIC_START		64  #define IRQ_SIC_MMCI0B 		(IRQ_SIC_START + SIC_INT_MMCI0B)  #define IRQ_SIC_MMCI1B 		(IRQ_SIC_START + SIC_INT_MMCI1B)  #define IRQ_SIC_KMI0		(IRQ_SIC_START + SIC_INT_KMI0) @@ -120,7 +120,7 @@  #define IRQ_SIC_PCI1		(IRQ_SIC_START + SIC_INT_PCI1)  #define IRQ_SIC_PCI2		(IRQ_SIC_START + SIC_INT_PCI2)  #define IRQ_SIC_PCI3		(IRQ_SIC_START + SIC_INT_PCI3) -#define IRQ_SIC_END		63 +#define IRQ_SIC_END		95  #define IRQ_GPIO0_START		(IRQ_SIC_END + 1)  #define IRQ_GPIO0_END		(IRQ_GPIO0_START + 31) diff --git a/arch/arm/mach-versatile/include/mach/memory.h b/arch/arm/mach-versatile/include/mach/memory.h deleted file mode 100644 index 79aeab86b90..00000000000 --- a/arch/arm/mach-versatile/include/mach/memory.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - *  arch/arm/mach-versatile/include/mach/memory.h - * - *  Copyright (C) 2003 ARM Limited - * - * 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 - */ -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h index ec087407b16..6f938ccb0c5 100644 --- a/arch/arm/mach-versatile/include/mach/platform.h +++ b/arch/arm/mach-versatile/include/mach/platform.h @@ -231,12 +231,14 @@  /* PCI space */  #define VERSATILE_PCI_BASE             0x41000000	/* PCI Interface */  #define VERSATILE_PCI_CFG_BASE	       0x42000000 +#define VERSATILE_PCI_IO_BASE          0x43000000  #define VERSATILE_PCI_MEM_BASE0        0x44000000  #define VERSATILE_PCI_MEM_BASE1        0x50000000  #define VERSATILE_PCI_MEM_BASE2        0x60000000  /* Sizes of above maps */  #define VERSATILE_PCI_BASE_SIZE	       0x01000000  #define VERSATILE_PCI_CFG_BASE_SIZE    0x02000000 +#define VERSATILE_PCI_IO_BASE_SIZE     0x01000000  #define VERSATILE_PCI_MEM_BASE0_SIZE   0x0c000000	/* 32Mb */  #define VERSATILE_PCI_MEM_BASE1_SIZE   0x10000000	/* 256Mb */  #define VERSATILE_PCI_MEM_BASE2_SIZE   0x10000000	/* 256Mb */ diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h deleted file mode 100644 index 8ffc12a7cb2..00000000000 --- a/arch/arm/mach-versatile/include/mach/system.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - *  arch/arm/mach-versatile/include/mach/system.h - * - *  Copyright (C) 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 - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <linux/io.h> -#include <mach/hardware.h> -#include <mach/platform.h> - -static inline void arch_idle(void) -{ -	/* -	 * This should do all the clock switching -	 * and wait for interrupt tricks -	 */ -	cpu_do_idle(); -} - -static inline void arch_reset(char mode, const char *cmd) -{ -	u32 val; - -	val = __raw_readl(IO_ADDRESS(VERSATILE_SYS_RESETCTL)) & ~0x7; -	val |= 0x105; - -	__raw_writel(0xa05f, IO_ADDRESS(VERSATILE_SYS_LOCK)); -	__raw_writel(val, IO_ADDRESS(VERSATILE_SYS_RESETCTL)); -	__raw_writel(0, IO_ADDRESS(VERSATILE_SYS_LOCK)); -} - -#endif diff --git a/arch/arm/mach-versatile/include/mach/timex.h b/arch/arm/mach-versatile/include/mach/timex.h deleted file mode 100644 index 426199b1add..00000000000 --- a/arch/arm/mach-versatile/include/mach/timex.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - *  arch/arm/mach-versatile/include/mach/timex.h - * - *  Versatile architecture timex specifications - * - *  Copyright (C) 2003 ARM Limited - * - * 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 - */ - -#define CLOCK_TICK_RATE		(50000000 / 16) diff --git a/arch/arm/mach-versatile/include/mach/uncompress.h b/arch/arm/mach-versatile/include/mach/uncompress.h index 3dd0048afb3..986e3d303f3 100644 --- a/arch/arm/mach-versatile/include/mach/uncompress.h +++ b/arch/arm/mach-versatile/include/mach/uncompress.h @@ -43,4 +43,3 @@ static inline void flush(void)   * nothing to do   */  #define arch_decomp_setup() -#define arch_decomp_wdog() diff --git a/arch/arm/mach-versatile/include/mach/vmalloc.h b/arch/arm/mach-versatile/include/mach/vmalloc.h deleted file mode 100644 index ebd8a2543d3..00000000000 --- a/arch/arm/mach-versatile/include/mach/vmalloc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - *  arch/arm/mach-versatile/include/mach/vmalloc.h - * - *  Copyright (C) 2003 ARM Limited - *  Copyright (C) 2000 Russell King. - * - * 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 - */ -#define VMALLOC_END		0xd8000000 diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 13c7e5f90a8..c97be4ea76d 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -23,8 +23,8 @@  #include <linux/io.h>  #include <mach/hardware.h> +#include <mach/irqs.h>  #include <asm/irq.h> -#include <asm/system.h>  #include <asm/mach/pci.h>  /* @@ -43,9 +43,9 @@  #define PCI_IMAP0		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)  #define PCI_IMAP1		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)  #define PCI_IMAP2		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) -#define PCI_SMAP0		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10) -#define PCI_SMAP1		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) -#define PCI_SMAP2		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) +#define PCI_SMAP0		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) +#define PCI_SMAP1		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) +#define PCI_SMAP2		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c)  #define PCI_SELFID		__IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)  #define DEVICE_ID_OFFSET		0x00 @@ -170,11 +170,11 @@ static struct pci_ops pci_versatile_ops = {  	.write	= versatile_write_config,  }; -static struct resource io_mem = { -	.name	= "PCI I/O space", +static struct resource unused_mem = { +	.name	= "PCI unused",  	.start	= VERSATILE_PCI_MEM_BASE0,  	.end	= VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1, -	.flags	= IORESOURCE_IO, +	.flags	= IORESOURCE_MEM,  };  static struct resource non_mem = { @@ -191,13 +191,13 @@ static struct resource pre_mem = {  	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,  }; -static int __init pci_versatile_setup_resources(struct resource **resource) +static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)  {  	int ret = 0; -	ret = request_resource(&iomem_resource, &io_mem); +	ret = request_resource(&iomem_resource, &unused_mem);  	if (ret) { -		printk(KERN_ERR "PCI: unable to allocate I/O " +		printk(KERN_ERR "PCI: unable to allocate unused "  		       "memory region (%d)\n", ret);  		goto out;  	} @@ -205,7 +205,7 @@ static int __init pci_versatile_setup_resources(struct resource **resource)  	if (ret) {  		printk(KERN_ERR "PCI: unable to allocate non-prefetchable "  		       "memory region (%d)\n", ret); -		goto release_io_mem; +		goto release_unused_mem;  	}  	ret = request_resource(&iomem_resource, &pre_mem);  	if (ret) { @@ -215,20 +215,18 @@ static int __init pci_versatile_setup_resources(struct resource **resource)  	}  	/* -	 * bus->resource[0] is the IO resource for this bus -	 * bus->resource[1] is the mem resource for this bus -	 * bus->resource[2] is the prefetch mem resource for this bus +	 * the mem resource for this bus +	 * the prefetch mem resource for this bus  	 */ -	resource[0] = &io_mem; -	resource[1] = &non_mem; -	resource[2] = &pre_mem; +	pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); +	pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);  	goto out;   release_non_mem:  	release_resource(&non_mem); - release_io_mem: -	release_resource(&io_mem); + release_unused_mem: +	release_resource(&unused_mem);   out:  	return ret;  } @@ -248,9 +246,12 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)  		goto out;  	} +	ret = pci_ioremap_io(0, VERSATILE_PCI_IO_BASE); +	if (ret) +		goto out; +  	if (nr == 0) { -		sys->mem_offset = 0; -		ret = pci_versatile_setup_resources(sys->resource); +		ret = pci_versatile_setup_resources(sys);  		if (ret < 0) {  			printk("pci_versatile_setup: resources... oops?\n");  			goto out; @@ -294,6 +295,19 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)  	__raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2);  	/* +	 * For many years the kernel and QEMU were symbiotically buggy +	 * in that they both assumed the same broken IRQ mapping. +	 * QEMU therefore attempts to auto-detect old broken kernels +	 * so that they still work on newer QEMU as they did on old +	 * QEMU. Since we now use the correct (ie matching-hardware) +	 * IRQ mapping we write a definitely different value to a +	 * PCI_INTERRUPT_LINE register to tell QEMU that we expect +	 * real hardware behaviour and it need not be backwards +	 * compatible for us. This write is harmless on real hardware. +	 */ +	__raw_writel(0, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE); + +	/*  	 * Do not to map Versatile FPGA PCI device into memory space  	 */  	pci_slot_ignore |= (1 << myslot); @@ -304,13 +318,10 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)  } -struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys) -{ -	return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys); -} -  void __init pci_versatile_preinit(void)  { +	pcibios_min_mem = 0x50000000; +  	__raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0);  	__raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28, PCI_IMAP1);  	__raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28, PCI_IMAP2); @@ -325,30 +336,26 @@ void __init pci_versatile_preinit(void)  /*   * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.   */ -static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	int irq; -	int devslot = PCI_SLOT(dev->devfn); -	/* slot,  pin,	irq -	 *  24     1     27 -	 *  25     1     28 -	 *  26     1     29 -	 *  27     1     30 +	/* +	 * Slot	INTA	INTB	INTC	INTD +	 * 31	PCI1	PCI2	PCI3	PCI0 +	 * 30	PCI0	PCI1	PCI2	PCI3 +	 * 29	PCI3	PCI0	PCI1	PCI2  	 */ -	irq = 27 + ((slot + pin - 1) & 3); - -	printk("PCI map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq); +	irq = IRQ_SIC_PCI0 + ((slot + 2 + pin - 1) & 3);  	return irq;  }  static struct hw_pci versatile_pci __initdata = { -	.swizzle		= NULL,  	.map_irq		= versatile_map_irq,  	.nr_controllers		= 1, +	.ops			= &pci_versatile_ops,  	.setup			= pci_versatile_setup, -	.scan			= pci_versatile_scan_bus,  	.preinit		= pci_versatile_preinit,  }; diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index aa9730fb13b..1caef109379 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -21,7 +21,6 @@  #include <linux/init.h>  #include <linux/device.h> -#include <linux/sysdev.h>  #include <linux/amba/bus.h>  #include <linux/io.h> @@ -35,9 +34,11 @@  MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= versatile_map_io, +	.init_early	= versatile_init_early,  	.init_irq	= versatile_init_irq, -	.timer		= &versatile_timer, +	.init_time	= versatile_timer_init,  	.init_machine	= versatile_init, +	.restart	= versatile_restart,  MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c new file mode 100644 index 00000000000..3621b000a0f --- /dev/null +++ b/arch/arm/mach-versatile/versatile_dt.c @@ -0,0 +1,51 @@ +/* + * Versatile board support using the device tree + * + *  Copyright (C) 2010 Secret Lab Technologies Ltd. + *  Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com> + *  Copyright (C) 2004 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/of_irq.h> +#include <linux/of_platform.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include "core.h" + +static void __init versatile_dt_init(void) +{ +	of_platform_populate(NULL, of_default_bus_match_table, +			     versatile_auxdata_lookup, NULL); +} + +static const char *versatile_dt_match[] __initconst = { +	"arm,versatile-ab", +	"arm,versatile-pb", +	NULL, +}; + +DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)") +	.map_io		= versatile_map_io, +	.init_early	= versatile_init_early, +	.init_irq	= versatile_init_irq, +	.init_machine	= versatile_dt_init, +	.dt_compat	= versatile_dt_match, +	.restart	= versatile_restart, +MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index bf469642a3f..9a53d0bd914 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -21,7 +21,6 @@  #include <linux/init.h>  #include <linux/device.h> -#include <linux/sysdev.h>  #include <linux/amba/bus.h>  #include <linux/amba/pl061.h>  #include <linux/amba/mmci.h> @@ -48,48 +47,22 @@ static struct mmci_platform_data mmc1_plat_data = {  	.gpio_cd	= -1,  }; -static struct pl061_platform_data gpio2_plat_data = { -	.gpio_base	= 16, -	.irq_base	= IRQ_GPIO2_START, -}; - -static struct pl061_platform_data gpio3_plat_data = { -	.gpio_base	= 24, -	.irq_base	= IRQ_GPIO3_START, -}; - -#define UART3_IRQ	{ IRQ_SIC_UART3, NO_IRQ } -#define UART3_DMA	{ 0x86, 0x87 } -#define SCI1_IRQ	{ IRQ_SIC_SCI3, NO_IRQ } -#define SCI1_DMA	{ 0x88, 0x89 } +#define UART3_IRQ	{ IRQ_SIC_UART3 } +#define SCI1_IRQ	{ IRQ_SIC_SCI3 }  #define MMCI1_IRQ	{ IRQ_MMCI1A, IRQ_SIC_MMCI1B } -#define MMCI1_DMA	{ 0x85, 0 } - -/* - * These devices are connected via the core APB bridge - */ -#define GPIO2_IRQ	{ IRQ_GPIOINT2, NO_IRQ } -#define GPIO2_DMA	{ 0, 0 } -#define GPIO3_IRQ	{ IRQ_GPIOINT3, NO_IRQ } -#define GPIO3_DMA	{ 0, 0 }  /*   * These devices are connected via the DMA APB bridge   */  /* FPGA Primecells */ -AMBA_DEVICE(uart3, "fpga:09", UART3,    NULL); -AMBA_DEVICE(sci1,  "fpga:0a", SCI1,     NULL); -AMBA_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data); +APB_DEVICE(uart3, "fpga:09", UART3,    NULL); +APB_DEVICE(sci1,  "fpga:0a", SCI1,     NULL); +APB_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data); -/* DevChip Primecells */ -AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    &gpio2_plat_data); -AMBA_DEVICE(gpio3, "dev:e7",  GPIO3,    &gpio3_plat_data);  static struct amba_device *amba_devs[] __initdata = {  	&uart3_device, -	&gpio2_device, -	&gpio3_device,  	&sci1_device,  	&mmc1_device,  }; @@ -108,9 +81,11 @@ static void __init versatile_pb_init(void)  MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= versatile_map_io, +	.init_early	= versatile_init_early,  	.init_irq	= versatile_init_irq, -	.timer		= &versatile_timer, +	.init_time	= versatile_timer_init,  	.init_machine	= versatile_pb_init, +	.restart	= versatile_restart,  MACHINE_END  | 
