summaryrefslogtreecommitdiff
path: root/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/philips/hdd6330/lcd-hdd6330.c')
-rw-r--r--firmware/target/arm/philips/hdd6330/lcd-hdd6330.c101
1 files changed, 91 insertions, 10 deletions
diff --git a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c b/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c
index c8127c4450..53c0be1d6e 100644
--- a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c
+++ b/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c
@@ -80,21 +80,102 @@ void lcd_yuv_set_options(unsigned options)
80 lcd_yuv_options = options; 80 lcd_yuv_options = options;
81} 81}
82 82
83#define CSUB_X 2
84#define CSUB_Y 2
85
86/* YUV- > RGB565 conversion
87 * |R| |1.000000 -0.000001 1.402000| |Y'|
88 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
89 * |B| |1.000000 1.772000 0.000000| |Pr|
90 * Scaled, normalized, rounded and tweaked to yield RGB 565:
91 * |R| |74 0 101| |Y' - 16| >> 9
92 * |G| = |74 -24 -51| |Cb - 128| >> 8
93 * |B| |74 128 0| |Cr - 128| >> 9
94*/
95
96extern void lcd_yuv_write_inner_loop(unsigned char const * const ysrc,
97 unsigned char const * const usrc,
98 unsigned char const * const vsrc,
99 int width);
100
83/* Performance function to blit a YUV bitmap directly to the LCD */ 101/* Performance function to blit a YUV bitmap directly to the LCD */
84void lcd_blit_yuv(unsigned char * const src[3], 102void lcd_blit_yuv(unsigned char * const src[3],
85 int src_x, int src_y, int stride, 103 int src_x, int src_y, int stride,
86 int x, int y, int width, int height) 104 int x, int y, int width, int height)
87{ 105{
88 (void)src; 106 int h;
89 (void)src_x; 107
90 (void)src_y; 108 width = (width + 1) & ~1;
91 (void)stride; 109
92 (void)x; 110 lcd_send_reg(0x01);
93 (void)y; 111 lcd_send_data(0x48);
94 (void)width; 112
95 (void)height; 113 lcd_send_reg(0x05);
114 lcd_send_data(0x0f);
115
116 lcd_send_reg(0x08);
117 lcd_send_data(y);
118
119 lcd_send_reg(0x09);
120 lcd_send_data(y + height - 1);
121
122 lcd_send_reg(0x0a);
123 lcd_send_data(x + 16);
124
125 lcd_send_reg(0x0b);
126 lcd_send_data(x + width - 1 + 16);
127
128 lcd_send_reg(0x06);
129
130 const int stride_div_csub_x = stride/CSUB_X;
131
132 h=0;
133 while (1)
134 {
135 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
136 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
137
138 const int uvoffset = stride_div_csub_x * (src_y/CSUB_Y) +
139 (src_x/CSUB_X);
140
141 const unsigned char *usrc = src[1] + uvoffset;
142 const unsigned char *vsrc = src[2] + uvoffset;
143
144 int pixels_to_write;
145
146 if (h==0)
147 {
148 while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
149 LCD2_BLOCK_CONFIG = 0;
150
151 if (height == 0) break;
152
153 pixels_to_write = (width * height) * 2;
154 h = height;
155
156 /* calculate how much we can do in one go */
157 if (pixels_to_write > 0x10000)
158 {
159 h = (0x10000/2) / width;
160 pixels_to_write = (width * h) * 2;
161 }
162
163 height -= h;
164 LCD2_BLOCK_CTRL = 0x10000080;
165 LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
166 LCD2_BLOCK_CTRL = 0x34000000;
167 }
168
169 lcd_yuv_write_inner_loop(ysrc,usrc,vsrc,width);
170
171 src_y++;
172 h--;
173 }
174
175 while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
176 LCD2_BLOCK_CONFIG = 0;
96} 177}
97 178
98/* Update the display. 179/* Update the display.
99 This must be called after all other LCD functions that change the display. */ 180 This must be called after all other LCD functions that change the display. */
100void lcd_update(void) 181void lcd_update(void)
@@ -146,7 +227,7 @@ void lcd_update_rect(int x, int y, int width, int height)
146 227
147 addr = (unsigned long*)&lcd_framebuffer[y][x]; 228 addr = (unsigned long*)&lcd_framebuffer[y][x];
148 229
149 while (height > 0) 230 while (height > 0)
150 { 231 {
151 int c, r; 232 int c, r;
152 int h, pixels_to_write; 233 int h, pixels_to_write;