diff options
Diffstat (limited to 'firmware/target/arm/philips/hdd1630/lcd-hdd1630.c')
-rwxr-xr-x | firmware/target/arm/philips/hdd1630/lcd-hdd1630.c | 91 |
1 files changed, 77 insertions, 14 deletions
diff --git a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c b/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c index b58bafab13..6bb0668352 100755 --- a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c +++ b/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c | |||
@@ -77,6 +77,7 @@ | |||
77 | 77 | ||
78 | /* Display status */ | 78 | /* Display status */ |
79 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | 79 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; |
80 | static unsigned mad_ctrl = 0; | ||
80 | 81 | ||
81 | /* wait for LCD */ | 82 | /* wait for LCD */ |
82 | static inline void lcd_wait_write(void) | 83 | static inline void lcd_wait_write(void) |
@@ -179,6 +180,7 @@ void lcd_init_device(void) | |||
179 | 180 | ||
180 | lcd_send_cmd(MADCTR); | 181 | lcd_send_cmd(MADCTR); |
181 | lcd_send_data(0); | 182 | lcd_send_data(0); |
183 | mad_ctrl = 0; | ||
182 | 184 | ||
183 | lcd_send_cmd(COLMOD); | 185 | lcd_send_cmd(COLMOD); |
184 | lcd_send_data(0x5); | 186 | lcd_send_data(0x5); |
@@ -260,12 +262,13 @@ void lcd_set_invert_display(bool yesno) | |||
260 | /* turn the display upside down (call lcd_update() afterwards) */ | 262 | /* turn the display upside down (call lcd_update() afterwards) */ |
261 | void lcd_set_flip(bool yesno) | 263 | void lcd_set_flip(bool yesno) |
262 | { | 264 | { |
263 | lcd_send_cmd(MADCTR); | 265 | if (yesno) |
264 | 266 | mad_ctrl |= ((1<<7) | (1<<6)); /* flip */ | |
265 | if (!yesno) | ||
266 | lcd_send_data(0); /* normal */ | ||
267 | else | 267 | else |
268 | lcd_send_data((1<<7) | (1<<6)); /* y-mirror, x-mirror */ | 268 | mad_ctrl &= ~((1<<7) | (1<<6)); /* normal */ |
269 | |||
270 | lcd_send_cmd(MADCTR); | ||
271 | lcd_send_data(mad_ctrl); | ||
269 | } | 272 | } |
270 | 273 | ||
271 | void lcd_yuv_set_options(unsigned options) | 274 | void lcd_yuv_set_options(unsigned options) |
@@ -273,21 +276,81 @@ void lcd_yuv_set_options(unsigned options) | |||
273 | lcd_yuv_options = options; | 276 | lcd_yuv_options = options; |
274 | } | 277 | } |
275 | 278 | ||
279 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
280 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
281 | int width, int stride); | ||
282 | |||
283 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
284 | int width, int stride, | ||
285 | int x_screen, int y_screen); | ||
286 | |||
276 | /* Performance function to blit a YUV bitmap directly to the LCD */ | 287 | /* Performance function to blit a YUV bitmap directly to the LCD */ |
277 | void lcd_blit_yuv(unsigned char * const src[3], | 288 | void lcd_blit_yuv(unsigned char * const src[3], |
278 | int src_x, int src_y, int stride, | 289 | int src_x, int src_y, int stride, |
279 | int x, int y, int width, int height) | 290 | int x, int y, int width, int height) |
280 | { | 291 | { |
281 | (void)src; | 292 | unsigned char const * yuv_src[3]; |
282 | (void)src_x; | 293 | off_t z; |
283 | (void)src_y; | 294 | |
284 | (void)stride; | 295 | /* Sorry, but width and height must be >= 2 or else */ |
285 | (void)x; | 296 | width &= ~1; |
286 | (void)y; | 297 | height >>= 1; |
287 | (void)width; | 298 | |
288 | (void)height; | 299 | z = stride*src_y; |
300 | yuv_src[0] = src[0] + z + src_x; | ||
301 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
302 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
303 | |||
304 | /* Set vertical address mode */ | ||
305 | lcd_send_cmd(MADCTR); | ||
306 | lcd_send_data(mad_ctrl | (1<<5)); | ||
307 | |||
308 | lcd_send_cmd(RASET); | ||
309 | lcd_send_data(x); | ||
310 | lcd_send_data(x + width - 1); | ||
311 | |||
312 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
313 | { | ||
314 | do | ||
315 | { | ||
316 | lcd_send_cmd(CASET); | ||
317 | lcd_send_data(y); | ||
318 | lcd_send_data(y + 1); | ||
319 | |||
320 | lcd_send_cmd(RAMWR); | ||
321 | |||
322 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); | ||
323 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
324 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
325 | yuv_src[2] += stride >> 1; | ||
326 | y += 2; | ||
327 | } | ||
328 | while (--height > 0); | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | do | ||
333 | { | ||
334 | lcd_send_cmd(CASET); | ||
335 | lcd_send_data(y); | ||
336 | lcd_send_data(y + 1); | ||
337 | |||
338 | lcd_send_cmd(RAMWR); | ||
339 | |||
340 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
341 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
342 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
343 | yuv_src[2] += stride >> 1; | ||
344 | y += 2; | ||
345 | } | ||
346 | while (--height > 0); | ||
347 | } | ||
348 | |||
349 | /* Restore the address mode */ | ||
350 | lcd_send_cmd(MADCTR); | ||
351 | lcd_send_data(mad_ctrl); | ||
289 | } | 352 | } |
290 | 353 | ||
291 | /* Update the display. | 354 | /* Update the display. |
292 | This must be called after all other LCD functions that change the display. */ | 355 | This must be called after all other LCD functions that change the display. */ |
293 | void lcd_update(void) | 356 | void lcd_update(void) |