Subversion Repositories freemyipod

Rev

Rev 521 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 521 Rev 560
Line -... Line 1...
-
 
1
 
1
//
2
//
2
//
3
//
3
//    Copyright 2010 TheSeven
4
//    Copyright 2010 TheSeven
4
//
5
//
5
//
6
//
Line 23... Line 24...
23
 
24
 
24
#include "global.h"
25
#include "global.h"
25
#include "thread.h"
26
#include "thread.h"
26
#include "s5l8702.h"
27
#include "s5l8702.h"
27
#include "util.h"
28
#include "util.h"
-
 
29
#include "clockgates-target.h"
28
 
30
 
29
 
31
 
30
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
32
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
31
    IDATA_ATTR __attribute__((aligned(16)));
33
    IDATA_ATTR __attribute__((aligned(16)));
32
 
34
 
33
static uint16_t lcd_color IDATA_ATTR;
35
static uint16_t lcd_color IDATA_ATTR;
34
 
36
 
35
static struct mutex lcd_mutex;
37
static struct mutex lcd_mutex IDATA_ATTR;
-
 
38
static struct wakeup lcd_wakeup IDATA_ATTR;
-
 
39
 
-
 
40
static bool lcd_dma_busy IDATA_ATTR;
-
 
41
static bool lcd_in_irq IDATA_ATTR;
36
 
42
 
37
 
43
 
38
void lcd_init()
44
void lcd_init()
39
{
45
{
-
 
46
    mutex_init(&lcd_mutex);
-
 
47
    wakeup_init(&lcd_wakeup);
-
 
48
    lcd_in_irq = false;
-
 
49
    lcd_dma_busy = true;
-
 
50
    clockgate_dma(0, 4, true);
-
 
51
    if (!(DMAC0C4CONFIG & 1))
-
 
52
    {
-
 
53
        lcd_dma_busy = false;
-
 
54
        clockgate_dma(0, 4, false);
-
 
55
    }
40
}
56
}
41
 
57
 
42
int lcd_get_width()
58
int lcd_get_width()
43
{
59
{
44
    return LCD_WIDTH;
60
    return LCD_WIDTH;
Line 80... Line 96...
80
}
96
}
81
 
97
 
82
bool displaylcd_busy() ICODE_ATTR;
98
bool displaylcd_busy() ICODE_ATTR;
83
bool displaylcd_busy()
99
bool displaylcd_busy()
84
{
100
{
85
    return DMAC0C4CONFIG & 1;
101
    return lcd_dma_busy;
86
}
102
}
87
 
103
 
88
bool displaylcd_safe()
104
bool displaylcd_safe()
89
{
105
{
-
 
106
    lcd_in_irq = true;
-
 
107
    if (!lcd_dma_busy) return true;
90
    return !(DMAC0C4CONFIG & 1);
108
    return !(DMAC0C4CONFIG & 1);
91
}
109
}
92
 
110
 
93
void displaylcd_sync() ICODE_ATTR;
111
void displaylcd_sync() ICODE_ATTR;
94
void displaylcd_sync()
112
void displaylcd_sync()
95
{
113
{
-
 
114
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
96
    while (displaylcd_busy()) sleep(100);
115
    while (displaylcd_busy()) wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
-
 
116
    mutex_unlock(&lcd_mutex);
97
}
117
}
98
 
118
 
