lcd drivers: Convert lcd_[remote_]framebuffer to a pointer
[maemo-rb.git] / firmware / target / arm / tms320dm320 / sansa-connect / lcd-sansaconnect.c
blob27eb0b407a5e5d753b6c115941fa9c8da378f9b3
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
10 * Copyright (C) 2011 by Tomasz Moń
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <sys/types.h>
23 #include "config.h"
24 #include "cpu.h"
25 #include "string.h"
26 #include "kernel.h"
27 #include "system.h"
28 #include "system-target.h"
29 #include "lcd.h"
30 #include "lcd-target.h"
31 #include "avr-sansaconnect.h"
33 extern bool lcd_on; /* lcd-memframe.c */
35 #if defined(HAVE_LCD_SLEEP)
36 void lcd_sleep(void)
38 if (lcd_on)
40 lcd_on = false;
42 avr_hid_lcm_sleep();
43 sleep(HZ/20);
45 /* disable video encoder */
46 bitclr16(&IO_VID_ENC_VMOD, 0x01);
48 sleep(HZ/20);
50 /* disable video encoder clock */
51 bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC);
55 void lcd_awake(void)
57 if (!lcd_on)
59 lcd_on = true;
61 /* enable video encoder clock */
62 bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC);
64 /* enable video encoder */
65 bitset16(&IO_VID_ENC_VMOD, 0x01);
67 avr_hid_lcm_wake();
69 send_event(LCD_EVENT_ACTIVATION, NULL);
71 lcd_update();
74 #endif
76 void lcd_init_device(void)
78 unsigned int addr;
80 /* Disable Video Encoder clock */
81 bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC);
83 /* configure GIO39, GIO34 as outputs */
84 IO_GIO_DIR2 &= ~((1 << 7) /* GIO39 */ | (1 << 2) /* GIO34 */);
86 IO_GIO_FSEL3 = (IO_GIO_FSEL3 & ~(0x300F)) |
87 (0x1000) /* GIO39 - FIELD_VENC */ |
88 (0x4); /* GIO34 - PWM1 (brightness control) */
90 /* OSD Clock = VENC Clock /2,
91 CCD clock PCLK,
92 VENC Clock from PLLA */
93 IO_CLK_SEL1 = 0x3;
95 /* Set VENC Clock Division to 11
96 OF bootloader sets division to 8, vmlinux sets it to 11 */
97 IO_CLK_DIV3 = (IO_CLK_DIV3 & ~(0x1F00)) | 0xB00;
99 /* Enable OSD clock */
100 bitset16(&IO_CLK_MOD1, CLK_MOD1_OSD);
102 /* magic values based on OF bootloader initialization */
103 /* Set DAC to powerdown mode (bit 2 to 1 in VMOD) */
104 IO_VID_ENC_VMOD = 0x2014; /* OF sets 0x2010 */
105 IO_VID_ENC_VDPRO = 0x80;
106 IO_VID_ENC_HSPLS = 0x4;
107 IO_VID_ENC_HINT = 0x4B0;
108 IO_VID_ENC_HSTART = 0x88;
109 IO_VID_ENC_HVALID = 0x3C0;
110 IO_VID_ENC_HSDLY = 0;
111 IO_VID_ENC_VSPLS = 0x2;
112 IO_VID_ENC_VINT = 0x152;
113 IO_VID_ENC_VSTART = 0x6;
114 IO_VID_ENC_VVALID = 0x140;
115 IO_VID_ENC_VSDLY = 0;
116 IO_VID_ENC_DCLKCTL = 0x3;
117 IO_VID_ENC_DCLKPTN0 = 0xC;
118 IO_VID_ENC_VDCTL = 0x6000;
119 IO_VID_ENC_SYNCTL = 0x2;
120 IO_VID_ENC_LCDOUT = 0x101;
121 IO_VID_ENC_VMOD = 0x2015; /* OF sets 0x2011 */
123 /* Copy Rockbox frame buffer to the second framebuffer */
124 lcd_update();
126 avr_hid_sync();
127 avr_hid_lcm_power_on();
129 /* set framebuffer address - OF sets RAM start address to 0x1000000 */
130 addr = ((int)FRAME-CONFIG_SDRAM_START)/32;
132 IO_OSD_OSDWINADH = addr >> 16;
133 IO_OSD_OSDWIN0ADL = addr & 0xFFFF;
135 IO_OSD_BASEPX = 0x44;
136 IO_OSD_BASEPY = 0x6;
137 IO_OSD_OSDWIN0XP = 0;
138 IO_OSD_OSDWIN0YP = 0;
139 IO_OSD_OSDWIN0XL = LCD_WIDTH*2; /* OF bootloader sets 480 */
140 IO_OSD_OSDWIN0YL = LCD_HEIGHT; /* OF bootloader sets 320 */
141 IO_OSD_OSDWIN0OFST = 0xF;
142 IO_OSD_OSDWINMD0 = 0x25FB;/* OF bootloader sets 25C3,
143 vmlinux changes this to 0x25FB */
144 IO_OSD_VIDWINMD = 0; /* disable video windows (OF sets 0x03) */
146 IO_OSD_OSDWINMD1 = 0; /* disable OSD window 1 */
148 /* Enable Video Encoder and OSD clocks */
149 bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC | CLK_MOD1_OSD);
151 /* Enable Video Encoder - RGB666, custom timing */
152 IO_VID_ENC_VMOD = 0x2015;
153 avr_hid_lcm_wake();
154 lcd_on = true;
157 #ifdef LCD_USE_DMA
158 static void dma_lcd_copy_buffer_rect(int x, int y, int width, int height)
160 char *dst, *src;
162 /* Image buffer A is 4KW, every pixel is one Word */
163 /* lines is maximum number of lines we can transfer in single run */
164 int lines = 4096/width;
165 if (lines > height)
166 lines = height;
168 /* Set source and destination addresses */
169 dst = (char*)(FRAME + LCD_WIDTH*y + x);
170 src = (char*)(FBADDR(x,y));
172 /* Flush cache to memory */
173 commit_dcache();
175 /* Addresses are relative to start of SDRAM */
176 src -= CONFIG_SDRAM_START;
177 dst -= CONFIG_SDRAM_START;
179 /* Enable Image Buffer clock */
180 bitset16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF);
182 /* Use Image Buffer A for DMA */
183 COP_BUF_MUX0 = (COP_BUF_MUX0 & 0xFFF0) | 0x0003;
185 /* Setup buffer offsets and transfer width/height */
186 COP_BUF_LOFST = width;
187 COP_DMA_XNUM = width;
188 COP_DMA_YNUM = lines;
190 /* DMA: No byte SWAP, no transformation, data bus shift down 0 bit */
191 COP_IMG_MODE &= 0xC0;
193 /* Set the start address of buffer */
194 COP_BUF_ADDR = 0x0000;
196 /* Setup SDRAM stride */
197 COP_SDEM_LOFST = LCD_WIDTH;
199 do {
200 int addr;
202 addr = (int)src;
203 addr >>= 1; /* Addresses are in 16-bit words */
205 /* Setup the registers to initiate the read from SDRAM */
206 COP_SDEM_ADDRH = addr >> 16;
207 COP_SDEM_ADDRL = addr & 0xFFFF;
209 /* Set direction and start */
210 COP_DMA_CTRL = 0x0001;
211 COP_DMA_CTRL |= 0x0002;
213 /* Wait for read to finish */
214 while (COP_DMA_CTRL & 0x02) {};
216 addr = (int)dst;
217 addr >>= 1;
219 COP_SDEM_ADDRH = addr >> 16;
220 COP_SDEM_ADDRL = addr & 0xFFFF;
222 /* Set direction and start transfer */
223 COP_DMA_CTRL = 0x0000;
224 COP_DMA_CTRL |= 0x0002;
226 /* Wait for the transfer to complete */
227 while (COP_DMA_CTRL & 0x02) {};
229 /* Decrease height, update pointers */
230 src += (LCD_WIDTH << 1)*lines;
231 dst += (LCD_WIDTH << 1)*lines;
233 height -= lines;
234 if (height < lines)
236 lines = height;
237 COP_DMA_YNUM = height;
239 } while (height > 0);
241 /* Disable Image Buffer clock */
242 bitclr16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF);
245 /* Update a fraction of the display. */
246 void lcd_update_rect(int x, int y, int width, int height)
247 __attribute__ ((section(".icode")));
248 void lcd_update_rect(int x, int y, int width, int height)
250 if (!lcd_on)
251 return;
253 if ((width | height) < 0)
254 return; /* Nothing left to do */
256 if (x + width > LCD_WIDTH)
257 width = LCD_WIDTH - x; /* Clip right */
258 if (x < 0)
259 width += x, x = 0; /* Clip left */
261 if (y + height > LCD_HEIGHT)
262 height = LCD_HEIGHT - y; /* Clip bottom */
263 if (y < 0)
264 height += y, y = 0; /* Clip top */
266 dma_lcd_copy_buffer_rect(x, y, width, height);
269 /* Update the display.
270 This must be called after all other LCD functions that change the display. */
271 void lcd_update(void) __attribute__ ((section(".icode")));
272 void lcd_update(void)
274 if (!lcd_on)
275 return;
277 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
279 #endif
281 void lcd_set_contrast(int val) {
282 (void) val;
283 // TODO:
286 void lcd_set_invert_display(bool yesno) {
287 (void) yesno;
288 // TODO:
291 void lcd_set_flip(bool yesno) {
292 (void) yesno;
293 // TODO: