summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/sandisk/sansa-view/lcd-view.c309
1 files changed, 103 insertions, 206 deletions
diff --git a/firmware/target/arm/sandisk/sansa-view/lcd-view.c b/firmware/target/arm/sandisk/sansa-view/lcd-view.c
index 9f02d1e2bf..6b24aadc8c 100644
--- a/firmware/target/arm/sandisk/sansa-view/lcd-view.c
+++ b/firmware/target/arm/sandisk/sansa-view/lcd-view.c
@@ -27,12 +27,7 @@
27#include "backlight-target.h" 27#include "backlight-target.h"
28#include "lcd.h" 28#include "lcd.h"
29 29
30#include "bitmaps/rockboxlogo.h" 30static bool display_on SHAREDBSS_ATTR = true;
31
32/* Power and display status */
33static bool power_on = false; /* Is the power turned on? */
34static bool display_on SHAREDBSS_ATTR = false; /* Is the display turned on? */
35static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
36static int lcd_type; 31static int lcd_type;
37 32
38#define LCD_DATA_OUT_GPIO GPIOH_OUTPUT_VAL 33#define LCD_DATA_OUT_GPIO GPIOH_OUTPUT_VAL
@@ -44,147 +39,109 @@ static int lcd_type;
44#define LCD_CS_GPIO GPIOH_OUTPUT_VAL 39#define LCD_CS_GPIO GPIOH_OUTPUT_VAL
45#define LCD_CS_PIN 7 40#define LCD_CS_PIN 7
46 41
47#ifdef BOOTLOADER
48static void lcd_init_gpio(void)
49{
50 /* BOOT: 0x5CC8
51 OF: 0x88284 */
52 42
53 outl(inl(0x70000010) | 0xFC000000, 0x70000010);
54 outl(inl(0x70000014) | 0xC300000, 0x70000014);
55 43
56 GPIOE_ENABLE = 0; 44static void lcd_init_gpio(void)
57 GPIOM_ENABLE &= ~0x3; 45{
58 GPIOF_ENABLE = 0; 46 DEV_INIT1 |= 0xfc000000;
59 GPIOJ_ENABLE &= ~0x1a; 47 DEV_INIT3 |= 0xc300000;
60 GPIOB_ENABLE &= ~0x8; 48
49 GPIOE_ENABLE = 0;
50 GPIOM_ENABLE &= ~0x3;
51 GPIOF_ENABLE = 0;
52 GPIOJ_ENABLE &= ~0x1a;
53 // reset low
54 GPIOB_ENABLE &= ~0x8;
55 // SPI chip select
61 GPIOH_OUTPUT_VAL |= 0x80; 56 GPIOH_OUTPUT_VAL |= 0x80;
62 GPIOH_OUTPUT_EN |= 0x80; 57 GPIOH_OUTPUT_EN |= 0x80;
63 GPIOH_ENABLE |= 0x80; 58 GPIOH_ENABLE |= 0x80;
59 // SPI clock
64 GPIOH_OUTPUT_VAL |= 0x40; 60 GPIOH_OUTPUT_VAL |= 0x40;
65 GPIOH_OUTPUT_EN |= 0x40; 61 GPIOH_OUTPUT_EN |= 0x40;
66 GPIOH_ENABLE |= 0x40; 62 GPIOH_ENABLE |= 0x40;
63 // unk
67 GPIOH_OUTPUT_VAL |= 0x20; 64 GPIOH_OUTPUT_VAL |= 0x20;
68 GPIOH_OUTPUT_EN |= 0x20; 65 GPIOH_OUTPUT_EN |= 0x20;
69 GPIOH_ENABLE |= 0x20; 66 GPIOH_ENABLE |= 0x20;
67 // SPI data
70 GPIOH_OUTPUT_VAL |= 0x10; 68 GPIOH_OUTPUT_VAL |= 0x10;
71 GPIOH_OUTPUT_EN |= 0x10; 69 GPIOH_OUTPUT_EN |= 0x10;
72 GPIOH_ENABLE |= 0x10; 70 GPIOH_ENABLE |= 0x10;
73 GPIOD_OUTPUT_VAL |= 0x1; /* backlight on */ 71 // LCD reset
74 GPIOD_ENABLE |= 0x1;
75 GPIOB_OUTPUT_VAL |= 0x4; 72 GPIOB_OUTPUT_VAL |= 0x4;
76 GPIOB_ENABLE |= 0x4; 73 GPIOB_ENABLE |= 0x4;
77 GPIOB_OUTPUT_EN |= 0x4; 74 GPIOB_OUTPUT_EN |= 0x4;
78 DEV_INIT2 = 0x40000000; 75 DEV_INIT2 = 0x40000000;
79 GPIOG_ENABLE |= 0x8; 76 // LCD type
80 GPIOG_OUTPUT_EN &= ~0x8; 77 GPIOG_ENABLE |= 0x8;
81 78 GPIOG_OUTPUT_EN &= ~0x8;
82 if (GPIOG_INPUT_VAL & 0x8) 79
83 lcd_type = 1; 80 if(GPIOG_INPUT_VAL & 0x8)
84 else
85 lcd_type = 0; 81 lcd_type = 0;
82 else
83 lcd_type = 1;
86} 84}
87#endif
88 85
89static void lcd_send_msg(unsigned char count, unsigned int data) 86static void lcd_send_msg(unsigned char count, unsigned int data)
90{ 87{
91 /* BOOT: 0x645C 88 GPIO_SET_BITWISE(LCD_CLOCK_GPIO, 1 << LCD_CLOCK_PIN);
92 OF: 0x88E90 */ 89 GPIO_CLEAR_BITWISE(LCD_CS_GPIO, 1 << LCD_CS_PIN);
93 int i;
94
95 LCD_CLOCK_GPIO |= (1 << LCD_CLOCK_PIN);
96 LCD_CS_GPIO &= ~(1 << LCD_CS_PIN);
97 90
98 for (i = count - 1; i >= 0; i--) 91 for(int i = count - 1; i >= 0; i--)
99 { 92 {
100 if (data & (1 << i)) 93 if(data & (1 << i))
101 { 94 GPIO_SET_BITWISE(LCD_DATA_OUT_GPIO, 1 << LCD_DATA_OUT_PIN);
102 LCD_DATA_OUT_GPIO &= ~(1 << LCD_DATA_OUT_PIN); 95 else
103 } else { 96 GPIO_CLEAR_BITWISE(LCD_DATA_OUT_GPIO, 1 << LCD_DATA_OUT_PIN);
104 LCD_DATA_OUT_GPIO |= (1 << LCD_DATA_OUT_PIN); 97 GPIO_CLEAR_BITWISE(LCD_CLOCK_GPIO, 1 << LCD_CLOCK_PIN);
105 }
106 LCD_CLOCK_GPIO &= ~(1 << LCD_CLOCK_PIN);
107 udelay(1); 98 udelay(1);
108 LCD_CLOCK_GPIO |= (1 << LCD_CLOCK_PIN); 99 GPIO_SET_BITWISE(LCD_CLOCK_GPIO, 1 << LCD_CLOCK_PIN);
109 udelay(2); 100 udelay(2);
110 } 101 }
111 102
112 LCD_CS_GPIO |= (1 << LCD_CS_PIN); 103 GPIO_SET_BITWISE(LCD_CS_GPIO, 1 << LCD_CS_PIN);
113 LCD_CLOCK_GPIO |= (1 << LCD_CLOCK_PIN);
114 udelay(1);
115}
116
117/*
118static void lcd_write_reg(unsigned int reg, unsigned int data)
119{
120// OF: 0x6278 - referenced from 0x62840
121
122// So far this function is always called with shift = 0x0 ?
123// If so can remove and simplify
124
125 unsigned int cmd;
126 unsigned int shift = 0;
127
128 cmd = shift << 0x2;
129 cmd |= 0x70;
130 cmd = cmd << 0x10;
131 cmd |= reg;
132 lcd_send_msg(0x18, cmd);
133
134 cmd = shift << 0x2;
135 cmd |= 0x72;
136 cmd = cmd << 0x10;
137 cmd |= data;
138 lcd_send_msg(0x18, cmd);
139
140// lcd_send_msg(0x70, reg);
141// lcd_send_msg(0x72, data);
142} 104}
143*/
144 105
145static void lcd_write_cmd(unsigned int cmd) 106static void lcd_send_cmd(unsigned int cmd)
146{ 107{
147 lcd_send_msg(0x18, (0x700000 | cmd)); 108 lcd_send_msg(24, (0x700000 | cmd));
148} 109}
149 110
150static void lcd_write_info(unsigned int data) 111static void lcd_send_data(unsigned int data)
151{ 112{
152 lcd_send_msg(0x18, (0x720000 | data)); 113 lcd_send_msg(24, (0x720000 | data));
153} 114}
154 115
155static void lcd_write_reg(unsigned int cmd, unsigned int data) 116static void lcd_write_reg(unsigned int cmd, unsigned int data)
156{ 117{
157 lcd_write_cmd(cmd); 118 lcd_send_cmd(cmd);
158 lcd_write_info(data); 119 lcd_send_data(data);
159} 120}
160 121
161void lcd_reset(void) 122void lcd_reset(void)
162{ 123{
163 /* BOOT: 0x623C 124 GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x4);
164 OF: 0x88BDC */
165
166 GPIOB_OUTPUT_VAL |= 0x4;
167 udelay(1000); 125 udelay(1000);
168 GPIOB_OUTPUT_VAL &= ~0x4; 126 GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x4);
169 udelay(10000); 127 udelay(10000);
170 GPIOB_OUTPUT_VAL |= 0x4; 128 GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x4);
171 udelay(50000); 129 udelay(50000);
172} 130}
173 131
174/* Run the powerup sequence for the driver IC */ 132/* Run the powerup sequence for the driver IC */
175static void lcd_power_on(void) 133static void lcd_power_on(void)
176{ 134{
135 lcd_init_gpio();
177 lcd_reset(); 136 lcd_reset();
178 /* OF: 0x5DC0 * 137
179 * r2: cmd *
180 * r3: data */
181 lcd_write_reg(0xE5, 0x8000); 138 lcd_write_reg(0xE5, 0x8000);
182 lcd_write_reg(0x0, 0x1); 139 lcd_write_reg(0x0, 0x1);
183 lcd_write_reg(0x1, 0x100); 140 lcd_write_reg(0x1, 0x100);
184 lcd_write_reg(0x2, 0x700); 141 lcd_write_reg(0x2, 0x700);
185 lcd_write_reg(0x3, 0x1230); 142 lcd_write_reg(0x3, 0x5230);
186 lcd_write_reg(0x4, 0x0); 143 lcd_write_reg(0x4, 0x0);
187 lcd_write_reg(0x8, 0x408); 144 lcd_write_reg(0x8, 0x408); /* back porch = 8, front porch = 4 */
188 lcd_write_reg(0x9, 0x0); 145 lcd_write_reg(0x9, 0x0);
189 lcd_write_reg(0xa, 0x0); 146 lcd_write_reg(0xa, 0x0);
190 lcd_write_reg(0xd, 0x0); 147 lcd_write_reg(0xd, 0x0);
@@ -200,8 +157,6 @@ static void lcd_power_on(void)
200 lcd_write_reg(0x12, 0x13c); 157 lcd_write_reg(0x12, 0x13c);
201 sleep(HZ/20); 158 sleep(HZ/20);
202 159
203 /* BOOT: BNE 0x5fb2 */
204
205 if (lcd_type == 0) 160 if (lcd_type == 0)
206 { 161 {
207 lcd_write_reg(0x13, 0x1700); 162 lcd_write_reg(0x13, 0x1700);
@@ -234,19 +189,17 @@ static void lcd_power_on(void)
234 lcd_write_reg(0x36, 0x504); 189 lcd_write_reg(0x36, 0x504);
235 lcd_write_reg(0x37, 0x707); 190 lcd_write_reg(0x37, 0x707);
236 lcd_write_reg(0x38, 0x306); 191 lcd_write_reg(0x38, 0x306);
237 lcd_write_reg(0x39, 0x9); 192 lcd_write_reg(0x39, 0x7);
238 } 193 }
239 194
240 /* BOOT: 0x6066 */
241 lcd_write_reg(0x3c, 0x700); 195 lcd_write_reg(0x3c, 0x700);
242 lcd_write_reg(0x3d, 0x700); 196 lcd_write_reg(0x3d, 0x700);
243 197
244 lcd_write_reg(0x50, 0x0); 198 lcd_write_reg(0x50, 0x0);
245 lcd_write_reg(0x51, 0xef); /* 239 - LCD_WIDTH */ 199 lcd_write_reg(0x51, 0xef);
246 lcd_write_reg(0x52, 0x0); 200 lcd_write_reg(0x52, 0x0);
247 lcd_write_reg(0x53, 0x13f); /* 319 - LCD_HEIGHT */ 201 lcd_write_reg(0x53, 0x13f);
248 202
249 /* BOOT: b 0x6114 */
250 lcd_write_reg(0x60, 0x2700); 203 lcd_write_reg(0x60, 0x2700);
251 lcd_write_reg(0x61, 0x1); 204 lcd_write_reg(0x61, 0x1);
252 lcd_write_reg(0x6a, 0x0); 205 lcd_write_reg(0x6a, 0x0);
@@ -258,7 +211,6 @@ static void lcd_power_on(void)
258 lcd_write_reg(0x84, 0x0); 211 lcd_write_reg(0x84, 0x0);
259 lcd_write_reg(0x85, 0x0); 212 lcd_write_reg(0x85, 0x0);
260 213
261 /* BOOT: 0x61A8 */
262 lcd_write_reg(0x90, 0x10); 214 lcd_write_reg(0x90, 0x10);
263 lcd_write_reg(0x92, 0x0); 215 lcd_write_reg(0x92, 0x0);
264 lcd_write_reg(0x93, 0x3); 216 lcd_write_reg(0x93, 0x3);
@@ -266,28 +218,14 @@ static void lcd_power_on(void)
266 lcd_write_reg(0x97, 0x0); 218 lcd_write_reg(0x97, 0x0);
267 lcd_write_reg(0x98, 0x0); 219 lcd_write_reg(0x98, 0x0);
268 220
269 lcd_write_reg(0xc, 0x110); 221 lcd_write_reg(0xc, 0x000); // SYSTEM mode
270 lcd_write_reg(0x7, 0x173); 222 lcd_write_reg(0x7, 0x173);
271 sleep(HZ/10); 223 sleep(HZ/10);
272
273 power_on = true;
274} 224}
275 225
276/* unknown 01 and 02 - sleep or enable on and off funcs? */
277void unknown01(void)
278{ 226{
279 /* BOOT: 0x62C4
280 OF: 0x88CA0 */
281 227
282 lcd_write_reg(0x10, 0x17B0); 228 lcd_power_on();
283 udelay(100);
284 lcd_write_reg(0x7, 0x173);
285}
286
287void unknown02(void)
288{
289 /* BOOT: 0x6308
290 OF: 0x88D0C */
291 229
292 lcd_write_reg(0x7, 0x160); 230 lcd_write_reg(0x7, 0x160);
293 lcd_write_reg(0x10, 0x17B1); 231 lcd_write_reg(0x10, 0x17B1);
@@ -295,9 +233,6 @@ void unknown02(void)
295 233
296void unknown03(bool r0) 234void unknown03(bool r0)
297{ 235{
298 /* BOOT: 0x6410
299 OF: 0x88E30 */
300
301 if (r0) 236 if (r0)
302 GPIOJ_ENABLE &= ~0x2; 237 GPIOJ_ENABLE &= ~0x2;
303 else 238 else
@@ -308,76 +243,71 @@ void unknown03(bool r0)
308 } 243 }
309} 244}
310 245
311/* Run the display on sequence for the driver IC */ 246void lcd_init_device(void)
312static void lcd_display_on(void)
313{ 247{
314 display_on = true; 248 lcd_power_on();
315} 249}
316 250
317 251#if defined(HAVE_LCD_ENABLE)
318#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
319bool lcd_active(void) 252bool lcd_active(void)
320{ 253{
321 return display_on; 254 return display_on;
322} 255}
323 256
324/* Turn off visible display operations */ 257void lcd_enable(bool on)
325static void lcd_display_off(void)
326{ 258{
327 display_on = false; 259 display_on = on;
260 if(on)
261 {
262 lcd_write_reg(0x10, 0x17B0);
263 udelay(100);
264 lcd_write_reg(0x7, 0x173);
265 }
266 else
267 {
268 lcd_write_reg(0x7, 0x160);
269 lcd_write_reg(0x10, 0x17B1);
270 }
328} 271}
329#endif 272#endif
330 273
331void lcd_init_device(void) 274static inline void lcd_send_frame_byte(unsigned char data)
332{ 275{
333 276 for(int bit = 0; bit < 8; bit++)
334#ifdef BOOTLOADER /* Bother at all to do this again? */ 277 {
335/* Init GPIO ports */ 278 if(data & 0x80)
336 lcd_init_gpio(); 279 GPIO_SET_BITWISE(LCD_DATA_OUT_GPIO, 1 << LCD_DATA_OUT_PIN);
337 lcd_power_on(); 280 else
338 lcd_display_on(); 281 GPIO_CLEAR_BITWISE(LCD_DATA_OUT_GPIO, 1 << LCD_DATA_OUT_PIN);
339#else 282 data <<= 1;
340 283 GPIO_CLEAR_BITWISE(LCD_CLOCK_GPIO, 1 << LCD_CLOCK_PIN);
341 power_on = true; 284 GPIO_SET_BITWISE(LCD_CLOCK_GPIO, 1 << LCD_CLOCK_PIN);
342 display_on = true; 285 }
343
344 lcd_set_invert_display(false);
345 lcd_set_flip(false);
346#endif
347} 286}
348 287
349#if defined(HAVE_LCD_ENABLE) 288static void lcd_send_frame(const fb_data *addr, int count)
350void lcd_enable(bool on)
351{ 289{
352 (void)on; 290 GPIO_SET_BITWISE(LCD_CLOCK_GPIO, 1 << LCD_CLOCK_PIN);
353} 291 GPIO_CLEAR_BITWISE(LCD_CS_GPIO, 1 << LCD_CS_PIN);
354#endif
355 292
356#if defined(HAVE_LCD_SLEEP) 293 lcd_send_frame_byte(0x72);
357void lcd_sleep(void) 294 while(count-- > 0)
358{ 295 {
296 lcd_send_frame_byte(*addr >> 8);
297 lcd_send_frame_byte(*addr++ & 0xff);
298 }
359 299
300 GPIO_SET_BITWISE(LCD_CS_GPIO, 1 << LCD_CS_PIN);
360} 301}
361#endif
362 302
363void lcd_update(void) 303void lcd_update(void)
364{ 304{
365 const fb_data *addr; 305 if(!display_on)
366 306 return;
367 addr = FBADDR(LCD_WIDTH,LCD_HEIGHT);
368
369 lcd_write_reg(0x20, 0x0); 307 lcd_write_reg(0x20, 0x0);
370 lcd_write_reg(0x21, 0x0); 308 lcd_write_reg(0x21, 0x0);
371 309 lcd_send_cmd(0x22);
372 int i,j; 310 lcd_send_frame(FBADDR(0, 0), LCD_WIDTH * LCD_HEIGHT);
373 for(i=0; i < LCD_HEIGHT; i++)
374 {
375 for(j=0; j < LCD_WIDTH; j++)
376 {
377 lcd_write_reg(0x22, *addr);
378 addr++;
379 }
380 }
381} 311}
382 312
383/* Update a fraction of the display. */ 313/* Update a fraction of the display. */
@@ -408,36 +338,3 @@ void lcd_set_flip(bool yesno)
408{ 338{
409 (void)yesno; 339 (void)yesno;
410} 340}
411
412/* Blitting functions */
413
414void lcd_yuv_set_options(unsigned options)
415{
416 lcd_yuv_options = options;
417}
418
419/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
420extern void lcd_write_yuv420_lines(fb_data *dst,
421 unsigned char const * const src[3],
422 int width,
423 int stride);
424extern void lcd_write_yuv420_lines_odither(fb_data *dst,
425 unsigned char const * const src[3],
426 int width,
427 int stride,
428 int x_screen, /* To align dither pattern */
429 int y_screen);
430
431void lcd_blit_yuv(unsigned char * const src[3],
432 int src_x, int src_y, int stride,
433 int x, int y, int width, int height)
434{
435 (void)src;
436 (void)src_x;
437 (void)src_y;
438 (void)stride;
439 (void)x;
440 (void)y;
441 (void)width;
442 (void)height;
443}