diff options
Diffstat (limited to 'firmware/target/arm/samsung/yh925')
-rw-r--r-- | firmware/target/arm/samsung/yh925/backlight-yh925.c | 47 | ||||
-rw-r--r-- | firmware/target/arm/samsung/yh925/lcd-as-yh925.S | 538 | ||||
-rw-r--r-- | firmware/target/arm/samsung/yh925/lcd-yh925.c | 638 | ||||
-rw-r--r-- | firmware/target/arm/samsung/yh925/powermgmt-yh925.c | 59 |
4 files changed, 1282 insertions, 0 deletions
diff --git a/firmware/target/arm/samsung/yh925/backlight-yh925.c b/firmware/target/arm/samsung/yh925/backlight-yh925.c new file mode 100644 index 0000000000..2dac1d7a81 --- /dev/null +++ b/firmware/target/arm/samsung/yh925/backlight-yh925.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardell | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "cpu.h" | ||
23 | #include "system.h" | ||
24 | #include "backlight.h" | ||
25 | #include "lcd.h" | ||
26 | |||
27 | void _backlight_on(void) | ||
28 | { | ||
29 | #ifdef HAVE_LCD_SLEEP | ||
30 | backlight_lcd_sleep_countdown(false); /* stop counter */ | ||
31 | #endif | ||
32 | #ifdef HAVE_LCD_ENABLE | ||
33 | lcd_enable(true); /* power on lcd + visible display */ | ||
34 | #endif | ||
35 | GPIO_SET_BITWISE(GPIOF_OUTPUT_VAL, 0x1); | ||
36 | } | ||
37 | |||
38 | void _backlight_off(void) | ||
39 | { | ||
40 | GPIO_CLEAR_BITWISE(GPIOF_OUTPUT_VAL, 0x1); | ||
41 | #ifdef HAVE_LCD_ENABLE | ||
42 | lcd_enable(false); /* power off visible display */ | ||
43 | #endif | ||
44 | #ifdef HAVE_LCD_SLEEP | ||
45 | backlight_lcd_sleep_countdown(true); /* start countdown */ | ||
46 | #endif | ||
47 | } | ||
diff --git a/firmware/target/arm/samsung/yh925/lcd-as-yh925.S b/firmware/target/arm/samsung/yh925/lcd-as-yh925.S new file mode 100644 index 0000000000..ba6c876d44 --- /dev/null +++ b/firmware/target/arm/samsung/yh925/lcd-as-yh925.S | |||
@@ -0,0 +1,538 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007-2008 by Michael Sevakis | ||
11 | * | ||
12 | * H10 20GB LCD assembly routines | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "cpu.h" | ||
26 | |||
27 | /**************************************************************************** | ||
28 | * void lcd_write_yuv_420_lines(unsigned char const * const src[3], | ||
29 | * int width, | ||
30 | * int stride); | ||
31 | * | ||
32 | * |R| |1.000000 -0.000001 1.402000| |Y'| | ||
33 | * |G| = |1.000000 -0.334136 -0.714136| |Pb| | ||
34 | * |B| |1.000000 1.772000 0.000000| |Pr| | ||
35 | * Scaled, normalized, rounded and tweaked to yield RGB 565: | ||
36 | * |R| |74 0 101| |Y' - 16| >> 9 | ||
37 | * |G| = |74 -24 -51| |Cb - 128| >> 8 | ||
38 | * |B| |74 128 0| |Cr - 128| >> 9 | ||
39 | * | ||
40 | * Write four RGB565 pixels in the following order on each loop: | ||
41 | * 1 3 + > down | ||
42 | * 2 4 \/ left | ||
43 | */ | ||
44 | .section .icode, "ax", %progbits | ||
45 | .align 2 | ||
46 | .global lcd_write_yuv420_lines | ||
47 | .type lcd_write_yuv420_lines, %function | ||
48 | lcd_write_yuv420_lines: | ||
49 | @ r0 = yuv_src | ||
50 | @ r1 = width | ||
51 | @ r2 = stride | ||
52 | stmfd sp!, { r4-r12, lr } @ save non-scratch | ||
53 | ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p | ||
54 | @ r5 = yuv_src[1] = Cb_p | ||
55 | @ r6 = yuv_src[2] = Cr_p | ||
56 | @ | ||
57 | mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c | ||
58 | add r0, r0, #0x8a00 @ | ||
59 | mov r14, #LCD2_DATA_MASK @ | ||
60 | @ | ||
61 | sub r2, r2, #1 @ Adjust stride because of increment | ||
62 | 10: @ loop line @ | ||
63 | ldrb r7, [r4], #1 @ r7 = *Y'_p++; | ||
64 | ldrb r8, [r5], #1 @ r8 = *Cb_p++; | ||
65 | ldrb r9, [r6], #1 @ r9 = *Cr_p++; | ||
66 | @ | ||
67 | sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74 | ||
68 | add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right | ||
69 | add r7, r12, r7, asl #5 @ by one less when adding - same for all | ||
70 | @ | ||
71 | sub r8, r8, #128 @ Cb -= 128 | ||
72 | sub r9, r9, #128 @ Cr -= 128 | ||
73 | @ | ||
74 | add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24 | ||
75 | add r10, r10, r10, asl #4 @ | ||
76 | add r10, r10, r8, asl #3 @ | ||
77 | add r10, r10, r8, asl #4 @ | ||
78 | @ | ||
79 | add r11, r9, r9, asl #2 @ r9 = Cr*101 | ||
80 | add r11, r11, r9, asl #5 @ | ||
81 | add r9, r11, r9, asl #6 @ | ||
82 | @ | ||
83 | add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8 | ||
84 | mov r8, r8, asr #2 @ | ||
85 | add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9 | ||
86 | mov r9, r9, asr #9 @ | ||
87 | rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8 | ||
88 | mov r10, r10, asr #8 @ | ||
89 | @ compute R, G, and B | ||
90 | add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu | ||
91 | add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv | ||
92 | add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv | ||
93 | @ | ||
94 | orr r12, r3, r11 @ check if clamping is needed... | ||
95 | orr r12, r12, r7, asr #1 @ ...at all | ||
96 | cmp r12, #31 @ | ||
97 | bls 15f @ no clamp @ | ||
98 | cmp r3, #31 @ clamp b | ||
99 | mvnhi r3, r3, asr #31 @ | ||
100 | andhi r3, r3, #31 @ | ||
101 | cmp r11, #31 @ clamp r | ||
102 | mvnhi r11, r11, asr #31 @ | ||
103 | andhi r11, r11, #31 @ | ||
104 | cmp r7, #63 @ clamp g | ||
105 | mvnhi r7, r7, asr #31 @ | ||
106 | andhi r7, r7, #63 @ | ||
107 | 15: @ no clamp @ | ||
108 | @ | ||
109 | ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride) | ||
110 | @ | ||
111 | orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11) | ||
112 | orr r3, r3, r7, lsl #5 @ r3 |= (g << 5) | ||
113 | @ | ||
114 | orr r7, r14, r3, lsr #8 @ store pixel | ||
115 | orr r11, r14, r3 @ | ||
116 | 20: @ | ||
117 | ldr r3, [r0] @ | ||
118 | tst r3, #LCD2_BUSY_MASK @ | ||
119 | bne 20b @ | ||
120 | str r7, [r0] @ | ||
121 | str r11, [r0] @ | ||
122 | @ | ||
123 | sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74 | ||
124 | add r12, r7, r7, asl #2 @ | ||
125 | add r7, r12, r7, asl #5 @ | ||
126 | @ compute R, G, and B | ||
127 | add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu | ||
128 | add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv | ||
129 | add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv | ||
130 | @ | ||
131 | orr r12, r3, r11 @ check if clamping is needed... | ||
132 | orr r12, r12, r7, asr #1 @ ...at all | ||
133 | cmp r12, #31 @ | ||
134 | bls 15f @ no clamp @ | ||
135 | cmp r3, #31 @ clamp b | ||
136 | mvnhi r3, r3, asr #31 @ | ||
137 | andhi r3, r3, #31 @ | ||
138 | cmp r11, #31 @ clamp r | ||
139 | mvnhi r11, r11, asr #31 @ | ||
140 | andhi r11, r11, #31 @ | ||
141 | cmp r7, #63 @ clamp g | ||
142 | mvnhi r7, r7, asr #31 @ | ||
143 | andhi r7, r7, #63 @ | ||
144 | 15: @ no clamp @ | ||
145 | @ | ||
146 | ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++) | ||
147 | @ | ||
148 | orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11) | ||
149 | orr r3, r3, r7, lsl #5 @ r3 |= (g << 5) | ||
150 | @ | ||
151 | orr r7, r14, r3, lsr #8 @ store pixel | ||
152 | orr r11, r14, r3 @ | ||
153 | 20: @ | ||
154 | ldr r3, [r0] @ | ||
155 | tst r3, #LCD2_BUSY_MASK @ | ||
156 | bne 20b @ | ||
157 | str r7, [r0] @ | ||
158 | str r11, [r0] @ | ||
159 | @ | ||
160 | sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74 | ||
161 | add r12, r7, r7, asl #2 @ | ||
162 | add r7, r12, r7, asl #5 @ | ||
163 | @ compute R, G, and B | ||
164 | add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu | ||
165 | add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv | ||
166 | add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv | ||
167 | @ | ||
168 | orr r12, r3, r11 @ check if clamping is needed... | ||
169 | orr r12, r12, r7, asr #1 @ ...at all | ||
170 | cmp r12, #31 @ | ||
171 | bls 15f @ no clamp @ | ||
172 | cmp r3, #31 @ clamp b | ||
173 | mvnhi r3, r3, asr #31 @ | ||
174 | andhi r3, r3, #31 @ | ||
175 | cmp r11, #31 @ clamp r | ||
176 | mvnhi r11, r11, asr #31 @ | ||
177 | andhi r11, r11, #31 @ | ||
178 | cmp r7, #63 @ clamp g | ||
179 | mvnhi r7, r7, asr #31 @ | ||
180 | andhi r7, r7, #63 @ | ||
181 | 15: @ no clamp @ | ||
182 | @ | ||
183 | ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride) | ||
184 | @ | ||
185 | orr r3, r3, r7, lsl #5 @ r3 = b | (g << 5) | ||
186 | orr r3, r3, r11, lsl #11 @ r3 |= (r << 11) | ||
187 | @ | ||
188 | orr r7, r14, r3, lsr #8 @ store pixel | ||
189 | orr r11, r14, r3 @ | ||
190 | 20: @ | ||
191 | ldr r3, [r0] @ | ||
192 | tst r3, #LCD2_BUSY_MASK @ | ||
193 | bne 20b @ | ||
194 | str r7, [r0] @ | ||
195 | str r11, [r0] @ | ||
196 | @ | ||
197 | sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74 | ||
198 | add r12, r7, r7, asl #2 @ | ||
199 | add r7, r12, r7, asl #5 @ | ||
200 | @ compute R, G, and B | ||
201 | add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu | ||
202 | add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv | ||
203 | add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv | ||
204 | @ | ||
205 | orr r12, r3, r11 @ check if clamping is needed... | ||
206 | orr r12, r12, r7, asr #1 @ ...at all | ||
207 | cmp r12, #31 @ | ||
208 | bls 15f @ no clamp @ | ||
209 | cmp r3, #31 @ clamp b | ||
210 | mvnhi r3, r3, asr #31 @ | ||
211 | andhi r3, r3, #31 @ | ||
212 | cmp r11, #31 @ clamp r | ||
213 | mvnhi r11, r11, asr #31 @ | ||
214 | andhi r11, r11, #31 @ | ||
215 | cmp r7, #63 @ clamp g | ||
216 | mvnhi r7, r7, asr #31 @ | ||
217 | andhi r7, r7, #63 @ | ||
218 | 15: @ no clamp @ | ||
219 | @ | ||
220 | orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11) | ||
221 | orr r3, r3, r7, lsl #5 @ r3 |= (g << 5) | ||
222 | @ | ||
223 | orr r7, r14, r3, lsr #8 @ store pixel | ||
224 | orr r11, r14, r3 @ | ||
225 | 20: @ | ||
226 | ldr r3, [r0] @ | ||
227 | tst r3, #LCD2_BUSY_MASK @ | ||
228 | bne 20b @ | ||
229 | str r7, [r0] @ | ||
230 | str r11, [r0] @ | ||
231 | @ | ||
232 | subs r1, r1, #2 @ subtract block from width | ||
233 | bgt 10b @ loop line @ | ||
234 | @ | ||
235 | ldmfd sp!, { r4-r12, pc } @ restore registers and return | ||
236 | .ltorg @ dump constant pool | ||
237 | .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines | ||
238 | |||
239 | |||
240 | /**************************************************************************** | ||
241 | * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3], | ||
242 | * int width, | ||
243 | * int stride, | ||
244 | * int x_screen, | ||
245 | * int y_screen); | ||
246 | * | ||
247 | * |R| |1.000000 -0.000001 1.402000| |Y'| | ||
248 | * |G| = |1.000000 -0.334136 -0.714136| |Pb| | ||
249 | * |B| |1.000000 1.772000 0.000000| |Pr| | ||
250 | * Red scaled at twice g & b but at same precision to place it in correct | ||
251 | * bit position after multiply and leave instruction count lower. | ||
252 | * |R| |258 0 408| |Y' - 16| | ||
253 | * |G| = |149 -49 -104| |Cb - 128| | ||
254 | * |B| |149 258 0| |Cr - 128| | ||
255 | * | ||
256 | * Write four RGB565 pixels in the following order on each loop: | ||
257 | * 1 3 + > down | ||
258 | * 2 4 \/ left | ||
259 | * | ||
260 | * Kernel pattern (raw|use order): | ||
261 | * 5 3 4 2 row0 row2 > down | ||
262 | * 1 7 0 6 | 5 1 3 7 4 0 2 6 col0 left | ||
263 | * 4 2 5 3 | 4 0 2 6 5 1 3 7 col2 \/ | ||
264 | * 0 6 1 7 | ||
265 | */ | ||
266 | .section .icode, "ax", %progbits | ||
267 | .align 2 | ||
268 | .global lcd_write_yuv420_lines_odither | ||
269 | .type lcd_write_yuv420_lines_odither, %function | ||
270 | lcd_write_yuv420_lines_odither: | ||
271 | @ r0 = yuv_src | ||
272 | @ r1 = width | ||
273 | @ r2 = stride | ||
274 | @ r3 = x_screen | ||
275 | @ [sp] = y_screen | ||
276 | stmfd sp!, { r4-r12, lr } @ save non-scratch | ||
277 | ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p | ||
278 | @ r5 = yuv_src[1] = Cb_p | ||
279 | @ r6 = yuv_src[2] = Cr_p | ||
280 | @ | ||
281 | ldr r0, [sp, #40] @ Line up pattern and kernel quadrant | ||
282 | eor r14, r3, r0 @ | ||
283 | and r14, r14, #0x2 @ | ||
284 | mov r14, r14, lsl #6 @ 0x00 or 0x80 | ||
285 | @ | ||
286 | mov r0, #0x7000000c @ r0 = &LCD2_PORT = 0x70008a0c | ||
287 | add r0, r0, #0x8a00 @ | ||
288 | @ | ||
289 | sub r2, r2, #1 @ Adjust stride because of increment | ||
290 | 10: @ loop line @ | ||
291 | @ | ||
292 | ldrb r7, [r4], #1 @ r7 = *Y'_p++; | ||
293 | ldrb r8, [r5], #1 @ r8 = *Cb_p++; | ||
294 | ldrb r9, [r6], #1 @ r9 = *Cr_p++; | ||
295 | @ | ||
296 | eor r14, r14, #0x80 @ flip pattern quadrant | ||
297 | @ | ||
298 | sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149 | ||
299 | add r12, r7, r7, asl #2 @ | ||
300 | add r12, r12, r12, asl #4 @ | ||
301 | add r7, r12, r7, asl #6 @ | ||
302 | @ | ||
303 | sub r8, r8, #128 @ Cb -= 128 | ||
304 | sub r9, r9, #128 @ Cr -= 128 | ||
305 | @ | ||
306 | add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49 | ||
307 | add r10, r10, r8, asl #5 @ | ||
308 | add r10, r10, r9, asl #3 @ | ||
309 | add r10, r10, r9, asl #5 @ | ||
310 | add r10, r10, r9, asl #6 @ | ||
311 | @ | ||
312 | mov r8, r8, asl #1 @ r8 = bu = Cb*258 | ||
313 | add r8, r8, r8, asl #7 @ | ||
314 | @ | ||
315 | add r9, r9, r9, asl #1 @ r9 = rv = Cr*408 | ||
316 | add r9, r9, r9, asl #4 @ | ||
317 | mov r9, r9, asl #3 @ | ||
318 | @ | ||
319 | @ compute R, G, and B | ||
320 | add r3, r8, r7 @ r3 = b' = Y + bu | ||
321 | add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv | ||
322 | rsb r7, r10, r7 @ r7 = g' = Y + guv | ||
323 | @ | ||
324 | @ r8 = bu, r9 = rv, r10 = guv | ||
325 | @ | ||
326 | sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256 | ||
327 | add r3, r12, r3, lsr #8 @ | ||
328 | @ | ||
329 | sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256 | ||
330 | add r11, r12, r11, lsr #8 @ | ||
331 | @ | ||
332 | sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256 | ||
333 | add r7, r12, r7, lsr #8 @ | ||
334 | @ | ||
335 | add r12, r14, #0x200 @ | ||
336 | @ | ||
337 | add r3, r3, r12 @ b = r3 + delta | ||
338 | add r11, r11, r12, lsl #1 @ r = r11 + delta*2 | ||
339 | add r7, r7, r12, lsr #1 @ g = r7 + delta/2 | ||
340 | @ | ||
341 | orr r12, r3, r11, asr #1 @ check if clamping is needed... | ||
342 | orr r12, r12, r7 @ ...at all | ||
343 | movs r12, r12, asr #15 @ | ||
344 | beq 15f @ no clamp @ | ||
345 | movs r12, r3, asr #15 @ clamp b | ||
346 | mvnne r3, r12, lsr #15 @ | ||
347 | andne r3, r3, #0x7c00 @ mask b only if clamped | ||
348 | movs r12, r11, asr #16 @ clamp r | ||
349 | mvnne r11, r12, lsr #16 @ | ||
350 | movs r12, r7, asr #15 @ clamp g | ||
351 | mvnne r7, r12, lsr #15 @ | ||
352 | 15: @ no clamp @ | ||
353 | @ | ||
354 | ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride) | ||
355 | @ | ||
356 | and r11, r11, #0xf800 @ pack pixel | ||
357 | and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) | | ||
358 | orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) | | ||
359 | orr r3, r11, r3, lsr #10 @ (b >> 10) | ||
360 | @ | ||
361 | mov r11, #LCD2_DATA_MASK @ store pixel | ||
362 | orr r7, r11, r3, lsr #8 @ | ||
363 | orr r11, r11, r3 @ | ||
364 | 20: @ | ||
365 | ldr r3, [r0] @ | ||
366 | tst r3, #LCD2_BUSY_MASK @ | ||
367 | bne 20b @ | ||
368 | str r7, [r0] @ | ||
369 | str r11, [r0] @ | ||
370 | @ | ||
371 | sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149 | ||
372 | add r12, r7, r7, asl #2 @ | ||
373 | add r12, r12, r12, asl #4 @ | ||
374 | add r7, r12, r7, asl #6 @ | ||
375 | @ compute R, G, and B | ||
376 | add r3, r8, r7 @ r3 = b' = Y + bu | ||
377 | add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv | ||
378 | rsb r7, r10, r7 @ r7 = g' = Y + guv | ||
379 | @ | ||
380 | sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256 | ||
381 | add r3, r12, r3, lsr #8 @ | ||
382 | @ | ||
383 | sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256 | ||
384 | add r11, r12, r11, lsr #8 @ | ||
385 | @ | ||
386 | sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256 | ||
387 | add r7, r12, r7, lsr #8 @ | ||
388 | @ | ||
389 | @ This element is zero - use r14 @ | ||
390 | @ | ||
391 | add r3, r3, r14 @ b = r3 + delta | ||
392 | add r11, r11, r14, lsl #1 @ r = r11 + delta*2 | ||
393 | add r7, r7, r14, lsr #1 @ g = r7 + delta/2 | ||
394 | @ | ||
395 | orr r12, r3, r11, asr #1 @ check if clamping is needed... | ||
396 | orr r12, r12, r7 @ ...at all | ||
397 | movs r12, r12, asr #15 @ | ||
398 | beq 15f @ no clamp @ | ||
399 | movs r12, r3, asr #15 @ clamp b | ||
400 | mvnne r3, r12, lsr #15 @ | ||
401 | andne r3, r3, #0x7c00 @ mask b only if clamped | ||
402 | movs r12, r11, asr #16 @ clamp r | ||
403 | mvnne r11, r12, lsr #16 @ | ||
404 | movs r12, r7, asr #15 @ clamp g | ||
405 | mvnne r7, r12, lsr #15 @ | ||
406 | 15: @ no clamp @ | ||
407 | @ | ||
408 | ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++) | ||
409 | @ | ||
410 | and r11, r11, #0xf800 @ pack pixel | ||
411 | and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) | | ||
412 | orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) | | ||
413 | orr r3, r11, r3, lsr #10 @ (b >> 10) | ||
414 | @ | ||
415 | mov r11, #LCD2_DATA_MASK @ store pixel | ||
416 | orr r7, r11, r3, lsr #8 @ | ||
417 | orr r11, r11, r3 @ | ||
418 | 20: @ | ||
419 | ldr r3, [r0] @ | ||
420 | tst r3, #LCD2_BUSY_MASK @ | ||
421 | bne 20b @ | ||
422 | str r7, [r0] @ | ||
423 | str r11, [r0] @ | ||
424 | @ | ||
425 | sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149 | ||
426 | add r12, r7, r7, asl #2 @ | ||
427 | add r12, r12, r12, asl #4 @ | ||
428 | add r7, r12, r7, asl #6 @ | ||
429 | @ compute R, G, and B | ||
430 | add r3, r8, r7 @ r3 = b' = Y + bu | ||
431 | add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv | ||
432 | rsb r7, r10, r7 @ r7 = g' = Y + guv | ||
433 | @ | ||
434 | @ r8 = bu, r9 = rv, r10 = guv | ||
435 | @ | ||
436 | sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256 | ||
437 | add r3, r12, r3, lsr #8 @ | ||
438 | @ | ||
439 | sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256 | ||
440 | add r11, r12, r11, lsr #8 @ | ||
441 | @ | ||
442 | sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256 | ||
443 | add r7, r12, r7, lsr #8 @ | ||
444 | @ | ||
445 | add r12, r14, #0x100 @ | ||
446 | @ | ||
447 | add r3, r3, r12 @ b = r3 + delta | ||
448 | add r11, r11, r12, lsl #1 @ r = r11 + delta*2 | ||
449 | add r7, r7, r12, lsr #1 @ g = r7 + delta/2 | ||
450 | @ | ||
451 | orr r12, r3, r11, asr #1 @ check if clamping is needed... | ||
452 | orr r12, r12, r7 @ ...at all | ||
453 | movs r12, r12, asr #15 @ | ||
454 | beq 15f @ no clamp @ | ||
455 | movs r12, r3, asr #15 @ clamp b | ||
456 | mvnne r3, r12, lsr #15 @ | ||
457 | andne r3, r3, #0x7c00 @ mask b only if clamped | ||
458 | movs r12, r11, asr #16 @ clamp r | ||
459 | mvnne r11, r12, lsr #16 @ | ||
460 | movs r12, r7, asr #15 @ clamp g | ||
461 | mvnne r7, r12, lsr #15 @ | ||
462 | 15: @ no clamp @ | ||
463 | @ | ||
464 | ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride) | ||
465 | @ | ||
466 | and r11, r11, #0xf800 @ pack pixel | ||
467 | and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) | | ||
468 | orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) | | ||
469 | orr r3, r11, r3, lsr #10 @ (b >> 10) | ||
470 | @ | ||
471 | mov r11, #LCD2_DATA_MASK @ store pixel | ||
472 | orr r7, r11, r3, lsr #8 @ | ||
473 | orr r11, r11, r3 @ | ||
474 | 20: @ | ||
475 | ldr r3, [r0] @ | ||
476 | tst r3, #LCD2_BUSY_MASK @ | ||
477 | bne 20b @ | ||
478 | str r7, [r0] @ | ||
479 | str r11, [r0] @ | ||
480 | @ | ||
481 | sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149 | ||
482 | add r12, r7, r7, asl #2 @ | ||
483 | add r12, r12, r12, asl #4 @ | ||
484 | add r7, r12, r7, asl #6 @ | ||
485 | @ compute R, G, and B | ||
486 | add r3, r8, r7 @ r3 = b' = Y + bu | ||
487 | add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv | ||
488 | rsb r7, r10, r7 @ r7 = g' = Y + guv | ||
489 | @ | ||
490 | sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256 | ||
491 | add r3, r12, r3, lsr #8 @ | ||
492 | @ | ||
493 | sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256 | ||
494 | add r11, r12, r11, lsr #8 @ | ||
495 | @ | ||
496 | sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256 | ||
497 | add r7, r12, r7, lsr #8 @ | ||
498 | @ | ||
499 | add r12, r14, #0x300 @ | ||
500 | @ | ||
501 | add r3, r3, r12 @ b = r3 + delta | ||
502 | add r11, r11, r12, lsl #1 @ r = r11 + delta*2 | ||
503 | add r7, r7, r12, lsr #1 @ g = r7 + delta/2 | ||
504 | @ | ||
505 | orr r12, r3, r11, asr #1 @ check if clamping is needed... | ||
506 | orr r12, r12, r7 @ ...at all | ||
507 | movs r12, r12, asr #15 @ | ||
508 | beq 15f @ no clamp @ | ||
509 | movs r12, r3, asr #15 @ clamp b | ||
510 | mvnne r3, r12, lsr #15 @ | ||
511 | andne r3, r3, #0x7c00 @ mask b only if clamped | ||
512 | movs r12, r11, asr #16 @ clamp r | ||
513 | mvnne r11, r12, lsr #16 @ | ||
514 | movs r12, r7, asr #15 @ clamp g | ||
515 | mvnne r7, r12, lsr #15 @ | ||
516 | 15: @ no clamp @ | ||
517 | @ | ||
518 | and r11, r11, #0xf800 @ pack pixel | ||
519 | and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) | | ||
520 | orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) | | ||
521 | orr r3, r11, r3, lsr #10 @ (b >> 10) | ||
522 | @ | ||
523 | mov r11, #LCD2_DATA_MASK @ store pixel | ||
524 | orr r7, r11, r3, lsr #8 @ | ||
525 | orr r11, r11, r3 @ | ||
526 | 20: @ | ||
527 | ldr r3, [r0] @ | ||
528 | tst r3, #LCD2_BUSY_MASK @ | ||
529 | bne 20b @ | ||
530 | str r7, [r0] @ | ||
531 | str r11, [r0] @ | ||
532 | @ | ||
533 | subs r1, r1, #2 @ subtract block from width | ||
534 | bgt 10b @ loop line @ | ||
535 | @ | ||
536 | ldmfd sp!, { r4-r12, pc } @ restore registers and return | ||
537 | .ltorg @ dump constant pool | ||
538 | .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither | ||
diff --git a/firmware/target/arm/samsung/yh925/lcd-yh925.c b/firmware/target/arm/samsung/yh925/lcd-yh925.c new file mode 100644 index 0000000000..8afcf58bea --- /dev/null +++ b/firmware/target/arm/samsung/yh925/lcd-yh925.c | |||
@@ -0,0 +1,638 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardell | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "cpu.h" | ||
23 | #include "lcd.h" | ||
24 | #include "kernel.h" | ||
25 | #include "system.h" | ||
26 | |||
27 | /** Initialized in lcd_init_device() **/ | ||
28 | /* Is the power turned on? */ | ||
29 | static bool power_on; | ||
30 | /* Is the display turned on? */ | ||
31 | static bool display_on; | ||
32 | /* Amount of vertical offset. Used for flip offset correction/detection. */ | ||
33 | static int y_offset; | ||
34 | /* Reverse flag. Must be remembered when display is turned off. */ | ||
35 | static unsigned short disp_control_rev; | ||
36 | /* Contrast setting << 8 */ | ||
37 | static int lcd_contrast; | ||
38 | |||
39 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | ||
40 | |||
41 | /* Forward declarations */ | ||
42 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | ||
43 | static void lcd_display_off(void); | ||
44 | #endif | ||
45 | |||
46 | /* register defines for the Renesas HD66773R */ | ||
47 | #define R_START_OSC 0x00 | ||
48 | #define R_DEVICE_CODE_READ 0x00 | ||
49 | #define R_DRV_OUTPUT_CONTROL 0x01 | ||
50 | #define R_DRV_AC_CONTROL 0x02 | ||
51 | #define R_POWER_CONTROL1 0x03 | ||
52 | #define R_POWER_CONTROL2 0x04 | ||
53 | #define R_ENTRY_MODE 0x05 | ||
54 | #define R_COMPARE_REG 0x06 | ||
55 | #define R_DISP_CONTROL 0x07 | ||
56 | #define R_FRAME_CYCLE_CONTROL 0x0b | ||
57 | #define R_POWER_CONTROL3 0x0c | ||
58 | #define R_POWER_CONTROL4 0x0d | ||
59 | #define R_POWER_CONTROL5 0x0e | ||
60 | #define R_GATE_SCAN_START_POS 0x0f | ||
61 | #define R_VERT_SCROLL_CONTROL 0x11 | ||
62 | #define R_1ST_SCR_DRV_POS 0x14 | ||
63 | #define R_2ND_SCR_DRV_POS 0x15 | ||
64 | #define R_HORIZ_RAM_ADDR_POS 0x16 | ||
65 | #define R_VERT_RAM_ADDR_POS 0x17 | ||
66 | #define R_RAM_WRITE_DATA_MASK 0x20 | ||
67 | #define R_RAM_ADDR_SET 0x21 | ||
68 | #define R_WRITE_DATA_2_GRAM 0x22 | ||
69 | #define R_RAM_READ_DATA 0x22 | ||
70 | #define R_GAMMA_FINE_ADJ_POS1 0x30 | ||
71 | #define R_GAMMA_FINE_ADJ_POS2 0x31 | ||
72 | #define R_GAMMA_FINE_ADJ_POS3 0x32 | ||
73 | #define R_GAMMA_GRAD_ADJ_POS 0x33 | ||
74 | #define R_GAMMA_FINE_ADJ_NEG1 0x34 | ||
75 | #define R_GAMMA_FINE_ADJ_NEG2 0x35 | ||
76 | #define R_GAMMA_FINE_ADJ_NEG3 0x36 | ||
77 | #define R_GAMMA_GRAD_ADJ_NEG 0x37 | ||
78 | #define R_GAMMA_AMP_ADJ_POS 0x3a | ||
79 | #define R_GAMMA_AMP_ADJ_NEG 0x3b | ||
80 | |||
81 | static inline void lcd_wait_write(void) | ||
82 | { | ||
83 | while (LCD2_PORT & LCD2_BUSY_MASK); | ||
84 | } | ||
85 | |||
86 | /* Send command */ | ||
87 | static inline void lcd_send_cmd(unsigned cmd) | ||
88 | { | ||
89 | lcd_wait_write(); | ||
90 | LCD2_PORT = LCD2_CMD_MASK; /* Send MSB first (should always be 0) */ | ||
91 | lcd_wait_write(); | ||
92 | LCD2_PORT = LCD2_CMD_MASK | cmd; | ||
93 | } | ||
94 | |||
95 | /* Send 16-bit data */ | ||
96 | static inline void lcd_send_data(unsigned data) | ||
97 | { | ||
98 | lcd_wait_write(); | ||
99 | LCD2_PORT = (data >> 8) | LCD2_DATA_MASK; /* Send MSB first */ | ||
100 | lcd_wait_write(); | ||
101 | LCD2_PORT = (data & 0xff) | LCD2_DATA_MASK; | ||
102 | } | ||
103 | |||
104 | /* Send 16-bit data byte-swapped. Only needed until we can use block transfer. */ | ||
105 | static inline void lcd_send_data_swapped(unsigned v) | ||
106 | { | ||
107 | lcd_wait_write(); | ||
108 | LCD2_PORT = LCD2_DATA_MASK | (v & 0xff); /* Send LSB first */ | ||
109 | LCD2_PORT = LCD2_DATA_MASK | (v >> 8); | ||
110 | } | ||
111 | |||
112 | /* Write value to register */ | ||
113 | static void lcd_write_reg(int reg, int val) | ||
114 | { | ||
115 | lcd_send_cmd(reg); | ||
116 | lcd_send_data(val); | ||
117 | } | ||
118 | |||
119 | /*** hardware configuration ***/ | ||
120 | |||
121 | int lcd_default_contrast(void) | ||
122 | { | ||
123 | return DEFAULT_CONTRAST_SETTING; | ||
124 | } | ||
125 | |||
126 | void lcd_set_contrast(int val) | ||
127 | { | ||
128 | /* Clamp val in range 0-14, 16-30 */ | ||
129 | if (val < 1) | ||
130 | val = 0; | ||
131 | else if (val <= 15) | ||
132 | --val; | ||
133 | else if (val > 30) | ||
134 | val = 30; | ||
135 | |||
136 | lcd_contrast = val << 8; | ||
137 | |||
138 | if (!power_on) | ||
139 | return; | ||
140 | |||
141 | /* VCOMG=1, VDV4-0=xxxxx, VCM4-0=11000 */ | ||
142 | lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast); | ||
143 | } | ||
144 | |||
145 | void lcd_set_invert_display(bool yesno) | ||
146 | { | ||
147 | if (yesno == (disp_control_rev == 0x0000)) | ||
148 | return; | ||
149 | |||
150 | disp_control_rev = yesno ? 0x0000 : 0x0004; | ||
151 | |||
152 | if (!display_on) | ||
153 | return; | ||
154 | |||
155 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */ | ||
156 | lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev); | ||
157 | } | ||
158 | |||
159 | |||
160 | /* turn the display upside down (call lcd_update() afterwards) */ | ||
161 | void lcd_set_flip(bool yesno) | ||
162 | { | ||
163 | /* NOT MODIFIED FOR THE YH-925 */ | ||
164 | |||
165 | if (yesno == (y_offset != 0)) | ||
166 | return; | ||
167 | |||
168 | /* The LCD controller is 132x160 while the LCD itself is 128x160, so we need | ||
169 | * to shift the origin by 4 when we flip the LCD */ | ||
170 | y_offset = yesno ? 4 : 0; | ||
171 | |||
172 | if (!power_on) | ||
173 | return; | ||
174 | |||
175 | /* SCN4-0=000x0 (G1/G160) */ | ||
176 | lcd_write_reg(R_GATE_SCAN_START_POS, yesno ? 0x0002 : 0x0000); | ||
177 | /* SM=0, GS=x, SS=x, NL4-0=10011 (G1-G160) */ | ||
178 | lcd_write_reg(R_DRV_OUTPUT_CONTROL, yesno ? 0x0213 : 0x0113); | ||
179 | } | ||
180 | |||
181 | /* LCD init */ | ||
182 | void lcd_init_device(void) | ||
183 | { | ||
184 | #if 0 | ||
185 | /* This is the OF LCD init */ | ||
186 | int i; | ||
187 | |||
188 | DEV_EN2 |= 0x2000; | ||
189 | DEV_INIT1 |= 0xfc000000; | ||
190 | CLCD_CLOCK_SRC &= ~0xf; | ||
191 | DEV_INIT2 &= ~0x400; | ||
192 | |||
193 | GPIOF_ENABLE |= 0x4; | ||
194 | GPIOF_OUTPUT_EN |= 0x4; | ||
195 | GPIOF_OUTPUT_VAL &= ~0x4; | ||
196 | udelay(300000); | ||
197 | GPIOF_OUTPUT_VAL |= 0x4; | ||
198 | |||
199 | outl(0x220, 0x70008a00); | ||
200 | outl(0x1f00, 0x70008a04); | ||
201 | LCD2_BLOCK_CTRL = 0x10008080; | ||
202 | LCD2_BLOCK_CONFIG = 0xf00000; | ||
203 | udelay(100000); | ||
204 | |||
205 | for (i = 0; i < 8; i++) | ||
206 | { | ||
207 | lcd_send_data(0); | ||
208 | udelay(1); | ||
209 | } | ||
210 | |||
211 | lcd_write_reg(R_START_OSC, 0x0001); | ||
212 | udelay(20000); | ||
213 | lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x0315); | ||
214 | lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); | ||
215 | lcd_write_reg(R_ENTRY_MODE, 0x1028); | ||
216 | lcd_write_reg(R_COMPARE_REG, 0x0000); | ||
217 | lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4008); | ||
218 | lcd_write_reg(R_RAM_ADDR_SET, 0x0000); | ||
219 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0700); | ||
220 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0000); | ||
221 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0000); | ||
222 | lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0100); | ||
223 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0707); | ||
224 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0007); | ||
225 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0700); | ||
226 | lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0001); | ||
227 | lcd_write_reg(R_GATE_SCAN_START_POS, 0x0000); | ||
228 | lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000); | ||
229 | lcd_write_reg(R_1ST_SCR_DRV_POS, 0xaf10); | ||
230 | lcd_write_reg(R_2ND_SCR_DRV_POS, 0x0000); | ||
231 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00); /* ((LCD_HEIGHT - 1) << 8 | 0 */ | ||
232 | lcd_write_reg(R_VERT_RAM_ADDR_POS, 0xaf10); /* ((LCD_WIDTH + 16 - 1) << 8) | 16 */ | ||
233 | lcd_write_reg(R_GAMMA_AMP_ADJ_POS, 0x1600); | ||
234 | lcd_write_reg(R_GAMMA_AMP_ADJ_NEG, 0x0006); | ||
235 | lcd_write_reg(R_DISP_CONTROL, 0x0104); | ||
236 | lcd_write_reg(R_POWER_CONTROL4, 0x0100); | ||
237 | lcd_write_reg(R_POWER_CONTROL5, 0x0d18); | ||
238 | lcd_write_reg(R_POWER_CONTROL3, 0x0000); | ||
239 | udelay(50000); | ||
240 | lcd_write_reg(R_POWER_CONTROL1, 0x0008); | ||
241 | lcd_write_reg(R_POWER_CONTROL3, 0x0000); | ||
242 | lcd_write_reg(R_POWER_CONTROL2, 0x0000); | ||
243 | udelay(50000); | ||
244 | lcd_write_reg(R_POWER_CONTROL5, 0x2d18); | ||
245 | lcd_write_reg(R_POWER_CONTROL3, 0x0000); | ||
246 | udelay(50000); | ||
247 | lcd_write_reg(R_POWER_CONTROL4, 0x0110); | ||
248 | //~ lcd_clear_display(); | ||
249 | lcd_write_reg(R_DISP_CONTROL, 0x0105); | ||
250 | udelay(20000); | ||
251 | lcd_write_reg(R_DISP_CONTROL, 0x0125); | ||
252 | lcd_write_reg(R_DISP_CONTROL, 0x0127); | ||
253 | udelay(20000); | ||
254 | lcd_write_reg(R_DISP_CONTROL, 0x0137); | ||
255 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | ||
256 | |||
257 | GPIOF_ENABLE |= 0x02; | ||
258 | GPIOF_OUTPUT_EN |= 0x02; | ||
259 | GPIOF_OUTPUT_VAL |= 0x02; | ||
260 | #endif | ||
261 | |||
262 | #ifndef BOOTLOADER | ||
263 | /* The OF won't boot if this is done in the bootloader - ideally we should | ||
264 | tweak the lcd controller speed settings but this will do for now */ | ||
265 | CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */ | ||
266 | #endif | ||
267 | |||
268 | /* only these bits are needed from the OF init */ | ||
269 | lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x0215); | ||
270 | lcd_write_reg(R_ENTRY_MODE, 0x1028); | ||
271 | |||
272 | power_on = true; | ||
273 | display_on = true; | ||
274 | y_offset = 0; | ||
275 | disp_control_rev = 0x0004; | ||
276 | lcd_contrast = DEFAULT_CONTRAST_SETTING << 8; | ||
277 | } | ||
278 | |||
279 | /* THE SLEEP AND POWER FUNCTIONS HAVE NOT BEEN MODIFIED FOR THE YH-925 */ | ||
280 | |||
281 | #ifdef HAVE_LCD_SLEEP | ||
282 | static void lcd_power_on(void) | ||
283 | { | ||
284 | /* Be sure standby bit is clear. */ | ||
285 | /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=0 */ | ||
286 | lcd_write_reg(R_POWER_CONTROL1, 0x0000); | ||
287 | |||
288 | /** Power ON Sequence **/ | ||
289 | /* Per datasheet Rev.1.10, Jun.21.2003, p. 99 */ | ||
290 | |||
291 | lcd_write_reg(R_START_OSC, 0x0001); /* Start Oscillation */ | ||
292 | /* 10ms or more for oscillation circuit to stabilize */ | ||
293 | sleep(HZ/50); | ||
294 | /* Instruction (1) for power setting; VC2-0, VRH3-0, CAD, | ||
295 | VRL3-0, VCM4-0, VDV4-0 */ | ||
296 | /* VC2-0=001 */ | ||
297 | lcd_write_reg(R_POWER_CONTROL3, 0x0001); | ||
298 | /* VRL3-0=0100, PON=0, VRH3-0=0001 */ | ||
299 | lcd_write_reg(R_POWER_CONTROL4, 0x0401); | ||
300 | /* CAD=1 */ | ||
301 | lcd_write_reg(R_POWER_CONTROL2, 0x8000); | ||
302 | /* VCOMG=0, VDV4-0=xxxxx (19), VCM4-0=11000 */ | ||
303 | lcd_write_reg(R_POWER_CONTROL5, 0x0018 | lcd_contrast); | ||
304 | /* Instruction (2) for power setting; BT2-0, DC2-0, AP2-0 */ | ||
305 | /* BT2-0=000, DC2-0=001, AP2-0=011, SLP=0, STB=0 */ | ||
306 | lcd_write_reg(R_POWER_CONTROL1, 0x002c); | ||
307 | /* Instruction (3) for power setting; VCOMG = "1" */ | ||
308 | /* VCOMG=1, VDV4-0=xxxxx (19), VCM4-0=11000 */ | ||
309 | lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast); | ||
310 | |||
311 | /* 40ms or more; time for step-up circuits 1,2 to stabilize */ | ||
312 | sleep(HZ/25); | ||
313 | |||
314 | /* Instruction (4) for power setting; PON = "1" */ | ||
315 | /* VRL3-0=0100, PON=1, VRH3-0=0001 */ | ||
316 | lcd_write_reg(R_POWER_CONTROL4, 0x0411); | ||
317 | |||
318 | /* 40ms or more; time for step-up circuit 4 to stabilize */ | ||
319 | sleep(HZ/25); | ||
320 | |||
321 | /* Instructions for other mode settings (in register order). */ | ||
322 | /* SM=0, GS=x, SS=0, NL4-0=10011 (G1-G160)*/ | ||
323 | lcd_write_reg(R_DRV_OUTPUT_CONTROL, y_offset ? 0x0013 : 0x0113); /* different to X5 */ | ||
324 | /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */ | ||
325 | lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); | ||
326 | /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */ | ||
327 | lcd_write_reg(R_ENTRY_MODE, 0x1028); /* different to X5 */ | ||
328 | /* CP15-0=0000000000000000 */ | ||
329 | lcd_write_reg(R_COMPARE_REG, 0x0000); | ||
330 | /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */ | ||
331 | lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4000); | ||
332 | /* SCN4-0=000x0 (G1/G160) */ | ||
333 | /* lcd_write_reg(R_GATE_SCAN_START_POS, y_offset ? 0x0000 : 0x0002); */ | ||
334 | /* VL7-0=0x00 */ | ||
335 | lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000); | ||
336 | /* SE17-10(End)=0x9f (159), SS17-10(Start)=0x00 */ | ||
337 | lcd_write_reg(R_1ST_SCR_DRV_POS, 0x9f00); | ||
338 | /* SE27-20(End)=0x5c (92), SS27-20(Start)=0x00 */ | ||
339 | lcd_write_reg(R_2ND_SCR_DRV_POS, 0x5c00); | ||
340 | /* HEA7-0=7f, HSA7-0=00 */ | ||
341 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00); | ||
342 | /* PKP12-10=0x0, PKP02-00=0x0 */ | ||
343 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0003); | ||
344 | /* PKP32-30=0x4, PKP22-20=0x0 */ | ||
345 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0400); | ||
346 | /* PKP52-50=0x4, PKP42-40=0x7 */ | ||
347 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0407); | ||
348 | /* PRP12-10=0x3, PRP02-00=0x5 */ | ||
349 | lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0305); | ||
350 | /* PKN12-10=0x0, PKN02-00=0x3 */ | ||
351 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0003); | ||
352 | /* PKN32-30=0x7, PKN22-20=0x4 */ | ||
353 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0704); | ||
354 | /* PKN52-50=0x4, PRN42-40=0x7 */ | ||
355 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0407); | ||
356 | /* PRN12-10=0x5, PRN02-00=0x3 */ | ||
357 | lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0503); | ||
358 | /* VRP14-10=0x14, VRP03-00=0x09 */ | ||
359 | lcd_write_reg(R_GAMMA_AMP_ADJ_POS, 0x1409); | ||
360 | /* VRN14-00=0x06, VRN03-00=0x02 */ | ||
361 | lcd_write_reg(R_GAMMA_AMP_ADJ_NEG, 0x0602); | ||
362 | |||
363 | /* 100ms or more; time for step-up circuits to stabilize */ | ||
364 | sleep(HZ/10); | ||
365 | |||
366 | power_on = true; | ||
367 | } | ||
368 | |||
369 | static void lcd_power_off(void) | ||
370 | { | ||
371 | /* Display must be off first */ | ||
372 | if (display_on) | ||
373 | lcd_display_off(); | ||
374 | |||
375 | power_on = false; | ||
376 | |||
377 | /** Power OFF sequence **/ | ||
378 | /* Per datasheet Rev.1.10, Jun.21.2003, p. 99 */ | ||
379 | |||
380 | /* Step-up1 halt setting bit */ | ||
381 | /* BT2-0=110, DC2-0=001, AP2-0=011, SLP=0, STB=0 */ | ||
382 | lcd_write_reg(R_POWER_CONTROL1, 0x062c); | ||
383 | /* Step-up3,4 halt setting bit */ | ||
384 | /* VRL3-0=0100, PON=0, VRH3-0=0001 */ | ||
385 | lcd_write_reg(R_POWER_CONTROL4, 0x0401); | ||
386 | /* VCOMG=0, VDV4-0=10011, VCM4-0=11000 */ | ||
387 | lcd_write_reg(R_POWER_CONTROL5, 0x0018 | lcd_contrast); | ||
388 | |||
389 | /* Wait 100ms or more */ | ||
390 | sleep(HZ/10); | ||
391 | |||
392 | /* Step-up2,amp halt setting bit */ | ||
393 | /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=0 */ | ||
394 | lcd_write_reg(R_POWER_CONTROL1, 0x0000); | ||
395 | } | ||
396 | |||
397 | void lcd_sleep(void) | ||
398 | { | ||
399 | if (power_on) | ||
400 | lcd_power_off(); | ||
401 | |||
402 | /* Set standby mode */ | ||
403 | /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=1 */ | ||
404 | lcd_write_reg(R_POWER_CONTROL1, 0x0001); | ||
405 | } | ||
406 | #endif | ||
407 | |||
408 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | ||
409 | static void lcd_display_off(void) | ||
410 | { | ||
411 | display_on = false; | ||
412 | |||
413 | /** Display OFF sequence **/ | ||
414 | /* Per datasheet Rev.1.10, Jun.21.2003, p. 97 */ | ||
415 | |||
416 | /* EQ1-0=00 already */ | ||
417 | |||
418 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=10 */ | ||
419 | lcd_write_reg(R_DISP_CONTROL, 0x0032 | disp_control_rev); | ||
420 | |||
421 | sleep(HZ/25); /* Wait 2 frames or more */ | ||
422 | |||
423 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=10 */ | ||
424 | lcd_write_reg(R_DISP_CONTROL, 0x0022 | disp_control_rev); | ||
425 | |||
426 | sleep(HZ/25); /* Wait 2 frames or more */ | ||
427 | |||
428 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=00 */ | ||
429 | lcd_write_reg(R_DISP_CONTROL, 0x0000); | ||
430 | } | ||
431 | #endif | ||
432 | |||
433 | #if defined(HAVE_LCD_ENABLE) | ||
434 | static void lcd_display_on(void) | ||
435 | { | ||
436 | /* Be sure power is on first */ | ||
437 | if (!power_on) | ||
438 | lcd_power_on(); | ||
439 | |||
440 | /** Display ON Sequence **/ | ||
441 | /* Per datasheet Rev.1.10, Jun.21.2003, p. 97 */ | ||
442 | |||
443 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=01 */ | ||
444 | lcd_write_reg(R_DISP_CONTROL, 0x0001); | ||
445 | |||
446 | sleep(HZ/25); /* Wait 2 frames or more */ | ||
447 | |||
448 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=01 */ | ||
449 | lcd_write_reg(R_DISP_CONTROL, 0x0021 | disp_control_rev); | ||
450 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=11 */ | ||
451 | lcd_write_reg(R_DISP_CONTROL, 0x0023 | disp_control_rev); | ||
452 | |||
453 | sleep(HZ/25); /* Wait 2 frames or more */ | ||
454 | |||
455 | /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */ | ||
456 | lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev); | ||
457 | |||
458 | display_on = true; | ||
459 | } | ||
460 | |||
461 | void lcd_enable(bool on) | ||
462 | { | ||
463 | if (on == display_on) | ||
464 | return; | ||
465 | |||
466 | if (on) | ||
467 | { | ||
468 | lcd_display_on(); | ||
469 | /* Probably out of sync and we don't wanna pepper the code with | ||
470 | lcd_update() calls for this. */ | ||
471 | lcd_update(); | ||
472 | lcd_activation_call_hook(); | ||
473 | } | ||
474 | else | ||
475 | { | ||
476 | lcd_display_off(); | ||
477 | } | ||
478 | } | ||
479 | #endif | ||
480 | |||
481 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | ||
482 | bool lcd_active(void) | ||
483 | { | ||
484 | return display_on; | ||
485 | } | ||
486 | #endif | ||
487 | |||
488 | /*** update functions ***/ | ||
489 | |||
490 | void lcd_yuv_set_options(unsigned options) | ||
491 | { | ||
492 | lcd_yuv_options = options; | ||
493 | } | ||
494 | |||
495 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
496 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
497 | int width, | ||
498 | int stride); | ||
499 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
500 | int width, | ||
501 | int stride, | ||
502 | int x_screen, /* To align dither pattern */ | ||
503 | int y_screen); | ||
504 | |||
505 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
506 | void lcd_blit_yuv(unsigned char * const src[3], | ||
507 | int src_x, int src_y, int stride, | ||
508 | int x, int y, int width, int height) | ||
509 | { | ||
510 | const unsigned char *yuv_src[3]; | ||
511 | const unsigned char *ysrc_max; | ||
512 | int y0; | ||
513 | int options; | ||
514 | |||
515 | /* NOT MODIFIED FOR THE YH-925 */ | ||
516 | |||
517 | if (!display_on) | ||
518 | return; | ||
519 | |||
520 | width &= ~1; | ||
521 | height &= ~1; | ||
522 | |||
523 | /* calculate the drawing region */ | ||
524 | |||
525 | /* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin | ||
526 | * is actually the bottom left and horizontal and vertical are swapped. | ||
527 | * Rockbox expects the origin to be the top left so we need to use | ||
528 | * 127 - y instead of just y */ | ||
529 | |||
530 | /* max vert << 8 | start vert */ | ||
531 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | ||
532 | |||
533 | y0 = LCD_HEIGHT - 1 - y + y_offset; | ||
534 | |||
535 | /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=0, LG2-0=000 */ | ||
536 | lcd_write_reg(R_ENTRY_MODE, 0x1020); | ||
537 | |||
538 | yuv_src[0] = src[0] + src_y * stride + src_x; | ||
539 | yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1); | ||
540 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
541 | ysrc_max = yuv_src[0] + height * stride; | ||
542 | |||
543 | options = lcd_yuv_options; | ||
544 | |||
545 | do | ||
546 | { | ||
547 | /* max horiz << 8 | start horiz */ | ||
548 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1)); | ||
549 | |||
550 | /* position cursor (set AD0-AD15) */ | ||
551 | /* start vert << 8 | start horiz */ | ||
552 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y0); | ||
553 | |||
554 | /* start drawing */ | ||
555 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | ||
556 | |||
557 | if (options & LCD_YUV_DITHER) | ||
558 | { | ||
559 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, | ||
560 | x, y); | ||
561 | y -= 2; | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
566 | } | ||
567 | |||
568 | y0 -= 2; | ||
569 | yuv_src[0] += stride << 1; | ||
570 | yuv_src[1] += stride >> 1; | ||
571 | yuv_src[2] += stride >> 1; | ||
572 | } | ||
573 | while (yuv_src[0] < ysrc_max); | ||
574 | |||
575 | /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */ | ||
576 | lcd_write_reg(R_ENTRY_MODE, 0x1028); | ||
577 | } | ||
578 | |||
579 | |||
580 | /* Update a fraction of the display. */ | ||
581 | void lcd_update_rect(int x0, int y0, int width, int height) | ||
582 | { | ||
583 | int x1, y1; | ||
584 | int lcd_x0, lcd_x1, lcd_y0, lcd_y1; | ||
585 | unsigned short *addr; | ||
586 | |||
587 | if (!display_on) | ||
588 | return; | ||
589 | |||
590 | /* calculate the drawing region */ | ||
591 | y1 = (y0 + height) - 1; /* max vert */ | ||
592 | x1 = (x0 + width) - 1; /* max horiz */ | ||
593 | |||
594 | if(x1 >= LCD_WIDTH) | ||
595 | x1 = LCD_WIDTH - 1; | ||
596 | if (x1 <= 0) | ||
597 | return; /* nothing left to do, 0 is harmful to lcd_write_data() */ | ||
598 | if(y1 >= LCD_HEIGHT) | ||
599 | y1 = LCD_HEIGHT-1; | ||
600 | |||
601 | /* The LCD is actually 128x160 rotated 90 degrees */ | ||
602 | lcd_x0 = (LCD_HEIGHT - 1) - y1 + 4; | ||
603 | lcd_x1 = (LCD_HEIGHT - 1) - y0 + 4; | ||
604 | lcd_y0 = x0 + 16; | ||
605 | lcd_y1 = x1 + 16; | ||
606 | |||
607 | /* set the drawing window */ | ||
608 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (lcd_x1 << 8) | lcd_x0); | ||
609 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (lcd_y1 << 8) | lcd_y0); | ||
610 | |||
611 | /* set the starting position */ | ||
612 | lcd_write_reg(R_RAM_ADDR_SET, (lcd_y0 << 8) | lcd_x1); | ||
613 | |||
614 | /* start drawing */ | ||
615 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | ||
616 | |||
617 | addr = (unsigned short*)&lcd_framebuffer[y0][x0]; | ||
618 | |||
619 | int c, r; | ||
620 | |||
621 | /* for each row */ | ||
622 | for (r = 0; r < height; r++) { | ||
623 | /* for each column */ | ||
624 | for (c = 0; c < width; c++) { | ||
625 | /* output 1 pixel */ | ||
626 | lcd_send_data(*addr++); | ||
627 | } | ||
628 | |||
629 | addr += (LCD_WIDTH - width); | ||
630 | } | ||
631 | } | ||
632 | |||
633 | /* Update the display. | ||
634 | This must be called after all other LCD functions that change the display. */ | ||
635 | void lcd_update(void) | ||
636 | { | ||
637 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
638 | } | ||
diff --git a/firmware/target/arm/samsung/yh925/powermgmt-yh925.c b/firmware/target/arm/samsung/yh925/powermgmt-yh925.c new file mode 100644 index 0000000000..6d7e3487aa --- /dev/null +++ b/firmware/target/arm/samsung/yh925/powermgmt-yh925.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese | ||
11 | * Revisions copyright (C) 2005 by Gerald Van Baren | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "adc.h" | ||
25 | #include "powermgmt.h" | ||
26 | |||
27 | /* TODO: Not yet calibrated */ | ||
28 | |||
29 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
30 | { | ||
31 | 3733 | ||
32 | }; | ||
33 | |||
34 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
35 | { | ||
36 | 3627 | ||
37 | }; | ||
38 | |||
39 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
40 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
41 | { | ||
42 | { 3733, 3772, 3821, 3840, 3869, 3917, 3985, 4034, 4072, 4140, 4198 } | ||
43 | }; | ||
44 | |||
45 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
46 | const unsigned short percent_to_volt_charge[11] = | ||
47 | { | ||
48 | 3956, 3995, 4024, 4043, 4063, 4082, 4111, 4140, 4179, 4218, 4266 | ||
49 | }; | ||
50 | |||
51 | #define BATTERY_SCALE_FACTOR 4650 | ||
52 | /* full-scale ADC readout (2^10) in millivolt */ | ||
53 | |||
54 | /* Returns battery voltage from ADC [millivolts] */ | ||
55 | unsigned int battery_adc_voltage(void) | ||
56 | { | ||
57 | /* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */ | ||
58 | return 4100; | ||
59 | } | ||