summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c')
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
new file mode 100644
index 0000000000..1de6a8e62f
--- /dev/null
+++ b/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
@@ -0,0 +1,286 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: lcd-nano2g.c 28868 2010-12-21 06:59:17Z Buschel $
9 *
10 * Copyright (C) 2009 by Dave Chapman
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
23#include "hwcompat.h"
24#include "kernel.h"
25#include "lcd.h"
26#include "system.h"
27#include "cpu.h"
28#include "pmu-target.h"
29#include "power.h"
30
31
32#define R_HORIZ_GRAM_ADDR_SET 0x200
33#define R_VERT_GRAM_ADDR_SET 0x201
34#define R_WRITE_DATA_TO_GRAM 0x202
35#define R_HORIZ_ADDR_START_POS 0x210
36#define R_HORIZ_ADDR_END_POS 0x211
37#define R_VERT_ADDR_START_POS 0x212
38#define R_VERT_ADDR_END_POS 0x213
39
40
41/* LCD type 1 register defines */
42
43#define R_COLUMN_ADDR_SET 0x2a
44#define R_ROW_ADDR_SET 0x2b
45#define R_MEMORY_WRITE 0x2c
46
47
48/** globals **/
49
50int lcd_type; /* also needed in debug-s5l8702.c */
51
52
53static inline void s5l_lcd_write_cmd_data(int cmd, int data)
54{
55 while (LCD_STATUS & 0x10);
56 LCD_WCMD = cmd;
57
58 while (LCD_STATUS & 0x10);
59 LCD_WDATA = data;
60}
61
62static inline void s5l_lcd_write_cmd(unsigned short cmd)
63{
64 while (LCD_STATUS & 0x10);
65 LCD_WCMD = cmd;
66}
67
68static inline void s5l_lcd_write_data(unsigned short data)
69{
70 while (LCD_STATUS & 0x10);
71 LCD_WDATA = data;
72}
73
74/*** hardware configuration ***/
75
76int lcd_default_contrast(void)
77{
78 return 0x1f;
79}
80
81void lcd_set_contrast(int val)
82{
83 (void)val;
84}
85
86void lcd_set_invert_display(bool yesno)
87{
88 (void)yesno;
89}
90
91void lcd_set_flip(bool yesno)
92{
93 (void)yesno;
94}
95
96bool lcd_active(void)
97{
98 return true;
99}
100
101void lcd_shutdown(void)
102{
103 pmu_write(0x2b, 0); /* Kill the backlight, instantly. */
104 pmu_write(0x29, 0);
105
106 if (lcd_type == 3)
107 {
108 s5l_lcd_write_cmd_data(0x7, 0x172);
109 s5l_lcd_write_cmd_data(0x30, 0x3ff);
110 sleep(HZ / 10);
111 s5l_lcd_write_cmd_data(0x7, 0x120);
112 s5l_lcd_write_cmd_data(0x30, 0x0);
113 s5l_lcd_write_cmd_data(0x100, 0x780);
114 s5l_lcd_write_cmd_data(0x7, 0x0);
115 s5l_lcd_write_cmd_data(0x101, 0x260);
116 s5l_lcd_write_cmd_data(0x102, 0xa9);
117 sleep(HZ / 30);
118 s5l_lcd_write_cmd_data(0x100, 0x700);
119 s5l_lcd_write_cmd_data(0x100, 0x704);
120 }
121 else if (lcd_type == 1)
122 {
123 s5l_lcd_write_cmd(0x28);
124 s5l_lcd_write_cmd(0x10);
125 sleep(HZ / 10);
126 }
127 else
128 {
129 s5l_lcd_write_cmd(0x28);
130 sleep(HZ / 20);
131 s5l_lcd_write_cmd(0x10);
132 sleep(HZ / 20);
133 }
134}
135
136void lcd_sleep(void)
137{
138 lcd_shutdown();
139}
140
141/* LCD init */
142void lcd_init_device(void)
143{
144 /* Detect lcd type */
145 lcd_type = (PDAT6 & 0x30) >> 4;
146}
147
148/*** Update functions ***/
149
150static inline void lcd_write_pixel(fb_data pixel)
151{
152 LCD_WDATA = pixel;
153}
154
155/* Update the display.
156 This must be called after all other LCD functions that change the display. */
157void lcd_update(void) ICODE_ATTR;
158void lcd_update(void)
159{
160 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
161}
162
163/* Line write helper function. */
164extern void lcd_write_line(const fb_data *addr,
165 int pixelcount,
166 const unsigned int lcd_base_addr);
167
168/* Update a fraction of the display. */
169void lcd_update_rect(int, int, int, int) ICODE_ATTR;
170void lcd_update_rect(int x, int y, int width, int height)
171{
172 int y0, x0, y1, x1;
173 fb_data* p;
174
175 /* Both x and width need to be preprocessed due to asm optimizations */
176 x = x & ~1; /* ensure x is even */
177 width = (width + 3) & ~3; /* ensure width is a multiple of 4 */
178
179 x0 = x; /* start horiz */
180 y0 = y; /* start vert */
181 x1 = (x + width) - 1; /* max horiz */
182 y1 = (y + height) - 1; /* max vert */
183
184 if (lcd_type & 2) {
185 s5l_lcd_write_cmd_data(R_HORIZ_ADDR_START_POS, x0);
186 s5l_lcd_write_cmd_data(R_HORIZ_ADDR_END_POS, x1);
187 s5l_lcd_write_cmd_data(R_VERT_ADDR_START_POS, y0);
188 s5l_lcd_write_cmd_data(R_VERT_ADDR_END_POS, y1);
189
190 s5l_lcd_write_cmd_data(R_HORIZ_GRAM_ADDR_SET, (x1 << 8) | x0);
191 s5l_lcd_write_cmd_data(R_VERT_GRAM_ADDR_SET, (y1 << 8) | y0);
192
193 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM);
194 } else {
195 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET);
196 s5l_lcd_write_data(x0 >> 8);
197 s5l_lcd_write_data(x0 & 0xff);
198 s5l_lcd_write_data(x1 >> 8);
199 s5l_lcd_write_data(x1 & 0xff);
200
201 s5l_lcd_write_cmd(R_ROW_ADDR_SET);
202 s5l_lcd_write_data(y0 >> 8);
203 s5l_lcd_write_data(y0 & 0xff);
204 s5l_lcd_write_data(y1 >> 8);
205 s5l_lcd_write_data(y1 & 0xff);
206
207 s5l_lcd_write_cmd(R_MEMORY_WRITE);
208 }
209 for (y = y0; y <= y1; y++)
210 for (x = x0; x <= x1; x++)
211 s5l_lcd_write_data(lcd_framebuffer[y][x]);
212 return;
213
214 /* Copy display bitmap to hardware */
215 p = &lcd_framebuffer[y0][x0];
216 if (LCD_WIDTH == width) {
217 /* Write all lines at once */
218 lcd_write_line(p, height*LCD_WIDTH, LCD_BASE);
219 } else {
220 y1 = height;
221 do {
222 /* Write a single line */
223 lcd_write_line(p, width, LCD_BASE);
224 p += LCD_WIDTH;
225 } while (--y1 > 0 );
226 }
227}
228
229/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
230extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
231 const unsigned int lcd_baseadress,
232 int width,
233 int stride);
234
235/* Blit a YUV bitmap directly to the LCD */
236void lcd_blit_yuv(unsigned char * const src[3],
237 int src_x, int src_y, int stride,
238 int x, int y, int width, int height)
239{
240 unsigned int z, y0, x0, y1, x1;;
241 unsigned char const * yuv_src[3];
242
243 width = (width + 1) & ~1; /* ensure width is even */
244
245 x0 = x; /* start horiz */
246 y0 = y; /* start vert */
247 x1 = (x + width) - 1; /* max horiz */
248 y1 = (y + height) - 1; /* max vert */
249
250 if (lcd_type & 2) {
251 s5l_lcd_write_cmd_data(R_HORIZ_ADDR_START_POS, x0);
252 s5l_lcd_write_cmd_data(R_HORIZ_ADDR_END_POS, x1);
253 s5l_lcd_write_cmd_data(R_VERT_ADDR_START_POS, y0);
254 s5l_lcd_write_cmd_data(R_VERT_ADDR_END_POS, y1);
255
256 s5l_lcd_write_cmd_data(R_HORIZ_GRAM_ADDR_SET, (x1 << 8) | x0);
257 s5l_lcd_write_cmd_data(R_VERT_GRAM_ADDR_SET, (y1 << 8) | y0);
258
259 s5l_lcd_write_cmd(0);
260 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM);
261 } else {
262 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET);
263 s5l_lcd_write_data(x0); /* Start column */
264 s5l_lcd_write_data(x1); /* End column */
265
266 s5l_lcd_write_cmd(R_ROW_ADDR_SET);
267 s5l_lcd_write_data(y0); /* Start row */
268 s5l_lcd_write_data(y1); /* End row */
269
270 s5l_lcd_write_cmd(R_MEMORY_WRITE);
271 }
272
273 z = stride * src_y;
274 yuv_src[0] = src[0] + z + src_x;
275 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
276 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
277
278 height >>= 1;
279
280 do {
281 lcd_write_yuv420_lines(yuv_src, LCD_BASE, width, stride);
282 yuv_src[0] += stride << 1;
283 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
284 yuv_src[2] += stride >> 1;
285 } while (--height > 0);
286}