summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c
new file mode 100644
index 0000000000..c9cce6d653
--- /dev/null
+++ b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c
@@ -0,0 +1,230 @@
1#include "config.h"
2#include "cpu.h"
3#include "string.h"
4#include "lcd.h"
5#include "kernel.h"
6#include "lcd-target.h"
7
8#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
9
10static volatile bool lcd_on = true;
11volatile bool lcd_poweroff = false;
12/*
13** These are imported from lcd-16bit.c
14*/
15extern unsigned fg_pattern;
16extern unsigned bg_pattern;
17
18#if 0
19bool lcd_enabled()
20{
21 return lcd_on;
22}
23#endif
24
25void printscreen(unsigned int colour) {
26 int i;
27 int base = 0x84100000;
28 for(i=0;i<(320*240*2);i++) {
29 writel(colour,base);
30 base++;
31 }
32}
33
34unsigned int LCDBANK(unsigned int address)
35{
36 return ((address >> 22) & 0xff);
37}
38
39unsigned int LCDBASEU(unsigned int address)
40{
41 return (address & ((1 << 22)-1)) >> 1;
42}
43
44unsigned int LCDBASEL(unsigned int address)
45{
46 address += 320*240*2;
47 return (address & ((1 << 22)-1)) >> 1;
48}
49
50
51/* LCD init */
52void lcd_init_device(void)
53{
54 int i;
55#ifdef BOOTLOADER
56 /* When the Rockbox bootloader starts, we are changing framebuffer address,
57 but we don't want what's shown on the LCD to change until we do an
58 lcd_update(), so copy the data from the old framebuffer to the new one */
59 unsigned short *buf = (unsigned short*)FRAME1;
60
61 memcpy(FRAME1, (short *)((LCDSADDR1)<<1), 320*240*2);
62
63 /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode
64 so convert the frambuffer data accordingly */
65 for(i=0; i< 320*240; i++){
66 *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0);
67 buf++;
68 }
69 return;
70#endif
71}
72
73/* Update a fraction of the display. */
74void lcd_update_rect(int x, int y, int width, int height)
75{
76 (void)x;
77 (void)width;
78 (void)y;
79 (void)height;
80
81 if(!lcd_on)
82 {
83 sleep(200);
84 return;
85 }
86 memcpy(((char*)FRAME2) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH)));
87}
88
89void lcd_enable(bool state)
90{
91 (void)state;
92}
93
94bool lcd_enabled(void)
95{
96 return true;
97}
98
99/* Update the display.
100 This must be called after all other LCD functions that change the display. */
101void lcd_update(void)
102{
103 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
104}
105
106void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
107 int stride, int x, int y, int width,
108 int height)
109{
110 fb_data *dst, *dst_end;
111 unsigned int transcolor;
112
113 /* nothing to draw? */
114 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
115 || (x + width <= 0) || (y + height <= 0))
116 return;
117
118 /* clipping */
119 if (x < 0)
120 {
121 width += x;
122 src_x -= x;
123 x = 0;
124 }
125 if (y < 0)
126 {
127 height += y;
128 src_y -= y;
129 y = 0;
130 }
131 if (x + width > LCD_WIDTH)
132 width = LCD_WIDTH - x;
133 if (y + height > LCD_HEIGHT)
134 height = LCD_HEIGHT - y;
135
136 src += stride * src_y + src_x; /* move starting point */
137 dst = &lcd_framebuffer[(y)][(x)];
138 dst_end = dst + height * LCD_WIDTH;
139 width *= 2;
140 stride *= 2;
141 transcolor = TRANSPARENT_COLOR;
142 asm volatile(
143 "rowstart: \n"
144 "mov r0, #0 \n"
145 "nextpixel: \n"
146 "ldrh r1, [%0, r0] \n" /* Load word src+r0 */
147 "cmp r1, %5 \n" /* Compare to transparent color */
148 "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */
149 "add r0, r0, #2 \n"
150 "cmp r0, %2 \n" /* r0 == width? */
151 "bne nextpixel \n" /* More in this row? */
152 "add %0, %0, %4 \n" /* src += stride */
153 "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */
154 "cmp %1, %3 \n"
155 "bne rowstart \n" /* if(dst != dst_end), keep going */
156 : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" );
157}
158
159/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
160extern void lcd_write_yuv420_lines(fb_data *dst,
161 unsigned char chroma_buf[LCD_HEIGHT/2*3],
162 unsigned char const * const src[3],
163 int width,
164 int stride);
165/* Performance function to blit a YUV bitmap directly to the LCD */
166/* For the Gigabeat - show it rotated */
167/* So the LCD_WIDTH is now the height */
168void lcd_yuv_blit(unsigned char * const src[3],
169 int src_x, int src_y, int stride,
170 int x, int y, int width, int height)
171{
172 /* Caches for chroma data so it only need be recaculated every other
173 line */
174 unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */
175 unsigned char const * yuv_src[3];
176 off_t z;
177
178 if (!lcd_on)
179 return;
180
181 /* Sorry, but width and height must be >= 2 or else */
182 width &= ~1;
183 height >>= 1;
184
185 fb_data *dst = (fb_data*)FRAME1 + x * LCD_WIDTH + (LCD_WIDTH - y) - 1;
186
187 z = stride*src_y;
188 yuv_src[0] = src[0] + z + src_x;
189 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
190 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
191
192 do
193 {
194 lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width,
195 stride);
196 yuv_src[0] += stride << 1; /* Skip down two luma lines */
197 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
198 yuv_src[2] += stride >> 1;
199 dst -= 2;
200 }
201 while (--height > 0);
202}
203
204void lcd_set_contrast(int val) {
205 (void) val;
206 // TODO:
207}
208
209void lcd_set_invert_display(bool yesno) {
210 (void) yesno;
211 // TODO:
212}
213
214void lcd_blit(const fb_data* data, int bx, int y, int bwidth,
215 int height, int stride)
216{
217 (void) data;
218 (void) bx;
219 (void) y;
220 (void) bwidth;
221 (void) height;
222 (void) stride;
223 //TODO:
224}
225
226void lcd_set_flip(bool yesno) {
227 (void) yesno;
228 // TODO:
229}
230