diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/philips/hdd6330/lcd-hdd6330.c | 98 |
1 files changed, 63 insertions, 35 deletions
diff --git a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c b/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c index 3d9cb036f1..c8127c4450 100644 --- a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c +++ b/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c | |||
@@ -30,14 +30,7 @@ static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | |||
30 | /* wait for LCD */ | 30 | /* wait for LCD */ |
31 | static inline void lcd_wait_write(void) | 31 | static inline void lcd_wait_write(void) |
32 | { | 32 | { |
33 | int i = 0; | 33 | while (LCD2_PORT & LCD2_BUSY_MASK); |
34 | while (LCD2_PORT & LCD2_BUSY_MASK) | ||
35 | { | ||
36 | if (i < 2000) | ||
37 | i++; | ||
38 | else | ||
39 | LCD2_PORT &= ~LCD2_BUSY_MASK; | ||
40 | } | ||
41 | } | 34 | } |
42 | 35 | ||
43 | /* send LCD data */ | 36 | /* send LCD data */ |
@@ -48,19 +41,13 @@ static void lcd_send_data(unsigned data) | |||
48 | } | 41 | } |
49 | 42 | ||
50 | /* send LCD command */ | 43 | /* send LCD command */ |
51 | static void lcd_send_cmd(unsigned cmd) | 44 | static void lcd_send_reg(unsigned reg) |
52 | { | 45 | { |
53 | lcd_wait_write(); | 46 | lcd_wait_write(); |
54 | LCD2_PORT = LCD2_CMD_MASK | (cmd & 0xff); | 47 | LCD2_PORT = LCD2_CMD_MASK | (reg & 0xff); |
55 | lcd_wait_write(); | 48 | lcd_wait_write(); |
56 | } | 49 | } |
57 | 50 | ||
58 | static inline void lcd_send_pixel(unsigned pixel) | ||
59 | { | ||
60 | lcd_send_data(pixel >> 8); | ||
61 | lcd_send_data(pixel); | ||
62 | } | ||
63 | |||
64 | void lcd_init_device(void) | 51 | void lcd_init_device(void) |
65 | { | 52 | { |
66 | /* init handled by the OF bootloader */ | 53 | /* init handled by the OF bootloader */ |
@@ -118,42 +105,83 @@ void lcd_update(void) | |||
118 | /* Update a fraction of the display. */ | 105 | /* Update a fraction of the display. */ |
119 | void lcd_update_rect(int x, int y, int width, int height) | 106 | void lcd_update_rect(int x, int y, int width, int height) |
120 | { | 107 | { |
121 | const fb_data *addr; | 108 | unsigned long *addr; |
122 | 109 | int new_x, new_width; | |
110 | |||
111 | /* Ensure x and width are both even - so we can read 32-bit aligned | ||
112 | data from lcd_framebuffer */ | ||
113 | new_x = x&~1; | ||
114 | new_width = width&~1; | ||
115 | if (new_x+new_width < x+width) new_width += 2; | ||
116 | x = new_x; | ||
117 | width = new_width; | ||
118 | |||
123 | if (x + width >= LCD_WIDTH) | 119 | if (x + width >= LCD_WIDTH) |
124 | width = LCD_WIDTH - x; | 120 | width = LCD_WIDTH - x; |
125 | if (y + height >= LCD_HEIGHT) | 121 | if (y + height >= LCD_HEIGHT) |
126 | height = LCD_HEIGHT - y; | 122 | height = LCD_HEIGHT - y; |
127 | 123 | ||
128 | if ((width <= 0) || (height <= 0)) | 124 | if ((width <= 0) || (height <= 0)) |
129 | return; /* Nothing left to do. */ | 125 | return; /* Nothing left to do. */ |
130 | 126 | ||
131 | addr = &lcd_framebuffer[y][x]; | 127 | lcd_send_reg(0x01); |
132 | |||
133 | lcd_send_cmd(0x01); | ||
134 | lcd_send_data(0x48); | 128 | lcd_send_data(0x48); |
135 | 129 | ||
136 | lcd_send_cmd(0x05); | 130 | lcd_send_reg(0x05); |
137 | lcd_send_data(0x0f); | 131 | lcd_send_data(0x0f); |
138 | 132 | ||
139 | lcd_send_cmd(0x08); | 133 | lcd_send_reg(0x08); |
140 | lcd_send_data(y); | 134 | lcd_send_data(y); |
141 | 135 | ||
142 | lcd_send_cmd(0x09); | 136 | lcd_send_reg(0x09); |
143 | lcd_send_data(y + height - 1); | 137 | lcd_send_data(y + height - 1); |
144 | 138 | ||
145 | lcd_send_cmd(0x0a); | 139 | lcd_send_reg(0x0a); |
146 | lcd_send_data(x + 16); | 140 | lcd_send_data(x + 16); |
147 | 141 | ||
148 | lcd_send_cmd(0x0b); | 142 | lcd_send_reg(0x0b); |
149 | lcd_send_data(x + width - 1 + 16); | 143 | lcd_send_data(x + width - 1 + 16); |
150 | 144 | ||
151 | lcd_send_cmd(0x06); | 145 | lcd_send_reg(0x06); |
152 | do { | 146 | |
153 | int w = width; | 147 | addr = (unsigned long*)&lcd_framebuffer[y][x]; |
154 | do { | 148 | |
155 | lcd_send_pixel(*addr++); | 149 | while (height > 0) |
156 | } while (--w > 0); | 150 | { |
157 | addr += LCD_WIDTH - width; | 151 | int c, r; |
158 | } while (--height > 0); | 152 | int h, pixels_to_write; |
153 | |||
154 | pixels_to_write = (width * height) * 2; | ||
155 | h = height; | ||
156 | |||
157 | /* calculate how much we can do in one go */ | ||
158 | if (pixels_to_write > 0x10000) | ||
159 | { | ||
160 | h = (0x10000/2) / width; | ||
161 | pixels_to_write = (width * h) * 2; | ||
162 | } | ||
163 | |||
164 | LCD2_BLOCK_CTRL = 0x10000080; | ||
165 | LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1); | ||
166 | LCD2_BLOCK_CTRL = 0x34000000; | ||
167 | |||
168 | /* for each row */ | ||
169 | for (r = 0; r < h; r++) | ||
170 | { | ||
171 | /* for each column */ | ||
172 | for (c = 0; c < width; c += 2) | ||
173 | { | ||
174 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); | ||
175 | |||
176 | /* output 2 pixels */ | ||
177 | LCD2_BLOCK_DATA = *addr++; | ||
178 | } | ||
179 | addr += (LCD_WIDTH - width)/2; | ||
180 | } | ||
181 | |||
182 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY)); | ||
183 | LCD2_BLOCK_CONFIG = 0; | ||
184 | |||
185 | height -= h; | ||
186 | } | ||
159 | } | 187 | } |