|
@@ -497,3 +497,179 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
|
|
|
ctrl = readl(versatile_ib2_ctrl);
|
|
|
ctrl |= 0x01;
|
|
|
writel(ctrl, versatile_ib2_ctrl);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * 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)
|
|
|
+{
|
|
|
+ void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
|
|
|
+ const char *panel_name;
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ is_sanyo_2_5_lcd = false;
|
|
|
+
|
|
|
+ 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->panel = versatile_clcd_get_panel(panel_name);
|
|
|
+ if (!fb->panel)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ return versatile_clcd_setup_dma(fb, SZ_1M);
|
|
|
+}
|
|
|
+
|
|
|
+static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
|
|
|
+{
|
|
|
+ clcdfb_decode(fb, regs);
|
|
|
+
|
|
|
+ /* 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 = versatile_clcd_decode,
|
|
|
+ .disable = versatile_clcd_disable,
|
|
|
+ .enable = versatile_clcd_enable,
|
|
|
+ .setup = versatile_clcd_setup,
|
|
|
+ .mmap = versatile_clcd_mmap_dma,
|
|
|
+ .remove = versatile_clcd_remove_dma,
|
|
|
+};
|
|
|
+
|
|
|
+static struct pl061_platform_data gpio0_plat_data = {
|
|
|
+ .gpio_base = 0,
|
|
|
+ .irq_base = IRQ_GPIO0_START,
|
|
|
+};
|
|
|
+
|
|
|
+static struct pl061_platform_data gpio1_plat_data = {
|
|
|
+ .gpio_base = 8,
|
|
|
+ .irq_base = IRQ_GPIO1_START,
|
|
|
+};
|
|
|
+
|
|
|
+static struct pl022_ssp_controller ssp0_plat_data = {
|
|
|
+ .bus_id = 0,
|
|
|
+ .enable_dma = 0,
|
|
|
+ .num_chipselect = 1,
|
|
|
+};
|
|
|
+
|
|
|
+#define AACI_IRQ { IRQ_AACI }
|
|
|
+#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
|
|
|
+#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 { }
|
|
|
+#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 { }
|
|
|
+#define WATCHDOG_IRQ { IRQ_WDOGINT }
|
|
|
+#define GPIO0_IRQ { IRQ_GPIOINT0 }
|
|
|
+#define GPIO1_IRQ { IRQ_GPIOINT1 }
|
|
|
+#define RTC_IRQ { IRQ_RTCINT }
|
|
|
+
|
|
|
+/*
|
|
|
+ * These devices are connected via the DMA APB bridge
|
|
|
+ */
|
|
|
+#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 */
|
|
|
+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 */
|
|
|
+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(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,
|
|
|
+ &uart0_device,
|
|
|
+ &uart1_device,
|
|
|
+ &uart2_device,
|
|
|
+ &smc_device,
|
|
|
+ &mpmc_device,
|
|
|
+ &clcd_device,
|
|
|
+ &sctl_device,
|
|
|
+ &wdog_device,
|
|
|
+ &gpio0_device,
|
|
|
+ &gpio1_device,
|
|
|
+ &rtc_device,
|
|
|
+ &sci0_device,
|
|
|
+ &ssp0_device,
|
|
|
+ &aaci_device,
|
|
|
+ &mmc0_device,
|
|
|
+ &kmi0_device,
|
|
|
+ &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
|