blob: d7dee2036ddb96590372123d5d1f4351bf0b02b5 [file] [log] [blame]
Mark Arigo22e7bf32008-06-27 18:40:25 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Mark Arigo
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Mark Arigo22e7bf32008-06-27 18:40:25 +000016 *
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/* wait for LCD */
31static inline void lcd_wait_write(void)
32{
33 int i = 0;
34 while (LCD2_PORT & LCD2_BUSY_MASK)
35 {
36 if (i < 2000)
37 i++;
38 else
39 LCD2_PORT &= ~LCD2_BUSY_MASK;
40 }
41}
42
43/* send LCD data */
44static void lcd_send_data(unsigned data)
45{
46 lcd_wait_write();
47 LCD2_PORT = LCD2_DATA_MASK | (data & 0xff);
48}
49
50/* send LCD command */
51static void lcd_send_cmd(unsigned cmd)
52{
53 lcd_wait_write();
54 LCD2_PORT = LCD2_CMD_MASK | (cmd & 0xff);
55 lcd_wait_write();
56}
57
58static inline void lcd_send_pixel(unsigned pixel)
59{
60 lcd_send_data(pixel >> 8);
61 lcd_send_data(pixel);
62}
63
64void lcd_init_device(void)
65{
66#if 0
67 /* this sequence from the OF bootloader */
68
69 DEV_EN2 |= 0x2000;
70 outl(inl(0x70000014) & ~0xf000000, 0x70000014);
71 outl(inl(0x70000014) | 0xa000000, 0x70000014);
72 DEV_INIT1 &= 0xc000;
73 DEV_INIT1 |= 0x8000;
74 MLCD_SCLK_DIV &= ~0x800;
75 CLCD_CLOCK_SRC |= 0xc0000000;
76 DEV_INIT2 &= ~0x400;
77 outl(inl(0x7000002c) | ((1<<4)<<24), 0x7000002c);
78 DEV_INIT2 &= ~((1<<4)<<24);
79 udelay(10000);
80
81 DEV_INIT2 |= ((1<<4)<<24);
82 outl(0x220, 0x70008a00);
83 outl(0x1f00, 0x70008a04);
84 LCD2_BLOCK_CTRL = 0x10008080;
85 LCD2_BLOCK_CONFIG = 0xF00000;
86
87 GPIOJ_ENABLE |= 0x4;
88 GPIOJ_OUTPUT_VAL |= 0x4;
89 GPIOJ_OUTPUT_EN |= 0x4;
90
91 lcd_send_cmd(0x1);
92 udelay(10000);
93
94 lcd_send_cmd(0x25);
95 lcd_send_data(0x3f);
96
97 lcd_send_cmd(0x11);
98 udelay(120000);
99
100 lcd_send_cmd(0x20);
101 lcd_send_cmd(0x38);
102 lcd_send_cmd(0x13);
103
104 lcd_send_cmd(0xb4);
105 lcd_send_data(0x2);
106 lcd_send_data(0x6);
107 lcd_send_data(0x8);
108 lcd_send_data(0xd);
109
110 lcd_send_cmd(0xb5);
111 lcd_send_data(0x2);
112 lcd_send_data(0x6);
113 lcd_send_data(0x8);
114 lcd_send_data(0xd);
115
116 lcd_send_cmd(0xb6);
117 lcd_send_data(0x19);
118 lcd_send_data(0x23);
119 lcd_send_data(0x2d);
120
121 lcd_send_cmd(0xb7);
122 lcd_send_data(0x5);
123
124 lcd_send_cmd(0xba);
125 lcd_send_data(0x7);
126 lcd_send_data(0x18);
127
128 lcd_send_cmd(0x36);
129 lcd_send_data(0);
130
131 lcd_send_cmd(0x3a);
132 lcd_send_data(0x5);
133
134 lcd_send_cmd(0x2d);
135 lcd_send_data(0x1);
136 lcd_send_data(0x2);
137 lcd_send_data(0x3);
138 lcd_send_data(0x4);
139 lcd_send_data(0x5);
140 lcd_send_data(0x6);
141 lcd_send_data(0x7);
142 lcd_send_data(0x8);
143 lcd_send_data(0x9);
144 lcd_send_data(0xa);
145 lcd_send_data(0xb);
146 lcd_send_data(0xc);
147 lcd_send_data(0xd);
148 lcd_send_data(0xe);
149 lcd_send_data(0xf);
150 lcd_send_data(0x10);
151 lcd_send_data(0x11);
152 lcd_send_data(0x12);
153 lcd_send_data(0x13);
154 lcd_send_data(0x14);
155 lcd_send_data(0x15);
156 lcd_send_data(0x16);
157 lcd_send_data(0x17);
158 lcd_send_data(0x18);
159 lcd_send_data(0x19);
160 lcd_send_data(0x1a);
161 lcd_send_data(0x1b);
162 lcd_send_data(0x1c);
163 lcd_send_data(0x1d);
164 lcd_send_data(0x1e);
165 lcd_send_data(0x1f);
166 lcd_send_data(0x20);
167 lcd_send_data(0x21);
168 lcd_send_data(0x22);
169 lcd_send_data(0x23);
170 lcd_send_data(0x24);
171 lcd_send_data(0x25);
172 lcd_send_data(0x26);
173 lcd_send_data(0x27);
174 lcd_send_data(0x28);
175 lcd_send_data(0x29);
176 lcd_send_data(0x2a);
177 lcd_send_data(0x2b);
178 lcd_send_data(0x2c);
179 lcd_send_data(0x2d);
180 lcd_send_data(0x2e);
181 lcd_send_data(0x2f);
182 lcd_send_data(0x30);
183
184 lcd_send_cmd(0x29);
185#endif
186}
187
188/*** hardware configuration ***/
189int lcd_default_contrast(void)
190{
191 return DEFAULT_CONTRAST_SETTING;
192}
193
194void lcd_set_contrast(int val)
195{
196 (void)val;
197}
198
199void lcd_set_invert_display(bool yesno)
200{
201 (void)yesno;
202}
203
204/* turn the display upside down (call lcd_update() afterwards) */
205void lcd_set_flip(bool yesno)
206{
207 (void)yesno;
208}
209
210void lcd_yuv_set_options(unsigned options)
211{
212 lcd_yuv_options = options;
213}
214
215/* Performance function to blit a YUV bitmap directly to the LCD */
216void lcd_blit_yuv(unsigned char * const src[3],
217 int src_x, int src_y, int stride,
218 int x, int y, int width, int height)
219{
220 (void)src;
221 (void)src_x;
222 (void)src_y;
223 (void)stride;
224 (void)x;
225 (void)y;
226 (void)width;
227 (void)height;
228}
229
230/* Update the display.
231 This must be called after all other LCD functions that change the display. */
232void lcd_update(void)
233{
234 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
235}
236
237/* Update a fraction of the display. */
238void lcd_update_rect(int x, int y, int width, int height)
239{
240 const fb_data *addr;
241
242 if (x + width >= LCD_WIDTH)
243 width = LCD_WIDTH - x;
244 if (y + height >= LCD_HEIGHT)
245 height = LCD_HEIGHT - y;
246
247 if ((width <= 0) || (height <= 0))
248 return; /* Nothing left to do. */
249
250 addr = &lcd_framebuffer[y][x];
251
252 lcd_send_cmd(0x2a);
253 lcd_send_data(x);
254 lcd_send_data(x + width - 1);
255
256 lcd_send_cmd(0x2b);
257 lcd_send_data(y);
258 lcd_send_data(y + height - 1);
259
260 lcd_send_cmd(0x2c);
261 do {
262 int w = width;
263 do {
264 lcd_send_pixel(*addr++);
265 } while (--w > 0);
266 addr += LCD_WIDTH - width;
267 } while (--height > 0);
268}