2 * LCD driver for s3c2410
5 #include <l4/arm_drivers/lcd.h>
9 #include <l4/re/c/dataspace.h>
10 #include <l4/re/c/rm.h>
11 #include <l4/re/c/util/cap_alloc.h>
12 #include <l4/re/c/mem_alloc.h>
15 #define LCD_NAME "LCD s3c2410"
17 static void *fb_vaddr;
18 static l4_addr_t fb_paddr;
33 LCDCON1_ENABLE_BIT = 1,
34 LCDCON1_BPPMODE_16BPP = 0xc << 1,
35 LCDCON1_PNRMODE_LCD = 3 << 5,
37 LCDCON1_ENABLE_VALUE = LCDCON1_ENABLE_BIT | LCDCON1_BPPMODE_16BPP
38 | LCDCON1_PNRMODE_LCD | LCDCON1_CLKVAL,
40 LCDCON2_LINEVAL = (HEIGHT-1) << 14,
41 LCDCON2_ENABLE_VALUE = LCDCON2_LINEVAL,
43 LCDCON3_HOZVAL = (WIDTH-1) << 8,
44 LCDCON3_ENABLE_VALUE = LCDCON3_HOZVAL,
46 LCDCON4_ENABLE_VALUE = 7,
48 LCDCON5_PWREN = 1 << 3,
49 LCDCON5_FRM565 = 1 << 11,
50 LCDCON5_ENABLE_VALUE = LCDCON5_PWREN | LCDCON5_FRM565 | 1,
53 // wr(0x00000179 & ~LCDCON1_ENABLE_BIT, LCDCON1);
54 // wr(0x019fc3c1, LCDCON2);
55 // wr(0x0039df67, LCDCON3);
56 // wr(0x00000007, LCDCON4);
57 // wr(0x00000f09, LCDCON5);
60 static const char *arm_lcd_get_info(void)
63 static int probe(const char *configstr)
66 return !l4io_lookup_device(LCD_NAME, NULL, 0, 0);
69 static unsigned int fbmem_size(void) { return (1 << 22); } //height() * bpl(); }
71 static unsigned long lcd_control_virt_base;
73 static int get_fbinfo(l4re_video_view_info_t *vinfo)
77 vinfo->bytes_per_line = 2 * vinfo->width;
79 vinfo->pixel_info.bytes_per_pixel = 2;
80 vinfo->pixel_info.r.shift = 0;
81 vinfo->pixel_info.r.size = 5;
82 vinfo->pixel_info.g.shift = 5;
83 vinfo->pixel_info.g.size = 6;
84 vinfo->pixel_info.b.shift = 11;
85 vinfo->pixel_info.b.size = 5;
86 vinfo->pixel_info.a.shift = 0;
87 vinfo->pixel_info.a.size = 0;
93 static void setup_memory(void)
96 l4io_device_handle_t dh;
97 l4io_resource_handle_t hdl;
103 if (l4io_lookup_device(LCD_NAME, &dh, 0, &hdl))
105 printf("Could not get s3c2410fb\n");
108 lcd_control_virt_base = l4io_request_resource_iomem(dh, &hdl);
110 if (lcd_control_virt_base == 0)
112 printf("Could not map controller space for '%s'\n", arm_lcd_get_info());
116 // get some frame buffer
117 l4re_ds_t mem = l4re_util_cap_alloc();
118 if (l4_is_invalid_cap(mem))
121 if (l4re_ma_alloc(fbmem_size(), mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED))
123 printf("Could not get video memory.\n");
128 if (l4re_rm_attach(&fb_vaddr, fbmem_size(),
129 L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
130 mem, 0, L4_PAGESHIFT))
133 printf("Could not map fb\n");
137 printf("Video memory is at virtual %p (size: 0x%x Bytes)\n",
138 fb_vaddr, fbmem_size());
140 // get physical address
141 if (l4re_ds_phys(mem, 0, &fb_paddr, &phys_size)
142 || phys_size != fbmem_size())
144 printf("Getting the physical address failed or not contiguous\n");
147 printf("Physical video memory is at %p\n", (void *)fb_paddr);
150 static inline void wr(unsigned long val, unsigned long regoff)
151 { *(volatile unsigned long *)(lcd_control_virt_base + regoff) = val; }
152 static inline unsigned long rd(unsigned long regoff)
153 { return *(volatile unsigned long *)(lcd_control_virt_base + regoff); }
155 static void *fb(void)
165 s3c2410fb: got LCD region
166 s3c2410fb: got and enabled clock
167 s3c2410fb: map_video_memory(fbi=c04ce274)
168 s3c2410fb: map_video_memory: clear ffc00000:0012c000
169 s3c2410fb: map_video_memory: dma=30600000 cpu=ffc00000 size=0012c000
170 s3c2410fb: got video memory
171 s3c2410fb: LCDSADDR1 = 0x18300000
172 s3c2410fb: LCDSADDR2 = 0x1834b000
173 s3c2410fb: LCDSADDR3 = 0x000001e0
174 s3c2410fb: LPCSEL = 0x00000cf0
175 s3c2410fb: replacing TPAL 00000000
176 s3c2410fb: check_var(var=c04ce008, info=c04ce000)
177 s3c2410fb: s3c2410fb_activate_var: var->xres = 480
178 s3c2410fb: s3c2410fb_activate_var: var->yres = 640
179 s3c2410fb: s3c2410fb_activate_var: var->bpp = 16
180 s3c2410fb: setting vert: up=2, low=16, sync=2
181 s3c2410fb: setting horz: lft=104, rt=8, sync=8
182 s3c2410fb: new register set:
183 s3c2410fb: lcdcon[1] = 0x00000179
184 s3c2410fb: lcdcon[2] = 0x019fc3c1
185 s3c2410fb: lcdcon[3] = 0x0039df67
186 s3c2410fb: lcdcon[4] = 0x00000007
187 s3c2410fb: lcdcon[5] = 0x00000f09
188 s3c2410fb: LCDSADDR1 = 0x18300000
189 s3c2410fb: LCDSADDR2 = 0x1834b000
190 s3c2410fb: LCDSADDR3 = 0x000001e0
191 Console: switching to colour frame buffer device 80x58
192 fb0: s3c2410fb frame buffer device
195 static void pl110_enable(void)
199 wr(0x00000179 & ~LCDCON1_ENABLE_BIT, LCDCON1);
200 wr(0x019fc3c1, LCDCON2);
201 wr(0x0039df67, LCDCON3);
202 wr(0x00000007, LCDCON4);
203 wr(0x00000f09, LCDCON5);
205 wr(LCDCON1_ENABLE_VALUE & ~LCDCON1_ENABLE_BIT, LCDCON1);
206 wr(LCDCON2_ENABLE_VALUE, LCDCON2);
207 wr(LCDCON3_ENABLE_VALUE, LCDCON3);
208 wr(LCDCON4_ENABLE_VALUE, LCDCON4);
209 wr(LCDCON5_ENABLE_VALUE, LCDCON5);
213 wr(fb_paddr >> 1, LCDSADDR1);
214 wr((fb_paddr + 640*480*2) >> 1, LCDSADDR2);
217 wr(0x00000179, LCDCON1);
220 // for (; i < 0x20; i+=4)
221 // printf("%02x: %08lx\n", i, rd(i));
225 static void pl110_disable(void)
228 static struct arm_lcd_ops arm_lcd_ops_pl110 = {
231 .get_fbinfo = get_fbinfo,
232 .get_video_mem_size = fbmem_size,
233 .get_info = arm_lcd_get_info,
234 .enable = pl110_enable,
235 .disable = pl110_disable,
238 arm_lcd_register(&arm_lcd_ops_pl110);