summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-02-05 04:43:19 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-02-05 04:43:19 +0000
commit1f021af60cd0351a309666c2e32b3d1b8b2cbd6f (patch)
tree88710bcc59d80831327b00d59af0eb6a6f758de6 /firmware/target/arm/imx31/gigabeat-s
parent3f85a4bc97fb2120870fcd4a6650fd72d4a6338f (diff)
downloadrockbox-1f021af60cd0351a309666c2e32b3d1b8b2cbd6f.tar.gz
rockbox-1f021af60cd0351a309666c2e32b3d1b8b2cbd6f.zip
Gigabeat S mixer: Make some progress. Get the tick and core sleep working using the AVIC. Redo the startup code to remap from IRAM and not include the lcd driver frambuffer in the remapping (until it can be moved). Clean up LCD driver. For other misc. changes, see the diffs. Now it progresses to ATA init and fails with -11 but without crashing or hanging. Replace all bootloaders.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16216 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/avic-imx31.c305
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/avic-imx31.h124
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c55
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S222
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c224
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c4
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c8
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-imx31.c18
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-target.h20
9 files changed, 352 insertions, 628 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
index 8236a38014..99a52e56d5 100644
--- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
@@ -20,204 +20,161 @@
20#include "system.h" 20#include "system.h"
21#include "imx31l.h" 21#include "imx31l.h"
22#include "avic-imx31.h" 22#include "avic-imx31.h"
23#include "panic.h"
23#include "debug.h" 24#include "debug.h"
24 25
26static const char * avic_int_names[64] =
27{
28 "RESERVED0", "RESERVED1", "RESERVED2", "I2C3",
29 "I2C2", "MPEG4_ENCODER", "RTIC", "FIR",
30 "MMC/SDHC2", "MMC/SDHC1", "I2C1", "SSI2",
31 "SSI1", "CSPI2", "CSPI1", "ATA",
32 "MBX", "CSPI3", "UART3", "IIM",
33 "SIM1", "SIM2", "RNGA", "EVTMON",
34 "KPP", "RTC", "PWN", "EPIT2",
35 "EPIT1", "GPT", "PWR_FAIL", "CCM_DVFS",
36 "UART2", "NANDFC", "SDMA", "USB_HOST1",
37 "USB_HOST2", "USB_OTG", "RESERVED3", "MSHC1",
38 "MSHC2", "IPU_ERR", "IPU", "RESERVED4",
39 "RESERVED5", "UART1", "UART4", "UART5",
40 "ETC_IRQ", "SCC_SCM", "SCC_SMN", "GPIO2",
41 "GPIO1", "CCM_CLK", "PCMCIA", "WDOG",
42 "GPIO3", "RESERVED6", "EXT_PWMG", "EXT_TEMP",
43 "EXT_SENS1", "EXT_SENS2", "EXT_WDOG", "EXT_TV"
44};
45
46static void UIE_VECTOR(void)
47{
48 set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS);
49 long offset = FIVECSR;
50 long offsetn = (long)NIVECSR >> 16;
51
52 if (offsetn == -1)
53 offset = offsetn; /* Could be FIQ */
54
55 panicf("Unhandled %s %ld: %s",
56 offsetn >= 0 ? "IRQ" : "FIQ", offset,
57 offset >= 0 ? avic_int_names[offset] : "");
58}
59
60/* We use the AVIC */
61void __attribute__((naked)) irq_handler(void)
62{
63 panicf("Unhandled IRQ");
64}
65
66/* Accoring to section 9.3.5 of the UM, the AVIC doesn't accelerate
67 * fast interrupts and they must be dispatched */
68void __attribute__((naked)) fiq_handler(void)
69{
70 asm volatile (
71 "mov r10, #0x6c000000 \n" /* load AVIC base address */
72 "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */
73 "add r10, r10, #100 \n" /* move pointer to base of VECTOR table */
74 "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */
75 "bx r8 \n" /* jump to FIQ service routine */
76 );
77}
78
25void avic_init(void) 79void avic_init(void)
26{ 80{
27 /*following the steps in the AVIC setup in imx31 man*/ 81 /* Disable all interrupts and set to unhandled */
82 avic_disable_int(ALL);
28 83
29 /*Initialize interrupt structures*/ 84 /* Init all interrupts to type IRQ */
30 int i,avicstart; 85 avic_set_int_type(ALL, IRQ);
31 /*get start of avic_init section for address calculation*/
32 __asm__ ("ldr %0,=_avicstart\n\t"
33 :"=r"(avicstart):);
34 86
35 for(i=0; i < 64;i++) 87 /* Set NM bit to enable VIC */
36 { 88 INTCNTL |= INTCNTL_NM;
37 imx31_int[i].name = (char *)&imx31_int_names[i];
38 imx31_int[i].int_type=IRQ;
39 /*integer i MUST be multiplied by 8 b/c gnu as
40 generates 2 instructions for each vector instruction
41 in vector_init(). Hence the value of 8 byte intervals
42 between each vector start address*/
43 imx31_int[i].addr=(avicstart+(i*8));
44 imx31_int[i].priority=0;
45 imx31_int[i].pInt_Handler=Unhandled_Int;
46 }
47
48 /*enable all Interrupts*/
49 avic_enable_int(ALL,IRQ,0);
50
51 /*Setup all interrupt type IRQ*/
52 avic_set_int_type(ALL,IRQ);
53
54 /*Set NM bit to enable VIC*/
55 INTCNTL |= (1 << 18);
56 89
57 /*Setup Registers Vector0-Vector63 for interrupt handler functions*/ 90 /* Enable IRQ/FIQ in imx31 INTCNTL reg */
58 for(i=0; i < 64;i++) 91 INTCNTL &= ~(INTCNTL_ABFEN | INTCNTL_NIDIS | INTCNTL_FIDIS);
59 writel(imx31_int[i].addr,(VECTOR_BASE_ADDR+(i*8))); 92
60 93 /* Enable VE bit in CP15 Control reg to enable VIC */
61 /*disable FIQ for now until the interrupt handlers are more mature...*/ 94 asm volatile (
62 disable_fiq(); 95 "mrc p15, 0, r0, c1, c0, 0 \n"
63 /*enable_fiq();*/ 96 "orr r0, r0, #(1 << 24) \n"
64 97 "mcr p15, 0, r0, c1, c0, 0 \n"
65 /*enable IRQ in imx31 INTCNTL reg*/ 98 : : : "r0");
66 INTCNTL &= ~(NIDIS); 99
67 /*disable FIQ in imx31 INTCNTL reg*/ 100 /* Enable normal interrupts at all priorities */
68 INTCNTL |= FIDIS; 101 NIMASK = 16;
69
70 /*enable IRQ in ARM11 core, enable VE bit in CP15 Control reg to enable VIC*/
71 __asm__ ("mrs r0,cpsr\t\n"
72 "bic r0,r0,#0x80\t\n"
73 "msr cpsr,r0\t\n"
74 "mrc p15,0,r0,c1,c0,0\n\t"
75 "orr r0,r0,#0x1000000\n\t"
76 "mcr p15,0,r0,c1,c0,0\n\t":::
77 "r0");
78} 102}
79 103
80void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, 104void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
81 void (*pInt_Handler) (void)) 105 void (*handler)(void))
82{ 106{
83 int i; 107 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED,
108 IRQ_FIQ_STATUS);
84 109
85 if(ints == ALL) 110 if (ints != ALL) /* No mass-enable allowed */
86 { 111 {
87 avic_set_int_type(ALL,intstype); 112 avic_set_int_type(ints, intstype);
88 for(i=0;i<64;i++) 113 VECTOR(ints) = (long)handler;
89 INTENNUM= (long)i; 114 INTENNUM = ints;
90 if(!(*pInt_Handler)) 115 }
91 pInt_Handler=Unhandled_Int; 116
92 return; 117 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);
93 }
94
95 imx31_int[ints].int_type=intstype;
96 imx31_int[ints].pInt_Handler=pInt_Handler;
97 avic_set_int_type(ints,intstype);
98 INTENNUM=(long)ints;
99} 118}
100 119
101void avic_disable_int(enum IMX31_INT_LIST ints) 120void avic_disable_int(enum IMX31_INT_LIST ints)
102{ 121{
103 int i; 122 long i;
104 123
105 if(ints == ALL) 124 if (ints == ALL)
106 { 125 {
107 for(i=0;i<64;i++) 126 for (i = 0; i < 64; i++)
108 INTDISNUM=(long)i; 127 {
109 imx31_int[ints].pInt_Handler=Unhandled_Int; 128 INTDISNUM = i;
110 return; 129 VECTOR(i) = (long)UIE_VECTOR;
130 }
111 } 131 }
112 132 else
113 INTDISNUM=(long)ints; 133 {
134 INTDISNUM = ints;
135 VECTOR(ints) = (long)UIE_VECTOR;
136 }
114} 137}
115 138
116void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype) 139static void set_int_type(int i, enum INT_TYPE intstype)
117{ 140{
118 int i; 141 volatile unsigned long *reg;
119 if(ints == ALL) 142 long val;
120 {
121 imx31_int[ints].int_type=intstype;
122 for(i=0;i<64;i++)
123 {
124 if(intstype > CCM_DVFS)
125 INTTYPEH=(long)(intstype-32);
126 else INTTYPEL=(long)intstype;
127 }
128 return;
129 }
130
131 imx31_int[ints].int_type=intstype;
132 if(intstype > CCM_DVFS)
133 INTTYPEH=(long)(intstype-32);
134 else INTTYPEL=(long)intstype;
135}
136 143
137void Unhandled_Int(void) 144 if (i >= 32)
138{ 145 {
139 enum IMX31_INT_LIST ints = 0; 146 reg = &INTTYPEH;
140 DEBUGF("Unhandled Interrupt:\n"); 147 val = 1L << (i - 32);
141 DEBUGF("Name : %s\n",imx31_int[ints].name); 148 }
142 DEBUGF("Interrupt Type : "); 149 else
143 if(imx31_int[ints].int_type==IRQ) 150 {
144 DEBUGF("IRQ\n"); 151 reg = &INTTYPEL;
145 else DEBUGF("FIQ\n"); 152 val = 1L << i;
146 DEBUGF("Handler Address : 0x%x\n",imx31_int[ints].addr); 153 }
147 DEBUGF("Priority : %d",imx31_int[ints].priority); 154
155 if (intstype == IRQ)
156 val = *reg & ~val;
157 else
158 val = *reg | val;
159
160 *reg = val;
148} 161}
149 162
150void vector_init(void) 163void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype)
151{ 164{
152 165 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED,
153 /*64 branch instructions, one for every vector in avic 166 IRQ_FIQ_STATUS);
154 A better idea would to calculate the shellcode for each of these 167
155 instructions...*/ 168 if (ints == ALL)
156 169 {
157 170 int i;
158 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED0].pInt_Handler)); 171 for (i = 0; i < 64; i++)
159 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED1].pInt_Handler)); 172 set_int_type(i, intstype);
160 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED2].pInt_Handler)); 173 }
161 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C3].pInt_Handler)); 174 else
162 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C2].pInt_Handler)); 175 {
163 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MPEG4_ENCODER].pInt_Handler)); 176 set_int_type(ints, intstype);
164 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTIC].pInt_Handler)); 177 }
165 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[FIR].pInt_Handler)); 178
166 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC2].pInt_Handler)); 179 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);
167 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC1].pInt_Handler));
168 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C1].pInt_Handler));
169 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI2].pInt_Handler));
170 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI1].pInt_Handler));
171 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI2].pInt_Handler));
172 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI1].pInt_Handler));
173 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ATA].pInt_Handler));
174 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MBX].pInt_Handler));
175 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI3].pInt_Handler));
176 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART3].pInt_Handler));
177 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IIM].pInt_Handler));
178 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM1].pInt_Handler));
179 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM2].pInt_Handler));
180 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RNGA].pInt_Handler));
181 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EVTMON].pInt_Handler));
182 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[KPP].pInt_Handler));
183 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTC].pInt_Handler));
184 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWN].pInt_Handler));
185 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT2].pInt_Handler));
186 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT1].pInt_Handler));
187 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPT].pInt_Handler));
188 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWR_FAIL].pInt_Handler));
189 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_DVFS].pInt_Handler));
190 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART2].pInt_Handler));
191 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[NANDFC].pInt_Handler));
192 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SDMA].pInt_Handler));
193 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST1].pInt_Handler));
194 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST2].pInt_Handler));
195 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_OTG].pInt_Handler));
196 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED3].pInt_Handler));
197 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC1].pInt_Handler));
198 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC2].pInt_Handler));
199 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU_ERR].pInt_Handler));
200 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU].pInt_Handler));
201 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED4].pInt_Handler));
202 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED5].pInt_Handler));
203 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART1].pInt_Handler));
204 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART4].pInt_Handler));
205 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART5].pInt_Handler));
206 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ETC_IRQ].pInt_Handler));
207 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SCM].pInt_Handler));
208 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SMN].pInt_Handler));
209 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO2].pInt_Handler));
210 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO1].pInt_Handler));
211 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_CLK].pInt_Handler));
212 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PCMCIA].pInt_Handler));
213 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[WDOG].pInt_Handler));
214 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO3].pInt_Handler));
215 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED6].pInt_Handler));
216 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_PWMG].pInt_Handler));
217 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TEMP].pInt_Handler));
218 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS1].pInt_Handler));
219 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS2].pInt_Handler));
220 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_WDOG].pInt_Handler));
221 __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TV].pInt_Handler));
222
223} 180}
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h
index 53a37b353b..29a3ec8dd0 100644
--- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h
+++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h
@@ -19,107 +19,37 @@
19#ifndef AVIC_IMX31_H 19#ifndef AVIC_IMX31_H
20#define AVIC_IMX31_H 20#define AVIC_IMX31_H
21 21
22 22enum INT_TYPE
23enum INT_TYPE {IRQ=0,FIQ}; 23{
24 24 IRQ = 0,
25struct int_names { 25 FIQ
26 char name[16];
27}; 26};
28 27
29static const struct int_names imx31_int_names[64] = 28enum IMX31_INT_LIST
30{ {"RESERVED0"}, 29{
31 {"RESERVED1"}, 30 __IMX31_INT_FIRST = -1,
32 {"RESERVED2"}, 31 RESERVED0, RESERVED1, RESERVED2, I2C3,
33 {"I2C3"}, 32 I2C2, MPEG4_ENCODER, RTIC, FIR,
34 {"I2C2"}, 33 MMC_SDHC2, MMC_SDHC1, I2C1, SSI2,
35 {"MPEG4_ENCODER"}, 34 SSI1, CSPI2, CSPI1, ATA,
36 {"RTIC"}, 35 MBX, CSPI3, UART3, IIM,
37 {"FIR"}, 36 SIM1, SIM2, RNGA, EVTMON,
38 {"MMC/SDHC2"}, 37 KPP, RTC, PWN, EPIT2,
39 {"MMC/SDHC1"}, 38 EPIT1, GPT, PWR_FAIL, CCM_DVFS,
40 {"I2C1"}, 39 UART2, NANDFC, SDMA, USB_HOST1,
41 {"SSI2"}, 40 USB_HOST2, USB_OTG, RESERVED3, MSHC1,
42 {"SSI1"}, 41 MSHC2, IPU_ERR, IPU, RESERVED4,
43 {"CSPI2"}, 42 RESERVED5, UART1, UART4, UART5,
44 {"CSPI1"}, 43 ETC_IRQ, SCC_SCM, SCC_SMN, GPIO2,
45 {"ATA"}, 44 GPIO1, CCM_CLK, PCMCIA, WDOG,
46 {"MBX"}, 45 GPIO3, RESERVED6, EXT_PWMG, EXT_TEMP,
47 {"CSPI3"}, 46 EXT_SENS1, EXT_SENS2, EXT_WDOG, EXT_TV,
48 {"UART3"}, 47 ALL
49 {"IIM"}, 48};
50 {"SIM1"},
51 {"SIM2"},
52 {"RNGA"},
53 {"EVTMON"},
54 {"KPP"},
55 {"RTC"},
56 {"PWN"},
57 {"EPIT2"},
58 {"EPIT1"},
59 {"GPT"},
60 {"PWR_FAIL"},
61 {"CCM_DVFS"},
62 {"UART2"},
63 {"NANDFC"},
64 {"SDMA"},
65 {"USB_HOST1"},
66 {"USB_HOST2"},
67 {"USB_OTG"},
68 {"RESERVED3"},
69 {"MSHC1"},
70 {"MSHC2"},
71 {"IPU_ERR"},
72 {"IPU"},
73 {"RESERVED4"},
74 {"RESERVED5"},
75 {"UART1"},
76 {"UART4"},
77 {"UART5"},
78 {"ETC_IRQ"},
79 {"SCC_SCM"},
80 {"SCC_SMN"},
81 {"GPIO2"},
82 {"GPIO1"},
83 {"CCM_CLK"},
84 {"PCMCIA"},
85 {"WDOG"},
86 {"GPIO3"},
87 {"RESERVED6"},
88 {"EXT_PWMG"},
89 {"EXT_TEMP"},
90 {"EXT_SENS1"},
91 {"EXT_SENS2"},
92 {"EXT_WDOG"},
93 {"EXT_TV"} };
94
95enum IMX31_INT_LIST {
96 RESERVED0 = 0,RESERVED1,RESERVED2,I2C3,
97 I2C2,MPEG4_ENCODER,RTIC,FIR,MMC_SDHC2,
98 MMC_SDHC1,I2C1,SSI2,SSI1,CSPI2,CSPI1,
99 ATA,MBX,CSPI3,UART3,IIM,SIM1,SIM2,
100 RNGA,EVTMON,KPP,RTC,PWN,EPIT2,EPIT1,
101 GPT,PWR_FAIL,CCM_DVFS,UART2,NANDFC,
102 SDMA,USB_HOST1,USB_HOST2,USB_OTG,
103 RESERVED3,MSHC1,MSHC2,IPU_ERR,IPU,
104 RESERVED4,RESERVED5,UART1,UART4,UART5,
105 ETC_IRQ,SCC_SCM,SCC_SMN,GPIO2,GPIO1,
106 CCM_CLK,PCMCIA,WDOG,GPIO3,RESERVED6,
107 EXT_PWMG,EXT_TEMP,EXT_SENS1,EXT_SENS2,
108 EXT_WDOG,EXT_TV,ALL };
109
110static struct avic_int {
111 char * name;
112 enum INT_TYPE int_type;
113 unsigned int addr;
114 unsigned int priority;
115 void (*pInt_Handler) (void);
116} imx31_int[64];
117 49
118void avic_init(void); 50void avic_init(void);
119void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, 51void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
120 void (*pInt_Handler) (void)); 52 void (*handler)(void));
121void avic_disable_int(enum IMX31_INT_LIST ints) ; 53void avic_disable_int(enum IMX31_INT_LIST ints);
122void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); 54void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype);
123void Unhandled_Int(void);
124void vector_init(void) __attribute__ ((section(".avic_int"),naked));
125#endif 55#endif
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
index 9df90a2344..7f882405a5 100644
--- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
@@ -1,25 +1,60 @@
1#include "config.h"
2#include "system.h"
3#include "avic-imx31.h"
1#include "kernel.h" 4#include "kernel.h"
2#include "thread.h" 5#include "thread.h"
3
4#include <stdio.h> 6#include <stdio.h>
5#include "lcd.h"
6 7
7extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 8extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
8 9
9void timer4(void) { 10#ifndef BOOTLOADER
10 int i; 11static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void)
12{
13 int i;
14
15 EPITSR1 = 1; /* Clear the pending status */
16
11 /* Run through the list of tick tasks */ 17 /* Run through the list of tick tasks */
12 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 18 for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
13 { 19 {
14 if(tick_funcs[i]) 20 if(tick_funcs[i])
15 {
16 tick_funcs[i](); 21 tick_funcs[i]();
17 }
18 } 22 }
19 23
20 current_tick++; 24 current_tick++;
21
22 /* following needs to be fixed. */
23 /*wake_up_thread();*/
24} 25}
26#endif
27
28void tick_start(unsigned int interval_in_ms)
29{
30 EPITCR1 &= ~(1 << 0); /* Disable the counter */
31 EPITCR1 |= (1 << 16); /* Reset */
25 32
33 CLKCTL_CGR0 |= (0x3 << 6); /* Clock ON */
34 CLKCTL_WIMR0 &= ~(1 << 23); /* Clear wakeup mask */
35
36 /* NOTE: This isn't really accurate yet but it's close enough to work
37 * with for the moment */
38
39 /* CLKSRC=32KHz, EPIT Output Disconnected, Enabled
40 * prescale 1/32, Reload from modulus register, Compare interrupt enabled,
41 * Count from load value */
42 EPITCR1 = (0x3 << 24) | (1 << 19) | (32 << 4) |
43 (1 << 3) | (1 << 2) | (1 << 1);
44 EPITSR1 = 1; /* Clear any pending interrupt */
45#ifndef BOOTLOADER
46 EPITLR1 = interval_in_ms;
47 EPITCMPR1 = 0; /* Event when counter reaches 0 */
48 avic_enable_int(EPIT1, IRQ, EPIT1_HANDLER);
49#else
50 (void)interval_in_ms;
51#endif
52
53 EPITCR1 |= (1 << 0); /* Enable the counter */
54
55 /* Why does only this trigger the counter? Remove when we find out. */
56 asm volatile (
57 "mcr p15, 0, %0, c7, c0, 4 \n"
58 : : "r" (0)
59 );
60}
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S b/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S
deleted file mode 100644
index d431c95f29..0000000000
--- a/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S
+++ /dev/null
@@ -1,222 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Michael Sevakis
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include "cpu.h"
22
23/****************************************************************************
24 * void lcd_write_yuv_420_lines(fb_data *dst,
25 * unsigned char chroma_buf[LCD_HEIGHT/2*3],
26 unsigned char const * const src[3],
27 * int width,
28 * int stride);
29 *
30 * |R| |1.000000 -0.000001 1.402000| |Y'|
31 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
32 * |B| |1.000000 1.772000 0.000000| |Pr|
33 * Scaled, normalized, rounded and tweaked to yield RGB 565:
34 * |R| |74 0 101| |Y' - 16| >> 9
35 * |G| = |74 -24 -51| |Cb - 128| >> 8
36 * |B| |74 128 0| |Cr - 128| >> 9
37 */
38 .section .icode, "ax", %progbits
39 .align 2
40 .global lcd_write_yuv420_lines
41 .type lcd_write_yuv420_lines, %function
42lcd_write_yuv420_lines:
43 @ r0 = dst
44 @ r1 = chroma_buf
45 @ r2 = yuv_src
46 @ r3 = width
47 @ [sp] = stride
48 stmdb sp!, { r4-r12, lr } @ save non-scratch
49 stmdb sp!, { r0, r3 } @ save dst and width
50 mov r14, #74 @ r14 = Y factor
51 ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
52 @ r5 = yuv_src[1] = Cb_p
53 @ r6 = yuv_src[2] = Cr_p
5410: @ loop line 1 @
55 ldrb r2, [r4], #1 @ r2 = *Y'_p++;
56 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
57 ldrb r11, [r6], #1 @ r11 = *Cr_p++;
58 @
59 @ compute Y
60 sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74
61 mul r7, r2, r14 @
62 @
63 sub r8, r8, #128 @ Cb -= 128
64 sub r11, r11, #128 @ Cr -= 128
65 @
66 mvn r2, #24 @ compute guv
67 mul r10, r2, r8 @ r10 = Cb*-24
68 mvn r2, #51 @
69 mla r10, r2, r11, r10 @ r10 = r10 + Cr*-51
70 @
71 mov r2, #101 @ compute rv
72 mul r9, r11, r2 @ r9 = rv = Cr*101
73 @
74 @ store chromas in line buffer
75 add r8, r8, #2 @ bu = (Cb + 2) >> 2
76 mov r8, r8, asr #2 @
77 strb r8, [r1], #1 @
78 add r9, r9, #256 @ rv = (Cr + 256) >> 9
79 mov r9, r9, asr #9 @
80 strb r9, [r1], #1 @
81 mov r10, r10, asr #8 @ guv >>= 8
82 strb r10, [r1], #1 @
83 @ compute R, G, and B
84 add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu
85 add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv
86 add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv
87 @
88 orr r12, r2, r11 @ check if clamping is needed...
89 orr r12, r12, r7, asr #1 @ ...at all
90 cmp r12, #31 @
91 bls 15f @ no clamp @
92 mov r12, #31 @
93 cmp r12, r2 @ clamp b
94 andlo r2, r12, r2, asr #31 @
95 eorlo r2, r2, r12 @
96 cmp r12, r11 @ clamp r
97 andlo r11, r12, r11, asr #31 @
98 eorlo r11, r11, r12 @
99 cmp r12, r7, asr #1 @ clamp g
100 andlo r7, r12, r7, asr #31 @
101 eorlo r7, r7, r12 @
102 orrlo r7, r7, r7, asl #1 @
10315: @ no clamp @
104 @
105 orr r12, r2, r7, lsl #5 @ r4 |= (g << 5)
106 ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++
107 orr r12, r12, r11, lsl #11 @ r4 = b | (r << 11)
108 strh r12, [r0], #240 @ store pixel
109 @
110 sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74
111 mul r7, r2, r14 @ next Y
112 @ compute R, G, and B
113 add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu
114 add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv
115 add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv
116 @
117 orr r12, r2, r11 @ check if clamping is needed...
118 orr r12, r12, r7, asr #1 @ ...at all
119 cmp r12, #31 @
120 bls 15f @ no clamp @
121 mov r12, #31 @
122 cmp r12, r2 @ clamp b
123 andlo r2, r12, r2, asr #31 @
124 eorlo r2, r2, r12 @
125 cmp r12, r11 @ clamp r
126 andlo r11, r12, r11, asr #31 @
127 eorlo r11, r11, r12 @
128 cmp r12, r7, asr #1 @ clamp g
129 andlo r7, r12, r7, asr #31 @
130 eorlo r7, r7, r12 @
131 orrlo r7, r7, r7, asl #1 @
13215: @ no clamp @
133 @
134 orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11)
135 orr r12, r12, r7, lsl #5 @ r4 |= (g << 5)
136 strh r12, [r0, #240]! @ store pixel
137 add r0, r0, #2*240 @
138 @
139 subs r3, r3, #2 @
140 bgt 10b @ loop line 1 @
141 @ do second line
142 @
143 ldmia sp!, { r0, r3 } @ pop dst and width
144 sub r0, r0, #2 @ set dst to start of next line
145 sub r1, r1, r3, asl #1 @ rewind chroma pointer...
146 ldr r2, [sp, #40] @ r2 = stride
147 add r1, r1, r3, asr #1 @ ... (r1 -= width/2*3)
148 @ move sources to start of next line
149 sub r2, r2, r3 @ r2 = skip = stride - width
150 add r4, r4, r2 @ r4 = Y'_p + skip
151 @
15220: @ loop line 2 @
153 ldrb r2, [r4], #1 @ r7 = Y' = *Y'_p++
154 ldrsb r8, [r1], #1 @ reload saved chromas
155 ldrsb r9, [r1], #1 @
156 ldrsb r10, [r1], #1 @
157 @
158 sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74
159 mul r7, r2, r14 @
160 @ compute R, G, and B
161 add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu
162 add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv
163 add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv
164 @
165 orr r12, r2, r11 @ check if clamping is needed...
166 orr r12, r12, r7, asr #1 @ ...at all
167 cmp r12, #31 @
168 bls 25f @ no clamp @
169 mov r12, #31 @
170 cmp r12, r2 @ clamp b
171 andlo r2, r12, r2, asr #31 @
172 eorlo r2, r2, r12 @
173 cmp r12, r11 @ clamp r
174 andlo r11, r12, r11, asr #31 @
175 eorlo r11, r11, r12 @
176 cmp r12, r7, asr #1 @ clamp g
177 andlo r7, r12, r7, asr #31 @
178 eorlo r7, r7, r12 @
179 orrlo r7, r7, r7, asl #1 @
18025: @ no clamp @
181 @
182 orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11)
183 ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++
184 orr r12, r12, r7, lsl #5 @ r4 |= (g << 5)
185 strh r12, [r0], #240 @ store pixel
186 @
187 @ do second pixel
188 @
189 sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74
190 mul r7, r2, r14 @
191 @ compute R, G, and B
192 add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu
193 add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv
194 add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv
195 @
196 orr r12, r2, r11 @ check if clamping is needed...
197 orr r12, r12, r7, asr #1 @ ...at all
198 cmp r12, #31 @
199 bls 25f @ no clamp @
200 mov r12, #31 @
201 cmp r12, r2 @ clamp b
202 andlo r2, r12, r2, asr #31 @
203 eorlo r2, r2, r12 @
204 cmp r12, r11 @ clamp r
205 andlo r11, r12, r11, asr #31 @
206 eorlo r11, r11, r12 @
207 cmp r12, r7, asr #1 @ clamp g
208 andlo r7, r12, r7, asr #31 @
209 eorlo r7, r7, r12 @
210 orrlo r7, r7, r7, asl #1 @
21125: @ no clamp @
212 @
213 orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11)
214 orr r12, r12, r7, lsl #5 @ r4 |= (g << 5)
215 strh r12, [r0, #240]! @ store pixel
216 add r0, r0, #2*240 @
217 @
218 subs r3, r3, #2 @
219 bgt 20b @ loop line 2 @
220 @
221 ldmia sp!, { r4-r12, pc } @ restore registers and return
222 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c
index c9cce6d653..b39ddbe77d 100644
--- a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c
@@ -9,12 +9,15 @@
9 9
10static volatile bool lcd_on = true; 10static volatile bool lcd_on = true;
11volatile bool lcd_poweroff = false; 11volatile bool lcd_poweroff = false;
12static unsigned lcd_yuv_options = 0;
12/* 13/*
13** These are imported from lcd-16bit.c 14** These are imported from lcd-16bit.c
14*/ 15*/
15extern unsigned fg_pattern; 16extern unsigned fg_pattern;
16extern unsigned bg_pattern; 17extern unsigned bg_pattern;
17 18
19extern struct viewport* current_vp;
20
18#if 0 21#if 0
19bool lcd_enabled() 22bool lcd_enabled()
20{ 23{
@@ -22,68 +25,60 @@ bool lcd_enabled()
22} 25}
23#endif 26#endif
24 27
25void printscreen(unsigned int colour) { 28void printscreen(unsigned int colour)
29{
26 int i; 30 int i;
27 int base = 0x84100000; 31 char * base = (char *)FRAME;
28 for(i=0;i<(320*240*2);i++) { 32 for(i = 0; i < (320*240*2); i++)
29 writel(colour,base); 33 {
34 writel(colour, base);
30 base++; 35 base++;
31 } 36 }
32} 37}
33 38
34unsigned int LCDBANK(unsigned int address)
35{
36 return ((address >> 22) & 0xff);
37}
38
39unsigned int LCDBASEU(unsigned int address)
40{
41 return (address & ((1 << 22)-1)) >> 1;
42}
43
44unsigned int LCDBASEL(unsigned int address)
45{
46 address += 320*240*2;
47 return (address & ((1 << 22)-1)) >> 1;
48}
49
50
51/* LCD init */ 39/* LCD init */
52void lcd_init_device(void) 40void lcd_init_device(void)
53{ 41{
54 int i;
55#ifdef BOOTLOADER
56 /* When the Rockbox bootloader starts, we are changing framebuffer address,
57 but we don't want what's shown on the LCD to change until we do an
58 lcd_update(), so copy the data from the old framebuffer to the new one */
59 unsigned short *buf = (unsigned short*)FRAME1;
60
61 memcpy(FRAME1, (short *)((LCDSADDR1)<<1), 320*240*2);
62
63 /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode
64 so convert the frambuffer data accordingly */
65 for(i=0; i< 320*240; i++){
66 *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0);
67 buf++;
68 }
69 return;
70#endif
71} 42}
72 43
73/* Update a fraction of the display. */ 44/* Update a fraction of the display. */
74void lcd_update_rect(int x, int y, int width, int height) 45void lcd_update_rect(int x, int y, int width, int height)
75{ 46{
76 (void)x; 47 fb_data *dst, *src;
77 (void)width;
78 (void)y;
79 (void)height;
80 48
81 if(!lcd_on) 49 if (!lcd_on)
82 {
83 sleep(200);
84 return; 50 return;
51
52 if (x + width > LCD_WIDTH)
53 width = LCD_WIDTH - x; /* Clip right */
54 if (x < 0)
55 width += x, x = 0; /* Clip left */
56 if (width <= 0)
57 return; /* nothing left to do */
58
59 if (y + height > LCD_HEIGHT)
60 height = LCD_HEIGHT - y; /* Clip bottom */
61 if (y < 0)
62 height += y, y = 0; /* Clip top */
63 if (height <= 0)
64 return; /* nothing left to do */
65
66 /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer
67 * and lcd_framebuffer */
68 dst = (fb_data *)FRAME + LCD_WIDTH*y + x;
69 src = &lcd_framebuffer[y][x];
70
71 /* Copy part of the Rockbox framebuffer to the second framebuffer */
72 if (width < LCD_WIDTH)
73 {
74 /* Not full width - do line-by-line */
75 lcd_copy_buffer_rect(dst, src, width, height);
76 }
77 else
78 {
79 /* Full width - copy as one line */
80 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
85 } 81 }
86 memcpy(((char*)FRAME2) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH)));
87} 82}
88 83
89void lcd_enable(bool state) 84void lcd_enable(bool state)
@@ -100,68 +95,82 @@ bool lcd_enabled(void)
100 This must be called after all other LCD functions that change the display. */ 95 This must be called after all other LCD functions that change the display. */
101void lcd_update(void) 96void lcd_update(void)
102{ 97{
103 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 98 if (!lcd_on)
99 return;
100
101 lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0],
102 LCD_WIDTH*LCD_HEIGHT, 1);
104} 103}
105 104
106void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, 105void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
107 int stride, int x, int y, int width, 106 int stride, int x, int y, int width,
108 int height) 107 int height)
109{ 108{
110 fb_data *dst, *dst_end; 109#if 0
111 unsigned int transcolor; 110 int w, px;
112 111 fb_data *dst;
113 /* nothing to draw? */
114 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
115 || (x + width <= 0) || (y + height <= 0))
116 return;
117 112
118 /* clipping */
119 if (x < 0)
120 {
121 width += x;
122 src_x -= x;
123 x = 0;
124 }
125 if (y < 0)
126 {
127 height += y;
128 src_y -= y;
129 y = 0;
130 }
131 if (x + width > LCD_WIDTH) 113 if (x + width > LCD_WIDTH)
132 width = LCD_WIDTH - x; 114 width = LCD_WIDTH - x; /* Clip right */
115 if (x < 0)
116 width += x, x = 0; /* Clip left */
117 if (width <= 0)
118 return; /* nothing left to do */
119
133 if (y + height > LCD_HEIGHT) 120 if (y + height > LCD_HEIGHT)
134 height = LCD_HEIGHT - y; 121 height = LCD_HEIGHT - y; /* Clip bottom */
122 if (y < 0)
123 height += y, y = 0; /* Clip top */
124 if (height <= 0)
125 return; /* nothing left to do */
135 126
136 src += stride * src_y + src_x; /* move starting point */ 127 src += stride * src_y + src_x; /* move starting point */
137 dst = &lcd_framebuffer[(y)][(x)]; 128 dst = &lcd_framebuffer[y][x];
138 dst_end = dst + height * LCD_WIDTH; 129
139 width *= 2; 130 asm volatile (
140 stride *= 2; 131 ".rowstart: \r\n"
141 transcolor = TRANSPARENT_COLOR; 132 "mov %[w], %[width] \r\n" /* Load width for inner loop */
142 asm volatile( 133 ".nextpixel: \r\n"
143 "rowstart: \n" 134 "ldrh %[px], [%[s]], #2 \r\n" /* Load src pixel */
144 "mov r0, #0 \n" 135 "add %[d], %[d], #2 \r\n" /* Uncoditionally increment dst */
145 "nextpixel: \n" 136 "cmp %[px], %[fgcolor] \r\n" /* Compare to foreground color */
146 "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ 137 "streqh %[fgpat], [%[d], #-2] \r\n" /* Store foregroud if match */
147 "cmp r1, %5 \n" /* Compare to transparent color */ 138 "cmpne %[px], %[transcolor] \r\n" /* Compare to transparent color */
148 "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ 139 "strneh %[px], [%[d], #-2] \r\n" /* Store dst if not transparent */
149 "add r0, r0, #2 \n" 140 "subs %[w], %[w], #1 \r\n" /* Width counter has run down? */
150 "cmp r0, %2 \n" /* r0 == width? */ 141 "bgt .nextpixel \r\n" /* More in this row? */
151 "bne nextpixel \n" /* More in this row? */ 142 "add %[s], %[s], %[sstp], lsl #1 \r\n" /* Skip over to start of next line */
152 "add %0, %0, %4 \n" /* src += stride */ 143 "add %[d], %[d], %[dstp], lsl #1 \r\n"
153 "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ 144 "subs %[h], %[h], #1 \r\n" /* Height counter has run down? */
154 "cmp %1, %3 \n" 145 "bgt .rowstart \r\n" /* More rows? */
155 "bne rowstart \n" /* if(dst != dst_end), keep going */ 146 : [w]"=&r"(w), [h]"+&r"(height), [px]"=&r"(px),
156 : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); 147 [s]"+&r"(src), [d]"+&r"(dst)
148 : [width]"r"(width),
149 [sstp]"r"(stride - width),
150 [dstp]"r"(LCD_WIDTH - width),
151 [transcolor]"r"(TRANSPARENT_COLOR),
152 [fgcolor]"r"(REPLACEWITHFG_COLOR),
153 [fgpat]"r"(current_vp->fg_pattern)
154 );
155#endif
156}
157
158void lcd_yuv_set_options(unsigned options)
159{
160 lcd_yuv_options = options;
157} 161}
158 162
159/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ 163/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
160extern void lcd_write_yuv420_lines(fb_data *dst, 164extern void lcd_write_yuv420_lines(fb_data *dst,
161 unsigned char chroma_buf[LCD_HEIGHT/2*3],
162 unsigned char const * const src[3], 165 unsigned char const * const src[3],
163 int width, 166 int width,
164 int stride); 167 int stride);
168extern void lcd_write_yuv420_lines_odither(fb_data *dst,
169 unsigned char const * const src[3],
170 int width,
171 int stride,
172 int x_screen, /* To align dither pattern */
173 int y_screen);
165/* Performance function to blit a YUV bitmap directly to the LCD */ 174/* Performance function to blit a YUV bitmap directly to the LCD */
166/* For the Gigabeat - show it rotated */ 175/* For the Gigabeat - show it rotated */
167/* So the LCD_WIDTH is now the height */ 176/* So the LCD_WIDTH is now the height */
@@ -171,7 +180,6 @@ void lcd_yuv_blit(unsigned char * const src[3],
171{ 180{
172 /* Caches for chroma data so it only need be recaculated every other 181 /* Caches for chroma data so it only need be recaculated every other
173 line */ 182 line */
174 unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */
175 unsigned char const * yuv_src[3]; 183 unsigned char const * yuv_src[3];
176 off_t z; 184 off_t z;
177 185
@@ -182,23 +190,39 @@ void lcd_yuv_blit(unsigned char * const src[3],
182 width &= ~1; 190 width &= ~1;
183 height >>= 1; 191 height >>= 1;
184 192
185 fb_data *dst = (fb_data*)FRAME1 + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; 193 y = LCD_WIDTH - 1 - y;
194 fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y;
186 195
187 z = stride*src_y; 196 z = stride*src_y;
188 yuv_src[0] = src[0] + z + src_x; 197 yuv_src[0] = src[0] + z + src_x;
189 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); 198 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
190 yuv_src[2] = src[2] + (yuv_src[1] - src[1]); 199 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
191 200
192 do 201 if (lcd_yuv_options & LCD_YUV_DITHER)
202 {
203 do
204 {
205 lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x);
206 yuv_src[0] += stride << 1; /* Skip down two luma lines */
207 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
208 yuv_src[2] += stride >> 1;
209 dst -= 2;
210 y -= 2;
211 }
212 while (--height > 0);
213 }
214 else
193 { 215 {
194 lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, 216 do
195 stride); 217 {
196 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 218 lcd_write_yuv420_lines(dst, yuv_src, width, stride);
197 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 219 yuv_src[0] += stride << 1; /* Skip down two luma lines */
198 yuv_src[2] += stride >> 1; 220 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
199 dst -= 2; 221 yuv_src[2] += stride >> 1;
222 dst -= 2;
223 }
224 while (--height > 0);
200 } 225 }
201 while (--height > 0);
202} 226}
203 227
204void lcd_set_contrast(int val) { 228void lcd_set_contrast(int val) {
diff --git a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c
index e8ec495449..e116439217 100644
--- a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c
@@ -21,16 +21,20 @@
21#include "mmu-arm.h" 21#include "mmu-arm.h"
22 22
23void memory_init(void) { 23void memory_init(void) {
24#if 0
24 ttb_init(); 25 ttb_init();
25 set_page_tables(); 26 set_page_tables();
26 enable_mmu(); 27 enable_mmu();
28#endif
27} 29}
28 30
29void set_page_tables() { 31void set_page_tables() {
32#if 0
30 map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */ 33 map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */
31 /*This pa *might* change*/ 34 /*This pa *might* change*/
32 map_section(0x80000000, 0, 64, CACHE_ALL); /* map RAM to 0 and enable caching for it */ 35 map_section(0x80000000, 0, 64, CACHE_ALL); /* map RAM to 0 and enable caching for it */
33 map_section((int)FRAME1, (int)FRAME1, 1, BUFFERED); /* enable buffered writing for the framebuffer */ 36 map_section((int)FRAME1, (int)FRAME1, 1, BUFFERED); /* enable buffered writing for the framebuffer */
34 map_section((int)FRAME2, (int)FRAME2, 1, BUFFERED); 37 map_section((int)FRAME2, (int)FRAME2, 1, BUFFERED);
38#endif
35} 39}
36 40
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
index b62051e41d..8485679aa4 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
@@ -27,8 +27,6 @@
27 27
28static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ 28static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */
29 29
30void fiq_handler(void) __attribute__((naked));
31
32void pcm_play_lock(void) 30void pcm_play_lock(void)
33{ 31{
34} 32}
@@ -77,12 +75,6 @@ void pcm_play_dma_pause(bool pause)
77{ 75{
78} 76}
79 77
80/* Get more samples to play out - call pcm_play_dma_stop and
81 pcm_play_dma_stopped_callback if the data runs out */
82void fiq_handler(void)
83{
84}
85
86/* Set the pcm frequency hardware will use when play is next started or 78/* Set the pcm frequency hardware will use when play is next started or
87 when pcm_apply_settings is called. Do not apply the setting to the 79 when pcm_apply_settings is called. Do not apply the setting to the
88 hardware here but simply cache it. */ 80 hardware here but simply cache it. */
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
index 544ae3afe6..ed5a26cd6e 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
@@ -13,27 +13,15 @@ int system_memory_guard(int newmode)
13 return 0; 13 return 0;
14} 14}
15 15
16extern void timer4(void);
17extern void dma0(void); /* free */
18extern void dma1(void);
19extern void dma3(void);
20
21void irq_handler(void)
22{
23}
24
25#ifdef BOOTLOADER
26void fiq_handler(void)
27{
28}
29#endif
30
31void system_reboot(void) 16void system_reboot(void)
32{ 17{
33} 18}
34 19
35void system_init(void) 20void system_init(void)
36{ 21{
22#ifndef BOOTLOADER
23 avic_init();
24#endif
37} 25}
38 26
39inline void dumpregs(void) 27inline void dumpregs(void)
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h
index e87b93b13a..1f7a2475af 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h
@@ -19,15 +19,15 @@
19#ifndef SYSTEM_TARGET_H 19#ifndef SYSTEM_TARGET_H
20#define SYSTEM_TARGET_H 20#define SYSTEM_TARGET_H
21 21
22#include "mmu-imx31.h"
23#include "system-arm.h" 22#include "system-arm.h"
23#include "mmu-arm.h"
24 24
25#define CPUFREQ_NORMAL 532000000 25#define CPUFREQ_NORMAL 532000000
26 26
27static inline void udelay(unsigned int usecs) 27static inline void udelay(unsigned int usecs)
28{ 28{
29 volatile signed int stop = EPITCNT1 - usecs; 29 volatile signed int stop = EPITCNT1 - usecs;
30 while (EPITCNT1 > stop); 30 while ((signed int)EPITCNT1 > stop);
31} 31}
32 32
33#define __dbg_hw_info(...) 0 33#define __dbg_hw_info(...) 0
@@ -36,6 +36,22 @@ static inline void udelay(unsigned int usecs)
36#define HAVE_INVALIDATE_ICACHE 36#define HAVE_INVALIDATE_ICACHE
37static inline void invalidate_icache(void) 37static inline void invalidate_icache(void)
38{ 38{
39 long rd = 0;
40 asm volatile(
41 "mcr p15, 0, %0, c7, c10, 0 \n"
42 "mcr p15, 0, %0, c7, c5, 0 \n"
43 : : "r"(rd)
44 );
45}
46
47#define HAVE_FLUSH_ICACHE
48static inline void flush_icache(void)
49{
50 long rd = 0;
51 asm volatile (
52 "mcr p15, 0, %0, c7, c10, 0 \n"
53 : : "r"(rd)
54 );
39} 55}
40 56
41struct ARM_REGS { 57struct ARM_REGS {