Subversion Repositories freemyipod

Rev

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

Rev 489 Rev 492
Line 30... Line 30...
30
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
30
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff]
31
    IDATA_ATTR __attribute__((aligned(16)));
31
    IDATA_ATTR __attribute__((aligned(16)));
32
 
32
 
33
static uint16_t lcd_color IDATA_ATTR;
33
static uint16_t lcd_color IDATA_ATTR;
34
 
34
 
-
 
35
static struct mutex lcd_mutex;
-
 
36
 
35
 
37
 
36
void lcd_init()
38
void lcd_init()
37
{
39
{
38
}
40
}
39
 
41
 
Line 55... Line 57...
55
int lcd_get_format()
57
int lcd_get_format()
56
{
58
{
57
    return LCD_FORMAT;
59
    return LCD_FORMAT;
58
}
60
}
59
 
61
 
-
 
62
static void lcd_send_cmd(uint16_t cmd) ICODE_ATTR __attribute__((noinline));
60
static void lcd_send_cmd(uint16_t cmd)
63
static void lcd_send_cmd(uint16_t cmd)
61
{
64
{
62
    while (LCDSTATUS & 0x10);
65
    while (LCDSTATUS & 0x10);
63
    LCDWCMD = cmd;
66
    LCDWCMD = cmd;
64
}
67
}
65
 
68
 
-
 
69
static void lcd_send_data(uint16_t data) ICODE_ATTR __attribute__((noinline));
66
static void lcd_send_data(uint16_t data)
70
static void lcd_send_data(uint16_t data)
67
{
71
{
68
    while (LCDSTATUS & 0x10);
72
    while (LCDSTATUS & 0x10);
69
    LCDWDATA = (data & 0xff) | ((data & 0x7f00) << 1);
73
    LCDWDATA = (data & 0xff) | ((data & 0x7f00) << 1);
70
}
74
}
71
 
75
 
-
 
76
static uint32_t lcd_detect() ICODE_ATTR;
72
static uint32_t lcd_detect()
77
static uint32_t lcd_detect()
73
{
78
{
74
    return (PDAT6 & 0x30) >> 4;
79
    return (PDAT6 & 0x30) >> 4;
75
}
80
}
76
 
81
 
-
 
82
bool displaylcd_busy() ICODE_ATTR;
77
bool displaylcd_busy()
83
bool displaylcd_busy()
78
{
84
{
79
    return DMAC0C4CONFIG & 1;
85
    return DMAC0C4CONFIG & 1;
80
}
86
}
81
 
87
 
82
bool displaylcd_safe()
88
bool displaylcd_safe()
83
{
89
{
84
    return !(DMAC0C4CONFIG & 1);
90
    return !(DMAC0C4CONFIG & 1);
85
}
91
}
86
 
92
 
-
 
93
void displaylcd_sync() ICODE_ATTR;
87
void displaylcd_sync()
94
void displaylcd_sync()
88
{
95
{
-
 
96
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
89
    while (displaylcd_busy()) sleep(100);
97
    while (displaylcd_busy()) sleep(100);
-
 
98
    mutex_unlock(&lcd_mutex);
90
}
99
}
91
 
100
 
