summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2015-09-26 06:06:42 +0200
committerCástor Muñoz <cmvidal@gmail.com>2015-12-17 09:14:58 +0100
commit5c67ebbc333b1a6394404ae6d312f93ca7db9899 (patch)
tree7f58dccec04edb174209e34d2fb53929e3f110df
parentf753b8ead1a798b90b6c2ecd0c62c2f4b6c4eea7 (diff)
downloadrockbox-5c67ebbc333b1a6394404ae6d312f93ca7db9899.tar.gz
rockbox-5c67ebbc333b1a6394404ae6d312f93ca7db9899.zip
iPod Classic: prepare LCD driver for the bootloader
Optimizes encoding of LCD command sequences. Change-Id: I9d1eb735e5a972c1a176177ed570a3fe991d7b9f
-rw-r--r--firmware/export/s5l8702.h1
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c268
2 files changed, 130 insertions, 139 deletions
diff --git a/firmware/export/s5l8702.h b/firmware/export/s5l8702.h
index 6ec59eaf37..83d754d537 100644
--- a/firmware/export/s5l8702.h
+++ b/firmware/export/s5l8702.h
@@ -433,6 +433,7 @@
433#define LCD_CONFIG (*((uint32_t volatile*)(0x38300000))) 433#define LCD_CONFIG (*((uint32_t volatile*)(0x38300000)))
434#define LCD_WCMD (*((uint32_t volatile*)(0x38300004))) 434#define LCD_WCMD (*((uint32_t volatile*)(0x38300004)))
435#define LCD_STATUS (*((uint32_t volatile*)(0x3830001c))) 435#define LCD_STATUS (*((uint32_t volatile*)(0x3830001c)))
436#define LCD_PHTIME (*((uint32_t volatile*)(0x38300020)))
436#define LCD_WDATA (*((uint32_t volatile*)(0x38300040))) 437#define LCD_WDATA (*((uint32_t volatile*)(0x38300040)))
437 438
438 439
diff --git a/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
index bf6c1a1402..45768f9bd4 100644
--- a/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
@@ -54,147 +54,100 @@ static struct mutex lcd_mutex;
54static uint16_t lcd_dblbuf[LCD_HEIGHT][LCD_WIDTH] CACHEALIGN_ATTR; 54static uint16_t lcd_dblbuf[LCD_HEIGHT][LCD_WIDTH] CACHEALIGN_ATTR;
55static bool lcd_ispowered; 55static bool lcd_ispowered;
56 56
57#define SLEEP 0 57#define CMD 0 /* send command with N data */
58#define CMD16 1 58#define MREG 1 /* write multiple registers */
59#define DATA16 2 59#define SLEEP 2
60#define REG15 3
61#define END 0xff 60#define END 0xff
62 61
62#define CMD16(len) (CMD | ((len) << 8))
63#define MREG16(len) (MREG | ((len) << 8))
64#define SLEEP16(t) (SLEEP | ((t) << 8))
65
63/* powersave sequences */ 66/* powersave sequences */
64 67
65static const unsigned short lcd_sleep_sequence_01[] = 68static const unsigned char lcd_sleep_seq_01[] =
66{ 69{
67 CMD16, 0x028, /* Display Off */ 70 CMD, 0x28, 0, /* Display Off */
68 SLEEP, 0x005, /* 50 ms */ 71 SLEEP, 5, /* 50 ms */
69 CMD16, 0x010, /* Sleep In Mode */ 72 CMD, 0x10, 0, /* Sleep In Mode */
70 SLEEP, 0x005, /* 50 ms */ 73 SLEEP, 5, /* 50 ms */
71 END 74 END
72}; 75};
73 76
74static const unsigned short lcd_deep_stby_sequence_23[] = 77static const unsigned short lcd_enter_deepstby_seq_23[] =
75{ 78{
76 /* Display Off */ 79 /* Display Off */
77 REG15, 0x007, 0x0172, 80 MREG16(1), 0x007, 0x0172,
78 REG15, 0x030, 0x03ff, 81 MREG16(1), 0x030, 0x03ff,
79 SLEEP, 0x00a, 82 SLEEP16(9),
80 REG15, 0x007, 0x0120, 83 MREG16(1), 0x007, 0x0120,
81 REG15, 0x030, 0x0000, 84 MREG16(1), 0x030, 0x0000,
82 REG15, 0x100, 0x0780, 85 MREG16(1), 0x100, 0x0780,
83 REG15, 0x007, 0x0000, 86 MREG16(1), 0x007, 0x0000,
84 REG15, 0x101, 0x0260, 87 MREG16(1), 0x101, 0x0260,
85 REG15, 0x102, 0x00a9, 88 MREG16(1), 0x102, 0x00a9,
86 SLEEP, 0x003, 89 SLEEP16(3),
87 REG15, 0x100, 0x0700, 90 MREG16(1), 0x100, 0x0700,
88 91
89 /* Deep Standby Mode */ 92 /* Deep Standby Mode */
90 REG15, 0x100, 0x0704, 93 MREG16(1), 0x100, 0x0704,
91 SLEEP, 0x005, 94 SLEEP16(5),
92 END 95 END
93}; 96};
94 97
95#ifdef HAVE_LCD_SLEEP 98#ifdef HAVE_LCD_SLEEP
96/* init sequences */ 99/* init sequences */
97 100
98static const unsigned short lcd_init_sequence_01[] = 101static const unsigned char lcd_awake_seq_01[] =
99{ 102{
100 CMD16, 0x011, /* Sleep Out Mode */ 103 CMD, 0x11, 0, /* Sleep Out Mode */
101 SLEEP, 0x006, /* 60 ms */ 104 SLEEP, 6, /* 60 ms */
102 CMD16, 0x029, /* Display On */ 105 CMD, 0x29, 0, /* Display On */
103 END 106 END
104}; 107};
105 108
106static const unsigned short lcd_init_sequence_23[] = 109static const unsigned short lcd_init_seq_23[] =
107{ 110{
108 /* Display settings */ 111 /* Display settings */
109 REG15, 0x008, 0x0808, 112 MREG16(1), 0x008, 0x0808,
110 REG15, 0x010, 0x0013, 113 MREG16(7), 0x010, 0x0013, 0x0300, 0x0101, 0x0a03, 0x0a0e, 0x0a19, 0x2402,
111 REG15, 0x011, 0x0300, 114 MREG16(1), 0x018, 0x0001,
112 REG15, 0x012, 0x0101, 115 MREG16(1), 0x090, 0x0021,
113 REG15, 0x013, 0x0a03,
114 REG15, 0x014, 0x0a0e,
115 REG15, 0x015, 0x0a19,
116 REG15, 0x016, 0x2402,
117 REG15, 0x018, 0x0001,
118 REG15, 0x090, 0x0021,
119 116
120 /* Gamma settings */ 117 /* Gamma settings */
121 REG15, 0x300, 0x0307, 118 MREG16(14), 0x300, 0x0307, 0x0003, 0x0402, 0x0303, 0x0300, 0x0407, 0x1c04,
122 REG15, 0x301, 0x0003, 119 0x0307, 0x0003, 0x0402, 0x0303, 0x0300, 0x0407, 0x1c04,
123 REG15, 0x302, 0x0402, 120 MREG16(14), 0x310, 0x0707, 0x0407, 0x0306, 0x0303, 0x0300, 0x0407, 0x1c01,
124 REG15, 0x303, 0x0303, 121 0x0707, 0x0407, 0x0306, 0x0303, 0x0300, 0x0407, 0x1c01,
125 REG15, 0x304, 0x0300, 122 MREG16(14), 0x320, 0x0206, 0x0102, 0x0404, 0x0303, 0x0300, 0x0407, 0x1c1f,
126 REG15, 0x305, 0x0407, 123 0x0206, 0x0102, 0x0404, 0x0303, 0x0300, 0x0407, 0x1c1f,
127 REG15, 0x306, 0x1c04,
128 REG15, 0x307, 0x0307,
129 REG15, 0x308, 0x0003,
130 REG15, 0x309, 0x0402,
131 REG15, 0x30a, 0x0303,
132 REG15, 0x30b, 0x0300,
133 REG15, 0x30c, 0x0407,
134 REG15, 0x30d, 0x1c04,
135
136 REG15, 0x310, 0x0707,
137 REG15, 0x311, 0x0407,
138 REG15, 0x312, 0x0306,
139 REG15, 0x313, 0x0303,
140 REG15, 0x314, 0x0300,
141 REG15, 0x315, 0x0407,
142 REG15, 0x316, 0x1c01,
143 REG15, 0x317, 0x0707,
144 REG15, 0x318, 0x0407,
145 REG15, 0x319, 0x0306,
146 REG15, 0x31a, 0x0303,
147 REG15, 0x31b, 0x0300,
148 REG15, 0x31c, 0x0407,
149 REG15, 0x31d, 0x1c01,
150
151 REG15, 0x320, 0x0206,
152 REG15, 0x321, 0x0102,
153 REG15, 0x322, 0x0404,
154 REG15, 0x323, 0x0303,
155 REG15, 0x324, 0x0300,
156 REG15, 0x325, 0x0407,
157 REG15, 0x326, 0x1c1f,
158 REG15, 0x327, 0x0206,
159 REG15, 0x328, 0x0102,
160 REG15, 0x329, 0x0404,
161 REG15, 0x32a, 0x0303,
162 REG15, 0x32b, 0x0300,
163 REG15, 0x32c, 0x0407,
164 REG15, 0x32d, 0x1c1f,
165 124
166 /* GRAM and Base Imagen settings (ili9326ds) */ 125 /* GRAM and Base Imagen settings (ili9326ds) */
167 REG15, 0x400, 0x001d, 126 MREG16(2), 0x400, 0x001d, 0x0001,
168 REG15, 0x401, 0x0001, 127 MREG16(1), 0x205, 0x0060,
169 REG15, 0x205, 0x0060,
170 128
171 /* Power settings */ 129 /* Power settings */
172 REG15, 0x007, 0x0001, 130 MREG16(1), 0x007, 0x0001,
173 REG15, 0x031, 0x0071, 131 MREG16(1), 0x031, 0x0071,
174 REG15, 0x110, 0x0001, 132 MREG16(1), 0x110, 0x0001,
175 REG15, 0x100, 0x17b0, 133 MREG16(6), 0x100, 0x17b0, 0x0220, 0x00bd, 0x1500, 0x0103, 0x0105,
176 REG15, 0x101, 0x0220,
177 REG15, 0x102, 0x00bd,
178 REG15, 0x103, 0x1500,
179 REG15, 0x105, 0x0103,
180 REG15, 0x106, 0x0105,
181 134
182 /* Display On */ 135 /* Display On */
183 REG15, 0x007, 0x0021, 136 MREG16(1), 0x007, 0x0021,
184 REG15, 0x001, 0x0110, 137 MREG16(1), 0x001, 0x0110,
185 REG15, 0x003, 0x0230, 138 MREG16(1), 0x003, 0x0230,
186 REG15, 0x002, 0x0500, 139 MREG16(1), 0x002, 0x0500,
187 REG15, 0x007, 0x0031, 140 MREG16(1), 0x007, 0x0031,
188 REG15, 0x030, 0x0007, 141 MREG16(1), 0x030, 0x0007,
189 SLEEP, 0x003, 142 SLEEP16(3),
190 REG15, 0x030, 0x03ff, 143 MREG16(1), 0x030, 0x03ff,
191 SLEEP, 0x006, 144 SLEEP16(6),
192 REG15, 0x007, 0x0072, 145 MREG16(1), 0x007, 0x0072,
193 SLEEP, 0x00f, 146 SLEEP16(15),
194 REG15, 0x007, 0x0173, 147 MREG16(1), 0x007, 0x0173,
195 END 148 END
196}; 149};
197#endif 150#endif /* HAVE_LCD_SLEEP */
198 151
199/* DMA configuration */ 152/* DMA configuration */
200 153
@@ -261,30 +214,54 @@ static inline void s5l_lcd_write_data(unsigned short data)
261 LCD_WDATA = data; 214 LCD_WDATA = data;
262} 215}
263 216
264static void lcd_run_sequence(const unsigned short *seq) 217static void lcd_run_seq8(const unsigned char *seq)
265{ 218{
266 unsigned short tmp; 219 int n;
267 220
268 while (1) switch (*seq++) 221 while (1) switch (*seq++)
269 { 222 {
270 case SLEEP: 223 case CMD:
271 sleep(*seq++);
272 break;
273 case CMD16:
274 s5l_lcd_write_cmd(*seq++); 224 s5l_lcd_write_cmd(*seq++);
225 n = *seq++;
226 while (n--)
227 s5l_lcd_write_data(*seq++);
275 break; 228 break;
276 case DATA16: 229 case SLEEP:
277 s5l_lcd_write_data(*seq++); 230 sleep(*seq++);
278 break;
279 case REG15:
280 tmp = *seq++; /* avoid compiler warning */
281 s5l_lcd_write_reg(tmp, *seq++);
282 break; 231 break;
283 case END: 232 case END:
284 default: 233 default:
285 /* bye */ 234 /* bye */
286 return; 235 return;
287 } 236 }
237}
238
239static void lcd_run_seq16(const unsigned short *seq)
240{
241 int action, param;
242 unsigned short reg;
243
244 while (1)
245 {
246 action = *seq & 0xff;
247 param = *seq++ >> 8;
248
249 switch (action)
250 {
251 case MREG:
252 reg = *seq++;
253 while (param--)
254 s5l_lcd_write_reg(reg++, *seq++);
255 break;
256 case SLEEP:
257 sleep(param);
258 break;
259 case END:
260 default:
261 /* bye */
262 return;
263 }
264 }
288} 265}
289 266
290/*** hardware configuration ***/ 267/*** hardware configuration ***/
@@ -314,36 +291,43 @@ bool lcd_active(void)
314 return lcd_ispowered; 291 return lcd_ispowered;
315} 292}
316 293
317void lcd_shutdown(void) 294void lcd_powersave(void)
318{
319 pmu_write(0x2b, 0); /* Kill the backlight, instantly. */
320 pmu_write(0x29, 0);
321
322 lcd_sleep();
323}
324
325void lcd_sleep(void)
326{ 295{
327 mutex_lock(&lcd_mutex); 296 mutex_lock(&lcd_mutex);
328 297
329 lcd_run_sequence((lcd_type & 2) ? lcd_deep_stby_sequence_23 298 if (lcd_type & 2)
330 : lcd_sleep_sequence_01); 299 lcd_run_seq16(lcd_enter_deepstby_seq_23);
300 else
301 lcd_run_seq8(lcd_sleep_seq_01);
331 302
332 /* mask lcd controller clock gate */ 303 /* mask lcd controller clock gate */
333 PWRCON(0) |= (1 << 1); 304 PWRCON(0) |= (1 << CLOCKGATE_LCD);
334 305
335 lcd_ispowered = false; 306 lcd_ispowered = false;
336 307
337 mutex_unlock(&lcd_mutex); 308 mutex_unlock(&lcd_mutex);
338} 309}
339 310
311void lcd_shutdown(void)
312{
313 pmu_write(0x2b, 0); /* Kill the backlight, instantly. */
314 pmu_write(0x29, 0);
315
316 lcd_powersave();
317}
318
340#ifdef HAVE_LCD_SLEEP 319#ifdef HAVE_LCD_SLEEP
320void lcd_sleep(void)
321{
322 lcd_powersave();
323}
324
341void lcd_awake(void) 325void lcd_awake(void)
342{ 326{
343 mutex_lock(&lcd_mutex); 327 mutex_lock(&lcd_mutex);
344 328
345 /* unmask lcd controller clock gate */ 329 /* unmask lcd controller clock gate */
346 PWRCON(0) &= ~(1 << 1); 330 PWRCON(0) &= ~(1 << CLOCKGATE_LCD);
347 331
348 if (lcd_type & 2) { 332 if (lcd_type & 2) {
349 /* release from deep standby mode (ili9320ds s12.3) */ 333 /* release from deep standby mode (ili9320ds s12.3) */
@@ -352,10 +336,10 @@ void lcd_awake(void)
352 udelay(1000); 336 udelay(1000);
353 } 337 }
354 338
355 lcd_run_sequence(lcd_init_sequence_23); 339 lcd_run_seq16(lcd_init_seq_23);
356 } 340 }
357 else 341 else
358 lcd_run_sequence(lcd_init_sequence_01); 342 lcd_run_seq8(lcd_awake_seq_01);
359 343
360 lcd_ispowered = true; 344 lcd_ispowered = true;
361 345
@@ -368,11 +352,17 @@ void lcd_awake(void)
368/* LCD init */ 352/* LCD init */
369void lcd_init_device(void) 353void lcd_init_device(void)
370{ 354{
371 /* Detect lcd type */
372 mutex_init(&lcd_mutex); 355 mutex_init(&lcd_mutex);
356
357 /* unmask lcd controller clock gate */
358 PWRCON(0) &= ~(1 << CLOCKGATE_LCD);
359
360 /* Detect lcd type */
373 lcd_type = (PDAT6 & 0x30) >> 4; 361 lcd_type = (PDAT6 & 0x30) >> 4;
362
374 while (!(LCD_STATUS & 0x2)); 363 while (!(LCD_STATUS & 0x2));
375 LCD_CONFIG = 0x80100db0; 364 LCD_CONFIG = 0x80100db0;
365 LCD_PHTIME = 0x33;
376 366
377 /* Configure DMA channel */ 367 /* Configure DMA channel */
378 dmac_ch_init(&lcd_dma_ch, &lcd_dma_ch_cfg); 368 dmac_ch_init(&lcd_dma_ch, &lcd_dma_ch_cfg);
@@ -398,7 +388,7 @@ void lcd_update(void)
398} 388}
399 389
400/* Line write helper function. */ 390/* Line write helper function. */
401extern void lcd_write_line(const fb_data *addr, 391extern void lcd_write_line(const fb_data *addr,
402 int pixelcount, 392 int pixelcount,
403 const unsigned int lcd_base_addr); 393 const unsigned int lcd_base_addr);
404 394
@@ -456,7 +446,7 @@ void lcd_update_rect(int x, int y, int width, int height)
456 int pixels = width * height; 446 int pixels = width * height;
457 fb_data* p = FBADDR(x,y); 447 fb_data* p = FBADDR(x,y);
458 uint16_t* out = lcd_dblbuf[0]; 448 uint16_t* out = lcd_dblbuf[0];
459 449
460#ifdef HAVE_LCD_SLEEP 450#ifdef HAVE_LCD_SLEEP
461 if (!lcd_active()) return; 451 if (!lcd_active()) return;
462#endif 452#endif
@@ -495,7 +485,7 @@ void lcd_blit_yuv(unsigned char * const src[3],
495{ 485{
496 unsigned int z; 486 unsigned int z;
497 unsigned char const * yuv_src[3]; 487 unsigned char const * yuv_src[3];
498 488
499#ifdef HAVE_LCD_SLEEP 489#ifdef HAVE_LCD_SLEEP
500 if (!lcd_active()) return; 490 if (!lcd_active()) return;
501#endif 491#endif