summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/samsung-ypz5/lcd-ypz5.c
diff options
context:
space:
mode:
authorLorenzo Miori <memorys60@gmail.com>2013-11-15 22:05:40 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2013-12-02 20:48:21 +0100
commit1deab739803ee768e393bba41446450a792b6410 (patch)
tree26b5a121d6a03d2f394aa285ab017b1f317caf37 /firmware/target/arm/imx233/samsung-ypz5/lcd-ypz5.c
parent15155ed10006f84c42bc435e354a16b3f391d55e (diff)
downloadrockbox-1deab739803ee768e393bba41446450a792b6410.tar.gz
rockbox-1deab739803ee768e393bba41446450a792b6410.zip
Initial commit for the YP-Z5 port
The port uses the imx233 soc, it's a STMP3650 based Samsung player Change-Id: I50b6d7e77fd292fab5ed26de87853cd5aaf9eaa4 Reviewed-on: http://gerrit.rockbox.org/490 Reviewed-by: Amaury Pouly <amaury.pouly@gmail.com>
Diffstat (limited to 'firmware/target/arm/imx233/samsung-ypz5/lcd-ypz5.c')
-rw-r--r--firmware/target/arm/imx233/samsung-ypz5/lcd-ypz5.c294
1 files changed, 294 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/samsung-ypz5/lcd-ypz5.c b/firmware/target/arm/imx233/samsung-ypz5/lcd-ypz5.c
new file mode 100644
index 0000000000..4f7d9b88b5
--- /dev/null
+++ b/firmware/target/arm/imx233/samsung-ypz5/lcd-ypz5.c
@@ -0,0 +1,294 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (c) 2013 by Lorenzo Miori
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#include <sys/types.h> /* off_t */
21#include <string.h>
22#include "cpu.h"
23#include "system.h"
24#include "backlight-target.h"
25#include "lcd.h"
26#include "lcdif-imx233.h"
27#include "clkctrl-imx233.h"
28#include "pinctrl-imx233.h"
29#include "dcp-imx233.h"
30#include "logf.h"
31#ifndef BOOTLOADER
32#include "button.h"
33#include "font.h"
34#include "action.h"
35#endif
36#include "dma-imx233.h"
37
38#include "regs/regs-lcdif.h"
39
40/**
41 * NOTE
42 * We don't know exact LCD models nor we have datasheets for them
43 * Register function are partly guessed from the values, others are guessed from other LCD
44 * drivers and others have been confirmed studying their values
45 */
46
47static enum lcd_type_t
48{
49 LCD_TYPE_ZERO = 0,
50 LCD_TYPE_ONE = 1
51} lcd_type = LCD_TYPE_ZERO;
52
53static void lcd_write_reg(uint16_t reg, uint16_t data)
54{
55 imx233_lcdif_pio_send(false, 1, &reg);
56 if(reg != 0x22)
57 imx233_lcdif_pio_send(true, 1, &data);
58}
59
60/*
61 * The two LCD types require different initialization sequences
62 */
63void lcd_init_seq(void)
64{
65 switch (lcd_type)
66 {
67 case LCD_TYPE_ZERO:
68 {
69 lcd_write_reg(0x11, 0x1f1e);
70 lcd_write_reg(0x38, 0xf0f);
71 lcd_write_reg(0x12, 0x1101);
72 lcd_write_reg(0x13, 0x808);
73 lcd_write_reg(0x14, 0x3119);
74 lcd_write_reg(0x10, 0x1a10);
75 udelay(0xc350);
76 lcd_write_reg(0x13, 0x83b);
77 udelay(0x30d40);
78 lcd_write_reg(1, 0x90c); /* Display mode */
79 lcd_write_reg(2, 0x200);
80 lcd_write_reg(3, 0x1030);
81 lcd_write_reg(7, 5);
82 lcd_write_reg(8, 0x503);
83 lcd_write_reg(11, 0);
84 lcd_write_reg(12, 0);
85 /* Gamma control */
86 lcd_write_reg(0x30, 0x606);
87 lcd_write_reg(0x31, 0x606);
88 lcd_write_reg(0x32, 0x305);
89 lcd_write_reg(0x33, 2);
90 lcd_write_reg(0x34, 0x503);
91 lcd_write_reg(0x35, 0x606);
92 lcd_write_reg(0x36, 0x606);
93 lcd_write_reg(0x37, 0x200);
94
95 lcd_write_reg(0x11, 0x1f1e);
96 lcd_write_reg(0x38, 0xf0f);
97 /* Set initial LCD limits and RAM settings */
98 lcd_write_reg(0x40, 0); //BPP ?
99 lcd_write_reg(0x42, 0x9f00);
100 lcd_write_reg(0x43, 0);
101 lcd_write_reg(0x44, 0x7f00); /* Horizontal initial refresh zone [0 - 127] */
102 lcd_write_reg(0x45, 0x9f00); /* Vertical initial refresh zone [0 - 159] */
103
104 lcd_write_reg(14, 0x13);
105 lcd_write_reg(0xa9, 0x14);
106 lcd_write_reg(0xa7, 0x30);
107 lcd_write_reg(0xa8, 0x124);
108 lcd_write_reg(0x6f, 0x1d00);
109 lcd_write_reg(0x70, 3);
110 lcd_write_reg(7, 1);
111 lcd_write_reg(0x10, 0x1a10);
112 udelay(0x9c40);
113 lcd_write_reg(7, 0x21);
114 lcd_write_reg(7, 0x23);
115 udelay(0x9c40);
116 lcd_write_reg(7, 0x37); /* Seems to be "power on" */
117 break;
118 }
119 case LCD_TYPE_ONE:
120 {
121 lcd_write_reg(0, 1);
122 udelay(0x2710);
123 lcd_write_reg(0x11, 0x171b);
124 lcd_write_reg(0x12, 0);
125 lcd_write_reg(0x13, 0x80d);
126 lcd_write_reg(0x14, 0x18);
127 lcd_write_reg(0x10, 0x1a10);
128 udelay(0xc350);
129 lcd_write_reg(0x13, 0x81d);
130 udelay(0xc350);
131 lcd_write_reg(1, 0x90c); /* Display mode */
132 lcd_write_reg(2, 0x200);
133 lcd_write_reg(3, 0x1030);
134 lcd_write_reg(7, 5);
135 lcd_write_reg(8, 0x30a);
136 lcd_write_reg(11, 4);
137 lcd_write_reg(12, 0);
138 /* Gamma control */
139 lcd_write_reg(0x30, 0x300);
140 lcd_write_reg(0x31, 0);
141 lcd_write_reg(0x32, 0);
142 lcd_write_reg(0x33, 0x404);
143 lcd_write_reg(0x34, 0x707);
144 lcd_write_reg(0x35, 0x700);
145 lcd_write_reg(0x36, 0x703);
146 lcd_write_reg(0x37, 4);
147
148 lcd_write_reg(0x38, 0);
149 /* Set initial LCD limits and RAM settings */
150 lcd_write_reg(0x40, 0);
151 lcd_write_reg(0x42, 0x9f00); /* LCD Display Start Address Register 0 */
152 lcd_write_reg(0x43, 0); /* LCD Display Start Address Register 1 */
153 lcd_write_reg(0x44, 0x7f00); /* Horizontal initial refresh zone [0 - 127] */
154 lcd_write_reg(0x45, 0x9f00); /* Vertical initial refresh zone [0 - 159] */
155
156 lcd_write_reg(7, 1);
157 udelay(0x2710);
158 lcd_write_reg(7, 0x21);
159 lcd_write_reg(7, 0x23);
160 udelay(0x2710);
161 lcd_write_reg(7, 0x1037);
162 udelay(0x2710);
163 lcd_write_reg(7, 0x35);
164 lcd_write_reg(7, 0x36);
165 lcd_write_reg(7, 0x37);
166 udelay(10000);
167 break;
168 }
169 default:
170 break;
171 }
172}
173
174static void send_update_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
175{
176 /* Set horizontal refresh zone */
177 lcd_write_reg(0x44, (x | (y + w - 1) << 0x8));
178 /* Set vertical refresh zone */
179 lcd_write_reg(0x45, (y | (y + h - 1) << 0x8));
180 lcd_write_reg(0x21, x | y << 8);
181 /* Set register index to 0x22 to write screen data. 0 is mock value */
182 lcd_write_reg(0x22, 0);
183}
184
185static void setup_lcd_pins(void)
186{
187 imx233_lcdif_setup_system_pins(16);
188 /* lcd_rd */
189 imx233_pinctrl_acquire(0, 9, "lcd rd");
190 imx233_pinctrl_set_function(0, 9, PINCTRL_FUNCTION_GPIO);
191 imx233_pinctrl_set_gpio(0, 9, false);
192 /*
193 * This pin is important to know the LCD type
194 * There are two types that require two different initialization sequences
195 */
196 /* lcd_tp */
197 imx233_pinctrl_acquire(3, 12, "lcd type");
198 imx233_pinctrl_set_function(3, 12, PINCTRL_FUNCTION_GPIO);
199 imx233_pinctrl_enable_gpio(3, 12, false);
200 /* Sense LCD Type */
201 lcd_type = imx233_pinctrl_get_gpio(3, 12) ? LCD_TYPE_ONE : LCD_TYPE_ZERO;
202}
203
204static void setup_parameters(void)
205{
206 imx233_lcdif_init();
207 imx233_lcdif_enable(true);
208 imx233_lcdif_set_word_length(16);
209 imx233_lcdif_set_data_swizzle(false);
210 imx233_lcdif_set_timings(2, 1, 1, 1);
211 BF_WR_V(LCDIF_CTRL, MODE86, 8080_MODE);
212
213 imx233_lcdif_reset_lcd(true);
214 udelay(50);
215 imx233_lcdif_reset_lcd(false);
216 udelay(10);
217 imx233_lcdif_reset_lcd(true);
218}
219
220void lcd_init_device(void)
221{
222 /* Setup interface pins */
223 setup_lcd_pins();
224 /* Set LCD parameters */
225 setup_parameters();
226 /* Send initialization sequence to LCD */
227 lcd_init_seq();
228}
229
230struct lcdif_cmd_t
231{
232 struct apb_dma_command_t dma;
233 uint32_t ctrl0;
234 uint32_t pad[4];
235} __attribute__((packed)) CACHEALIGN_ATTR;
236
237struct lcdif_cmd_t lcdif_dma;
238void lcd_update(void)
239{
240 unsigned size = LCD_WIDTH * LCD_HEIGHT * sizeof(fb_data);
241
242 send_update_rect(0,0,LCD_WIDTH,LCD_HEIGHT);
243 /* We can safely do the transfer in a single shot, since 160 * 128 * 2 < 65k,
244 * the maximum transfer size!
245 */
246 lcdif_dma.dma.cmd |= BF_OR3(APB_CHx_CMD, CMDWORDS(1), XFER_COUNT(size), COMMAND(2));
247 lcdif_dma.ctrl0 = HW_LCDIF_CTRL & ~BM_LCDIF_CTRL_COUNT;
248 lcdif_dma.ctrl0 |= BF_OR2(LCDIF_CTRL, COUNT(size/2), DATA_SELECT(1));
249 lcdif_dma.dma.buffer = FBADDR(0,0);
250 lcdif_dma.dma.cmd |= BM_APB_CHx_CMD_SEMAPHORE;
251
252 imx233_dma_start_command(APB_LCDIF, &lcdif_dma.dma);
253 imx233_dma_wait_completion(APB_LCDIF, HZ);
254}
255
256void lcd_update_rect(int x, int y, int w, int h)
257{
258 (void)x;
259 (void)y;
260 (void)w;
261 (void)h;
262 lcd_update();
263}
264
265#ifndef BOOTLOADER
266bool lcd_debug_screen(void)
267{
268 lcd_setfont(FONT_SYSFIXED);
269
270 while(1)
271 {
272 int button = get_action(CONTEXT_STD, HZ / 10);
273 switch(button)
274 {
275 case ACTION_STD_NEXT:
276 case ACTION_STD_PREV:
277 case ACTION_STD_OK:
278 case ACTION_STD_MENU:
279 lcd_setfont(FONT_UI);
280 return true;
281 case ACTION_STD_CANCEL:
282 lcd_setfont(FONT_UI);
283 return false;
284 }
285
286 lcd_clear_display();
287 lcd_putsf(0, 0, "LCD type: %d", lcd_type);
288 lcd_update();
289 yield();
290 }
291
292 return true;
293}
294#endif