Subversion Repositories freemyipod

Rev

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

Rev 650 Rev 704
Line 24... Line 24...
24
#include "global.h"
24
#include "global.h"
25
#include "thread.h"
25
#include "thread.h"
26
#include "s5l8720.h"
26
#include "s5l8720.h"
27
#include "util.h"
27
#include "util.h"
28
#include "clockgates-target.h"
28
#include "clockgates-target.h"
-
 
29
#include "lcd.h"
29
 
30
 
30
 
31
 
31
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]
32
    IDATA_ATTR __attribute__((aligned(16)));
33
    IDATA_ATTR __attribute__((aligned(16)));
33
 
34
 
Line 35... Line 36...
35
 
36
 
36
static struct mutex lcd_mutex IDATA_ATTR;
37
static struct mutex lcd_mutex IDATA_ATTR;
37
static struct wakeup lcd_wakeup IDATA_ATTR;
38
static struct wakeup lcd_wakeup IDATA_ATTR;
38
 
39
 
39
static bool lcd_dma_busy IDATA_ATTR;
40
static bool lcd_dma_busy IDATA_ATTR;
40
static bool lcd_in_irq IDATA_ATTR;
-
 
41
 
41
 
42
 
42
 
43
void lcd_init()
43
void lcd_init()
44
{
44
{
45
    mutex_init(&lcd_mutex);
45
    mutex_init(&lcd_mutex);
46
    wakeup_init(&lcd_wakeup);
46
    wakeup_init(&lcd_wakeup);
47
    lcd_in_irq = false;
-
 
48
    lcd_dma_busy = true;
47
    lcd_dma_busy = true;
49
    clockgate_dma(0, 4, true);
48
    clockgate_dma(0, 4, true);
50
    if (!(DMAC0C4CONFIG & 1))
49
    if (!(DMAC0C4CONFIG & 1))
51
    {
50
    {
52
        lcd_dma_busy = false;
51
        lcd_dma_busy = false;
Line 96... Line 95...
96
bool displaylcd_busy()
95
bool displaylcd_busy()
97
{
96
{
98
    return lcd_dma_busy;
97
    return lcd_dma_busy;
99
}
98
}
100
 
99
 
101
bool displaylcd_safe()
-
 
102
{
-
 
103
    lcd_in_irq = true;
-
 
104
    if (!lcd_dma_busy) return true;
-
 
105
    return !(DMAC0C4CONFIG & 1);
-
 
106
}
-
 
107
 
-
 
108
void displaylcd_sync() ICODE_ATTR;
100
void displaylcd_sync() ICODE_ATTR;
109
void displaylcd_sync()
101
void displaylcd_sync()
110
{
102
{
111
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
103
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
112
    while (displaylcd_busy()) wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
104
    while (displaylcd_busy()) wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
113
    mutex_unlock(&lcd_mutex);
105
    mutex_unlock(&lcd_mutex);
114
}
106
}
115
 
107
 
116
void displaylcd_setup(unsigned int startx, unsigned int endx,
108
void displaylcd_setup(unsigned int startx, unsigned int endx,
117
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
109
                      unsigned int starty, unsigned int endy, bool safe) ICODE_ATTR;
118
void displaylcd_setup(unsigned int startx, unsigned int endx,
110
void displaylcd_setup(unsigned int startx, unsigned int endx,
119
                      unsigned int starty, unsigned int endy)
111
                      unsigned int starty, unsigned int endy, bool safe)
120
{
112
{
121
    if (!lcd_in_irq)
113
    if (!safe)
122
    {
114
    {
123
        mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
115
        mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
124
        displaylcd_sync();
116
        displaylcd_sync();
125
    }
117
    }
-
 
118
    else while (DMAC0C4CONFIG & 1);
126
    lcd_send_cmd(0x2a);
119
    lcd_send_cmd(0x2a);
127
    lcd_send_data(startx);
120
    lcd_send_data(startx);
128
    lcd_send_data(endx);
121
    lcd_send_data(endx);
129
    lcd_send_cmd(0x2b);
122
    lcd_send_cmd(0x2b);
130
    lcd_send_data(starty);
123
    lcd_send_data(starty);
Line 156... Line 149...
156
void displaylcd_native(unsigned int startx, unsigned int endx,
149
void displaylcd_native(unsigned int startx, unsigned int endx,
157
                       unsigned int starty, unsigned int endy, void* data)
150
                       unsigned int starty, unsigned int endy, void* data)
158
{
151
{
159
    int pixels = (endx - startx + 1) * (endy - starty + 1);
152
    int pixels = (endx - startx + 1) * (endy - starty + 1);
160
    if (pixels <= 0) return;
153
    if (pixels <= 0) return;
-
 
154
    displaylcd_setup(startx, endx, starty, endy, false);
-
 
155
    displaylcd_dma(data, pixels, false);
-
 
156
    mutex_unlock(&lcd_mutex);
-
 
157
}
-
 
158
 
-
 
159
void displaylcd_safe_native(unsigned int startx, unsigned int endx,
-
 
160
                       unsigned int starty, unsigned int endy, void* data)
-
 
161
{
-
 
162
    int pixels = (endx - startx + 1) * (endy - starty + 1);
-
 
163
    if (pixels <= 0) return;
161
    displaylcd_setup(startx, endx, starty, endy);
164
    displaylcd_setup(startx, endx, starty, endy, true);
162
    displaylcd_dma(data, pixels, false);
165
    displaylcd_dma(data, pixels, false);
163
    if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
-
 
164
}
166
}
165
 
167
 
166
void filllcd_native(unsigned int startx, unsigned int endx,
168
void filllcd_native(unsigned int startx, unsigned int endx,
167
                    unsigned int starty, unsigned int endy, int color)
169
                    unsigned int starty, unsigned int endy, int color)
168
{
170
{
169
    int pixels = (endx - startx + 1) * (endy - starty + 1);
171
    int pixels = (endx - startx + 1) * (endy - starty + 1);
170
    if (pixels <= 0) return;
172
    if (pixels <= 0) return;
171
    displaylcd_setup(startx, endx, starty, endy);
173
    displaylcd_setup(startx, endx, starty, endy, false);
172
    lcd_color = color;
174
    lcd_color = color;
173
    displaylcd_dma(&lcd_color, pixels, true);
175
    displaylcd_dma(&lcd_color, pixels, true);
174
    if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
176
    mutex_unlock(&lcd_mutex);
175
}
177
}
176
 
178
 
177
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
179
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
178
                       unsigned int height, void* data, unsigned int datax,
180
                       unsigned int height, void* data, unsigned int datax,
179
                       unsigned int datay, unsigned int stride, bool solid)
181
                       unsigned int datay, unsigned int stride, bool solid)
Line 183... Line 185...
183
                       unsigned int datay, unsigned int stride, bool solid)
185
                       unsigned int datay, unsigned int stride, bool solid)
184
{
186
{
185
//TODO: This is ARMv5E optimized assembly, should be converted to ARMv6
187
//TODO: This is ARMv5E optimized assembly, should be converted to ARMv6
186
    __asm__ volatile("    muls r12, r2, r3             \n");
188
    __asm__ volatile("    muls r12, r2, r3             \n");
187
    __asm__ volatile("    bxeq lr                      \n");
189
    __asm__ volatile("    bxeq lr                      \n");
188
    __asm__ volatile("    stmfd sp!, {r2-r11,lr}       \n");
190
    __asm__ volatile("    stmfd sp!, {r1-r11,lr}       \n");
-
 
191
    __asm__ volatile("    mov r12, #0                  \n");
-
 
192
    __asm__ volatile("    str r12, [sp]                \n");
189
    __asm__ volatile("    mov r12, r2                  \n");
193
    __asm__ volatile("    mov r12, r2                  \n");
190
    __asm__ volatile("    add r8, r2, r2,lsl#1         \n");
194
    __asm__ volatile("    add r8, r2, r2,lsl#1         \n");
191
    __asm__ volatile("    add r3, r1, r3               \n");
195
    __asm__ volatile("    add r3, r1, r3               \n");
192
    __asm__ volatile("    sub r3, r3, #1               \n");
196
    __asm__ volatile("    sub r3, r3, #1               \n");
193
    __asm__ volatile("    mov r2, r1                   \n");
197
    __asm__ volatile("    mov r2, r1                   \n");
194
    __asm__ volatile("    add r1, r0, r12              \n");
198
    __asm__ volatile("    add r1, r0, r12              \n");
195
    __asm__ volatile("    sub r1, r1, #1               \n");
199
    __asm__ volatile("    sub r1, r1, #1               \n");
196
    __asm__ volatile("    bl displaylcd_setup          \n");
200
    __asm__ volatile("    bl displaylcd_setup          \n");
-
 
201
    __asm__ volatile("    add sp, sp, #4               \n");
197
    __asm__ volatile("    mov r0, r8                   \n");
202
    __asm__ volatile("    mov r0, r8                   \n");
198
    __asm__ volatile("    bl malloc                    \n");
203
    __asm__ volatile("    bl malloc                    \n");
199
    __asm__ volatile("    cmp r0, #0                   \n");
204
    __asm__ volatile("    cmp r0, #0                   \n");
200
    __asm__ volatile("    beq displaylcd_dither_unlock \n");
205
    __asm__ volatile("    beq displaylcd_dither_unlock \n");
201
    __asm__ volatile("    mov r2, r8                   \n");
206
    __asm__ volatile("    mov r2, r8                   \n");
Line 308... Line 313...
308
}
313
}
309
 
314
 
310
void INT_DMAC0C4()
315
void INT_DMAC0C4()
311
{
316
{
312
    DMAC0INTTCCLR = 0x10;
317
    DMAC0INTTCCLR = 0x10;
313
    lcd_in_irq = true;
-
 
314
    lcd_dma_busy = false;
318
    lcd_dma_busy = false;
315
    clockgate_dma(0, 4, false);
319
    clockgate_dma(0, 4, false);
316
    lcdconsole_callback();
320
    lcdconsole_callback();
317
    wakeup_signal(&lcd_wakeup);
321
    wakeup_signal(&lcd_wakeup);
318
    lcd_in_irq = false;
-
 
319
}
322
}
320
 
323
 
321
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
324
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
322
    ICODE_ATTR __attribute__((naked, noinline));
325
    ICODE_ATTR __attribute__((naked, noinline));
323
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
326
int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)