|
@@ -673,3 +673,145 @@ struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
|
|
|
#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)
|
|
|
+
|
|
|
+static void versatile_leds_event(led_event_t ledevt)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ local_irq_save(flags);
|
|
|
+ val = readl(VA_LEDS_BASE);
|
|
|
+
|
|
|
+ switch (ledevt) {
|
|
|
+ case led_idle_start:
|
|
|
+ val = val & ~VERSATILE_SYS_LED0;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case led_idle_end:
|
|
|
+ val = val | VERSATILE_SYS_LED0;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case led_timer:
|
|
|
+ val = val ^ VERSATILE_SYS_LED1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case led_halted:
|
|
|
+ val = 0;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ writel(val, VA_LEDS_BASE);
|
|
|
+ local_irq_restore(flags);
|
|
|
+}
|
|
|
+#endif /* CONFIG_LEDS */
|
|
|
+
|
|
|
+void versatile_restart(char mode, const char *cmd)
|
|
|
+{
|
|
|
+ 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);
|
|
|
+}
|
|
|
+
|
|
|
+/* Early initializations */
|
|
|
+void __init versatile_init_early(void)
|
|
|
+{
|
|
|
+ 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);
|
|
|
+}
|
|
|
+
|
|
|
+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);
|
|
|
+
|
|
|
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
|
|
+ struct amba_device *d = amba_devs[i];
|
|
|
+ amba_device_register(d, &iomem_resource);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Where is the timer (VA)?
|
|
|
+ */
|
|
|
+#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE)
|
|
|
+#define TIMER1_VA_BASE (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
|
|
|
+#define TIMER2_VA_BASE __io_address(VERSATILE_TIMER2_3_BASE)
|
|
|
+#define TIMER3_VA_BASE (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Set up timer interrupt, and return the current time in seconds.
|
|
|
+ */
|
|
|
+static 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)
|
|
|
+ */
|
|
|
+ writel(0, TIMER0_VA_BASE + TIMER_CTRL);
|
|
|
+ writel(0, TIMER1_VA_BASE + TIMER_CTRL);
|
|
|
+ writel(0, TIMER2_VA_BASE + TIMER_CTRL);
|
|
|
+ writel(0, TIMER3_VA_BASE + TIMER_CTRL);
|
|
|
+
|
|
|
+ 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,
|
|
|
+};
|
|
|
+
|