summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c399
1 files changed, 399 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c b/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c
new file mode 100644
index 0000000000..532a149185
--- /dev/null
+++ b/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c
@@ -0,0 +1,399 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
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
22#include "lcd.h"
23#include "system.h"
24#include "lcd-x1000.h"
25#include "gpio-x1000.h"
26
27/* LCD controller is probably an RM68090.
28 */
29
30static const uint32_t q1_lcd_cmd_enable[] = {
31 LCD_INSTR_CMD, 0x00,
32 LCD_INSTR_CMD, 0xbe,
33 LCD_INSTR_DAT, 0xc3,
34 LCD_INSTR_DAT, 0x29,
35
36 LCD_INSTR_CMD, 0x00,
37 LCD_INSTR_CMD, 0x01,
38 LCD_INSTR_DAT, 0x01,
39 LCD_INSTR_DAT, 0x04,
40
41 LCD_INSTR_CMD, 0x00,
42 LCD_INSTR_CMD, 0x02,
43 LCD_INSTR_DAT, 0x01,
44 LCD_INSTR_DAT, 0x00,
45
46 LCD_INSTR_CMD, 0x00,
47 LCD_INSTR_CMD, 0x03,
48 LCD_INSTR_DAT, 0x00,
49 LCD_INSTR_DAT, 0x10,
50
51 LCD_INSTR_CMD, 0x00,
52 LCD_INSTR_CMD, 0x05,
53 LCD_INSTR_DAT, 0x00,
54 LCD_INSTR_DAT, 0x00,
55
56 LCD_INSTR_CMD, 0x00,
57 LCD_INSTR_CMD, 0x06,
58 LCD_INSTR_DAT, 0x00,
59 LCD_INSTR_DAT, 0x00,
60
61 LCD_INSTR_CMD, 0x00,
62 LCD_INSTR_CMD, 0x07,
63 LCD_INSTR_DAT, 0x01,
64 LCD_INSTR_DAT, 0x03,
65
66 LCD_INSTR_CMD, 0x00,
67 LCD_INSTR_CMD, 0x08,
68 LCD_INSTR_DAT, 0x03,
69 LCD_INSTR_DAT, 0x03,
70
71 LCD_INSTR_CMD, 0x00,
72 LCD_INSTR_CMD, 0x0d,
73 LCD_INSTR_DAT, 0x00,
74 LCD_INSTR_DAT, 0x00,
75
76 LCD_INSTR_CMD, 0x00,
77 LCD_INSTR_CMD, 0x10,
78 LCD_INSTR_DAT, 0x00,
79 LCD_INSTR_DAT, 0xc1,
80
81 LCD_INSTR_CMD, 0x00,
82 LCD_INSTR_CMD, 0x11,
83 LCD_INSTR_DAT, 0xb1,
84 LCD_INSTR_DAT, 0x08,
85
86 LCD_INSTR_CMD, 0x00,
87 LCD_INSTR_CMD, 0x12,
88 LCD_INSTR_DAT, 0xb1,
89 LCD_INSTR_DAT, 0x08,
90
91 LCD_INSTR_CMD, 0x00,
92 LCD_INSTR_CMD, 0x13,
93 LCD_INSTR_DAT, 0x00,
94 LCD_INSTR_DAT, 0x0f,
95
96 LCD_INSTR_CMD, 0x00,
97 LCD_INSTR_CMD, 0x14,
98 LCD_INSTR_DAT, 0x00,
99 LCD_INSTR_DAT, 0x14,
100
101 LCD_INSTR_CMD, 0x00,
102 LCD_INSTR_CMD, 0x15,
103 LCD_INSTR_DAT, 0x00,
104 LCD_INSTR_DAT, 0x04,
105
106 LCD_INSTR_CMD, 0x00,
107 LCD_INSTR_CMD, 0x16,
108 LCD_INSTR_DAT, 0x00,
109 LCD_INSTR_DAT, 0x00,
110
111 LCD_INSTR_CMD, 0x00,
112 LCD_INSTR_CMD, 0x22,
113 LCD_INSTR_DAT, 0x00,
114 LCD_INSTR_DAT, 0x00,
115
116 LCD_INSTR_CMD, 0x00,
117 LCD_INSTR_CMD, 0x23,
118 LCD_INSTR_DAT, 0x00,
119 LCD_INSTR_DAT, 0x00,
120
121 LCD_INSTR_CMD, 0x00,
122 LCD_INSTR_CMD, 0x30,
123 LCD_INSTR_DAT, 0x7c,
124 LCD_INSTR_DAT, 0x3f,
125
126 LCD_INSTR_CMD, 0x00,
127 LCD_INSTR_CMD, 0x32,
128 LCD_INSTR_DAT, 0x00,
129 LCD_INSTR_DAT, 0x00,
130
131 LCD_INSTR_CMD, 0x00,
132 LCD_INSTR_CMD, 0x70,
133 LCD_INSTR_DAT, 0x00,
134 LCD_INSTR_DAT, 0x01,
135
136 LCD_INSTR_CMD, 0x00,
137 LCD_INSTR_CMD, 0x91,
138 LCD_INSTR_DAT, 0x01,
139 LCD_INSTR_DAT, 0x00,
140
141 LCD_INSTR_CMD, 0x00,
142 LCD_INSTR_CMD, 0xe0,
143 LCD_INSTR_DAT, 0x00,
144 LCD_INSTR_DAT, 0x01,
145
146 LCD_INSTR_CMD, 0x00,
147 LCD_INSTR_CMD, 0xe1,
148 LCD_INSTR_DAT, 0x00,
149 LCD_INSTR_DAT, 0x61,
150
151 LCD_INSTR_CMD, 0x01,
152 LCD_INSTR_CMD, 0x00,
153 LCD_INSTR_DAT, 0x10,
154 LCD_INSTR_DAT, 0x30,
155
156 LCD_INSTR_CMD, 0x01,
157 LCD_INSTR_CMD, 0x01,
158 LCD_INSTR_DAT, 0xf6,
159 LCD_INSTR_DAT, 0x3f,
160
161 LCD_INSTR_CMD, 0x01,
162 LCD_INSTR_CMD, 0x02,
163 LCD_INSTR_DAT, 0x50,
164 LCD_INSTR_DAT, 0x1f,
165
166 LCD_INSTR_CMD, 0x01,
167 LCD_INSTR_CMD, 0x03,
168 LCD_INSTR_DAT, 0x00,
169 LCD_INSTR_DAT, 0x30,
170
171 LCD_INSTR_CMD, 0x01,
172 LCD_INSTR_CMD, 0x08,
173 LCD_INSTR_DAT, 0x03,
174 LCD_INSTR_DAT, 0x00,
175
176 LCD_INSTR_CMD, 0x01,
177 LCD_INSTR_CMD, 0x11,
178 LCD_INSTR_DAT, 0x00,
179 LCD_INSTR_DAT, 0x01,
180
181 LCD_INSTR_CMD, 0x01,
182 LCD_INSTR_CMD, 0x35,
183 LCD_INSTR_DAT, 0x76,
184 LCD_INSTR_DAT, 0x66,
185
186 LCD_INSTR_CMD, 0x01,
187 LCD_INSTR_CMD, 0x39,
188 LCD_INSTR_DAT, 0x00,
189 LCD_INSTR_DAT, 0x26,
190
191 LCD_INSTR_CMD, 0x04,
192 LCD_INSTR_CMD, 0x00,
193 LCD_INSTR_DAT, 0x00,
194 LCD_INSTR_DAT, 0xc7,
195
196 LCD_INSTR_CMD, 0x04,
197 LCD_INSTR_CMD, 0x01,
198 LCD_INSTR_DAT, 0x00,
199 LCD_INSTR_DAT, 0x00,
200
201 LCD_INSTR_CMD, 0x06,
202 LCD_INSTR_CMD, 0x06,
203 LCD_INSTR_DAT, 0x00,
204 LCD_INSTR_DAT, 0x00,
205
206 LCD_INSTR_CMD, 0x03,
207 LCD_INSTR_CMD, 0x00,
208 LCD_INSTR_DAT, 0x0d,
209 LCD_INSTR_DAT, 0x0e,
210
211 LCD_INSTR_CMD, 0x03,
212 LCD_INSTR_CMD, 0x01,
213 LCD_INSTR_DAT, 0x00,
214 LCD_INSTR_DAT, 0x03,
215
216 LCD_INSTR_CMD, 0x03,
217 LCD_INSTR_CMD, 0x02,
218 LCD_INSTR_DAT, 0x08,
219 LCD_INSTR_DAT, 0x08,
220
221 LCD_INSTR_CMD, 0x03,
222 LCD_INSTR_CMD, 0x03,
223 LCD_INSTR_DAT, 0x02,
224 LCD_INSTR_DAT, 0x01,
225
226 LCD_INSTR_CMD, 0x03,
227 LCD_INSTR_CMD, 0x04,
228 LCD_INSTR_DAT, 0x03,
229 LCD_INSTR_DAT, 0x01,
230
231 LCD_INSTR_CMD, 0x03,
232 LCD_INSTR_CMD, 0x05,
233 LCD_INSTR_DAT, 0x00,
234 LCD_INSTR_DAT, 0x04,
235
236 LCD_INSTR_CMD, 0x03,
237 LCD_INSTR_CMD, 0x06,
238 LCD_INSTR_DAT, 0x1b,
239 LCD_INSTR_DAT, 0x21,
240
241 LCD_INSTR_CMD, 0x03,
242 LCD_INSTR_CMD, 0x07,
243 LCD_INSTR_DAT, 0x0f,
244 LCD_INSTR_DAT, 0x0e,
245
246 LCD_INSTR_CMD, 0x03,
247 LCD_INSTR_CMD, 0x08,
248 LCD_INSTR_DAT, 0x01,
249 LCD_INSTR_DAT, 0x04,
250
251 LCD_INSTR_CMD, 0x03,
252 LCD_INSTR_CMD, 0x09,
253 LCD_INSTR_DAT, 0x08,
254 LCD_INSTR_DAT, 0x08,
255
256 LCD_INSTR_CMD, 0x03,
257 LCD_INSTR_CMD, 0x0a,
258 LCD_INSTR_DAT, 0x02,
259 LCD_INSTR_DAT, 0x01,
260
261 LCD_INSTR_CMD, 0x03,
262 LCD_INSTR_CMD, 0x0b,
263 LCD_INSTR_DAT, 0x03,
264 LCD_INSTR_DAT, 0x01,
265
266 LCD_INSTR_CMD, 0x03,
267 LCD_INSTR_CMD, 0x0c,
268 LCD_INSTR_DAT, 0x00,
269 LCD_INSTR_DAT, 0x03,
270
271 LCD_INSTR_CMD, 0x03,
272 LCD_INSTR_CMD, 0x0d,
273 LCD_INSTR_DAT, 0x31,
274 LCD_INSTR_DAT, 0x34,
275
276 /* X start */
277 LCD_INSTR_CMD, 0x02,
278 LCD_INSTR_CMD, 0x10,
279 LCD_INSTR_DAT, 0x00,
280 LCD_INSTR_DAT, 0x1e, /* 30 */
281
282 /* X end */
283 LCD_INSTR_CMD, 0x02,
284 LCD_INSTR_CMD, 0x11,
285 LCD_INSTR_DAT, 0x01,
286 LCD_INSTR_DAT, 0x85, /* 389 */
287
288 /* Y start */
289 LCD_INSTR_CMD, 0x02,
290 LCD_INSTR_CMD, 0x12,
291 LCD_INSTR_DAT, 0x00,
292 LCD_INSTR_DAT, 0x00, /* 0 */
293
294 /* Y end */
295 LCD_INSTR_CMD, 0x02,
296 LCD_INSTR_CMD, 0x13,
297 LCD_INSTR_DAT, 0x01,
298 LCD_INSTR_DAT, 0x8f, /* 399 */
299
300 /* RAM write start X? */
301 LCD_INSTR_CMD, 0x02,
302 LCD_INSTR_CMD, 0x00,
303 LCD_INSTR_DAT, 0x00,
304 LCD_INSTR_DAT, 0x1e,
305
306 /* RAM write start Y? */
307 LCD_INSTR_CMD, 0x02,
308 LCD_INSTR_CMD, 0x01,
309 LCD_INSTR_DAT, 0x00,
310 LCD_INSTR_DAT, 0x00,
311
312 LCD_INSTR_CMD, 0x00,
313 LCD_INSTR_CMD, 0x03,
314 LCD_INSTR_DAT, 0x00,
315 LCD_INSTR_DAT, 0x30,
316
317 LCD_INSTR_CMD, 0x02,
318 LCD_INSTR_CMD, 0x02,
319 LCD_INSTR_END,
320};
321
322/* NOTE this sleep mode may not be saving power, but it gets rid of the
323 * ghost image that would otherwise remain on the display */
324static const uint32_t q1_lcd_cmd_sleep[] = {
325 LCD_INSTR_CMD, 0x00,
326 LCD_INSTR_CMD, 0x10,
327 LCD_INSTR_DAT, 0x00,
328 LCD_INSTR_DAT, 0x03,
329
330 LCD_INSTR_CMD, 0x00,
331 LCD_INSTR_CMD, 0x07,
332 LCD_INSTR_DAT, 0x01,
333 LCD_INSTR_DAT, 0x01,
334
335 LCD_INSTR_END,
336};
337
338static const uint32_t q1_lcd_cmd_wake[] = {
339 LCD_INSTR_CMD, 0x00,
340 LCD_INSTR_CMD, 0x07,
341 LCD_INSTR_DAT, 0x01,
342 LCD_INSTR_DAT, 0x03,
343
344 LCD_INSTR_CMD, 0x00,
345 LCD_INSTR_CMD, 0x10,
346 LCD_INSTR_DAT, 0x00,
347 LCD_INSTR_DAT, 0xc1,
348
349 LCD_INSTR_END,
350};
351
352static const uint8_t __attribute__((aligned(64)))
353 q1_lcd_dma_wr_cmd[] = {0x02, 0x02, 0x02, 0x02};
354
355const struct lcd_tgt_config lcd_tgt_config = {
356 .bus_width = 8,
357 .cmd_width = 8,
358 .use_6800_mode = 0,
359 .use_serial = 0,
360 .clk_polarity = 0,
361 .dc_polarity = 0,
362 .wr_polarity = 1,
363 .te_enable = 0,
364 .big_endian = 1,
365 .dma_wr_cmd_buf = &q1_lcd_dma_wr_cmd,
366 .dma_wr_cmd_size = sizeof(q1_lcd_dma_wr_cmd),
367};
368
369void lcd_tgt_enable(bool enable)
370{
371 if(enable) {
372 /* power on the panel */
373 gpio_set_level(GPIO_LCD_PWR, 1);
374 gpio_set_level(GPIO_LCD_RST, 1);
375 gpio_set_level(GPIO_LCD_CE, 1);
376 gpio_set_level(GPIO_LCD_RD, 1);
377 mdelay(50);
378 gpio_set_level(GPIO_LCD_RST, 0);
379 mdelay(100);
380 gpio_set_level(GPIO_LCD_RST, 1);
381 mdelay(50);
382 gpio_set_level(GPIO_LCD_CE, 0);
383
384 /* Start the controller */
385 lcd_set_clock(X1000_CLK_MPLL, 50000000);
386 lcd_exec_commands(q1_lcd_cmd_enable);
387 } else {
388 /* FIXME: Shanling Q1 LCD power down sequence
389 * not important because we don't use it but it'd be nice to know */
390 }
391}
392
393void lcd_tgt_sleep(bool sleep)
394{
395 if(sleep)
396 lcd_exec_commands(q1_lcd_cmd_sleep);
397 else
398 lcd_exec_commands(q1_lcd_cmd_wake);
399}