Linux 2.6.25.3
[linux/fpc-iii.git] / arch / arm / mach-lh7a40x / clcd.c
blob1992db4c25236c19ca10b8007d58bf1125fba90c
1 /*
2 * arch/arm/mach-lh7a40x/clcd.c
4 * Copyright (C) 2004 Marc Singer
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
12 #include <linux/init.h>
13 #include <linux/device.h>
14 #include <linux/dma-mapping.h>
15 #include <linux/sysdev.h>
16 #include <linux/interrupt.h>
18 //#include <linux/module.h>
19 //#include <linux/time.h>
20 //#include <asm/hardware.h>
22 //#include <asm/mach/time.h>
23 #include <asm/irq.h>
24 #include <asm/mach/irq.h>
26 #include <asm/system.h>
27 #include <asm/hardware.h>
28 #include <linux/amba/bus.h>
29 #include <linux/amba/clcd.h>
31 #define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
32 #define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
33 #define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
34 #define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
36 #define ALI_SETUP __REG(ALI_PHYS + 0x00)
37 #define ALI_CONTROL __REG(ALI_PHYS + 0x04)
38 #define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
39 #define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
41 #include "lcd-panel.h"
43 static void lh7a40x_clcd_disable (struct clcd_fb *fb)
45 #if defined (CONFIG_MACH_LPD7A400)
46 CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */
47 #endif
49 #if defined (CONFIG_MACH_LPD7A404)
50 GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */
51 #endif
53 #if defined (CONFIG_ARCH_LH7A400)
54 HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */
55 #endif
57 #if defined (CONFIG_ARCH_LH7A404)
58 ALI_SETUP &= ~(1<<13); /* Disable ALI */
59 #endif
62 static void lh7a40x_clcd_enable (struct clcd_fb *fb)
64 struct clcd_panel_extra* extra
65 = (struct clcd_panel_extra*) fb->board_data;
67 #if defined (CONFIG_MACH_LPD7A400)
68 CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */
69 #endif
71 #if defined (CONFIG_MACH_LPD7A404)
72 GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */
73 GPIO_PCD |= (1<<3);
74 #endif
76 #if defined (CONFIG_ARCH_LH7A400)
78 if (extra) {
79 HRTFTC_HRSETUP
80 = (1 << 13)
81 | ((fb->fb.var.xres - 1) << 4)
82 | 0xc
83 | (extra->hrmode ? 1 : 0);
84 HRTFTC_HRCON
85 = ((extra->clsen ? 1 : 0) << 1)
86 | ((extra->spsen ? 1 : 0) << 0);
87 HRTFTC_HRTIMING1
88 = (extra->pcdel << 8)
89 | (extra->revdel << 4)
90 | (extra->lpdel << 0);
91 HRTFTC_HRTIMING2
92 = (extra->spldel << 9)
93 | (extra->pc2del << 0);
95 else
96 HRTFTC_HRSETUP
97 = (1 << 13)
98 | 0xc;
99 #endif
101 #if defined (CONFIG_ARCH_LH7A404)
103 if (extra) {
104 ALI_SETUP
105 = (1 << 13)
106 | ((fb->fb.var.xres - 1) << 4)
107 | 0xc
108 | (extra->hrmode ? 1 : 0);
109 ALI_CONTROL
110 = ((extra->clsen ? 1 : 0) << 1)
111 | ((extra->spsen ? 1 : 0) << 0);
112 ALI_TIMING1
113 = (extra->pcdel << 8)
114 | (extra->revdel << 4)
115 | (extra->lpdel << 0);
116 ALI_TIMING2
117 = (extra->spldel << 9)
118 | (extra->pc2del << 0);
120 else
121 ALI_SETUP
122 = (1 << 13)
123 | 0xc;
124 #endif
128 #define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
130 static int lh7a40x_clcd_setup (struct clcd_fb *fb)
132 dma_addr_t dma;
133 u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
134 *(lcd_panel.bpp/8));
136 fb->panel = &lcd_panel;
138 /* Enforce the sync polarity defaults */
139 if (!(fb->panel->tim2 & TIM2_IHS))
140 fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
141 if (!(fb->panel->tim2 & TIM2_IVS))
142 fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
144 #if defined (HAS_LCD_PANEL_EXTRA)
145 fb->board_data = &lcd_panel_extra;
146 #endif
148 fb->fb.screen_base
149 = dma_alloc_writecombine (&fb->dev->dev, len,
150 &dma, GFP_KERNEL);
151 printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
152 fb->fb.screen_base, (void*) dma, len,
153 (void*) io_p2v (CLCDC_PHYS));
154 printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
156 if (!fb->fb.screen_base) {
157 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
158 return -ENOMEM;
161 #if defined (USE_RGB555)
162 fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
163 #endif
165 fb->fb.fix.smem_start = dma;
166 fb->fb.fix.smem_len = len;
168 /* Drive PE4 high to prevent CPLD crash */
169 GPIO_PEDD |= (1<<4);
170 GPIO_PED |= (1<<4);
172 GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
174 // fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
175 // fb->fb.fbops->fb_set_par (&fb->fb);
177 return 0;
180 static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
182 return dma_mmap_writecombine(&fb->dev->dev, vma,
183 fb->fb.screen_base,
184 fb->fb.fix.smem_start,
185 fb->fb.fix.smem_len);
188 static void lh7a40x_clcd_remove (struct clcd_fb *fb)
190 dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
191 fb->fb.screen_base, fb->fb.fix.smem_start);
194 static struct clcd_board clcd_platform_data = {
195 .name = "lh7a40x FB",
196 .check = clcdfb_check,
197 .decode = clcdfb_decode,
198 .enable = lh7a40x_clcd_enable,
199 .setup = lh7a40x_clcd_setup,
200 .mmap = lh7a40x_clcd_mmap,
201 .remove = lh7a40x_clcd_remove,
202 .disable = lh7a40x_clcd_disable,
205 #define IRQ_CLCDC (IRQ_LCDINTR)
207 #define AMBA_DEVICE(name,busid,base,plat,pid) \
208 static struct amba_device name##_device = { \
209 .dev = { \
210 .coherent_dma_mask = ~0, \
211 .bus_id = busid, \
212 .platform_data = plat, \
213 }, \
214 .res = { \
215 .start = base##_PHYS, \
216 .end = (base##_PHYS) + (4*1024) - 1, \
217 .flags = IORESOURCE_MEM, \
218 }, \
219 .dma_mask = ~0, \
220 .irq = { IRQ_##base, }, \
221 /* .dma = base##_DMA,*/ \
222 .periphid = pid, \
225 AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110);
227 static struct amba_device *amba_devs[] __initdata = {
228 &clcd_device,
231 void __init lh7a40x_clcd_init (void)
233 int i;
234 int result;
235 printk ("CLCD: registering amba devices\n");
236 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
237 struct amba_device *d = amba_devs[i];
238 result = amba_device_register(d, &iomem_resource);
239 printk (" %d -> %d\n", i ,result);