diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-10-16 01:25:17 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-10-16 01:25:17 +0000 |
commit | a9b2fb5ee3114fe835f6515b6aeae7454f66d821 (patch) | |
tree | fc4e96d0c1f215565918406c8827b16b806c1345 /firmware/target | |
parent | a3fbbc9fa7e12fd3fce122bbd235dc362050e024 (diff) | |
download | rockbox-a9b2fb5ee3114fe835f6515b6aeae7454f66d821.tar.gz rockbox-a9b2fb5ee3114fe835f6515b6aeae7454f66d821.zip |
Finally full multicore support for PortalPlayer 502x targets with an eye towards the possibility of other types. All SVN targets the low-lag code to speed up blocking operations. Most files are modified here simple due to a name change to actually support a real event object and a param change to create_thread. Add some use of new features but just sit on things for a bit and leave full integration for later. Work will continue on to address size on sensitive targets and simplify things if possible. Any PP target having problems with SWP can easily be changed to sw corelocks with one #define change in config.h though only PP5020 has shown an issue and seems to work without any difficulties.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15134 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/i2c-pp.c | 16 | ||||
-rw-r--r-- | firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c | 8 | ||||
-rw-r--r-- | firmware/target/arm/sandisk/adc-c200_e200.c | 7 | ||||
-rw-r--r-- | firmware/target/arm/sandisk/ata-c200_e200.c | 27 | ||||
-rw-r--r-- | firmware/target/arm/system-pp502x.c | 55 | ||||
-rw-r--r-- | firmware/target/arm/system-target.h | 5 |
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 */ |
135 | static struct mutex i2c_mutex; | 135 | struct spinlock i2c_spin NOCACHEBSS_ATTR; |
136 | 136 | ||
137 | int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data) { | 137 | int 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 | ||
25 | static struct mutex adc_mutex NOCACHEBSS_ATTR; | 25 | static struct spinlock adc_spin NOCACHEBSS_ATTR; |
26 | 26 | ||
27 | /* used in the 2nd gen ADC interrupt */ | 27 | /* used in the 2nd gen ADC interrupt */ |
28 | static unsigned int_data; | 28 | static 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 | ||
101 | void adc_init(void) | 101 | void 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 | ||
24 | static struct mutex adc_mutex NOCACHEBSS_ATTR; | ||
25 | |||
26 | /* Read 10-bit channel data */ | 24 | /* Read 10-bit channel data */ |
27 | unsigned short adc_read(int channel) | 25 | unsigned 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 | ||
53 | void adc_init(void) | 51 | void 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 */ |
163 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; | 163 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; |
164 | static const char sd_thread_name[] = "ata/sd"; | 164 | static const char sd_thread_name[] = "ata/sd"; |
165 | static struct mutex sd_mtx; | 165 | static struct spinlock sd_spin NOCACHEBSS_ATTR; |
166 | static struct event_queue sd_queue; | 166 | static 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: | |||
1034 | static void sd_thread(void) __attribute__((noreturn)); | 1034 | static void sd_thread(void) __attribute__((noreturn)); |
1035 | static void sd_thread(void) | 1035 | static 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 | ||
25 | struct mutex boostctrl_mtx NOCACHEBSS_ATTR; | ||
26 | #endif | ||
27 | |||
28 | #ifndef BOOTLOADER | 24 | #ifndef BOOTLOADER |
29 | extern void TIMER1(void); | 25 | extern void TIMER1(void); |
30 | extern void TIMER2(void); | 26 | extern 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 |
128 | void scale_suspend_core(bool suspend) ICODE_ATTR; | ||
129 | void 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 | |||
152 | void set_cpu_frequency(long frequency) ICODE_ATTR; | ||
132 | void set_cpu_frequency(long frequency) | 153 | void set_cpu_frequency(long frequency) |
133 | #else | 154 | #else |
134 | static void pp_set_cpu_frequency(long frequency) | 155 | static 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 | ||
50 | extern struct spinlock boostctrl_spin; | ||
51 | #endif | ||
52 | |||
49 | static inline void udelay(unsigned usecs) | 53 | static 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 */ |