summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/i2c-pp.c16
-rw-r--r--firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c8
-rw-r--r--firmware/target/arm/sandisk/adc-c200_e200.c7
-rw-r--r--firmware/target/arm/sandisk/ata-c200_e200.c27
-rw-r--r--firmware/target/arm/system-pp502x.c55
-rw-r--r--firmware/target/arm/system-target.h5
6 files changed, 78 insertions, 40 deletions
diff --git a/firmware/target/arm/i2c-pp.c b/firmware/target/arm/i2c-pp.c
index 1cc25a1a10..e5813f9f9a 100644
--- a/firmware/target/arm/i2c-pp.c
+++ b/firmware/target/arm/i2c-pp.c
@@ -132,18 +132,18 @@ static int pp_i2c_send_byte(unsigned int addr, int data0)
132} 132}
133 133
134/* Public functions */ 134/* Public functions */
135static struct mutex i2c_mutex; 135struct spinlock i2c_spin NOCACHEBSS_ATTR;
136 136
137int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data) { 137int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data) {
138 unsigned int temp; 138 unsigned int temp;
139 int i; 139 int i;
140 spinlock_lock(&i2c_mutex); 140 spinlock_lock(&i2c_spin);
141 pp_i2c_send_byte(dev_addr, addr); 141 pp_i2c_send_byte(dev_addr, addr);
142 for (i = 0; i < len; i++) { 142 for (i = 0; i < len; i++) {
143 pp_i2c_read_byte(dev_addr, &temp); 143 pp_i2c_read_byte(dev_addr, &temp);
144 data[i] = temp; 144 data[i] = temp;
145 } 145 }
146 spinlock_unlock(&i2c_mutex); 146 spinlock_unlock(&i2c_spin);
147 return i; 147 return i;
148} 148}
149 149
@@ -151,10 +151,10 @@ int i2c_readbyte(unsigned int dev_addr, int addr)
151{ 151{
152 int data; 152 int data;
153 153
154 spinlock_lock(&i2c_mutex); 154 spinlock_lock(&i2c_spin);
155 pp_i2c_send_byte(dev_addr, addr); 155 pp_i2c_send_byte(dev_addr, addr);
156 pp_i2c_read_byte(dev_addr, &data); 156 pp_i2c_read_byte(dev_addr, &data);
157 spinlock_unlock(&i2c_mutex); 157 spinlock_unlock(&i2c_spin);
158 158
159 return data; 159 return data;
160} 160}
@@ -167,9 +167,9 @@ int pp_i2c_send(unsigned int addr, int data0, int data1)
167 data[0] = data0; 167 data[0] = data0;
168 data[1] = data1; 168 data[1] = data1;
169 169
170 spinlock_lock(&i2c_mutex); 170 spinlock_lock(&i2c_spin);
171 retval = pp_i2c_send_bytes(addr, 2, data); 171 retval = pp_i2c_send_bytes(addr, 2, data);
172 spinlock_unlock(&i2c_mutex); 172 spinlock_unlock(&i2c_spin);
173 173
174 return retval; 174 return retval;
175} 175}
@@ -221,7 +221,7 @@ void i2c_init(void)
221#endif 221#endif
222#endif 222#endif
223 223
224 spinlock_init(&i2c_mutex); 224 spinlock_init(&i2c_spin IF_COP(, SPINLOCK_TASK_SWITCH));
225 225
226 i2c_readbyte(0x8, 0); 226 i2c_readbyte(0x8, 0);
227} 227}
diff --git a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c b/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
index 8866c3dcde..3a854afcdc 100644
--- a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
+++ b/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
@@ -22,7 +22,7 @@
22#include "hwcompat.h" 22#include "hwcompat.h"
23#include "kernel.h" 23#include "kernel.h"
24 24
25static struct mutex adc_mutex NOCACHEBSS_ATTR; 25static struct spinlock adc_spin NOCACHEBSS_ATTR;
26 26
27/* used in the 2nd gen ADC interrupt */ 27/* used in the 2nd gen ADC interrupt */
28static unsigned int_data; 28static unsigned int_data;
@@ -33,7 +33,7 @@ unsigned short adc_scan(int channel)
33 unsigned short data = 0; 33 unsigned short data = 0;
34 34
35 (void)channel; /* there is only one */ 35 (void)channel; /* there is only one */
36 spinlock_lock(&adc_mutex); 36 spinlock_lock(&adc_spin);
37 37
38 if ((IPOD_HW_REVISION >> 16) == 1) 38 if ((IPOD_HW_REVISION >> 16) == 1)
39 { 39 {
@@ -69,7 +69,7 @@ unsigned short adc_scan(int channel)
69 69
70 data = int_data & 0xff; 70 data = int_data & 0xff;
71 } 71 }
72 spinlock_unlock(&adc_mutex); 72 spinlock_unlock(&adc_spin);
73 return data; 73 return data;
74} 74}
75 75
@@ -100,7 +100,7 @@ void ipod_2g_adc_int(void)
100 100
101void adc_init(void) 101void adc_init(void)
102{ 102{
103 spinlock_init(&adc_mutex); 103 spinlock_init(&adc_spin IF_COP(, SPINLOCK_TASK_SWITCH));
104 104
105 GPIOB_ENABLE |= 0x1e; /* enable B1..B4 */ 105 GPIOB_ENABLE |= 0x1e; /* enable B1..B4 */
106 106
diff --git a/firmware/target/arm/sandisk/adc-c200_e200.c b/firmware/target/arm/sandisk/adc-c200_e200.c
index 31321ece37..9dc8f3aabb 100644
--- a/firmware/target/arm/sandisk/adc-c200_e200.c
+++ b/firmware/target/arm/sandisk/adc-c200_e200.c
@@ -21,8 +21,6 @@
21#include "i2c-pp.h" 21#include "i2c-pp.h"
22#include "as3514.h" 22#include "as3514.h"
23 23
24static struct mutex adc_mutex NOCACHEBSS_ATTR;
25
26/* Read 10-bit channel data */ 24/* Read 10-bit channel data */
27unsigned short adc_read(int channel) 25unsigned short adc_read(int channel)
28{ 26{
@@ -30,7 +28,7 @@ unsigned short adc_read(int channel)
30 28
31 if ((unsigned)channel < NUM_ADC_CHANNELS) 29 if ((unsigned)channel < NUM_ADC_CHANNELS)
32 { 30 {
33 spinlock_lock(&adc_mutex); 31 spinlock_lock(&i2c_spin);
34 32
35 /* Select channel */ 33 /* Select channel */
36 if (pp_i2c_send( AS3514_I2C_ADDR, ADC_0, (channel << 4)) >= 0) 34 if (pp_i2c_send( AS3514_I2C_ADDR, ADC_0, (channel << 4)) >= 0)
@@ -44,7 +42,7 @@ unsigned short adc_read(int channel)
44 } 42 }
45 } 43 }
46 44
47 spinlock_unlock(&adc_mutex); 45 spinlock_unlock(&i2c_spin);
48 } 46 }
49 47
50 return data; 48 return data;
@@ -52,5 +50,4 @@ unsigned short adc_read(int channel)
52 50
53void adc_init(void) 51void adc_init(void)
54{ 52{
55 spinlock_init(&adc_mutex);
56} 53}
diff --git a/firmware/target/arm/sandisk/ata-c200_e200.c b/firmware/target/arm/sandisk/ata-c200_e200.c
index 14be27e19d..8e17152e6f 100644
--- a/firmware/target/arm/sandisk/ata-c200_e200.c
+++ b/firmware/target/arm/sandisk/ata-c200_e200.c
@@ -162,7 +162,7 @@ static struct sd_card_status sd_status[NUM_VOLUMES] =
162/* Shoot for around 75% usage */ 162/* Shoot for around 75% usage */
163static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; 163static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
164static const char sd_thread_name[] = "ata/sd"; 164static const char sd_thread_name[] = "ata/sd";
165static struct mutex sd_mtx; 165static struct spinlock sd_spin NOCACHEBSS_ATTR;
166static struct event_queue sd_queue; 166static struct event_queue sd_queue;
167 167
168/* Posted when card plugged status has changed */ 168/* Posted when card plugged status has changed */
@@ -801,7 +801,7 @@ int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
801 801
802 /* TODO: Add DMA support. */ 802 /* TODO: Add DMA support. */
803 803
804 spinlock_lock(&sd_mtx); 804 spinlock_lock(&sd_spin);
805 805
806 ata_led(true); 806 ata_led(true);
807 807
@@ -888,7 +888,7 @@ ata_read_retry:
888 while (1) 888 while (1)
889 { 889 {
890 ata_led(false); 890 ata_led(false);
891 spinlock_unlock(&sd_mtx); 891 spinlock_unlock(&sd_spin);
892 892
893 return ret; 893 return ret;
894 894
@@ -916,7 +916,7 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
916 const unsigned char *buf, *buf_end; 916 const unsigned char *buf, *buf_end;
917 int bank; 917 int bank;
918 918
919 spinlock_lock(&sd_mtx); 919 spinlock_lock(&sd_spin);
920 920
921 ata_led(true); 921 ata_led(true);
922 922
@@ -1016,7 +1016,7 @@ ata_write_retry:
1016 while (1) 1016 while (1)
1017 { 1017 {
1018 ata_led(false); 1018 ata_led(false);
1019 spinlock_unlock(&sd_mtx); 1019 spinlock_unlock(&sd_spin);
1020 1020
1021 return ret; 1021 return ret;
1022 1022
@@ -1034,7 +1034,7 @@ ata_write_error:
1034static void sd_thread(void) __attribute__((noreturn)); 1034static void sd_thread(void) __attribute__((noreturn));
1035static void sd_thread(void) 1035static void sd_thread(void)
1036{ 1036{
1037 struct event ev; 1037 struct queue_event ev;
1038 bool idle_notified = false; 1038 bool idle_notified = false;
1039 1039
1040 while (1) 1040 while (1)
@@ -1050,10 +1050,9 @@ static void sd_thread(void)
1050 1050
1051 /* Lock to keep us from messing with this variable while an init 1051 /* Lock to keep us from messing with this variable while an init
1052 may be in progress */ 1052 may be in progress */
1053 spinlock_lock(&sd_mtx); 1053 spinlock_lock(&sd_spin);
1054 card_info[1].initialized = 0; 1054 card_info[1].initialized = 0;
1055 sd_status[1].retry = 0; 1055 sd_status[1].retry = 0;
1056 spinlock_unlock(&sd_mtx);
1057 1056
1058 /* Either unmount because the card was pulled or unmount and 1057 /* Either unmount because the card was pulled or unmount and
1059 remount if already mounted since multiple messages may be 1058 remount if already mounted since multiple messages may be
@@ -1073,6 +1072,8 @@ static void sd_thread(void)
1073 1072
1074 if (action != SDA_NONE) 1073 if (action != SDA_NONE)
1075 queue_broadcast(SYS_FS_CHANGED, 0); 1074 queue_broadcast(SYS_FS_CHANGED, 0);
1075
1076 spinlock_unlock(&sd_spin);
1076 break; 1077 break;
1077 } /* SD_HOTSWAP */ 1078 } /* SD_HOTSWAP */
1078#endif /* HAVE_HOTSWAP */ 1079#endif /* HAVE_HOTSWAP */
@@ -1155,9 +1156,9 @@ int ata_init(void)
1155 { 1156 {
1156 initialized = true; 1157 initialized = true;
1157 1158
1158 spinlock_init(&sd_mtx); 1159 spinlock_init(&sd_spin IF_COP(, SPINLOCK_TASK_SWITCH));
1159 1160
1160 spinlock_lock(&sd_mtx); 1161 spinlock_lock(&sd_spin);
1161 1162
1162 /* init controller */ 1163 /* init controller */
1163 outl(inl(0x70000088) & ~(0x4), 0x70000088); 1164 outl(inl(0x70000088) & ~(0x4), 0x70000088);
@@ -1181,8 +1182,8 @@ int ata_init(void)
1181 ret = currcard->initialized; 1182 ret = currcard->initialized;
1182 1183
1183 queue_init(&sd_queue, true); 1184 queue_init(&sd_queue, true);
1184 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 1185 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
1185 sd_thread_name IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU, false)); 1186 sd_thread_name IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU));
1186 1187
1187 /* enable interupt for the mSD card */ 1188 /* enable interupt for the mSD card */
1188 sleep(HZ/10); 1189 sleep(HZ/10);
@@ -1195,7 +1196,7 @@ int ata_init(void)
1195 GPIOA_INT_CLR = 0x80; 1196 GPIOA_INT_CLR = 0x80;
1196 GPIOA_INT_EN |= 0x80; 1197 GPIOA_INT_EN |= 0x80;
1197#endif 1198#endif
1198 spinlock_unlock(&sd_mtx); 1199 spinlock_unlock(&sd_spin);
1199 } 1200 }
1200 1201
1201 return ret; 1202 return ret;
diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c
index 576459d6c1..d24d19f747 100644
--- a/firmware/target/arm/system-pp502x.c
+++ b/firmware/target/arm/system-pp502x.c
@@ -21,10 +21,6 @@
21#include "i2s.h" 21#include "i2s.h"
22#include "i2c-pp.h" 22#include "i2c-pp.h"
23 23
24#if NUM_CORES > 1
25struct mutex boostctrl_mtx NOCACHEBSS_ATTR;
26#endif
27
28#ifndef BOOTLOADER 24#ifndef BOOTLOADER
29extern void TIMER1(void); 25extern void TIMER1(void);
30extern void TIMER2(void); 26extern void TIMER2(void);
@@ -129,16 +125,42 @@ static void init_cache(void)
129} 125}
130 126
131#ifdef HAVE_ADJUSTABLE_CPU_FREQ 127#ifdef HAVE_ADJUSTABLE_CPU_FREQ
128void scale_suspend_core(bool suspend) ICODE_ATTR;
129void scale_suspend_core(bool suspend)
130{
131 unsigned int core = CURRENT_CORE;
132 unsigned int othercore = 1 - core;
133 static unsigned long proc_bits IBSS_ATTR;
134 static int oldstatus IBSS_ATTR;
135
136 if (suspend)
137 {
138 oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS);
139 proc_bits = PROC_CTL(othercore) & 0xc0000000;
140 PROC_CTL(othercore) = 0x40000000; nop;
141 PROC_CTL(core) = 0x48000003; nop;
142 }
143 else
144 {
145 PROC_CTL(core) = 0x4800001f; nop;
146 if (proc_bits == 0)
147 PROC_CTL(othercore) = 0;
148 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);
149 }
150}
151
152void set_cpu_frequency(long frequency) ICODE_ATTR;
132void set_cpu_frequency(long frequency) 153void set_cpu_frequency(long frequency)
133#else 154#else
134static void pp_set_cpu_frequency(long frequency) 155static void pp_set_cpu_frequency(long frequency)
135#endif 156#endif
136{ 157{
137#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) 158#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
138 /* Using mutex or spinlock isn't safe here. */ 159 spinlock_lock(&boostctrl_spin);
139 while (test_and_set(&boostctrl_mtx.locked, 1)) ;
140#endif 160#endif
141 161
162 scale_suspend_core(true);
163
142 cpu_frequency = frequency; 164 cpu_frequency = frequency;
143 165
144 switch (frequency) 166 switch (frequency)
@@ -149,17 +171,20 @@ static void pp_set_cpu_frequency(long frequency)
149 * have this limitation (and the post divider?) */ 171 * have this limitation (and the post divider?) */
150 case CPUFREQ_MAX: 172 case CPUFREQ_MAX:
151 CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ 173 CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */
152 DEV_TIMING1 = 0x00000808; 174 DEV_TIMING1 = 0x00000303;
153#if CONFIG_CPU == PP5020 175#if CONFIG_CPU == PP5020
154 PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */ 176 PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */
155 PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */ 177 PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */
156 PLL_CONTROL = 0x8a020a03; /* repeat setup */ 178 PLL_CONTROL = 0x8a020a03; /* repeat setup */
179 scale_suspend_core(false);
157 udelay(500); /* wait for relock */ 180 udelay(500); /* wait for relock */
158#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) 181#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
159 PLL_CONTROL = 0x8a121403; /* (20/3 * 24MHz) / 2 */ 182 PLL_CONTROL = 0x8a121403; /* (20/3 * 24MHz) / 2 */
183 scale_suspend_core(false);
160 udelay(250); 184 udelay(250);
161 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ 185 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
162#endif 186#endif
187 scale_suspend_core(true);
163 break; 188 break;
164 189
165 case CPUFREQ_NORMAL: 190 case CPUFREQ_NORMAL:
@@ -167,18 +192,23 @@ static void pp_set_cpu_frequency(long frequency)
167 DEV_TIMING1 = 0x00000303; 192 DEV_TIMING1 = 0x00000303;
168#if CONFIG_CPU == PP5020 193#if CONFIG_CPU == PP5020
169 PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */ 194 PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */
195 scale_suspend_core(false);
170 udelay(500); /* wait for relock */ 196 udelay(500); /* wait for relock */
171#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) 197#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
172 PLL_CONTROL = 0x8a220501; /* (5/1 * 24MHz) / 4 */ 198 PLL_CONTROL = 0x8a220501; /* (5/1 * 24MHz) / 4 */
199 scale_suspend_core(false);
173 udelay(250); 200 udelay(250);
174 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ 201 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
175#endif 202#endif
203 scale_suspend_core(true);
176 break; 204 break;
177 205
178 case CPUFREQ_SLEEP: 206 case CPUFREQ_SLEEP:
179 CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */ 207 CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */
180 PLL_CONTROL &= ~0x80000000; /* disable PLL */ 208 PLL_CONTROL &= ~0x80000000; /* disable PLL */
209 scale_suspend_core(false);
181 udelay(10000); /* let 32kHz source stabilize? */ 210 udelay(10000); /* let 32kHz source stabilize? */
211 scale_suspend_core(true);
182 break; 212 break;
183 213
184 default: 214 default:
@@ -186,12 +216,19 @@ static void pp_set_cpu_frequency(long frequency)
186 DEV_TIMING1 = 0x00000303; 216 DEV_TIMING1 = 0x00000303;
187 PLL_CONTROL &= ~0x80000000; /* disable PLL */ 217 PLL_CONTROL &= ~0x80000000; /* disable PLL */
188 cpu_frequency = CPUFREQ_DEFAULT; 218 cpu_frequency = CPUFREQ_DEFAULT;
219 PROC_CTL(CURRENT_CORE) = 0x4800001f; nop;
189 break; 220 break;
190 } 221 }
222
223 if (frequency == CPUFREQ_MAX)
224 DEV_TIMING1 = 0x00000808;
225
191 CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */ 226 CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */
192 227
228 scale_suspend_core(false);
229
193#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) 230#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
194 boostctrl_mtx.locked = 0; 231 spinlock_unlock(&boostctrl_spin);
195#endif 232#endif
196} 233}
197#endif /* !BOOTLOADER */ 234#endif /* !BOOTLOADER */
@@ -256,7 +293,7 @@ void system_init(void)
256 293
257#ifdef HAVE_ADJUSTABLE_CPU_FREQ 294#ifdef HAVE_ADJUSTABLE_CPU_FREQ
258#if NUM_CORES > 1 295#if NUM_CORES > 1
259 spinlock_init(&boostctrl_mtx); 296 cpu_boost_init();
260#endif 297#endif
261#else 298#else
262 pp_set_cpu_frequency(CPUFREQ_MAX); 299 pp_set_cpu_frequency(CPUFREQ_MAX);
diff --git a/firmware/target/arm/system-target.h b/firmware/target/arm/system-target.h
index 7a1ff4f79a..6e433be9d5 100644
--- a/firmware/target/arm/system-target.h
+++ b/firmware/target/arm/system-target.h
@@ -46,6 +46,10 @@
46#define inw(a) (*(volatile unsigned short *) (a)) 46#define inw(a) (*(volatile unsigned short *) (a))
47#define outw(a,b) (*(volatile unsigned short *) (b) = (a)) 47#define outw(a,b) (*(volatile unsigned short *) (b) = (a))
48 48
49#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && NUM_CORES > 1
50extern struct spinlock boostctrl_spin;
51#endif
52
49static inline void udelay(unsigned usecs) 53static inline void udelay(unsigned usecs)
50{ 54{
51 unsigned stop = USEC_TIMER + usecs; 55 unsigned stop = USEC_TIMER + usecs;
@@ -107,7 +111,6 @@ void flush_icache(void);
107 111
108#endif /* CPU_PP502x */ 112#endif /* CPU_PP502x */
109 113
110
111#endif /* CPU_PP */ 114#endif /* CPU_PP */
112 115
113#endif /* SYSTEM_TARGET_H */ 116#endif /* SYSTEM_TARGET_H */