92
void displaylcd(unsigned int startx, unsigned int endx,
101
void displaylcd_setup(unsigned int startx, unsigned int endx,
93
                unsigned int starty, unsigned int endy, void* data, int color)
102
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
-
 
103
void displaylcd_setup(unsigned int startx, unsigned int endx,
-
 
104
                      unsigned int starty, unsigned int endy)
94
{
105
{
-
 
106
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
95
    displaylcd_sync();
107
    displaylcd_sync();
96
    if (lcd_detect() & 2)
108
    if (lcd_detect() & 2)
97
    {
109
    {
98
        lcd_send_cmd(0x210);
110
        lcd_send_cmd(0x210);
99
        lcd_send_data(startx);
111
        lcd_send_data(startx);
Line 121... Line 133...
121
        lcd_send_data(starty & 0xff);
133
        lcd_send_data(starty & 0xff);
122
        lcd_send_data(endy >> 8);
134
        lcd_send_data(endy >> 8);
123
        lcd_send_data(endy & 0xff);
135
        lcd_send_data(endy & 0xff);
124
        lcd_send_cmd(0x2c);
136
        lcd_send_cmd(0x2c);
125
    }
137
    }
-
 
138
}
-
 
139
 
126
    int pixels = (endx - startx + 1) * (endy - starty + 1);
140
static void displaylcd_dma(void* data, int pixels, bool solid) ICODE_ATTR;
127
    if (pixels <= 0) return;
141
static void displaylcd_dma(void* data, int pixels, bool solid)
-
 
142
{
128
    int i;
143
    int i;
129
    bool solid = (int)data == -1;
-
 
130
    if (solid) lcd_color = color;
-
 
131
    for (i = -1; i < (int)ARRAYLEN(lcd_lli) && pixels > 0; i++, pixels -= 0xfff)
144
    for (i = -1; i < (int)ARRAYLEN(lcd_lli) && pixels > 0; i++, pixels -= 0xfff)
132
    {
145
    {
133
        bool last = i + 1 >= ARRAYLEN(lcd_lli) || pixels <= 0xfff;
146
        bool last = i + 1 >= ARRAYLEN(lcd_lli) || pixels <= 0xfff;
134
        struct dma_lli* lli = i < 0 ? (struct dma_lli*)((int)&DMAC0C4LLI) : &lcd_lli[i];
147
        struct dma_lli* lli = i < 0 ? (struct dma_lli*)((int)&DMAC0C4LLI) : &lcd_lli[i];
135
        lli->srcaddr = solid ? &lcd_color : data;
148
        lli->srcaddr = data;
136
        lli->dstaddr = (void*)((int)&LCDWDATA);
149
        lli->dstaddr = (void*)((int)&LCDWDATA);
137
        lli->nextlli = last ? NULL : &lcd_lli[i + 1];
150
        lli->nextlli = last ? NULL : &lcd_lli[i + 1];
138
        lli->control = 0x70240000 | (last ? pixels : 0xfff)
151
        lli->control = 0x70240000 | (last ? pixels : 0xfff)
139
                     | (last ? 0x80000000 : 0) | (solid ? 0 : 0x4000000);
152
                     | (last ? 0x80000000 : 0) | (solid ? 0 : 0x4000000);
140
        data = (void*)(((uint32_t)data) + 0x1ffe);
153
        data = (void*)(((uint32_t)data) + 0x1ffe);
141
    }
154
    }
142
    clean_dcache();
155
    clean_dcache();
143
    DMAC0C4CONFIG = 0x88c1;
156
    DMAC0C4CONFIG = 0x88c1;
144
}
157
}
145
 
158
 
-
 
159
void displaylcd_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;
-
 
164
    displaylcd_setup(startx, endx, starty, endy);
-
 
165
    displaylcd_dma(data, pixels, false);
-
 
166
    mutex_unlock(&lcd_mutex);
-
 
167
}
-
 
168
 
-
 
169
void filllcd_native(unsigned int startx, unsigned int endx,
-
 
170
                    unsigned int starty, unsigned int endy, int color)
-
 
171
{
-
 
172
    int pixels = (endx - startx + 1) * (endy - starty + 1);
-
 
173
    if (pixels <= 0) return;
-
 
174
    displaylcd_setup(startx, endx, starty, endy);
-
 
175
    lcd_color = color;
-
 
176
    displaylcd_dma(&lcd_color, pixels, true);
-
 
177
    mutex_unlock(&lcd_mutex);
-
 
178
}
-
 
179
 
-
 
180
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
-
 
181
                       unsigned int height, void* data, unsigned int datax,
