| Index: embios/trunk/target/ipodnano4g/lcd.S |
| — | — | @@ -1,164 +0,0 @@ |
| 2 | | -@
|
| 3 | | -@
|
| 4 | | -@ Copyright 2010 TheSeven
|
| 5 | | -@
|
| 6 | | -@
|
| 7 | | -@ This file is part of emBIOS.
|
| 8 | | -@
|
| 9 | | -@ emBIOS is free software: you can redistribute it and/or
|
| 10 | | -@ modify it under the terms of the GNU General Public License as
|
| 11 | | -@ published by the Free Software Foundation, either version 2 of the
|
| 12 | | -@ License, or (at your option) any later version.
|
| 13 | | -@
|
| 14 | | -@ emBIOS is distributed in the hope that it will be useful,
|
| 15 | | -@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | | -@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | | -@ See the GNU General Public License for more details.
|
| 18 | | -@
|
| 19 | | -@ You should have received a copy of the GNU General Public License
|
| 20 | | -@ along with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | | -@
|
| 22 | | -@
|
| 23 | | -
|
| 24 | | -
|
| 25 | | -.section .initcode.lcd_init, "ax", %progbits
|
| 26 | | -.align 2
|
| 27 | | -.global lcd_init
|
| 28 | | -.type lcd_init, %function
|
| 29 | | -lcd_init:
|
| 30 | | - mov pc, lr
|
| 31 | | -.size lcd_init, .-lcd_init
|
| 32 | | -
|
| 33 | | -.section .text.lcd_get_width, "ax", %progbits
|
| 34 | | -.align 2
|
| 35 | | -.global lcd_get_width
|
| 36 | | -.type lcd_get_width, %function
|
| 37 | | -lcd_get_width:
|
| 38 | | - mov r0, #176
|
| 39 | | - mov pc, lr
|
| 40 | | -.size lcd_get_width, .-lcd_get_width
|
| 41 | | -
|
| 42 | | -.section .text.lcd_get_height, "ax", %progbits
|
| 43 | | -.align 2
|
| 44 | | -.global lcd_get_height
|
| 45 | | -.type lcd_get_height, %function
|
| 46 | | -lcd_get_height:
|
| 47 | | - mov r0, #132
|
| 48 | | - mov pc, lr
|
| 49 | | -.size lcd_get_hright, .-lcd_get_height
|
| 50 | | -
|
| 51 | | -.section .text.lcd_get_bytes_per_pixel, "ax", %progbits
|
| 52 | | -.align 2
|
| 53 | | -.global lcd_get_bytes_per_pixel
|
| 54 | | -.type lcd_get_heightbytes_per_pixel, %function
|
| 55 | | -lcd_get_bytes_per_pixel:
|
| 56 | | - mov r0, #2
|
| 57 | | - mov pc, lr
|
| 58 | | -.size lcd_get_bytes_per_pixel, .-lcd_get_bytes_per_pixel
|
| 59 | | -
|
| 60 | | -.section .icode.displaylcd, "ax", %progbits
|
| 61 | | -.align 2
|
| 62 | | -.global displaylcd
|
| 63 | | -.type displaylcd, %function
|
| 64 | | -displaylcd:
|
| 65 | | - stmfd sp!, {r0,r1,r4,lr}
|
| 66 | | - mov r12, #0x38000000
|
| 67 | | - orr r12, r12, #0x300000
|
| 68 | | - mov r0, #0x2a
|
| 69 | | - bl displaylcd_sendlcdc
|
| 70 | | - ldr r0, [sp]
|
| 71 | | - bl displaylcd_sendlcdd
|
| 72 | | - ldr r0, [sp,#0x04]
|
| 73 | | - bl displaylcd_sendlcdd
|
| 74 | | - mov r0, #0x2b
|
| 75 | | - bl displaylcd_sendlcdc
|
| 76 | | - mov r0, r2
|
| 77 | | - tst r0, #0x100
|
| 78 | | - eorne r0, #0x300
|
| 79 | | - bl displaylcd_sendlcdd
|
| 80 | | - mov r0, r3
|
| 81 | | - tst r0, #0x100
|
| 82 | | - eorne r0, #0x300
|
| 83 | | - bl displaylcd_sendlcdd
|
| 84 | | - mov r0, #0x2c
|
| 85 | | - bl displaylcd_sendlcdc
|
| 86 | | - ldmia sp, {r0,r1}
|
| 87 | | - sub r1, r0
|
| 88 | | - add r1, r1, #1
|
| 89 | | - sub r3, r2
|
| 90 | | - add r3, r3, #1
|
| 91 | | - mul r2, r1, r3
|
| 92 | | - ldr r1, [sp,#0x10]
|
| 93 | | - cmp r1, #-1
|
| 94 | | - bne displaylcd_framebuf
|
| 95 | | -displaylcd_color:
|
| 96 | | - ldr r0, [sp,#0x14]
|
| 97 | | - bl displaylcd_sendlcdd
|
| 98 | | - subs r2, r2, #1
|
| 99 | | - bne displaylcd_color
|
| 100 | | - ldmfd sp!, {r4-r6,pc}
|
| 101 | | -displaylcd_framebuf:
|
| 102 | | - ldrh r0, [r1], #2
|
| 103 | | - bl displaylcd_sendlcdd
|
| 104 | | - subs r2, r2, #1
|
| 105 | | - bne displaylcd_framebuf
|
| 106 | | - ldmfd sp!, {r0,r1,r4,pc}
|
| 107 | | -
|
| 108 | | -displaylcd_sendlcdc:
|
| 109 | | - ldrh r4, [r12,#0x1c]
|
| 110 | | - tst r4, #0x10
|
| 111 | | - bne displaylcd_sendlcdc
|
| 112 | | - strh r0, [r12,#0x04]
|
| 113 | | - mov pc, lr
|
| 114 | | -displaylcd_sendlcdd:
|
| 115 | | - ldrh r4, [r12,#0x1c]
|
| 116 | | - tst r4, #0x10
|
| 117 | | - bne displaylcd_sendlcdd
|
| 118 | | - strh r0, [r12,#0x40]
|
| 119 | | - mov pc, lr
|
| 120 | | -.size displaylcd, .-displaylcd
|
| 121 | | -
|
| 122 | | -.section .icode.displaylcd_sync, "ax", %progbits
|
| 123 | | -.align 2
|
| 124 | | -.global displaylcd_sync
|
| 125 | | -.type displaylcd_sync, %function
|
| 126 | | -displaylcd_sync:
|
| 127 | | - mov pc, lr
|
| 128 | | -.size displaylcd_sync, .-displaylcd_sync
|
| 129 | | -
|
| 130 | | -.section .icode.displaylcd_busy, "ax", %progbits
|
| 131 | | -.align 2
|
| 132 | | -.global displaylcd_busy
|
| 133 | | -.type displaylcd_busy, %function
|
| 134 | | -displaylcd_busy:
|
| 135 | | - mov r0, #0
|
| 136 | | - mov pc, lr
|
| 137 | | -.size displaylcd_busy, .-displaylcd_busy
|
| 138 | | -
|
| 139 | | -.section .icode.displaylcd_safe, "ax", %progbits
|
| 140 | | -.align 2
|
| 141 | | -.global displaylcd_safe
|
| 142 | | -.type displaylcd_safe, %function
|
| 143 | | -displaylcd_safe:
|
| 144 | | - mov r0, #1
|
| 145 | | - mov pc, lr
|
| 146 | | -.size displaylcd_safe, .-displaylcd_safe
|
| 147 | | -
|
| 148 | | -.section .icode.lcd_translate_color, "ax", %progbits
|
| 149 | | -.align 2
|
| 150 | | -.global lcd_translate_color
|
| 151 | | -.type lcd_translate_color, %function
|
| 152 | | -lcd_translate_color:
|
| 153 | | - cmp r0, #0xff
|
| 154 | | - moveq r0, #-1
|
| 155 | | - moveq pc, lr
|
| 156 | | - cmp r0, #0
|
| 157 | | - movne r0, #0xff000000
|
| 158 | | - orrne r0, r0, #0xff0000
|
| 159 | | - mov r2, r2,lsr#2
|
| 160 | | - mov r1, r1,lsr#3
|
| 161 | | - orr r0, r0, r3,lsr#3
|
| 162 | | - orr r0, r0, r2,lsl#5
|
| 163 | | - orr r0, r0, r1,lsl#11
|
| 164 | | - mov pc, lr
|
| 165 | | -.size lcd_translate_color, .-lcd_translate_color
|
| Index: embios/trunk/target/ipodnano4g/lcd.c |
| — | — | @@ -0,0 +1,152 @@ |
| | 2 | +//
|
| | 3 | +//
|
| | 4 | +// Copyright 2010 TheSeven
|
| | 5 | +//
|
| | 6 | +//
|
| | 7 | +// This file is part of emBIOS.
|
| | 8 | +//
|
| | 9 | +// emBIOS is free software: you can redistribute it and/or
|
| | 10 | +// modify it under the terms of the GNU General Public License as
|
| | 11 | +// published by the Free Software Foundation, either version 2 of the
|
| | 12 | +// License, or (at your option) any later version.
|
| | 13 | +//
|
| | 14 | +// emBIOS is distributed in the hope that it will be useful,
|
| | 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| | 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| | 17 | +// See the GNU General Public License for more details.
|
| | 18 | +//
|
| | 19 | +// You should have received a copy of the GNU General Public License along
|
| | 20 | +// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
| | 21 | +//
|
| | 22 | +//
|
| | 23 | +
|
| | 24 | +
|
| | 25 | +#include "global.h"
|
| | 26 | +#include "thread.h"
|
| | 27 | +#include "s5l8720.h"
|
| | 28 | +#include "util.h"
|
| | 29 | +
|
| | 30 | +
|
| | 31 | +static struct dma_lli
|
| | 32 | +{
|
| | 33 | + void* srcaddr;
|
| | 34 | + void* dstaddr;
|
| | 35 | + struct dma_lli* nextlli;
|
| | 36 | + uint32_t control;
|
| | 37 | +} lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff] IDATA_ATTR __attribute__((aligned(16)));
|
| | 38 | +
|
| | 39 | +static uint16_t lcd_color IDATA_ATTR;
|
| | 40 | +
|
| | 41 | +
|
| | 42 | +void lcd_init()
|
| | 43 | +{
|
| | 44 | +}
|
| | 45 | +
|
| | 46 | +int lcd_get_width()
|
| | 47 | +{
|
| | 48 | + return LCD_WIDTH;
|
| | 49 | +}
|
| | 50 | +
|
| | 51 | +int lcd_get_height()
|
| | 52 | +{
|
| | 53 | + return LCD_HEIGHT;
|
| | 54 | +}
|
| | 55 | +
|
| | 56 | +int lcd_get_bytes_per_pixel()
|
| | 57 | +{
|
| | 58 | + return LCD_BYTESPERPIXEL;
|
| | 59 | +}
|
| | 60 | +
|
| | 61 | +static void lcd_send_cmd(uint16_t cmd)
|
| | 62 | +{
|
| | 63 | + while (LCDSTATUS & 0x10);
|
| | 64 | + LCDWCMD = cmd;
|
| | 65 | +}
|
| | 66 | +
|
| | 67 | +static void lcd_send_data(uint16_t data)
|
| | 68 | +{
|
| | 69 | + while (LCDSTATUS & 0x10);
|
| | 70 | + LCDWDATA = data;
|
| | 71 | +}
|
| | 72 | +
|
| | 73 | +void lcd_shutdown()
|
| | 74 | +{
|
| | 75 | +}
|
| | 76 | +
|
| | 77 | +bool displaylcd_busy()
|
| | 78 | +{
|
| | 79 | + return DMAC0C0CONFIG & 1;
|
| | 80 | +}
|
| | 81 | +
|
| | 82 | +bool displaylcd_safe()
|
| | 83 | +{
|
| | 84 | + return !(DMAC0C0CONFIG & 1);
|
| | 85 | +}
|
| | 86 | +
|
| | 87 | +void displaylcd_sync()
|
| | 88 | +{
|
| | 89 | + while (displaylcd_busy()) sleep(100);
|
| | 90 | +}
|
| | 91 | +
|
| | 92 | +void displaylcd(unsigned int startx, unsigned int endx,
|
| | 93 | + unsigned int starty, unsigned int endy, void* data, int color)
|
| | 94 | +{
|
| | 95 | + displaylcd_sync();
|
| | 96 | + lcd_send_cmd(0x2a);
|
| | 97 | + lcd_send_data(((startx & 0x7f00) << 1) | (startx & 0xff));
|
| | 98 | + lcd_send_data(((endx & 0x7f00) << 1) | (endx & 0xff));
|
| | 99 | + lcd_send_cmd(0x2b);
|
| | 100 | + lcd_send_data(((starty & 0x7f00) << 1) | (starty & 0xff));
|
| | 101 | + lcd_send_data(((endy & 0x7f00) << 1) | (endy & 0xff));
|
| | 102 | + lcd_send_cmd(0x2c);
|
| | 103 | + int pixels = (endx - startx + 1) * (endy - starty + 1);
|
| | 104 | + int i;
|
| | 105 | + bool solid = (int)data == -1;
|
| | 106 | + bool last = !ARRAYLEN(lcd_lli) || pixels <= 0xfff;
|
| | 107 | + if (solid) lcd_color = color;
|
| | 108 | + DMAC0C0SRCADDR = solid ? &lcd_color : data;
|
| | 109 | + DMAC0C0DESTADDR = (void*)((int)&LCDWDATA);
|
| | 110 | + DMAC0C0LLI = last ? (void*)0 : lcd_lli;
|
| | 111 | + DMAC0C0CONTROL = 0x70240000 | (last ? pixels : 0xfff)
|
| | 112 | + | (last ? 0x80000000 : 0) | (solid ? 0 : 0x4000000);
|
| | 113 | + void* origdata=data;
|
| | 114 | + data = (void*)(((uint32_t)data) + 0x1ffe);
|
| | 115 | + for (i = 0, pixels -= 0xfff; i < ARRAYLEN(lcd_lli) && pixels > 0; i++, pixels -= 0xfff)
|
| | 116 | + {
|
| | 117 | + last = i + 1 >= ARRAYLEN(lcd_lli) || pixels <= 0xfff;
|
| | 118 | + lcd_lli[i].srcaddr = solid ? &lcd_color : data;
|
| | 119 | + lcd_lli[i].dstaddr = (void*)((int)&LCDWDATA);
|
| | 120 | + lcd_lli[i].nextlli = last ? (void*)0 : &lcd_lli[i + 1];
|
| | 121 | + lcd_lli[i].control = 0x70240000 | (last ? pixels : 0xfff)
|
| | 122 | + | (last ? 0x80000000 : 0) | (solid ? 0 : 0x4000000);
|
| | 123 | + data = (void*)(((uint32_t)data) + 0x1ffe);
|
| | 124 | + }
|
| | 125 | + clean_dcache();
|
| | 126 | + DMAC0C0CONFIG = 0x88c1;
|
| | 127 | +}
|
| | 128 | +
|
| | 129 | +void INT_DMAC0C0()
|
| | 130 | +{
|
| | 131 | + DMAC0INTTCCLR = 1;
|
| | 132 | + lcdconsole_callback();
|
| | 133 | +}
|
| | 134 | +
|
| | 135 | +int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
|
| | 136 | + ICODE_ATTR __attribute__((naked, noinline));
|
| | 137 | +int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
|
| | 138 | +{
|
| | 139 | + asm volatile(
|
| | 140 | + "cmp r0, #0xff \n\t"
|
| | 141 | + "moveq r0, #-1 \n\t"
|
| | 142 | + "moveq pc, lr \n\t"
|
| | 143 | + "cmp r0, #0 \n\t"
|
| | 144 | + "movne r0, #0xff000000 \n\t"
|
| | 145 | + "orrne r0, r0, #0xff0000 \n\t"
|
| | 146 | + "mov r2, r2,lsr#2 \n\t"
|
| | 147 | + "orr r0, r0, r3,lsr#3 \n\t"
|
| | 148 | + "mov r1, r1,lsr#3 \n\t"
|
| | 149 | + "orr r0, r0, r2,lsl#5 \n\t"
|
| | 150 | + "orr r0, r0, r1,lsl#11 \n\t"
|
| | 151 | + "mov pc, lr \n\t"
|
| | 152 | + );
|
| | 153 | +}
|