summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700/yps3/lcd-yps3.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8700/yps3/lcd-yps3.c')
-rw-r--r--firmware/target/arm/s5l8700/yps3/lcd-yps3.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/firmware/target/arm/s5l8700/yps3/lcd-yps3.c b/firmware/target/arm/s5l8700/yps3/lcd-yps3.c
new file mode 100644
index 0000000000..6093eb3054
--- /dev/null
+++ b/firmware/target/arm/s5l8700/yps3/lcd-yps3.c
@@ -0,0 +1,336 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Bertrik Sikken
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23
24#include "s5l8700.h"
25#include "lcd.h"
26
27/* LCD driver for the Samsung YP-S3
28
29 It appears that this player can contain two display types.
30 Detection of the display type is done by looking at the level of pin P0.4.
31 Currently only display "type 2" has been implemented and tested.
32
33 This driver could use DMA to do the screen updates, but currently writes
34 the data to the LCD using the processor instead.
35*/
36
37
38static int lcd_type = 0;
39
40
41static void lcd_delay(int delay)
42{
43 volatile int i;
44 for (i = 0; i < delay; i++);
45}
46
47static void lcd_reset_delay(void)
48{
49 lcd_delay(10000);
50}
51
52static void lcd_reset(void)
53{
54 LCD_CON = 0xDB8;
55 LCD_PHTIME = 0x22;
56 LCD_RST_TIME = 0x7FFF;
57
58 lcd_reset_delay();
59 LCD_DRV_RST = 0;
60 lcd_reset_delay();
61 LCD_DRV_RST = 1;
62 lcd_reset_delay();
63 LCD_DRV_RST = 0;
64 lcd_reset_delay();
65 LCD_DRV_RST = 1;
66
67 LCD_INTCON = 0;
68}
69
70static void lcd_wcmd(unsigned int cmd)
71{
72 while ((LCD_STATUS & 0x10) != 0);
73 LCD_WCMD = cmd;
74}
75
76static void lcd_wdata(unsigned int data)
77{
78 while ((LCD_STATUS & 0x10) != 0);
79 LCD_WDATA = data;
80}
81
82static void lcd_wcmd_data(unsigned int cmd, unsigned int data)
83{
84 lcd_wcmd(cmd);
85 lcd_wdata(data);
86}
87
88void lcd_init1(void)
89{
90 lcd_wcmd(0x11);
91 lcd_delay(10000);
92
93 lcd_wcmd(0xF0);
94 lcd_wdata(0x5A);
95
96 lcd_wcmd(0xC0);
97 lcd_wdata(0x05);
98 lcd_wdata(0x01);
99
100 lcd_wcmd(0xC1);
101 lcd_wdata(0x04);
102
103 lcd_wcmd(0xC5);
104 lcd_wdata(0xB0);
105
106 lcd_wcmd(0xC6);
107 lcd_wdata(0x0);
108
109 lcd_wcmd(0xB1);
110 lcd_wdata(0x02);
111 lcd_wdata(0x0E);
112 lcd_wdata(0x00);
113
114 lcd_wcmd(0xF2);
115 lcd_wdata(0x01);
116
117 lcd_wcmd(0xE0);
118 lcd_wdata(0x09);
119 lcd_wdata(0x00);
120 lcd_wdata(0x06);
121 lcd_wdata(0x2E);
122 lcd_wdata(0x2B);
123 lcd_wdata(0x0B);
124 lcd_wdata(0x1A);
125 lcd_wdata(0x02);
126 lcd_wdata(0x06);
127 lcd_wdata(0x0C);
128 lcd_wdata(0x0D);
129 lcd_wdata(0x00);
130 lcd_wdata(0x05);
131 lcd_wdata(0x02);
132 lcd_wdata(0x05);
133
134 lcd_wcmd(0xE1);
135 lcd_wdata(0x06);
136 lcd_wdata(0x23);
137 lcd_wdata(0x25);
138 lcd_wdata(0x0F);
139 lcd_wdata(0x0A);
140 lcd_wdata(0x04);
141 lcd_wdata(0x02);
142 lcd_wdata(0x1A);
143 lcd_wdata(0x05);
144 lcd_wdata(0x03);
145 lcd_wdata(0x06);
146 lcd_wdata(0x01);
147 lcd_wdata(0x0C);
148 lcd_wdata(0x0B);
149 lcd_wdata(0x05);
150 lcd_wdata(0x05);
151
152 lcd_wcmd(0x3A);
153 lcd_wdata(0x05);
154
155 lcd_wcmd(0x29);
156
157 lcd_wcmd(0x2C);
158}
159
160void lcd_init2(void)
161{
162 lcd_wcmd_data(0x00, 0x0001);
163 lcd_delay(50000);
164
165 lcd_wcmd_data(0x07, 0x0000);
166 lcd_wcmd_data(0x12, 0x0000);
167 lcd_delay(10000);
168
169 lcd_wcmd(0);
170 lcd_wcmd(0);
171 lcd_wcmd(0);
172 lcd_wcmd(0);
173
174 lcd_wcmd_data(0xA4, 0x0001);
175 lcd_delay(10000);
176
177 lcd_wcmd_data(0x70, 0x1B00);
178 lcd_wcmd_data(0x08, 0x030A);
179 lcd_wcmd_data(0x30, 0x0000);
180 lcd_wcmd_data(0x31, 0x0305);
181 lcd_wcmd_data(0x32, 0x0304);
182 lcd_wcmd_data(0x33, 0x0107);
183 lcd_wcmd_data(0x34, 0x0304);
184
185 lcd_wcmd_data(0x35, 0x0204);
186 lcd_wcmd_data(0x36, 0x0707);
187 lcd_wcmd_data(0x37, 0x0701);
188 lcd_wcmd_data(0x38, 0x1B08);
189 lcd_wcmd_data(0x39, 0x030F);
190 lcd_wcmd_data(0x3A, 0x0E0E);
191
192 lcd_wcmd_data(0x07, 0x0001);
193 lcd_delay(50000);
194
195 lcd_wcmd_data(0x18, 0x0001);
196 lcd_wcmd_data(0x10, 0x12B0);
197 lcd_wcmd_data(0x11, 0x0001);
198
199 lcd_wcmd_data(0x12, 0x0114);
200 lcd_wcmd_data(0x13, 0x8D0F);
201 lcd_wcmd_data(0x12, 0x0134);
202 lcd_delay(1000);
203 lcd_wcmd_data(0x01, 0x0100);
204 lcd_wcmd_data(0x02, 0x0700);
205 lcd_wcmd_data(0x03, 0x5030);
206
207 lcd_wcmd_data(0x04, 0x0000);
208 lcd_wcmd_data(0x09, 0x0000);
209 lcd_wcmd_data(0x0C, 0x0000);
210 lcd_wcmd_data(0x0F, 0x0000);
211
212 lcd_wcmd_data(0x14, 0x8000);
213 lcd_wcmd_data(0x20, 0x0000);
214 lcd_wcmd_data(0x21, 0x0000);
215 lcd_wcmd_data(0x71, 0x0001);
216 lcd_wcmd_data(0x7A, 0x0000);
217 lcd_wcmd_data(0x90, 0x0000);
218 lcd_wcmd_data(0x91, 0x0100);
219 lcd_wcmd_data(0x92, 0x0000);
220 lcd_wcmd_data(0x98, 0x0001);
221 lcd_wcmd_data(0x99, 0x030C);
222 lcd_wcmd_data(0x9A, 0x030C);
223
224 lcd_delay(50000);
225 lcd_wcmd_data(0x07, 0x0001);
226 lcd_delay(30000);
227 lcd_wcmd_data(0x07, 0x0021);
228
229 lcd_wcmd_data(0x12, 0x1134);
230 lcd_delay(10000);
231
232 lcd_wcmd_data(0x07, 0x0233);
233 lcd_delay(30000);
234}
235
236
237void lcd_set_window1(int x, int y, int width, int height)
238{
239 (void)x;
240 (void)width;
241
242 lcd_wcmd(0x2A);
243 lcd_wdata(0);
244 lcd_wdata(y);
245 lcd_wdata(0);
246
247 lcd_wcmd(0x2B);
248 lcd_wdata(0);
249 lcd_wdata(y + height - 1);
250 lcd_wdata(0);
251}
252
253void lcd_set_window2(int x, int y, int width, int height)
254{
255 lcd_wcmd_data(0x50, x);
256 lcd_wcmd_data(0x51, x + width - 1);
257 lcd_wcmd_data(0x52, y);
258 lcd_wcmd_data(0x53, y + height - 1);
259}
260
261
262static void lcd_set_position1(int x, int y)
263{
264 (void)x;
265 (void)y;
266}
267
268static void lcd_set_position2(int x, int y)
269{
270 lcd_wcmd_data(0x20, x);
271 lcd_wcmd_data(0x21, y);
272 lcd_wcmd(0x22);
273}
274
275void lcd_init_device(void)
276{
277 /* enable LCD clock */
278 PWRCON &= ~(1 << 18);
279
280 /* configure LCD pins */
281 PCON0 &= ~(3 << 8);
282 PCON7 = (PCON7 & ~(0x000000FF)) | 0x00000033;
283 PCON_ASRAM = 2;
284
285 lcd_reset();
286
287 /* detect LCD type on P0.4 */
288 lcd_type = (PDAT0 & (1 << 4)) ? 1 : 2;
289
290 /* initialise display */
291 if (lcd_type == 1) {
292 lcd_init1();
293 } else {
294 lcd_init2();
295 }
296}
297
298void lcd_update_rect(int x, int y, int width, int height)
299{
300 fb_data* p;
301 int h, w;
302
303 if (lcd_type == 1) {
304 /* TODO implement and test */
305 lcd_set_window1(x, y, width, height);
306 lcd_set_position1(x, y);
307
308 for (h = 0; h < height; h++) {
309 p = &lcd_framebuffer[y][0];
310 for (w = 0; w < LCD_WIDTH; w++) {
311 while (LCD_STATUS & 0x10);
312 LCD_WDATA = *p++;
313 }
314 y++;
315 }
316 }
317 else {
318 lcd_set_window2(x, y, width, height);
319 lcd_set_position2(x, y);
320
321 for (h = 0; h < height; h++) {
322 p = &lcd_framebuffer[y][x];
323 for (w = 0; w < width; w++) {
324 while (LCD_STATUS & 0x10);
325 LCD_WDATA = *p++;
326 }
327 y++;
328 }
329 }
330}
331
332void lcd_update(void)
333{
334 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
335}
336