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>
21 //#include <asm/mach/time.h>
23 #include <asm/mach/irq.h>
25 #include <asm/system.h>
26 #include <mach/hardware.h>
27 #include <linux/amba/bus.h>
28 #include <linux/amba/clcd.h>
30 #define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
31 #define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
32 #define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
33 #define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
35 #define ALI_SETUP __REG(ALI_PHYS + 0x00)
36 #define ALI_CONTROL __REG(ALI_PHYS + 0x04)
37 #define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
38 #define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
40 #include "lcd-panel.h"
42 static void lh7a40x_clcd_disable (struct clcd_fb
*fb
)
44 #if defined (CONFIG_MACH_LPD7A400)
45 CPLD_CONTROL
&= ~(1<<1); /* Disable LCD Vee */
48 #if defined (CONFIG_MACH_LPD7A404)
49 GPIO_PCD
&= ~(1<<3); /* Disable LCD Vee */
52 #if defined (CONFIG_ARCH_LH7A400)
53 HRTFTC_HRSETUP
&= ~(1<<13); /* Disable HRTFT controller */
56 #if defined (CONFIG_ARCH_LH7A404)
57 ALI_SETUP
&= ~(1<<13); /* Disable ALI */
61 static void lh7a40x_clcd_enable (struct clcd_fb
*fb
)
63 struct clcd_panel_extra
* extra
64 = (struct clcd_panel_extra
*) fb
->board_data
;
66 #if defined (CONFIG_MACH_LPD7A400)
67 CPLD_CONTROL
|= (1<<1); /* Enable LCD Vee */
70 #if defined (CONFIG_MACH_LPD7A404)
71 GPIO_PCDD
&= ~(1<<3); /* Enable LCD Vee */
75 #if defined (CONFIG_ARCH_LH7A400)
80 | ((fb
->fb
.var
.xres
- 1) << 4)
82 | (extra
->hrmode
? 1 : 0);
84 = ((extra
->clsen
? 1 : 0) << 1)
85 | ((extra
->spsen
? 1 : 0) << 0);
88 | (extra
->revdel
<< 4)
89 | (extra
->lpdel
<< 0);
91 = (extra
->spldel
<< 9)
92 | (extra
->pc2del
<< 0);
100 #if defined (CONFIG_ARCH_LH7A404)
105 | ((fb
->fb
.var
.xres
- 1) << 4)
107 | (extra
->hrmode
? 1 : 0);
109 = ((extra
->clsen
? 1 : 0) << 1)
110 | ((extra
->spsen
? 1 : 0) << 0);
112 = (extra
->pcdel
<< 8)
113 | (extra
->revdel
<< 4)
114 | (extra
->lpdel
<< 0);
116 = (extra
->spldel
<< 9)
117 | (extra
->pc2del
<< 0);
127 #define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
129 static int lh7a40x_clcd_setup (struct clcd_fb
*fb
)
132 u32 len
= FRAMESIZE (lcd_panel
.mode
.xres
*lcd_panel
.mode
.yres
135 fb
->panel
= &lcd_panel
;
137 /* Enforce the sync polarity defaults */
138 if (!(fb
->panel
->tim2
& TIM2_IHS
))
139 fb
->fb
.var
.sync
|= FB_SYNC_HOR_HIGH_ACT
;
140 if (!(fb
->panel
->tim2
& TIM2_IVS
))
141 fb
->fb
.var
.sync
|= FB_SYNC_VERT_HIGH_ACT
;
143 #if defined (HAS_LCD_PANEL_EXTRA)
144 fb
->board_data
= &lcd_panel_extra
;
148 = dma_alloc_writecombine (&fb
->dev
->dev
, len
,
150 printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
151 fb
->fb
.screen_base
, (void*) dma
, len
,
152 (void*) io_p2v (CLCDC_PHYS
));
153 printk ("CLCD: pixclock %d\n", lcd_panel
.mode
.pixclock
);
155 if (!fb
->fb
.screen_base
) {
156 printk(KERN_ERR
"CLCD: unable to map framebuffer\n");
160 #if defined (USE_RGB555)
161 fb
->fb
.var
.green
.length
= 5; /* Panel uses RGB 5:5:5 */
164 fb
->fb
.fix
.smem_start
= dma
;
165 fb
->fb
.fix
.smem_len
= len
;
167 /* Drive PE4 high to prevent CPLD crash */
171 GPIO_PINMUX
|= (1<<1) | (1<<0); /* LCDVD[15:4] */
173 // fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
174 // fb->fb.fbops->fb_set_par (&fb->fb);
179 static int lh7a40x_clcd_mmap (struct clcd_fb
*fb
, struct vm_area_struct
*vma
)
181 return dma_mmap_writecombine(&fb
->dev
->dev
, vma
,
183 fb
->fb
.fix
.smem_start
,
184 fb
->fb
.fix
.smem_len
);
187 static void lh7a40x_clcd_remove (struct clcd_fb
*fb
)
189 dma_free_writecombine (&fb
->dev
->dev
, fb
->fb
.fix
.smem_len
,
190 fb
->fb
.screen_base
, fb
->fb
.fix
.smem_start
);
193 static struct clcd_board clcd_platform_data
= {
194 .name
= "lh7a40x FB",
195 .check
= clcdfb_check
,
196 .decode
= clcdfb_decode
,
197 .enable
= lh7a40x_clcd_enable
,
198 .setup
= lh7a40x_clcd_setup
,
199 .mmap
= lh7a40x_clcd_mmap
,
200 .remove
= lh7a40x_clcd_remove
,
201 .disable
= lh7a40x_clcd_disable
,
204 #define IRQ_CLCDC (IRQ_LCDINTR)
206 #define AMBA_DEVICE(name,busid,base,plat,pid) \
207 static struct amba_device name##_device = { \
209 .coherent_dma_mask = ~0, \
210 .init_name = busid, \
211 .platform_data = plat, \
214 .start = base##_PHYS, \
215 .end = (base##_PHYS) + (4*1024) - 1, \
216 .flags = IORESOURCE_MEM, \
219 .irq = { IRQ_##base, }, \
220 /* .dma = base##_DMA,*/ \
224 AMBA_DEVICE(clcd
, "cldc-lh7a40x", CLCDC
, &clcd_platform_data
, 0x41110);
226 static struct amba_device
*amba_devs
[] __initdata
= {
230 void __init
lh7a40x_clcd_init (void)
234 printk ("CLCD: registering amba devices\n");
235 for (i
= 0; i
< ARRAY_SIZE(amba_devs
); i
++) {
236 struct amba_device
*d
= amba_devs
[i
];
237 result
= amba_device_register(d
, &iomem_resource
);
238 printk (" %d -> %d\n", i
,result
);