Subversion Repositories freemyipod

Rev

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

Rev 683 Rev 704
Line 25... Line 25...
25
#include "global.h"
25
#include "global.h"
26
#include "thread.h"
26
#include "thread.h"
27
#include "s5l8702.h"
27
#include "s5l8702.h"
28
#include "util.h"
28
#include "util.h"
29
#include "clockgates-target.h"
29
#include "clockgates-target.h"
-
 
30
#include "lcd.h"
30
 
31
 
31
 
32
 
32
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
33
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
33
    IDATA_ATTR __attribute__((aligned(16)));
34
    IDATA_ATTR __attribute__((aligned(16)));
34
 
35
 
Line 36... Line 37...
36
 
37
 
37
static struct mutex lcd_mutex IDATA_ATTR;
38
static struct mutex lcd_mutex IDATA_ATTR;
38
static struct wakeup lcd_wakeup IDATA_ATTR;
39
static struct wakeup lcd_wakeup IDATA_ATTR;
39
 
40
 
40
static bool lcd_dma_busy IDATA_ATTR;
41
static bool lcd_dma_busy IDATA_ATTR;
41
static bool lcd_in_irq IDATA_ATTR;
-
 
42
 
42
 
43
 
43
 
44
int lcd_get_width()
44
int lcd_get_width()
45
{
45
{
46
    return LCD_WIDTH;
46
    return LCD_WIDTH;
Line 83... Line 83...
83
 
83
 
84
void lcd_init()
84
void lcd_init()
85
{
85
{
86
    mutex_init(&lcd_mutex);
86
    mutex_init(&lcd_mutex);
87
    wakeup_init(&lcd_wakeup);
87
    wakeup_init(&lcd_wakeup);
88
    lcd_in_irq = false;
-
 
89
    lcd_dma_busy = true;
88
    lcd_dma_busy = true;
90
    clockgate_dma(0, 4, true);
89
    clockgate_dma(0, 4, true);
91
    if (!(DMAC0C4CONFIG & 1))
90
    if (!(DMAC0C4CONFIG & 1))
92
    {
91
    {
93
        lcd_dma_busy = false;
92
        lcd_dma_busy = false;
Line 116... Line 115...
116
bool displaylcd_busy()
115
bool displaylcd_busy()
117
{
116
{
118
    return lcd_dma_busy;
117
    return lcd_dma_busy;
119
}
118
}
120
 
119
 
121
bool displaylcd_safe()
-
 
122
{
-
 
123
    lcd_in_irq = true;
-
 
124
    if (!lcd_dma_busy) return true;
-
 
125
    return !(DMAC0C4CONFIG & 1);
-
 
126
}
-
 
127
 
-
 
128
void displaylcd_sync() ICODE_ATTR;
120
void displaylcd_sync() ICODE_ATTR;
129
void displaylcd_sync()
121
void displaylcd_sync()
130
{
122
{
131
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
123
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
132
    while (displaylcd_busy()) wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
124
    while (displaylcd_busy()) wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
133
    mutex_unlock(&lcd_mutex);
125
    mutex_unlock(&lcd_mutex);
134
}
126
}
135
 
127
 
136
void displaylcd_setup(unsigned int startx, unsigned int endx,
128
void displaylcd_setup(unsigned int startx, unsigned int endx,
137
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
129
                      unsigned int starty, unsigned int endy, bool safe) ICODE_ATTR;
138
void displaylcd_setup(unsigned int startx, unsigned int endx,
130
void displaylcd_setup(unsigned int startx, unsigned int endx,
139
                      unsigned int starty, unsigned int endy)
131
                      unsigned int starty, unsigned int endy, bool safe)
140
{
132
{
141
    if (!lcd_in_irq)
133
    if (!safe)
142
    {
134
    {
143
        mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
135
        mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
144
        displaylcd_sync();
136
        displaylcd_sync();
145
    }
137
    }
-
 
138
    else while (DMAC0C4CONFIG & 1);
146
    if (lcd_detect() & 2)
139
    if (lcd_detect() & 2)
147
    {
140
    {
148
        lcd_send_cmd(0x210);
141
        lcd_send_cmd(0x210);
149
        lcd_send_data(startx);
142
        lcd_send_data(startx);
150
        lcd_send_cmd(0x211);
143
        lcd_send_cmd(0x211);
Line 199... Line 192...
199
void displaylcd_native(unsigned int startx, unsigned int endx,
192
void displaylcd_native(unsigned int startx, unsigned int endx,
200
                       unsigned int starty, unsigned int endy, void* data)
193
                       unsigned int starty, unsigned int endy, void* data)
201
{
194
{
202
    int pixels = (endx - startx + 1) * (endy - starty + 1);
195
    int pixels = (endx - startx + 1) * (endy - starty + 1);
203
    if (pixels <= 0) return;
196
    if (pixels <= 0) return;
-
 
197
    displaylcd_setup(startx, endx, starty, endy, false);
-
 
198
    displaylcd_dma(data, pixels, false);
-
 
199
    mutex_unlock(&lcd_mutex);
-
 
200
}
-
 
201
 
-
 
202
void displaylcd_safe_native(unsigned int startx, unsigned int endx,
-
 
203
                            unsigned int starty, unsigned int endy, void* data)
-
 
204
{
-
 
205
    int pixels = (endx - startx + 1) * (endy - starty + 1);
-
 
206
    if (pixels <= 0) return;
204
    displaylcd_setup(startx, endx, starty, endy);
207
    displaylcd_setup(startx, endx, starty, endy, true);
205
    displaylcd_dma(data, pixels, false);
208
    displaylcd_dma(data, pixels, false);
206
    if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
-
 
207
}
209
}
208
 
210
 
209
void filllcd_native(unsigned int startx, unsigned int endx,
211
void filllcd_native(unsigned int startx, unsigned int endx,
210
                    unsigned int starty, unsigned int endy, int color)
212
                    unsigned int starty, unsigned int endy, int color)
211
{
213
{
212
    int pixels = (endx - startx + 1) * (endy - starty + 1);
214
    int pixels = (endx - startx + 1) * (endy - starty + 1);
213
    if (pixels <= 0) return;
215
    if (pixels <= 0) return;
214
    displaylcd_setup(startx, endx, starty, endy);
216
    displaylcd_setup(startx, endx, starty, endy, false);
215
    lcd_color = color;
217
    lcd_color = color;
216
    displaylcd_dma(&lcd_color, pixels, true);
218
    displaylcd_dma(&lcd_color, pixels, true);
217
    if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
219
    mutex_unlock(&lcd_mutex);
218
}
220
}
219
 
221
 
220
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
222
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
221
                       unsigned int height, void* data, unsigned int datax,
223
                       unsigned int height, void* data, unsigned int datax,
222
                       unsigned int datay, unsigned int stride, bool solid)
224
                       unsigned int datay, unsigned int stride, bool solid)
Line 225... Line 227...
225
                       unsigned int height, void* data, unsigned int datax,
227
                       unsigned int height, void* data, unsigned int datax,
226
                       unsigned int datay, unsigned int stride, bool solid)
228
                       unsigned int datay, unsigned int stride, bool solid)
227
{
229
{
228
    __asm__ volatile("    muls r12, r2, r3             \n");
230
    __asm__ volatile("    muls r12, r2, r3             \n");
229
    __asm__ volatile("    bxeq lr                      \n");
231
    __asm__ volatile("    bxeq lr                      \n");
230
    __asm__ volatile("    stmfd sp!, {r2-r11,lr}       \n");
232
    __asm__ volatile("    stmfd sp!, {r1-r11,lr}       \n");
-
 
233
    __asm__ volatile("    mov r12, #0                  \n");
-
 
234
    __asm__ volatile("    str r12, [sp]                \n");
231
    __asm__ volatile("    mov r12, r2                  \n");
235
    __asm__ volatile("    mov r12, r2                  \n");
232
    __asm__ volatile("    add r8, r2, r2,lsl#1         \n");
236
    __asm__ volatile("    add r8, r2, r2,lsl#1         \n");
233
    __asm__ volatile("    add r3, r1, r3               \n");
237
    __asm__ volatile("    add r3, r1, r3               \n");
234
    __asm__ volatile("    sub r3, r3, #1               \n");
238
    __asm__ volatile("    sub r3, r3, #1               \n");
235
    __asm__ volatile("    mov r2, r1                   \n");
239
    __asm__ volatile("    mov r2, r1                   \n");
236
    __asm__ volatile("    add r1, r0, r12              \n");
240
    __asm__ volatile("    add r1, r0, r12              \n");
237
    __asm__ volatile("    sub r1, r1, #1               \n");
241
    __asm__ volatile("    sub r1, r1, #1               \n");
238
    __asm__ volatile("    bl displaylcd_setup          \n");
242
    __asm__ volatile("    bl displaylcd_setup          \n");
-
 
243
    __asm__ volatile("    add sp, sp, #4               \n");
239
    __asm__ volatile("    mov r0, r8                   \n");
244
    __asm__ volatile("    mov r0, r8                   \n");
240
    __asm__ volatile("    bl malloc                    \n");
245
    __asm__ volatile("    bl malloc                    \n");
241
    __asm__ volatile("    cmp r0, #0                   \n");
246
    __asm__ volatile("    cmp r0, #0                   \n");
242
    __asm__ volatile("    beq displaylcd_dither_unlock \n");
247
    __asm__ volatile("    beq displaylcd_dither_unlock \n");
243
    __asm__ volatile("    mov r2, r8                   \n");
248
    __asm__ volatile("    mov r2, r8                   \n");
Line 391... Line 396...
391
}
396
}
392
 
397
 
393
void INT_DMAC0C4()
398
void INT_DMAC0C4()
394
{
399
{
395
    DMAC0INTTCCLR = 0x10;
400
    DMAC0INTTCCLR = 0x10;
396
    lcd_in_irq = true;
-
 
397
    lcd_dma_busy = false;
401
    lcd_dma_busy = false;
398
    clockgate_dma(0, 4, false);
402
    clockgate_dma(0, 4, false);
399
    lcdconsole_callback();
403
    lcdconsole_callback();
400
    wakeup_signal(&lcd_wakeup);
404
    wakeup_signal(&lcd_wakeup);
401
    lcd_in_irq = false;
-
 
402
}
405
}
403
 
406
 
404
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
407
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
405
    ICODE_ATTR __attribute__((naked, noinline));
408
    ICODE_ATTR __attribute__((naked, noinline));
406
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
409
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)