summaryrefslogtreecommitdiff
path: root/arch/arm/mach-realview/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-realview/core.c')
-rw-r--r--arch/arm/mach-realview/core.c141
1 files changed, 127 insertions, 14 deletions
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 2f04d54711e7..5f1d55963ced 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -28,11 +28,14 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/io.h>
+#include <linux/smc911x.h>
+#include <asm/clkdev.h>
#include <asm/system.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
+#include <asm/mach-types.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/icst307.h>
@@ -49,7 +52,7 @@
#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
-/* used by entry-macro.S */
+/* used by entry-macro.S and platsmp.c */
void __iomem *gic_cpu_base_addr;
/*
@@ -124,6 +127,29 @@ int realview_flash_register(struct resource *res, u32 num)
return platform_device_register(&realview_flash_device);
}
+static struct smc911x_platdata realview_smc911x_platdata = {
+ .flags = SMC911X_USE_32BIT,
+ .irq_flags = IRQF_SHARED,
+ .irq_polarity = 1,
+};
+
+static struct platform_device realview_eth_device = {
+ .name = "smc911x",
+ .id = 0,
+ .num_resources = 2,
+};
+
+int realview_eth_register(const char *name, struct resource *res)
+{
+ if (name)
+ realview_eth_device.name = name;
+ realview_eth_device.resource = res;
+ if (strcmp(realview_eth_device.name, "smc911x") == 0)
+ realview_eth_device.dev.platform_data = &realview_smc911x_platdata;
+
+ return platform_device_register(&realview_eth_device);
+}
+
static struct resource realview_i2c_resource = {
.start = REALVIEW_I2C_BASE,
.end = REALVIEW_I2C_BASE + SZ_4K - 1,
@@ -177,9 +203,14 @@ static const struct icst307_params realview_oscvco_params = {
static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
{
void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
- void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
+ void __iomem *sys_osc;
u32 val;
+ if (machine_is_realview_pb1176())
+ sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
+ else
+ sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
+
val = readl(sys_osc) & ~0x7ffff;
val |= vco.v | (vco.r << 9) | (vco.s << 16);
@@ -188,13 +219,60 @@ static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
writel(0, sys_lock);
}
-struct clk realview_clcd_clk = {
- .name = "CLCDCLK",
+static struct clk oscvco_clk = {
.params = &realview_oscvco_params,
.setvco = realview_oscvco_set,
};
/*
+ * These are fixed clocks.
+ */
+static struct clk ref24_clk = {
+ .rate = 24000000,
+};
+
+static struct clk_lookup lookups[] = {
+ { /* UART0 */
+ .dev_id = "dev:f1",
+ .clk = &ref24_clk,
+ }, { /* UART1 */
+ .dev_id = "dev:f2",
+ .clk = &ref24_clk,
+ }, { /* UART2 */
+ .dev_id = "dev:f3",
+ .clk = &ref24_clk,
+ }, { /* UART3 */
+ .dev_id = "fpga:09",
+ .clk = &ref24_clk,
+ }, { /* KMI0 */
+ .dev_id = "fpga:06",
+ .clk = &ref24_clk,
+ }, { /* KMI1 */
+ .dev_id = "fpga:07",
+ .clk = &ref24_clk,
+ }, { /* MMC0 */
+ .dev_id = "fpga:05",
+ .clk = &ref24_clk,
+ }, { /* EB:CLCD */
+ .dev_id = "dev:20",
+ .clk = &oscvco_clk,
+ }, { /* PB:CLCD */
+ .dev_id = "issp:20",
+ .clk = &oscvco_clk,
+ }
+};
+
+static int __init clk_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
+ return 0;
+}
+arch_initcall(clk_init);
+
+/*
* CLCD support.
*/
#define SYS_CLCD_NLCDIOON (1 << 2)
@@ -226,7 +304,30 @@ static struct clcd_panel vga = {
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
- .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+ .bpp = 16,
+};
+
+static struct clcd_panel xvga = {
+ .mode = {
+ .name = "XVGA",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = 15748,
+ .left_margin = 152,
+ .right_margin = 48,
+ .upper_margin = 23,
+ .lower_margin = 3,
+ .hsync_len = 104,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
@@ -249,7 +350,7 @@ static struct clcd_panel sanyo_3_8_in = {
.width = -1,
.height = -1,
.tim2 = TIM2_BCD,
- .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
@@ -272,7 +373,7 @@ static struct clcd_panel sanyo_2_5_in = {
.width = -1,
.height = -1,
.tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
- .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
@@ -295,7 +396,7 @@ static struct clcd_panel epson_2_2_in = {
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
- .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
@@ -308,9 +409,15 @@ static struct clcd_panel epson_2_2_in = {
static struct clcd_panel *realview_clcd_panel(void)
{
void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
- struct clcd_panel *panel = &vga;
+ struct clcd_panel *vga_panel;
+ struct clcd_panel *panel;
u32 val;
+ if (machine_is_realview_eb())
+ vga_panel = &vga;
+ else
+ vga_panel = &xvga;
+
val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
if (val == SYS_CLCD_ID_SANYO_3_8)
panel = &sanyo_3_8_in;
@@ -319,11 +426,11 @@ static struct clcd_panel *realview_clcd_panel(void)
else if (val == SYS_CLCD_ID_EPSON_2_2)
panel = &epson_2_2_in;
else if (val == SYS_CLCD_ID_VGA)
- panel = &vga;
+ panel = vga_panel;
else {
printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
val);
- panel = &vga;
+ panel = vga_panel;
}
return panel;
@@ -358,12 +465,18 @@ static void realview_clcd_enable(struct clcd_fb *fb)
writel(val, sys_clcd);
}
-static unsigned long framesize = SZ_1M;
-
static int realview_clcd_setup(struct clcd_fb *fb)
{
+ unsigned long framesize;
dma_addr_t dma;
+ if (machine_is_realview_eb())
+ /* VGA, 16bpp */
+ framesize = 640 * 480 * 2;
+ else
+ /* XVGA, 16bpp */
+ framesize = 1024 * 768 * 2;
+
fb->panel = realview_clcd_panel();
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
@@ -588,7 +701,7 @@ void __init realview_timer_init(unsigned int timer_irq)
* The dummy clock device has to be registered before the main device
* so that the latter will broadcast the clock events
*/
- local_timer_setup(smp_processor_id());
+ local_timer_setup();
#endif
/*