99
void displaylcd_setup(unsigned int startx, unsigned int endx,
119
void displaylcd_setup(unsigned int startx, unsigned int endx,
100
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
120
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
101
void displaylcd_setup(unsigned int startx, unsigned int endx,
121
void displaylcd_setup(unsigned int startx, unsigned int endx,
102
                      unsigned int starty, unsigned int endy)
122
                      unsigned int starty, unsigned int endy)
103
{
123
{
104
    displaylcd_sync();
124
    if (!lcd_in_irq)
-
 
125
    {
105
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
126
        mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
-
 
127
        displaylcd_sync();
-
 
128
    }
106
    if (lcd_detect() & 2)
129
    if (lcd_detect() & 2)
107
    {
130
    {
108
        lcd_send_cmd(0x210);
131
        lcd_send_cmd(0x210);
109
        lcd_send_data(startx);
132
        lcd_send_data(startx);
110
        lcd_send_cmd(0x211);
133
        lcd_send_cmd(0x211);
Line 137... Line 160...
137
 
160
 
138
static void displaylcd_dma(void* data, int pixels, bool solid) ICODE_ATTR;
161
static void displaylcd_dma(void* data, int pixels, bool solid) ICODE_ATTR;
139
static void displaylcd_dma(void* data, int pixels, bool solid)
162
static void displaylcd_dma(void* data, int pixels, bool solid)
140
{
163
{
141
    int i;
164
    int i;
-
 
165
    lcd_dma_busy = true;
-
 
166
    clockgate_dma(0, 4, true);
142
    for (i = -1; i < (int)ARRAYLEN(lcd_lli) && pixels > 0; i++, pixels -= 0xfff)
167
    for (i = -1; i < (int)ARRAYLEN(lcd_lli) && pixels > 0; i++, pixels -= 0xfff)
143
    {
168
    {
144
        bool last = i + 1 >= ARRAYLEN(lcd_lli) || pixels <= 0xfff;
169
        bool last = i + 1 >= ARRAYLEN(lcd_lli) || pixels <= 0xfff;
145
        struct dma_lli* lli = i < 0 ? (struct dma_lli*)((int)&DMAC0C4LLI) : &lcd_lli[i];
170
        struct dma_lli* lli = i < 0 ? (struct dma_lli*)((int)&DMAC0C4LLI) : &lcd_lli[i];
146
        lli->srcaddr = data;
171
        lli->srcaddr = data;
Line 159... Line 184...
159
{
184
{
160
    int pixels = (endx - startx + 1) * (endy - starty + 1);
185
    int pixels = (endx - startx + 1) * (endy - starty + 1);
161
    if (pixels <= 0) return;
186
    if (pixels <= 0) return;
162
    displaylcd_setup(startx, endx, starty, endy);
187
    displaylcd_setup(startx, endx, starty, endy);
163
    displaylcd_dma(data, pixels, false);
188
    displaylcd_dma(data, pixels, false);
164
    mutex_unlock(&lcd_mutex);
189
    if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
165
}
190
}
166
 
191
 
167
void filllcd_native(unsigned int startx, unsigned int endx,
192
void filllcd_native(unsigned int startx, unsigned int endx,
168
                    unsigned int starty, unsigned int endy, int color)
193
                    unsigned int starty, unsigned int endy, int color)
169
{
194
{
170
    int pixels = (endx - startx + 1) * (endy - starty + 1);
195
    int pixels = (endx - startx + 1) * (endy - starty + 1);
171
    if (pixels <= 0) return;
196
    if (pixels <= 0) return;
172
    displaylcd_setup(startx, endx, starty, endy);
197
    displaylcd_setup(startx, endx, starty, endy);
173
    lcd_color = color;
198
    lcd_color = color;
174
    displaylcd_dma(&lcd_color, pixels, true);
199
    displaylcd_dma(&lcd_color, pixels, true);
175
    mutex_unlock(&lcd_mutex);
200
    if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
176
}
201
}
177
 
202
 
178
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
203
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
179
                       unsigned int height, void* data, unsigned int datax,
204
                       unsigned int height, void* data, unsigned int datax,
180
                       unsigned int datay, unsigned int stride, bool solid)
205
                       unsigned int datay, unsigned int stride, bool solid)
Line 297... Line 322...
297
}
322
}
298
 
323
 
299
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
324
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
300
{
325
{
301
    if (width * height <= 0) return;
326
    if (width * height <= 0) return;
302
    displaylcd_sync();
-
 
303
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
327
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
-
 
328
    displaylcd_sync();
304
    lcd_color = color;
329
    lcd_color = color;
305
    displaylcd_dither(x, y, width, height, &lcd_color, 0, 0, 0, true);
330
    displaylcd_dither(x, y, width, height, &lcd_color, 0, 0, 0, true);
306
    mutex_unlock(&lcd_mutex);
331
    mutex_unlock(&lcd_mutex);
307
}
332
}
308
 
333
 
Line 351... Line 376...
351
}
376
}
352
 
377
 
353
void INT_DMAC0C4()
378
void INT_DMAC0C4()
354
{
379
{
355
    DMAC0INTTCCLR = 0x10;
380
    DMAC0INTTCCLR = 0x10;
-
 
381
    lcd_in_irq = true;
-
 
382
    lcd_dma_busy = false;
-
 
383
    clockgate_dma(0, 4, false);
356
    lcdconsole_callback();
384
    lcdconsole_callback();
-
 
385
    wakeup_signal(&lcd_wakeup);
-
 
386
    lcd_in_irq = false;
357
}
387
}
358
 
388
 
359
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
389
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
360
    ICODE_ATTR __attribute__((naked, noinline));
390
    ICODE_ATTR __attribute__((naked, noinline));
361
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
391
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)