-
 
182
                       unsigned int datay, unsigned int stride, bool solid) ICODE_ATTR;
-
 
183
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
-
 
184
                       unsigned int height, void* data, unsigned int datax,
-
 
185
                       unsigned int datay, unsigned int stride, bool solid)
-
 
186
{
-
 
187
    int pixels = width * height;
-
 
188
    if (pixels <= 0) return;
-
 
189
    displaylcd_setup(x, x + width - 1, y, y + height - 1);
-
 
190
    int corrsize = width * 3;
-
 
191
    signed char* corr = (signed char*)malloc(corrsize);
-
 
192
    if (!corr)
-
 
193
    {
-
 
194
        mutex_unlock(&lcd_mutex);
-
 
195
        return;
-
 
196
    }
-
 
197
    memset(corr, 0, corrsize);
-
 
198
    unsigned char* in = (unsigned char*)data + (stride * datay + datax) * 3;
-
 
199
    for (y = 0; y < height; y++)
-
 
200
    {
-
 
201
        int i;
-
 
202
        signed char* corrptr = corr;
-
 
203
        signed char lastcorr[3] = {0};
-
 
204
        for (x = 0; x < width; x++)
-
 
205
        {
-
 
206
            unsigned int pixel = 0;
-
 
207
            signed char* lastcorrptr = lastcorr;
-
 
208
            int orig = *in++ + *corrptr + *lastcorrptr;
-
 
209
            orig = MAX(0, MIN(255, orig));
-
 
210
            unsigned int real = orig >> 3;
-
 
211
            pixel |= real << 11;
-
 
212
            int err = orig - ((real << 3) | (real >> 2));
-
 
213
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
-
 
214
            *lastcorrptr++ = err >> 1;
-
 
215
            orig = *in++ + *corrptr + *lastcorrptr;
-
 
216
            orig = MAX(0, MIN(255, orig));
-
 
217
            real = orig >> 2;
-
 
218
            pixel |= real << 5;
-
 
219
            err = orig - ((real << 2) | (real >> 4));
-
 
220
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
-
 
221
            *lastcorrptr++ = err >> 1;
-
 
222
            orig = *in++ + *corrptr + *lastcorrptr;
-
 
223
            orig = MAX(0, MIN(255, orig));
-
 
224
            real = orig >> 3;
-
 
225
            pixel |= real;
-
 
226
            err = orig - ((real << 3) | (real >> 2));
-
 
227
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
-
 
228
            *lastcorrptr++ = err >> 1;
-
 
229
            while (LCDSTATUS & 0x10);
-
 
230
            LCDWDATA = pixel;
-
 
231
            if (solid) in -= 3;
-
 
232
        }
-
 
233
        if (solid) in += stride * 3;
-
 
234
        else in += (stride - width) * 3;
-
 
235
    }
-
 
236
    free(corr);
-
 
237
    mutex_unlock(&lcd_mutex);
-
 
238
}
-
 
239
 
-
 
240
void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
-
 
241
                void* data, unsigned int datax, unsigned int datay, unsigned int stride)
-
 
242
{
-
 
243
    displaylcd_dither(x, y, width, height, data, datax, datay, stride, false);
-
 
244
}
-
 
245
 
-
 
246
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
-
 
247
{
-
 
248
    if (width * height <= 0) return;
-
 
249
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
-
 
250
    lcd_color = color;
-
 
251
    displaylcd_dither(x, y, width, height, &lcd_color, 0, 0, 0, true);
-
 
252
    mutex_unlock(&lcd_mutex);
-
 
253
}
-
 
254
 
146
void lcd_shutdown()
255
void lcd_shutdown()
147
{
256
{
148
    displaylcd_sync();
257
    displaylcd_sync();
149
    uint32_t type = lcd_detect();
258
    uint32_t type = lcd_detect();
150
    if (type & 2)
259
    if (type & 2)