freemyipod r268 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r267‎ | r268 | r269 >
Date:17:37, 22 November 2010
Author:theseven
Status:new
Tags:
Comment:
emBIOS: New LCD driver for iPod Nano 4G (now uses DMA)
Modified paths:
  • /embios/trunk/target/ipodnano4g/lcd.S (deleted) (history)
  • /embios/trunk/target/ipodnano4g/lcd.c (added) (history)

Diff [purge]

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+}