summaryrefslogtreecommitdiff
path: root/firmware/target/arm/samsung/yh820
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/samsung/yh820')
-rw-r--r--firmware/target/arm/samsung/yh820/backlight-yh820.c47
-rw-r--r--firmware/target/arm/samsung/yh820/lcd-as-yh820.S551
-rw-r--r--firmware/target/arm/samsung/yh820/lcd-yh820.c375
-rw-r--r--firmware/target/arm/samsung/yh820/powermgmt-yh820.c59
4 files changed, 1032 insertions, 0 deletions
diff --git a/firmware/target/arm/samsung/yh820/backlight-yh820.c b/firmware/target/arm/samsung/yh820/backlight-yh820.c
new file mode 100644
index 0000000000..5e2cf81e08
--- /dev/null
+++ b/firmware/target/arm/samsung/yh820/backlight-yh820.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
27void _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(GPIOB_OUTPUT_VAL, 0x2);
36}
37
38void _backlight_off(void)
39{
40 GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x2);
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/yh820/lcd-as-yh820.S b/firmware/target/arm/samsung/yh820/lcd-as-yh820.S
new file mode 100644
index 0000000000..e466624d04
--- /dev/null
+++ b/firmware/target/arm/samsung/yh820/lcd-as-yh820.S
@@ -0,0 +1,551 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jens Arnold
11 * Heavily based on lcd-as-memframe.c by Michael Sevakis
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 "cpu.h"
25
26/****************************************************************************
27 * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
28 * int width,
29 * int stride);
30 *
31 * |R| |1.000000 -0.000001 1.402000| |Y'|
32 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
33 * |B| |1.000000 1.772000 0.000000| |Pr|
34 * Scaled, normalized, rounded and tweaked to yield RGB 565:
35 * |R| |74 0 101| |Y' - 16| >> 9
36 * |G| = |74 -24 -51| |Cb - 128| >> 8
37 * |B| |74 128 0| |Cr - 128| >> 9
38 *
39 * Write four RGB565 pixels in the following order on each loop:
40 * 1 3 + > down
41 * 2 4 \/ left
42 */
43 .section .icode, "ax", %progbits
44 .align 2
45 .global lcd_write_yuv420_lines
46 .type lcd_write_yuv420_lines, %function
47lcd_write_yuv420_lines:
48 @ r0 = yuv_src
49 @ r1 = width
50 @ r2 = stride
51 stmfd sp!, { r4-r12 } @ save non-scratch
52 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
53 @ r5 = yuv_src[1] = Cb_p
54 @ r6 = yuv_src[2] = Cr_p
55 @ r0 = scratch
56 sub r2, r2, #1 @
57 mov r3, #0x70000000 @
58 orr r3, r3, #0x3000 @ r3 = LCD1_BASE
5910: @ loop line @
60 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
61 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
62 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
63 @
64 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
65 add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
66 add r7, r12, r7, asl #5 @ by one less when adding - same for all
67 @
68 sub r8, r8, #128 @ Cb -= 128
69 sub r9, r9, #128 @ Cr -= 128
70 @
71 add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
72 add r10, r10, r10, asl #4 @
73 add r10, r10, r8, asl #3 @
74 add r10, r10, r8, asl #4 @
75 @
76 add r11, r9, r9, asl #2 @ r9 = Cr*101
77 add r11, r11, r9, asl #5 @
78 add r9, r11, r9, asl #6 @
79 @
80 add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
81 mov r8, r8, asr #2 @
82 add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
83 mov r9, r9, asr #9 @
84 rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
85 mov r10, r10, asr #8 @
86 @ compute R, G, and B
87 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
88 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
89 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
90 @
91 orr r12, r0, r11 @ check if clamping is needed...
92 orr r12, r12, r7, asr #1 @ ...at all
93 cmp r12, #31 @
94 bls 15f @ no clamp @
95 cmp r0, #31 @ clamp b
96 mvnhi r0, r0, asr #31 @
97 andhi r0, r0, #31 @
98 cmp r11, #31 @ clamp r
99 mvnhi r11, r11, asr #31 @
100 andhi r11, r11, #31 @
101 cmp r7, #63 @ clamp g
102 mvnhi r7, r7, asr #31 @
103 andhi r7, r7, #63 @
10415: @ no clamp @
105 @
106 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
107 @
108 mov r11, r11, lsl #3 @
109 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
110 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1111: @ busy @
112 ldr r7, [r3] @ r7 = LCD1_BASE
113 tst r7, #LCD1_BUSY_MASK @ bridge busy?
114 bne 1b @
115 str r11, [r3, #0x10] @ send MSB
1161: @busy @
117 ldr r7, [r3] @ r7 = LCD1_BASE
118 tst r7, #LCD1_BUSY_MASK @ bridge busy?
119 bne 1b @
120 str r0, [r3, #0x10] @ send LSB
121 @
122 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
123 add r12, r7, r7, asl #2 @
124 add r7, r12, r7, asl #5 @
125 @ compute R, G, and B
126 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
127 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
128 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
129 @
130 orr r12, r0, r11 @ check if clamping is needed...
131 orr r12, r12, r7, asr #1 @ ...at all
132 cmp r12, #31 @
133 bls 15f @ no clamp @
134 cmp r0, #31 @ clamp b
135 mvnhi r0, r0, asr #31 @
136 andhi r0, r0, #31 @
137 cmp r11, #31 @ clamp r
138 mvnhi r11, r11, asr #31 @
139 andhi r11, r11, #31 @
140 cmp r7, #63 @ clamp g
141 mvnhi r7, r7, asr #31 @
142 andhi r7, r7, #63 @
14315: @ no clamp @
144 @
145 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
146 @
147 mov r11, r11, lsl #3 @
148 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
149 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1501: @ busy @
151 ldr r7, [r3] @ r7 = LCD1_BASE
152 tst r7, #LCD1_BUSY_MASK @ bridge busy?
153 bne 1b @
154 str r11, [r3, #0x10] @ send MSB
1551: @ busy @
156 ldr r7, [r3] @ r7 = LCD1_BASE
157 tst r7, #LCD1_BUSY_MASK @ bridge busy?
158 bne 1b @
159 str r0, [r3, #0x10] @ send LSB
160 @
161 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
162 add r12, r7, r7, asl #2 @
163 add r7, r12, r7, asl #5 @
164 @ compute R, G, and B
165 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
166 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
167 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
168 @
169 orr r12, r0, r11 @ check if clamping is needed...
170 orr r12, r12, r7, asr #1 @ ...at all
171 cmp r12, #31 @
172 bls 15f @ no clamp @
173 cmp r0, #31 @ clamp b
174 mvnhi r0, r0, asr #31 @
175 andhi r0, r0, #31 @
176 cmp r11, #31 @ clamp r
177 mvnhi r11, r11, asr #31 @
178 andhi r11, r11, #31 @
179 cmp r7, #63 @ clamp g
180 mvnhi r7, r7, asr #31 @
181 andhi r7, r7, #63 @
18215: @ no clamp @
183 @
184 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
185 @
186 @
187 mov r11, r11, lsl #3 @
188 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
189 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1901: @ busy @
191 ldr r7, [r3] @ r7 = LCD1_BASE
192 tst r7, #LCD1_BUSY_MASK @ bridge busy?
193 bne 1b @
194 str r11, [r3, #0x10] @ send MSB
1951: @ busy @
196 ldr r7, [r3] @ r7 = LCD1_BASE
197 tst r7, #LCD1_BUSY_MASK @ bridge busy?
198 bne 1b @
199 str r0, [r3, #0x10] @ send LSB
200 @
201 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
202 add r12, r7, r7, asl #2 @
203 add r7, r12, r7, asl #5 @
204 @ compute R, G, and B
205 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
206 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
207 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
208 @
209 orr r12, r0, r11 @ check if clamping is needed...
210 orr r12, r12, r7, asr #1 @ ...at all
211 cmp r12, #31 @
212 bls 15f @ no clamp @
213 cmp r0, #31 @ clamp b
214 mvnhi r0, r0, asr #31 @
215 andhi r0, r0, #31 @
216 cmp r11, #31 @ clamp r
217 mvnhi r11, r11, asr #31 @
218 andhi r11, r11, #31 @
219 cmp r7, #63 @ clamp g
220 mvnhi r7, r7, asr #31 @
221 andhi r7, r7, #63 @
22215: @ no clamp @
223 @
224 mov r11, r11, lsl #3 @
225 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
226 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
2271: @ busy @
228 ldr r7, [r3] @ r7 = LCD1_BASE
229 tst r7, #LCD1_BUSY_MASK @ bridge busy?
230 bne 1b @
231 str r11, [r3, #0x10] @ send MSB
2321: @ busy @
233 ldr r7, [r3] @ r7 = LCD1_BASE
234 tst r7, #LCD1_BUSY_MASK @ bridge busy?
235 bne 1b @
236 str r0, [r3, #0x10] @ send LSB
237 @
238 subs r1, r1, #2 @ subtract block from width
239 bgt 10b @ loop line @
240 @
241 ldmfd sp!, { r4-r12 } @ restore registers and return
242 bx lr @
243 .ltorg @ dump constant pool
244 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
245
246/****************************************************************************
247 * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
248 * int width,
249 * int stride,
250 * int x_screen,
251 * int y_screen);
252 *
253 * |R| |1.000000 -0.000001 1.402000| |Y'|
254 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
255 * |B| |1.000000 1.772000 0.000000| |Pr|
256 * Red scaled at twice g & b but at same precision to place it in correct
257 * bit position after multiply and leave instruction count lower.
258 * |R| |258 0 408| |Y' - 16|
259 * |G| = |149 -49 -104| |Cb - 128|
260 * |B| |149 258 0| |Cr - 128|
261 *
262 * Write four RGB565 pixels in the following order on each loop:
263 * 1 3 + > down
264 * 2 4 \/ left
265 *
266 * Kernel pattern (raw|rotated|use order):
267 * 5 3 4 2 2 6 3 7 row0 row2 > down
268 * 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
269 * 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
270 * 0 6 1 7 5 1 4 0
271 */
272 .section .icode, "ax", %progbits
273 .align 2
274 .global lcd_write_yuv420_lines_odither
275 .type lcd_write_yuv420_lines_odither, %function
276lcd_write_yuv420_lines_odither:
277 @ r0 = yuv_src
278 @ r1 = width
279 @ r2 = stride
280 @ r3 = x_screen
281 @ [sp] = y_screen
282 stmfd sp!, { r4-r12, lr } @ save non-scratch
283 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
284 @ r5 = yuv_src[1] = Cb_p
285 @ r6 = yuv_src[2] = Cr_p
286 @
287 sub r2, r2, #1 @
288 ldr r14, [sp, #40] @ Line up pattern and kernel quadrant
289 eor r14, r14, r3 @
290 and r14, r14, #0x2 @
291 mov r14, r14, lsl #6 @ 0x00 or 0x80
292 mov r3, #0x70000000 @
293 orr r3, r3, #0x3000 @ r3 = LCD1_BASE
29410: @ loop line @
295 @
296 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
297 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
298 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
299 @
300 eor r14, r14, #0x80 @ flip pattern quadrant
301 @
302 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
303 add r12, r7, r7, asl #2 @
304 add r12, r12, r12, asl #4 @
305 add r7, r12, r7, asl #6 @
306 @
307 sub r8, r8, #128 @ Cb -= 128
308 sub r9, r9, #128 @ Cr -= 128
309 @
310 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
311 add r10, r10, r8, asl #5 @
312 add r10, r10, r9, asl #3 @
313 add r10, r10, r9, asl #5 @
314 add r10, r10, r9, asl #6 @
315 @
316 mov r8, r8, asl #1 @ r8 = bu = Cb*258
317 add r8, r8, r8, asl #7 @
318 @
319 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
320 add r9, r9, r9, asl #4 @
321 mov r9, r9, asl #3 @
322 @
323 @ compute R, G, and B
324 add r0, r8, r7 @ r0 = b' = Y + bu
325 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
326 rsb r7, r10, r7 @ r7 = g' = Y + guv
327 @
328 @ r8 = bu, r9 = rv, r10 = guv
329 @
330 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
331 add r0, r12, r0, lsr #8 @
332 @
333 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
334 add r11, r12, r11, lsr #8 @
335 @
336 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
337 add r7, r12, r7, lsr #8 @
338 @
339 add r12, r14, #0x100 @
340 @
341 add r0, r0, r12 @ b = r0 + delta
342 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
343 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
344 @
345 orr r12, r0, r11, asr #1 @ check if clamping is needed...
346 orr r12, r12, r7 @ ...at all
347 movs r12, r12, asr #15 @
348 beq 15f @ no clamp @
349 movs r12, r0, asr #15 @ clamp b
350 mvnne r0, r12, lsr #15 @
351 andne r0, r0, #0x7c00 @ mask b only if clamped
352 movs r12, r11, asr #16 @ clamp r
353 mvnne r11, r12, lsr #16 @
354 movs r12, r7, asr #15 @ clamp g
355 mvnne r7, r12, lsr #15 @
35615: @ no clamp @
357 @
358 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
359 @
360
361 and r11, r11, #0xf800 @ pack pixel
362 mov r11, r11, lsr #8
363 and r7, r7, #0x7e00
364 orr r11, r11, r7, lsr #12
365 mov r7, r7, lsr#4
366 orr r0, r7, r0, lsr #10
3671: @ busy @
368 ldr r7, [r3] @ r7 = LCD1_BASE
369 tst r7, #LCD1_BUSY_MASK @ bridge busy?
370 bne 1b @
371 str r11, [r3, #0x10] @ send MSB
3721: @ busy @
373 ldr r7, [r3] @ r7 = LCD1_BASE
374 tst r7, #LCD1_BUSY_MASK @ bridge busy?
375 bne 1b @
376 str r0, [r3, #0x10] @ send LSB
377 @
378 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
379 add r12, r7, r7, asl #2 @
380 add r12, r12, r12, asl #4 @
381 add r7, r12, r7, asl #6 @
382 @ compute R, G, and B
383 add r0, r8, r7 @ r0 = b' = Y + bu
384 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
385 rsb r7, r10, r7 @ r7 = g' = Y + guv
386 @
387 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
388 add r0, r12, r0, lsr #8 @
389 @
390 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
391 add r11, r12, r11, lsr #8 @
392 @
393 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
394 add r7, r12, r7, lsr #8 @
395 @
396 add r12, r14, #0x200 @
397 @
398 add r0, r0, r12 @ b = r0 + delta
399 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
400 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
401 @
402 orr r12, r0, r11, asr #1 @ check if clamping is needed...
403 orr r12, r12, r7 @ ...at all
404 movs r12, r12, asr #15 @
405 beq 15f @ no clamp @
406 movs r12, r0, asr #15 @ clamp b
407 mvnne r0, r12, lsr #15 @
408 andne r0, r0, #0x7c00 @ mask b only if clamped
409 movs r12, r11, asr #16 @ clamp r
410 mvnne r11, r12, lsr #16 @
411 movs r12, r7, asr #15 @ clamp g
412 mvnne r7, r12, lsr #15 @
41315: @ no clamp @
414 @
415 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
416
417 and r11, r11, #0xf800 @ pack pixel
418 mov r11, r11, lsr #8
419 and r7, r7, #0x7e00
420 orr r11, r11, r7, lsr #12
421 mov r7, r7, lsr#4
422 orr r0, r7, r0, lsr #10
4231: @ busy @
424 ldr r7, [r3] @ r7 = LCD1_BASE
425 tst r7, #LCD1_BUSY_MASK @ bridge busy?
426 bne 1b @
427 str r11, [r3, #0x10] @ send MSB
4281: @ busy @
429 ldr r7, [r3] @ r7 = LCD1_BASE
430 tst r7, #LCD1_BUSY_MASK @ bridge busy?
431 bne 1b @
432 str r0, [r3, #0x10] @ send LSB
433
434 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
435 add r12, r7, r7, asl #2 @
436 add r12, r12, r12, asl #4 @
437 add r7, r12, r7, asl #6 @
438 @ compute R, G, and B
439 add r0, r8, r7 @ r0 = b' = Y + bu
440 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
441 rsb r7, r10, r7 @ r7 = g' = Y + guv
442 @
443 @ r8 = bu, r9 = rv, r10 = guv
444 @
445 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
446 add r0, r12, r0, lsr #8 @
447 @
448 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
449 add r11, r12, r11, lsr #8 @
450 @
451 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
452 add r7, r12, r7, lsr #8 @
453 @
454 add r12, r14, #0x300 @
455 @
456 add r0, r0, r12 @ b = r0 + delta
457 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
458 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
459 @
460 orr r12, r0, r11, asr #1 @ check if clamping is needed...
461 orr r12, r12, r7 @ ...at all
462 movs r12, r12, asr #15 @
463 beq 15f @ no clamp @
464 movs r12, r0, asr #15 @ clamp b
465 mvnne r0, r12, lsr #15 @
466 andne r0, r0, #0x7c00 @ mask b only if clamped
467 movs r12, r11, asr #16 @ clamp r
468 mvnne r11, r12, lsr #16 @
469 movs r12, r7, asr #15 @ clamp g
470 mvnne r7, r12, lsr #15 @
47115: @ no clamp @
472 @
473 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
474
475 and r11, r11, #0xf800 @ pack pixel
476 mov r11, r11, lsr #8
477 and r7, r7, #0x7e00
478 orr r11, r11, r7, lsr #12
479 mov r7, r7, lsr#4
480 orr r0, r7, r0, lsr #10
4811: @ busy @
482 ldr r7, [r3] @ r7 = LCD1_BASE
483 tst r7, #LCD1_BUSY_MASK @ bridge busy?
484 bne 1b @
485 str r11, [r3, #0x10] @ send MSB
4861: @ busy @
487 ldr r7, [r3] @ r7 = LCD1_BASE
488 tst r7, #LCD1_BUSY_MASK @ bridge busy?
489 bne 1b @
490 str r0, [r3, #0x10] @ send LSB
491
492 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
493 add r12, r7, r7, asl #2 @
494 add r12, r12, r12, asl #4 @
495 add r7, r12, r7, asl #6 @
496 @ compute R, G, and B
497 add r0, r8, r7 @ r0 = b' = Y + bu
498 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
499 rsb r7, r10, r7 @ r7 = g' = Y + guv
500 @
501 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
502 add r0, r12, r0, lsr #8 @
503 @
504 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
505 add r11, r12, r11, lsr #8 @
506 @
507 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
508 add r7, r12, r7, lsr #8 @
509 @
510 @ This element is zero - use r14 @
511 @
512 add r0, r0, r14 @ b = r0 + delta
513 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
514 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
515 @
516 orr r12, r0, r11, asr #1 @ check if clamping is needed...
517 orr r12, r12, r7 @ ...at all
518 movs r12, r12, asr #15 @
519 beq 15f @ no clamp @
520 movs r12, r0, asr #15 @ clamp b
521 mvnne r0, r12, lsr #15 @
522 andne r0, r0, #0x7c00 @ mask b only if clamped
523 movs r12, r11, asr #16 @ clamp r
524 mvnne r11, r12, lsr #16 @
525 movs r12, r7, asr #15 @ clamp g
526 mvnne r7, r12, lsr #15 @
52715: @ no clamp @
528
529 and r11, r11, #0xf800 @ pack pixel
530 mov r11, r11, lsr #8
531 and r7, r7, #0x7e00
532 orr r11, r11, r7, lsr #12
533 mov r7, r7, lsr#4
534 orr r0, r7, r0, lsr #10
5351: @ busy @
536 ldr r7, [r3] @ r7 = LCD1_BASE
537 tst r7, #LCD1_BUSY_MASK @ bridge busy?
538 bne 1b @
539 str r11, [r3, #0x10] @ send MSB
5401: @ busy @
541 ldr r7, [r3] @ r7 = LCD1_BASE
542 tst r7, #LCD1_BUSY_MASK @ bridge busy?
543 bne 1b @
544 str r0, [r3, #0x10] @ send LSB
545
546 subs r1, r1, #2 @ subtract block from width
547 bgt 10b @ loop line @
548 @
549 ldmfd sp!, { r4-r12, pc } @ restore registers and return
550 .ltorg @ dump constant pool
551 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/samsung/yh820/lcd-yh820.c b/firmware/target/arm/samsung/yh820/lcd-yh820.c
new file mode 100644
index 0000000000..d21f6c2854
--- /dev/null
+++ b/firmware/target/arm/samsung/yh820/lcd-yh820.c
@@ -0,0 +1,375 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Mark Arigo
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/* Display status */
28static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
29
30#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
31static bool is_lcd_enabled = true;
32#endif
33
34/* NOTE: the LCD is rotated 90 degrees */
35
36/* LCD command set for Samsung S6B33B2 */
37
38#define R_NOP 0x00
39#define R_OSCILLATION_MODE 0x02
40#define R_DRIVER_OUTPUT_MODE 0x10
41#define R_DCDC_SET 0x20
42#define R_BIAS_SET 0x22
43#define R_DCDC_CLOCK_DIV 0x24
44#define R_DCDC_AMP_ONOFF 0x26
45#define R_TEMP_COMPENSATION 0x28
46#define R_CONTRAST_CONTROL1 0x2a
47#define R_CONTRAST_CONTROL2 0x2b
48#define R_STANDBY_OFF 0x2c
49#define R_STANDBY_ON 0x2d
50#define R_DDRAM_BURST_OFF 0x2e
51#define R_DDRAM_BURST_ON 0x2f
52#define R_ADDRESSING_MODE 0x30
53#define R_ROW_VECTOR_MODE 0x32
54#define R_N_LINE_INVERSION 0x34
55#define R_FRAME_FREQ_CONTROL 0x36
56#define R_RED_PALETTE 0x38
57#define R_GREEN_PALETTE 0x3a
58#define R_BLUE_PALETTE 0x3c
59#define R_ENTRY_MODE 0x40
60#define R_X_ADDR_AREA 0x42
61#define R_Y_ADDR_AREA 0x43
62#define R_RAM_SKIP_AREA 0x45
63#define R_DISPLAY_OFF 0x50
64#define R_DISPLAY_ON 0x51
65#define R_SPEC_DISPLAY_PATTERN 0x53
66#define R_PARTIAL_DISPLAY_MODE 0x55
67#define R_PARTIAL_START_LINE 0x56
68#define R_PARTIAL_END_LINE 0x57
69#define R_AREA_SCROLL_MODE 0x59
70#define R_SCROLL_START_LINE 0x5a
71#define R_DATA_FORMAT_SELECT 0x60
72
73
74/* wait for LCD */
75static inline void lcd_wait_write(void)
76{
77 while (LCD1_CONTROL & LCD1_BUSY_MASK);
78}
79
80/* send LCD data */
81static void lcd_send_data(unsigned data)
82{
83 lcd_wait_write();
84 LCD1_DATA = data >> 8;
85 lcd_wait_write();
86 LCD1_DATA = data & 0xff;
87}
88
89/* send LCD command */
90static void lcd_send_command(unsigned cmd)
91{
92 lcd_wait_write();
93 LCD1_CMD = cmd;
94}
95
96/* LCD init */
97void lcd_init_device(void)
98{
99#if 0
100 /* This is the init sequence from the yh820 OF bootloader */
101 unsigned long tmp;
102
103 DEV_INIT1 &= ~0x3000;
104 tmp = DEV_INIT1;
105 DEV_INIT1 = tmp;
106 DEV_INIT2 &= ~0x400;
107
108 LCD1_CONTROL &= ~0x4;
109 udelay(15);
110 LCD1_CONTROL |= 0x4;
111
112 LCD1_CONTROL = 0x680;
113 LCD1_CONTROL = 0x684;
114
115 LCD1_CONTROL |= 0x1;
116 udelay(200);
117
118 lcd_send_command(R_STANDBY_OFF);
119 udelay(100000);
120
121 lcd_send_command(R_DISPLAY_OFF);
122 udelay(10000);
123
124 lcd_send_command(R_OSCILLATION_MODE);
125 lcd_send_command(0x01);
126 udelay(30000);
127
128 lcd_send_command(R_DCDC_SET);
129 lcd_send_command(0x01);
130 udelay(30000);
131
132 lcd_send_command(R_DCDC_AMP_ONOFF);
133 lcd_send_command(0x01);
134 udelay(30000);
135
136 lcd_send_command(R_DCDC_AMP_ONOFF);
137 lcd_send_command(0x09);
138 udelay(30000);
139
140 lcd_send_command(R_DCDC_AMP_ONOFF);
141 lcd_send_command(0x0b);
142 udelay(30000);
143
144 lcd_send_command(R_DCDC_AMP_ONOFF);
145 lcd_send_command(0x0f);
146 udelay(30000);
147
148 lcd_send_command(R_DCDC_CLOCK_DIV);
149 lcd_send_command(0x03);
150 udelay(10000);
151
152 lcd_send_command(R_CONTRAST_CONTROL1);
153 lcd_send_command(0x89);
154 udelay(10000);
155
156 lcd_send_command(R_TEMP_COMPENSATION);
157 lcd_send_command(0x01);
158 udelay(10000);
159
160 lcd_send_command(R_ADDRESSING_MODE);
161 lcd_send_command(0x19);
162 udelay(10000);
163
164 lcd_send_command(R_ROW_VECTOR_MODE);
165 lcd_send_command(0x00);
166 udelay(10000);
167
168 lcd_send_command(R_N_LINE_INVERSION);
169 lcd_send_command(0x8b);
170 udelay(10000);
171
172 lcd_send_command(R_ENTRY_MODE);
173 lcd_send_command(0x01);
174
175 lcd_send_command(R_DRIVER_OUTPUT_MODE);
176 lcd_send_command(0x34);
177 udelay(10000);
178
179 lcd_send_command(R_X_ADDR_AREA); /* vertical dimensions */
180 lcd_send_command(0x00); /* y1 */
181 lcd_send_command(LCD_HEIGHT - 1); /* y2 */
182
183 lcd_send_command(R_Y_ADDR_AREA); /* horizontal dimensions */
184 lcd_send_command(0x04); /* x1 + 4 */
185 lcd_send_command(LCD_WIDTH - 1 + 4); /* x2 + 4 */
186 udelay(100);
187
188 lcd_send_command(R_BIAS_SET);
189 lcd_send_command(0x01);
190
191 lcd_send_command(R_DDRAM_BURST_OFF);
192 udelay(100);
193
194 lcd_send_command(R_DISPLAY_ON);
195 udelay(30000);
196#endif
197}
198
199/*** hardware configuration ***/
200int lcd_default_contrast(void)
201{
202 return DEFAULT_CONTRAST_SETTING;
203}
204
205void lcd_set_contrast(int val)
206{
207 lcd_send_command(R_CONTRAST_CONTROL1);
208 lcd_send_command(val);
209}
210
211void lcd_set_invert_display(bool yesno)
212{
213 /* TODO: Implement lcd_set_invert_display() */
214 (void)yesno;
215}
216
217#if defined(HAVE_LCD_ENABLE)
218void lcd_enable(bool yesno)
219{
220 if (yesno == is_lcd_enabled)
221 return;
222
223 if ((is_lcd_enabled = yesno))
224 {
225 lcd_send_command(R_STANDBY_OFF);
226 lcd_send_command(R_DISPLAY_ON);
227 lcd_activation_call_hook();
228 }
229 else
230 {
231 lcd_send_command(R_STANDBY_ON);
232 }
233}
234#endif
235
236#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
237bool lcd_active(void)
238{
239 return is_lcd_enabled;
240}
241#endif
242
243#ifdef HAVE_LCD_FLIP
244/* turn the display upside down (call lcd_update() afterwards) */
245/* Note: since the lcd is rotated, this will flip horiz instead of vert */
246void lcd_set_flip(bool yesno)
247{
248 lcd_send_command(R_DRIVER_OUTPUT_MODE);
249 lcd_send_command(yesno ? 0x30 : 0x34);
250}
251#endif
252
253
254/*** update functions ***/
255
256void lcd_yuv_set_options(unsigned options)
257{
258 lcd_yuv_options = options;
259}
260
261/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
262extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
263 int width,
264 int stride);
265extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
266 int width,
267 int stride,
268 int x_screen, /* To align dither pattern */
269 int y_screen);
270/* Performance function to blit a YUV bitmap directly to the LCD */
271void lcd_blit_yuv(unsigned char * const src[3],
272 int src_x, int src_y, int stride,
273 int x, int y, int width, int height)
274{
275 unsigned char const * yuv_src[3];
276 off_t z;
277
278 /* Sorry, but width and height must be >= 2 or else */
279 width &= ~1;
280 height >>= 1;
281
282 z = stride*src_y;
283 yuv_src[0] = src[0] + z + src_x;
284 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
285 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
286
287 lcd_send_command(R_ENTRY_MODE);
288 lcd_send_command(0x03);
289
290 lcd_send_command(R_Y_ADDR_AREA);
291 lcd_send_command(x + 4);
292 lcd_send_command(x + width - 1 + 4);
293
294 if (lcd_yuv_options & LCD_YUV_DITHER)
295 {
296 do
297 {
298 lcd_send_command(R_X_ADDR_AREA);
299 lcd_send_command(y);
300 lcd_send_command(y + 1);
301
302 lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
303 yuv_src[0] += stride << 1; /* Skip down two luma lines */
304 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
305 yuv_src[2] += stride >> 1;
306 y += 2;
307 }
308 while (--height > 0);
309 }
310 else
311 {
312 do
313 {
314 lcd_send_command(R_X_ADDR_AREA);
315 lcd_send_command(y);
316 lcd_send_command(y + 1);
317
318 lcd_write_yuv420_lines(yuv_src, width, stride);
319 yuv_src[0] += stride << 1; /* Skip down two luma lines */
320 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
321 yuv_src[2] += stride >> 1;
322 y += 2;
323 }
324 while (--height > 0);
325 }
326}
327
328/* Update the display.
329 This must be called after all other LCD functions that change the display. */
330void lcd_update(void)
331{
332 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
333}
334
335/* Update a fraction of the display. */
336void lcd_update_rect(int x, int y, int width, int height)
337{
338 const fb_data *addr;
339
340 if (x + width >= LCD_WIDTH)
341 width = LCD_WIDTH - x;
342 if (y + height >= LCD_HEIGHT)
343 height = LCD_HEIGHT - y;
344
345 if ((width <= 0) || (height <= 0))
346 return; /* Nothing left to do. */
347
348 addr = &lcd_framebuffer[y][x];
349
350 if (width <= 1) {
351 lcd_send_command(R_ENTRY_MODE); /* The X end address must be larger */
352 lcd_send_command(0x03); /* that the X start address, so we */
353 lcd_send_command(R_Y_ADDR_AREA); /* switch to vertical mode for */
354 lcd_send_command(x + 4); /* single column updates and set */
355 lcd_send_command(x + 1 + 4); /* the window width to 2 */
356 } else {
357 lcd_send_command(R_ENTRY_MODE);
358 lcd_send_command(0x01);
359 lcd_send_command(R_Y_ADDR_AREA);
360 lcd_send_command(x + 4);
361 lcd_send_command(x + width - 1 + 4);
362 }
363
364 lcd_send_command(R_X_ADDR_AREA);
365 lcd_send_command(y);
366 lcd_send_command(y + height - 1);
367
368 do {
369 int w = width;
370 do {
371 lcd_send_data(*addr++);
372 } while (--w > 0);
373 addr += LCD_WIDTH - width;
374 } while (--height > 0);
375}
diff --git a/firmware/target/arm/samsung/yh820/powermgmt-yh820.c b/firmware/target/arm/samsung/yh820/powermgmt-yh820.c
new file mode 100644
index 0000000000..495590413c
--- /dev/null
+++ b/firmware/target/arm/samsung/yh820/powermgmt-yh820.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
29const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
30{
31 3695
32};
33
34const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
35{
36 3627
37};
38
39/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
40const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
41{
42 { 3695, 3714, 3772, 3791, 3811, 3850, 3908, 3985, 4024, 4111, 4198 }
43};
44
45/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
46const unsigned short percent_to_volt_charge[11] =
47{
48 3850, 3888, 3927, 3966, 4024, 4063, 4111, 4150, 4198, 4237, 4286
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] */
55unsigned int battery_adc_voltage(void)
56{
57 /* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */
58 return 4100;
59}