diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/imx31/avic-imx31.c | 15 | ||||
-rw-r--r-- | firmware/target/arm/imx31/avic-imx31.h | 33 | ||||
-rw-r--r-- | firmware/target/arm/imx31/debug-imx31.c | 12 | ||||
-rw-r--r-- | firmware/target/arm/imx31/dvfs_dptc-imx31.c | 41 | ||||
-rw-r--r-- | firmware/target/arm/imx31/dvfs_dptc-imx31.h | 10 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h | 224 |
6 files changed, 178 insertions, 157 deletions
diff --git a/firmware/target/arm/imx31/avic-imx31.c b/firmware/target/arm/imx31/avic-imx31.c index 51ba14d0b3..e349c97d82 100644 --- a/firmware/target/arm/imx31/avic-imx31.c +++ b/firmware/target/arm/imx31/avic-imx31.c | |||
@@ -119,8 +119,10 @@ void avic_init(void) | |||
119 | for (i = 0; i < 8; i++) | 119 | for (i = 0; i < 8; i++) |
120 | avic->nipriority[i] = 0; | 120 | avic->nipriority[i] = 0; |
121 | 121 | ||
122 | /* Set NM bit to enable VIC */ | 122 | /* Set NM bit to enable VIC. Mask fast interrupts. Core arbiter rise |
123 | avic->intcntl |= AVIC_INTCNTL_NM; | 123 | * for normal interrupts (for lowest latency). */ |
124 | avic->intcntl |= AVIC_INTCNTL_NM | AVIC_INTCNTL_FIDIS | | ||
125 | AVIC_INTCNTL_NIAD; | ||
124 | 126 | ||
125 | /* Enable VE bit in CP15 Control reg to enable VIC */ | 127 | /* Enable VE bit in CP15 Control reg to enable VIC */ |
126 | asm volatile ( | 128 | asm volatile ( |
@@ -213,7 +215,12 @@ void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype) | |||
213 | restore_interrupt(oldstatus); | 215 | restore_interrupt(oldstatus); |
214 | } | 216 | } |
215 | 217 | ||
216 | void avic_set_ni_level(unsigned int level) | 218 | void avic_set_ni_level(int level) |
217 | { | 219 | { |
218 | AVIC_NIMASK = level > 0x1f ? 0x1f : level; | 220 | if (level < 0) |
221 | level = 0x1f; /* -1 */ | ||
222 | else if (level > 15) | ||
223 | level = 15; | ||
224 | |||
225 | AVIC_NIMASK = level; | ||
219 | } | 226 | } |
diff --git a/firmware/target/arm/imx31/avic-imx31.h b/firmware/target/arm/imx31/avic-imx31.h index 43fd726db3..ba9e50652d 100644 --- a/firmware/target/arm/imx31/avic-imx31.h +++ b/firmware/target/arm/imx31/avic-imx31.h | |||
@@ -214,14 +214,16 @@ void avic_set_int_priority(enum IMX31_INT_LIST ints, | |||
214 | void avic_disable_int(enum IMX31_INT_LIST ints); | 214 | void avic_disable_int(enum IMX31_INT_LIST ints); |
215 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); | 215 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); |
216 | 216 | ||
217 | #define AVIC_NIL_DISABLE 0xf | 217 | #define AVIC_NIL_DISABLE 15 |
218 | #define AVIC_NIL_ENABLE 0x1f | 218 | #define AVIC_NIL_ENABLE (-1) |
219 | void avic_set_ni_level(unsigned int level); | 219 | void avic_set_ni_level(int level); |
220 | 220 | ||
221 | 221 | ||
222 | /* Call a service routine while allowing preemption by interrupts of higher | 222 | /* Call a service routine while allowing preemption by interrupts of higher |
223 | * priority. r4-r7 must be preserved for epilogue code to restore context. */ | 223 | * priority. Avoid using any app or other SVC stack by doing it with a mini |
224 | #define AVIC_NESTED_NI_CALL_PROLOGUE(prio) \ | 224 | * "stack on irq stack". Avoid actually enabling IRQ until the routine |
225 | * decides to do so; epilogue code will always disable them again. */ | ||
226 | #define AVIC_NESTED_NI_CALL_PROLOGUE(prio, stacksize) \ | ||
225 | ({ asm volatile ( \ | 227 | ({ asm volatile ( \ |
226 | "sub lr, lr, #4 \n" /* prepare return address */ \ | 228 | "sub lr, lr, #4 \n" /* prepare return address */ \ |
227 | "srsdb #0x12! \n" /* save LR_irq and SPSR_irq */ \ | 229 | "srsdb #0x12! \n" /* save LR_irq and SPSR_irq */ \ |
@@ -230,18 +232,25 @@ void avic_set_ni_level(unsigned int level); | |||
230 | "mov r1, %0 \n" /* load interrupt level */ \ | 232 | "mov r1, %0 \n" /* load interrupt level */ \ |
231 | "ldr r2, [r0, #0x04] \n" /* save NIMASK */ \ | 233 | "ldr r2, [r0, #0x04] \n" /* save NIMASK */ \ |
232 | "str r1, [r0, #0x04] \n" /* set interrupt level */ \ | 234 | "str r1, [r0, #0x04] \n" /* set interrupt level */ \ |
233 | "cpsie i, #0x13 \n" /* change to SVC mode, unmask IRQ */ \ | 235 | "mov r0, sp \n" /* grab IRQ stack */ \ |
234 | "stmfd sp!, { r2, lr } \n" /* push NIMASK and LR on SVC stack */ \ | 236 | "sub sp, sp, %1 \n" /* allocate space for routine to SP_irq */ \ |
235 | : : "i"(prio)); }) | 237 | "cps #0x13 \n" /* change to SVC mode */ \ |
238 | "mov r1, sp \n" /* save SP_svc */ \ | ||
239 | "mov sp, r0 \n" /* switch to SP_irq *copy* */ \ | ||
240 | "stmfd sp!, { r1, r2, lr } \n" /* push SP_svc, NIMASK and LR_svc */ \ | ||
241 | : : "i"(prio), "i"(stacksize)); }) | ||
236 | 242 | ||
237 | #define AVIC_NESTED_NI_CALL_EPILOGUE() \ | 243 | #define AVIC_NESTED_NI_CALL_EPILOGUE(stacksize) \ |
238 | ({ asm volatile ( \ | 244 | ({ asm volatile ( \ |
239 | "ldmfd sp!, { r2, lr } \n" /* pop original LR and NIMASK */ \ | 245 | "cpsid i \n" /* disable IRQ */ \ |
240 | "cpsid i, #0x12 \n" /* return to IRQ mode, mask IRQ */ \ | 246 | "ldmfd sp!, { r1, r2, lr } \n" /* pop SP_svc, NIMASK and LR_svc */ \ |
247 | "mov sp, r1 \n" /* restore SP_svc */ \ | ||
248 | "cps #0x12 \n" /* return to IRQ mode */ \ | ||
249 | "add sp, sp, %0 \n" /* deallocate routine space */ \ | ||
241 | "mov r0, #0x68000000 \n" /* AVIC BASE ADDR */ \ | 250 | "mov r0, #0x68000000 \n" /* AVIC BASE ADDR */ \ |
242 | "str r2, [r0, #0x04] \n" /* restore NIMASK */ \ | 251 | "str r2, [r0, #0x04] \n" /* restore NIMASK */ \ |
243 | "ldmfd sp!, { r0-r3, r12 } \n" /* reload context */ \ | 252 | "ldmfd sp!, { r0-r3, r12 } \n" /* reload context */ \ |
244 | "rfefd sp! \n" /* move stacked SPSR to CPSR, return */ \ | 253 | "rfefd sp! \n" /* move stacked SPSR to CPSR, return */ \ |
245 | ); }) | 254 | : : "i"(stacksize)); }) |
246 | 255 | ||
247 | #endif /* AVIC_IMX31_H */ | 256 | #endif /* AVIC_IMX31_H */ |
diff --git a/firmware/target/arm/imx31/debug-imx31.c b/firmware/target/arm/imx31/debug-imx31.c index 2c4f8b4023..783ba728a6 100644 --- a/firmware/target/arm/imx31/debug-imx31.c +++ b/firmware/target/arm/imx31/debug-imx31.c | |||
@@ -40,8 +40,10 @@ bool __dbg_hw_info(void) | |||
40 | unsigned int freq; | 40 | unsigned int freq; |
41 | uint32_t regval; | 41 | uint32_t regval; |
42 | 42 | ||
43 | extern volatile unsigned int dvfs_nr_dn, dvfs_nr_up, dvfs_nr_pnc; | 43 | extern volatile unsigned int dvfs_nr_dn, dvfs_nr_up, |
44 | extern volatile unsigned int dptc_nr_dn, dptc_nr_up, dptc_nr_pnc; | 44 | dvfs_nr_pnc, dvfs_nr_no; |
45 | extern volatile unsigned int dptc_nr_dn, dptc_nr_up, | ||
46 | dptc_nr_pnc, dptc_nr_no; | ||
45 | 47 | ||
46 | lcd_clear_display(); | 48 | lcd_clear_display(); |
47 | lcd_setfont(FONT_SYSFIXED); | 49 | lcd_setfont(FONT_SYSFIXED); |
@@ -119,13 +121,15 @@ bool __dbg_hw_info(void) | |||
119 | lcd_putsf(0, line++, "cpu_frequency: %ld Hz", cpu_frequency); | 121 | lcd_putsf(0, line++, "cpu_frequency: %ld Hz", cpu_frequency); |
120 | 122 | ||
121 | lcd_putsf(0, line++, "dvfs_level: %u", dvfs_get_level()); | 123 | lcd_putsf(0, line++, "dvfs_level: %u", dvfs_get_level()); |
122 | lcd_putsf(0, line++, "dvfs d|u|p: %u %u %u", dvfs_nr_dn, dvfs_nr_up, dvfs_nr_pnc); | 124 | lcd_putsf(0, line++, "dvfs d|u|p|n: %u %u %u %u", |
125 | dvfs_nr_dn, dvfs_nr_up, dvfs_nr_pnc, dvfs_nr_no); | ||
123 | regval = dvfs_dptc_get_voltage(); | 126 | regval = dvfs_dptc_get_voltage(); |
124 | lcd_putsf(0, line++, "cpu_voltage: %d.%03d V", regval / 1000, | 127 | lcd_putsf(0, line++, "cpu_voltage: %d.%03d V", regval / 1000, |
125 | regval % 1000); | 128 | regval % 1000); |
126 | 129 | ||
127 | lcd_putsf(0, line++, "dptc_wp: %u", dptc_get_wp()); | 130 | lcd_putsf(0, line++, "dptc_wp: %u", dptc_get_wp()); |
128 | lcd_putsf(0, line++, "dptc d|u|p: %u %u %u", dptc_nr_dn, dptc_nr_up, dptc_nr_pnc); | 131 | lcd_putsf(0, line++, "dptc d|u|p|n: %u %u %u %u", |
132 | dptc_nr_dn, dptc_nr_up, dptc_nr_pnc, dptc_nr_no); | ||
129 | lcd_putsf(0, line++, "DVCR0,1: %08lX %08lX", CCM_DCVR0, CCM_DCVR1); | 133 | lcd_putsf(0, line++, "DVCR0,1: %08lX %08lX", CCM_DCVR0, CCM_DCVR1); |
130 | lcd_putsf(0, line++, "DVCR2,3: %08lX %08lX", CCM_DCVR2, CCM_DCVR3); | 134 | lcd_putsf(0, line++, "DVCR2,3: %08lX %08lX", CCM_DCVR2, CCM_DCVR3); |
131 | lcd_putsf(0, line++, "SWITCHERS0: %08lX", mc13783_read(MC13783_SWITCHERS0)); | 135 | lcd_putsf(0, line++, "SWITCHERS0: %08lX", mc13783_read(MC13783_SWITCHERS0)); |
diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.c b/firmware/target/arm/imx31/dvfs_dptc-imx31.c index 680b015c81..cae9a384c9 100644 --- a/firmware/target/arm/imx31/dvfs_dptc-imx31.c +++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.c | |||
@@ -72,6 +72,7 @@ static bool dvfs_running = false; /* Has driver enabled DVFS? */ | |||
72 | unsigned int dvfs_nr_dn = 0; | 72 | unsigned int dvfs_nr_dn = 0; |
73 | unsigned int dvfs_nr_up = 0; | 73 | unsigned int dvfs_nr_up = 0; |
74 | unsigned int dvfs_nr_pnc = 0; | 74 | unsigned int dvfs_nr_pnc = 0; |
75 | unsigned int dvfs_nr_no = 0; | ||
75 | 76 | ||
76 | static void dvfs_stop(void); | 77 | static void dvfs_stop(void); |
77 | 78 | ||
@@ -83,7 +84,7 @@ static inline void wait_for_dvfs_update_en(void) | |||
83 | } | 84 | } |
84 | 85 | ||
85 | 86 | ||
86 | static void do_dvfs_update(unsigned int level) | 87 | static void do_dvfs_update(unsigned int level, bool in_isr) |
87 | { | 88 | { |
88 | const struct dvfs_clock_table_entry *setting = &dvfs_clock_table[level]; | 89 | const struct dvfs_clock_table_entry *setting = &dvfs_clock_table[level]; |
89 | unsigned long pmcr0 = CCM_PMCR0; | 90 | unsigned long pmcr0 = CCM_PMCR0; |
@@ -96,7 +97,7 @@ static void do_dvfs_update(unsigned int level) | |||
96 | 97 | ||
97 | pmcr0 &= ~CCM_PMCR0_VSCNT; | 98 | pmcr0 &= ~CCM_PMCR0_VSCNT; |
98 | 99 | ||
99 | if (level > ((pmcr0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS)) | 100 | if (level < ((pmcr0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS)) |
100 | { | 101 | { |
101 | pmcr0 |= CCM_PMCR0_UDSC; /* Up scaling, increase */ | 102 | pmcr0 |= CCM_PMCR0_UDSC; /* Up scaling, increase */ |
102 | pmcr0 |= setting->vscnt << CCM_PMCR0_VSCNT_POS; | 103 | pmcr0 |= setting->vscnt << CCM_PMCR0_VSCNT_POS; |
@@ -126,7 +127,15 @@ static void do_dvfs_update(unsigned int level) | |||
126 | } | 127 | } |
127 | 128 | ||
128 | CCM_PMCR0 = pmcr0; | 129 | CCM_PMCR0 = pmcr0; |
130 | /* Note: changes to frequency with ints unmaked seem to cause spurious | ||
131 | * DVFS interrupts with value CCM_PMCR0_FSVAI_NO_INT. These aren't | ||
132 | * supposed to happen. Only do the lengthy delay with them enabled iff | ||
133 | * called from the IRQ handler. */ | ||
134 | if (in_isr) | ||
135 | enable_irq(); | ||
129 | udelay(100); /* Software wait for voltage ramp-up */ | 136 | udelay(100); /* Software wait for voltage ramp-up */ |
137 | if (in_isr) | ||
138 | disable_irq(); | ||
130 | CCM_PDR0 = setting->pdr_val; | 139 | CCM_PDR0 = setting->pdr_val; |
131 | 140 | ||
132 | if (!(pmcr0 & CCM_PMCR0_DFSUP_POST_DIVIDERS)) | 141 | if (!(pmcr0 & CCM_PMCR0_DFSUP_POST_DIVIDERS)) |
@@ -160,7 +169,7 @@ static void set_current_dvfs_level(unsigned int level) | |||
160 | 169 | ||
161 | wait_for_dvfs_update_en(); | 170 | wait_for_dvfs_update_en(); |
162 | 171 | ||
163 | do_dvfs_update(level); | 172 | do_dvfs_update(level, false); |
164 | 173 | ||
165 | wait_for_dvfs_update_en(); | 174 | wait_for_dvfs_update_en(); |
166 | 175 | ||
@@ -191,7 +200,8 @@ static void __attribute__((used)) dvfs_int(void) | |||
191 | 200 | ||
192 | /* Upon the DECREASE event, the frequency will be changed to the next | 201 | /* Upon the DECREASE event, the frequency will be changed to the next |
193 | * higher state index. */ | 202 | * higher state index. */ |
194 | level++; | 203 | while (((1u << ++level) & DVFS_LEVEL_MASK) == 0); |
204 | |||
195 | dvfs_nr_dn++; | 205 | dvfs_nr_dn++; |
196 | break; | 206 | break; |
197 | 207 | ||
@@ -202,7 +212,8 @@ static void __attribute__((used)) dvfs_int(void) | |||
202 | 212 | ||
203 | /* Upon the INCREASE event, the frequency will be changed to the next | 213 | /* Upon the INCREASE event, the frequency will be changed to the next |
204 | * lower state index. */ | 214 | * lower state index. */ |
205 | level--; | 215 | while (((1u << --level) & DVFS_LEVEL_MASK) == 0); |
216 | |||
206 | dvfs_nr_up++; | 217 | dvfs_nr_up++; |
207 | break; | 218 | break; |
208 | 219 | ||
@@ -218,11 +229,11 @@ static void __attribute__((used)) dvfs_int(void) | |||
218 | break; | 229 | break; |
219 | 230 | ||
220 | case CCM_PMCR0_FSVAI_NO_INT: | 231 | case CCM_PMCR0_FSVAI_NO_INT: |
221 | default: | 232 | dvfs_nr_no++; |
222 | return; /* Do nothing. Freq change is not required */ | 233 | return; /* Do nothing. Freq change is not required */ |
223 | } /* end switch */ | 234 | } /* end switch */ |
224 | 235 | ||
225 | do_dvfs_update(level); | 236 | do_dvfs_update(level, true); |
226 | } | 237 | } |
227 | 238 | ||
228 | 239 | ||
@@ -230,9 +241,9 @@ static void __attribute__((used)) dvfs_int(void) | |||
230 | static __attribute__((naked, interrupt("IRQ"))) void CCM_DVFS_HANDLER(void) | 241 | static __attribute__((naked, interrupt("IRQ"))) void CCM_DVFS_HANDLER(void) |
231 | { | 242 | { |
232 | /* Audio can glitch with the long udelay if nested IRQ isn't allowed. */ | 243 | /* Audio can glitch with the long udelay if nested IRQ isn't allowed. */ |
233 | AVIC_NESTED_NI_CALL_PROLOGUE(INT_PRIO_DVFS); | 244 | AVIC_NESTED_NI_CALL_PROLOGUE(INT_PRIO_DVFS, 32*4); |
234 | asm volatile ("bl dvfs_int"); | 245 | asm volatile ("bl dvfs_int"); |
235 | AVIC_NESTED_NI_CALL_EPILOGUE(); | 246 | AVIC_NESTED_NI_CALL_EPILOGUE(32*4); |
236 | } | 247 | } |
237 | 248 | ||
238 | 249 | ||
@@ -281,7 +292,7 @@ static void dvfs_init(void) | |||
281 | imx31_regmod32(&CCM_LTR0, | 292 | imx31_regmod32(&CCM_LTR0, |
282 | DVFS_UPTHR << CCM_LTR0_UPTHR_POS | | 293 | DVFS_UPTHR << CCM_LTR0_UPTHR_POS | |
283 | DVFS_DNTHR << CCM_LTR0_DNTHR_POS | | 294 | DVFS_DNTHR << CCM_LTR0_DNTHR_POS | |
284 | DVFS_DIV3CK, | 295 | DVFS_DIV3CK << CCM_LTR0_DIV3CK_POS, |
285 | CCM_LTR0_UPTHR | CCM_LTR0_DNTHR | CCM_LTR0_DIV3CK); | 296 | CCM_LTR0_UPTHR | CCM_LTR0_DNTHR | CCM_LTR0_DIV3CK); |
286 | 297 | ||
287 | /* Set up LTR1. */ | 298 | /* Set up LTR1. */ |
@@ -356,7 +367,7 @@ static void dvfs_stop(void) | |||
356 | { | 367 | { |
357 | /* Set default frequency level */ | 368 | /* Set default frequency level */ |
358 | wait_for_dvfs_update_en(); | 369 | wait_for_dvfs_update_en(); |
359 | do_dvfs_update(DVFS_LEVEL_DEFAULT); | 370 | do_dvfs_update(DVFS_LEVEL_DEFAULT, false); |
360 | wait_for_dvfs_update_en(); | 371 | wait_for_dvfs_update_en(); |
361 | } | 372 | } |
362 | 373 | ||
@@ -379,6 +390,7 @@ static bool dptc_running = false; /* Has driver enabled DPTC? */ | |||
379 | unsigned int dptc_nr_dn = 0; | 390 | unsigned int dptc_nr_dn = 0; |
380 | unsigned int dptc_nr_up = 0; | 391 | unsigned int dptc_nr_up = 0; |
381 | unsigned int dptc_nr_pnc = 0; | 392 | unsigned int dptc_nr_pnc = 0; |
393 | unsigned int dptc_nr_no = 0; | ||
382 | 394 | ||
383 | static struct spi_transfer_desc dptc_pmic_xfer; /* Transfer descriptor */ | 395 | static struct spi_transfer_desc dptc_pmic_xfer; /* Transfer descriptor */ |
384 | static const unsigned char dptc_pmic_regs[2] = /* Register subaddresses */ | 396 | static const unsigned char dptc_pmic_regs[2] = /* Register subaddresses */ |
@@ -492,7 +504,12 @@ static void dptc_new_wp(unsigned int wp) | |||
492 | /* Interrupt vector for DPTC */ | 504 | /* Interrupt vector for DPTC */ |
493 | static __attribute__((interrupt("IRQ"))) void CCM_CLK_HANDLER(void) | 505 | static __attribute__((interrupt("IRQ"))) void CCM_CLK_HANDLER(void) |
494 | { | 506 | { |
495 | dptc_int(CCM_PMCR0); | 507 | unsigned long pmcr0 = CCM_PMCR0; |
508 | |||
509 | if ((pmcr0 & CCM_PMCR0_PTVAI) == CCM_PMCR0_PTVAI_NO_INT) | ||
510 | dptc_nr_no++; | ||
511 | |||
512 | dptc_int(pmcr0); | ||
496 | } | 513 | } |
497 | 514 | ||
498 | 515 | ||
diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.h b/firmware/target/arm/imx31/dvfs_dptc-imx31.h index 2bf6114a11..844fd6ebff 100644 --- a/firmware/target/arm/imx31/dvfs_dptc-imx31.h +++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.h | |||
@@ -107,6 +107,16 @@ struct dvfs_lt_signal_descriptor | |||
107 | uint8_t detect : 1; /* 1 = edge-detected */ | 107 | uint8_t detect : 1; /* 1 = edge-detected */ |
108 | }; | 108 | }; |
109 | 109 | ||
110 | #define DVFS_NUM_LEVELS 4 | ||
111 | #define DPTC_NUM_WP 17 | ||
112 | |||
113 | /* 0 and 3 are *required*. DVFS hardware depends upon DVSUP pins showing | ||
114 | * minimum (11) and maximum (00) levels or interrupts will be continuously | ||
115 | * asserted. */ | ||
116 | #define DVFS_LEVEL_0 (1u << 0) | ||
117 | #define DVFS_LEVEL_1 (1u << 1) | ||
118 | #define DVFS_LEVEL_2 (1u << 2) | ||
119 | #define DVFS_LEVEL_3 (1u << 3) | ||
110 | 120 | ||
111 | extern long cpu_voltage_setting; | 121 | extern long cpu_voltage_setting; |
112 | 122 | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h b/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h index 4876736a2b..7fc7b56dff 100644 --- a/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h | |||
@@ -24,12 +24,12 @@ | |||
24 | #define _DVFS_DPTC_TARGET_H_ | 24 | #define _DVFS_DPTC_TARGET_H_ |
25 | 25 | ||
26 | #define DVFS_LEVEL_DEFAULT 1 /* 264 MHz - safe frequency for 1.35V */ | 26 | #define DVFS_LEVEL_DEFAULT 1 /* 264 MHz - safe frequency for 1.35V */ |
27 | #define DVFS_NUM_LEVELS 3 /* 528 MHz, 264 MHz, 132 MHz */ | ||
28 | #define DVFS_NO_PWRRDY /* PWRRDY is connected to different SoC port */ | 27 | #define DVFS_NO_PWRRDY /* PWRRDY is connected to different SoC port */ |
28 | #define DVFS_LEVEL_MASK (DVFS_LEVEL_0 | DVFS_LEVEL_1 | DVFS_LEVEL_3) | ||
29 | 29 | ||
30 | #define DPTC_WP_DEFAULT 1 /* 1.600, 1.350, 1.350 */ | 30 | #define DPTC_WP_DEFAULT 1 /* 1.600, 1.350, 1.350 */ |
31 | #define DPTC_WP_PANIC 3 /* Up to minimum for > 400 MHz */ | 31 | #define DPTC_WP_PANIC 3 /* Up to minimum for > 400 MHz */ |
32 | #define DPTC_NUM_WP 17 | 32 | |
33 | 33 | ||
34 | #define VOLTAGE_SETTING_MIN MC13783_SW_1_350 | 34 | #define VOLTAGE_SETTING_MIN MC13783_SW_1_350 |
35 | #define VOLTAGE_SETTING_MAX MC13783_SW_1_625 | 35 | #define VOLTAGE_SETTING_MAX MC13783_SW_1_625 |
@@ -54,7 +54,7 @@ | |||
54 | * and the values have an additional division or the comments in the BSP are | 54 | * and the values have an additional division or the comments in the BSP are |
55 | * incorrect. | 55 | * incorrect. |
56 | */ | 56 | */ |
57 | #define DVFS_DIV3CK CCM_LTR0_DIV3CK_131072 | 57 | #define DVFS_DIV3CK 0x3 |
58 | 58 | ||
59 | /* UPCNT defines the amount of times the up threshold should be exceeded | 59 | /* UPCNT defines the amount of times the up threshold should be exceeded |
60 | * before DVFS will trigger frequency increase request. */ | 60 | * before DVFS will trigger frequency increase request. */ |
@@ -109,146 +109,120 @@ dvfs_dptc_voltage_table[DPTC_NUM_WP] = | |||
109 | { { MC13783_SW_1_225, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | 109 | { { MC13783_SW_1_225, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #if 1 | 112 | #if CONFIG_CKIH_FREQ == 27000000 |
113 | /* For 27 MHz PLL reference clock */ | 113 | /* For 27 MHz PLL reference clock */ |
114 | static const struct dptc_dcvr_table_entry | 114 | static const struct dptc_dcvr_table_entry |
115 | dptc_dcvr_table[DVFS_NUM_LEVELS][DPTC_NUM_WP] = | 115 | dptc_dcvr_table_0[DPTC_NUM_WP] = |
116 | { | 116 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ |
117 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ | 117 | { /* 528 MHz */ |
118 | { /* 528 MHz */ | 118 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, |
119 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, | 119 | { 0xffc00000, 0x90629890, 0xffc00000, 0xdd34ed20 }, |
120 | { 0xffc00000, 0x90629890, 0xffc00000, 0xdd34ed20 }, | 120 | { 0xffc00000, 0x90629890, 0xffc00000, 0xdd34ed20 }, |
121 | { 0xffc00000, 0x90629890, 0xffc00000, 0xdd34ed20 }, | 121 | { 0xffc00000, 0x90629894, 0xffc00000, 0xdd74fd24 }, |
122 | { 0xffc00000, 0x90629894, 0xffc00000, 0xdd74fd24 }, | 122 | { 0xffc00000, 0x90a2a894, 0xffc00000, 0xddb50d28 }, |
123 | { 0xffc00000, 0x90a2a894, 0xffc00000, 0xddb50d28 }, | 123 | { 0xffc00000, 0x90e2b89c, 0xffc00000, 0xde352d30 }, |
124 | { 0xffc00000, 0x90e2b89c, 0xffc00000, 0xde352d30 }, | 124 | { 0xffc00000, 0x9162d8a0, 0xffc00000, 0xdef55d38 }, |
125 | { 0xffc00000, 0x9162d8a0, 0xffc00000, 0xdef55d38 }, | 125 | { 0xffc00000, 0x91e2f8a8, 0xffc00000, 0xdfb58d44 }, |
126 | { 0xffc00000, 0x91e2f8a8, 0xffc00000, 0xdfb58d44 }, | 126 | { 0xffc00000, 0x926308b0, 0xffc00000, 0xe0b5cd54 }, |
127 | { 0xffc00000, 0x926308b0, 0xffc00000, 0xe0b5cd54 }, | 127 | { 0xffc00000, 0x92e328bc, 0xffc00000, 0xe1f60d64 }, |
128 | { 0xffc00000, 0x92e328bc, 0xffc00000, 0xe1f60d64 }, | 128 | { 0xffc00000, 0x93a358c0, 0xffc00000, 0xe3365d74 }, |
129 | { 0xffc00000, 0x93a358c0, 0xffc00000, 0xe3365d74 }, | 129 | { 0xffc00000, 0xf66388cc, 0xffc00000, 0xf6768d84 }, |
130 | { 0xffc00000, 0xf66388cc, 0xffc00000, 0xf6768d84 }, | 130 | { 0xffc00000, 0xf663b8d4, 0xffc00000, 0xf676dd98 }, |
131 | { 0xffc00000, 0xf663b8d4, 0xffc00000, 0xf676dd98 }, | 131 | { 0xffc00000, 0xf663e8e0, 0xffc00000, 0xf6773da4 }, |
132 | { 0xffc00000, 0xf663e8e0, 0xffc00000, 0xf6773da4 }, | 132 | { 0xffc00000, 0xf66418ec, 0xffc00000, 0xf6778dbc }, |
133 | { 0xffc00000, 0xf66418ec, 0xffc00000, 0xf6778dbc }, | 133 | { 0xffc00000, 0xf66458fc, 0xffc00000, 0xf677edd0 }, |
134 | { 0xffc00000, 0xf66458fc, 0xffc00000, 0xf677edd0 }, | 134 | { 0xffc00000, 0xf6648908, 0xffc00000, 0xf6783de8 }, |
135 | { 0xffc00000, 0xf6648908, 0xffc00000, 0xf6783de8 }, | 135 | }; |
136 | 136 | ||
137 | }, | 137 | static const struct dptc_dcvr_table_entry |
138 | { /* 264 MHz */ | 138 | dptc_dcvr_table_1_3[DPTC_NUM_WP] = |
139 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, | 139 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ |
140 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | 140 | { /* 264 MHz, 132 MHz */ |
141 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | 141 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, |
142 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd4d4348 }, | 142 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, |
143 | { 0xffc00000, 0x9088b228, 0xffc00000, 0xdd8d434c }, | 143 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, |
144 | { 0xffc00000, 0x90c8b228, 0xffc00000, 0xde0d534c }, | 144 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd4d4348 }, |
145 | { 0xffc00000, 0x9148b228, 0xffc00000, 0xdecd5350 }, | 145 | { 0xffc00000, 0x9088b228, 0xffc00000, 0xdd8d434c }, |
146 | { 0xffc00000, 0x91c8c22c, 0xffc00000, 0xdf8d6354 }, | 146 | { 0xffc00000, 0x90c8b228, 0xffc00000, 0xde0d534c }, |
147 | { 0xffc00000, 0x9248d22c, 0xffc00000, 0xe08d7354 }, | 147 | { 0xffc00000, 0x9148b228, 0xffc00000, 0xdecd5350 }, |
148 | { 0xffc00000, 0x92c8d230, 0xffc00000, 0xe1cd8358 }, | 148 | { 0xffc00000, 0x91c8c22c, 0xffc00000, 0xdf8d6354 }, |
149 | { 0xffc00000, 0x9388e234, 0xffc00000, 0xe30d935c }, | 149 | { 0xffc00000, 0x9248d22c, 0xffc00000, 0xe08d7354 }, |
150 | { 0xffc00000, 0xf648e234, 0xffc00000, 0xf64db364 }, | 150 | { 0xffc00000, 0x92c8d230, 0xffc00000, 0xe1cd8358 }, |
151 | { 0xffc00000, 0xf648f238, 0xffc00000, 0xf64dc368 }, | 151 | { 0xffc00000, 0x9388e234, 0xffc00000, 0xe30d935c }, |
152 | { 0xffc00000, 0xf648f23c, 0xffc00000, 0xf64dd36c }, | 152 | { 0xffc00000, 0xf648e234, 0xffc00000, 0xf64db364 }, |
153 | { 0xffc00000, 0xf649023c, 0xffc00000, 0xf64de370 }, | 153 | { 0xffc00000, 0xf648f238, 0xffc00000, 0xf64dc368 }, |
154 | { 0xffc00000, 0xf649123c, 0xffc00000, 0xf64df374 }, | 154 | { 0xffc00000, 0xf648f23c, 0xffc00000, 0xf64dd36c }, |
155 | { 0xffc00000, 0xf6492240, 0xffc00000, 0xf64e1378 }, | 155 | { 0xffc00000, 0xf649023c, 0xffc00000, 0xf64de370 }, |
156 | { 0xffc00000, 0xf649123c, 0xffc00000, 0xf64df374 }, | ||
157 | { 0xffc00000, 0xf6492240, 0xffc00000, 0xf64e1378 }, | ||
156 | 158 | ||
157 | }, | ||
158 | { /* 132 MHz */ | ||
159 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, | ||
160 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | ||
161 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | ||
162 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd4d4348 }, | ||
163 | { 0xffc00000, 0x9088b228, 0xffc00000, 0xdd8d434c }, | ||
164 | { 0xffc00000, 0x90c8b228, 0xffc00000, 0xde0d534c }, | ||
165 | { 0xffc00000, 0x9148b228, 0xffc00000, 0xdecd5350 }, | ||
166 | { 0xffc00000, 0x91c8c22c, 0xffc00000, 0xdf8d6354 }, | ||
167 | { 0xffc00000, 0x9248d22c, 0xffc00000, 0xe08d7354 }, | ||
168 | { 0xffc00000, 0x92c8d230, 0xffc00000, 0xe1cd8358 }, | ||
169 | { 0xffc00000, 0x9388e234, 0xffc00000, 0xe30d935c }, | ||
170 | { 0xffc00000, 0xf648e234, 0xffc00000, 0xf64db364 }, | ||
171 | { 0xffc00000, 0xf648f238, 0xffc00000, 0xf64dc368 }, | ||
172 | { 0xffc00000, 0xf648f23c, 0xffc00000, 0xf64dd36c }, | ||
173 | { 0xffc00000, 0xf649023c, 0xffc00000, 0xf64de370 }, | ||
174 | { 0xffc00000, 0xf649123c, 0xffc00000, 0xf64df374 }, | ||
175 | { 0xffc00000, 0xf6492240, 0xffc00000, 0xf64e1378 }, | ||
176 | }, | ||
177 | }; | 159 | }; |
178 | #else/* For 26 MHz PLL reference clock */ | 160 | #else/* For 26 MHz PLL reference clock */ |
179 | static const struct dptc_dcvr_table_entry | 161 | static const struct dptc_dcvr_table_entry |
180 | dptc_dcvr_table[DVFS_NUM_LEVELS][DPTC_NUM_WP] = | 162 | dptc_dcvr_table_0[DPTC_NUM_WP] = |
181 | { | 163 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ |
182 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ | 164 | { /* 528 MHz */ |
183 | { /* 528 MHz */ | 165 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, |
184 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, | 166 | { 0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0 }, |
185 | { 0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0 }, | 167 | { 0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0 }, |
186 | { 0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0 }, | 168 | { 0xffc00000, 0x95e3e8e8, 0xffc00000, 0xe5f70da4 }, |
187 | { 0xffc00000, 0x95e3e8e8, 0xffc00000, 0xe5f70da4 }, | 169 | { 0xffc00000, 0x9623f8e8, 0xffc00000, 0xe6371da8 }, |
188 | { 0xffc00000, 0x9623f8e8, 0xffc00000, 0xe6371da8 }, | 170 | { 0xffc00000, 0x966408f0, 0xffc00000, 0xe6b73db0 }, |
189 | { 0xffc00000, 0x966408f0, 0xffc00000, 0xe6b73db0 }, | 171 | { 0xffc00000, 0x96e428f4, 0xffc00000, 0xe7776dbc }, |
190 | { 0xffc00000, 0x96e428f4, 0xffc00000, 0xe7776dbc }, | 172 | { 0xffc00000, 0x976448fc, 0xffc00000, 0xe8379dc8 }, |
191 | { 0xffc00000, 0x976448fc, 0xffc00000, 0xe8379dc8 }, | 173 | { 0xffc00000, 0x97e46904, 0xffc00000, 0xe977ddd8 }, |
192 | { 0xffc00000, 0x97e46904, 0xffc00000, 0xe977ddd8 }, | 174 | { 0xffc00000, 0x98a48910, 0xffc00000, 0xeab81de8 }, |
193 | { 0xffc00000, 0x98a48910, 0xffc00000, 0xeab81de8 }, | 175 | { 0xffc00000, 0x9964b918, 0xffc00000, 0xebf86df8 }, |
194 | { 0xffc00000, 0x9964b918, 0xffc00000, 0xebf86df8 }, | 176 | { 0xffc00000, 0xffe4e924, 0xffc00000, 0xfff8ae08 }, |
195 | { 0xffc00000, 0xffe4e924, 0xffc00000, 0xfff8ae08 }, | 177 | { 0xffc00000, 0xffe5192c, 0xffc00000, 0xfff8fe1c }, |
196 | { 0xffc00000, 0xffe5192c, 0xffc00000, 0xfff8fe1c }, | 178 | { 0xffc00000, 0xffe54938, 0xffc00000, 0xfff95e2c }, |
197 | { 0xffc00000, 0xffe54938, 0xffc00000, 0xfff95e2c }, | 179 | { 0xffc00000, 0xffe57944, 0xffc00000, 0xfff9ae44 }, |
198 | { 0xffc00000, 0xffe57944, 0xffc00000, 0xfff9ae44 }, | 180 | { 0xffc00000, 0xffe5b954, 0xffc00000, 0xfffa0e58 }, |
199 | { 0xffc00000, 0xffe5b954, 0xffc00000, 0xfffa0e58 }, | 181 | { 0xffc00000, 0xffe5e960, 0xffc00000, 0xfffa6e70 }, |
200 | { 0xffc00000, 0xffe5e960, 0xffc00000, 0xfffa6e70 }, | 182 | }; |
201 | }, | 183 | |
202 | { /* 264 MHz */ | 184 | static const struct dptc_dcvr_table_entry |
203 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, | 185 | dptc_dcvr_table_1_3[DPTC_NUM_WP] = |
204 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | 186 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ |
205 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | 187 | { /* 264 MHz, 132 MHz */ |
206 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe5cdc368 }, | 188 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, |
207 | { 0xffc00000, 0x9609023c, 0xffc00000, 0xe60dc36c }, | 189 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, |
208 | { 0xffc00000, 0x9649023c, 0xffc00000, 0xe68dd36c }, | 190 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, |
209 | { 0xffc00000, 0x96c9023c, 0xffc00000, 0xe74dd370 }, | 191 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe5cdc368 }, |
210 | { 0xffc00000, 0x97491240, 0xffc00000, 0xe80de374 }, | 192 | { 0xffc00000, 0x9609023c, 0xffc00000, 0xe60dc36c }, |
211 | { 0xffc00000, 0x97c92240, 0xffc00000, 0xe94df374 }, | 193 | { 0xffc00000, 0x9649023c, 0xffc00000, 0xe68dd36c }, |
212 | { 0xffc00000, 0x98892244, 0xffc00000, 0xea8e0378 }, | 194 | { 0xffc00000, 0x96c9023c, 0xffc00000, 0xe74dd370 }, |
213 | { 0xffc00000, 0x99493248, 0xffc00000, 0xebce137c }, | 195 | { 0xffc00000, 0x97491240, 0xffc00000, 0xe80de374 }, |
214 | { 0xffc00000, 0xffc93248, 0xffc00000, 0xffce3384 }, | 196 | { 0xffc00000, 0x97c92240, 0xffc00000, 0xe94df374 }, |
215 | { 0xffc00000, 0xffc9424c, 0xffc00000, 0xffce4388 }, | 197 | { 0xffc00000, 0x98892244, 0xffc00000, 0xea8e0378 }, |
216 | { 0xffc00000, 0xffc95250, 0xffc00000, 0xffce538c }, | 198 | { 0xffc00000, 0x99493248, 0xffc00000, 0xebce137c }, |
217 | { 0xffc00000, 0xffc96250, 0xffc00000, 0xffce7390 }, | 199 | { 0xffc00000, 0xffc93248, 0xffc00000, 0xffce3384 }, |
218 | { 0xffc00000, 0xffc97254, 0xffc00000, 0xffce8394 }, | 200 | { 0xffc00000, 0xffc9424c, 0xffc00000, 0xffce4388 }, |
219 | { 0xffc00000, 0xffc98258, 0xffc00000, 0xffcea39c }, | 201 | { 0xffc00000, 0xffc95250, 0xffc00000, 0xffce538c }, |
220 | }, | 202 | { 0xffc00000, 0xffc96250, 0xffc00000, 0xffce7390 }, |
221 | { /* 132 MHz */ | 203 | { 0xffc00000, 0xffc97254, 0xffc00000, 0xffce8394 }, |
222 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, | 204 | { 0xffc00000, 0xffc98258, 0xffc00000, 0xffcea39c }, |
223 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | ||
224 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | ||
225 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe5cdc368 }, | ||
226 | { 0xffc00000, 0x9609023c, 0xffc00000, 0xe60dc36c }, | ||
227 | { 0xffc00000, 0x9649023c, 0xffc00000, 0xe68dd36c }, | ||
228 | { 0xffc00000, 0x96c9023c, 0xffc00000, 0xe74dd370 }, | ||
229 | { 0xffc00000, 0x97491240, 0xffc00000, 0xe80de374 }, | ||
230 | { 0xffc00000, 0x97c92240, 0xffc00000, 0xe94df374 }, | ||
231 | { 0xffc00000, 0x98892244, 0xffc00000, 0xea8e0378 }, | ||
232 | { 0xffc00000, 0x99493248, 0xffc00000, 0xebce137c }, | ||
233 | { 0xffc00000, 0xffc93248, 0xffc00000, 0xffce3384 }, | ||
234 | { 0xffc00000, 0xffc9424c, 0xffc00000, 0xffce4388 }, | ||
235 | { 0xffc00000, 0xffc95250, 0xffc00000, 0xffce538c }, | ||
236 | { 0xffc00000, 0xffc96250, 0xffc00000, 0xffce7390 }, | ||
237 | { 0xffc00000, 0xffc97254, 0xffc00000, 0xffce8394 }, | ||
238 | { 0xffc00000, 0xffc98258, 0xffc00000, 0xffcea39c }, | ||
239 | }, | ||
240 | }; | 205 | }; |
241 | #endif | 206 | #endif |
242 | 207 | ||
208 | static const struct dptc_dcvr_table_entry * const | ||
209 | dptc_dcvr_table [DVFS_NUM_LEVELS] = | ||
210 | { | ||
211 | dptc_dcvr_table_0, | ||
212 | dptc_dcvr_table_1_3, | ||
213 | NULL, | ||
214 | dptc_dcvr_table_1_3, | ||
215 | }; | ||
243 | 216 | ||
244 | /* For 27 MHz PLL reference clock */ | 217 | /* For 27 MHz PLL reference clock */ |
245 | static const struct dvfs_clock_table_entry | 218 | static const struct dvfs_clock_table_entry |
246 | dvfs_clock_table[DVFS_NUM_LEVELS] = | 219 | dvfs_clock_table[4] = |
247 | { | 220 | { |
248 | /* PLL val PDR0 val PLL VSCNT */ | 221 | /* PLL val PDR0 val PLL VSCNT */ |
249 | { 0x00082407, 0xff841e58, 1, 7 }, /* MCUPLL, 528 MHz, /1 = 528 MHz */ | 222 | { 0x00082407, 0xff841e58, 1, 7 }, /* MCUPLL, 528 MHz, /1 = 528 MHz */ |
250 | { 0x00082407, 0xff841e59, 1, 7 }, /* MCUPLL, 528 MHz, /2 = 264 MHz */ | 223 | { 0x00082407, 0xff841e59, 1, 7 }, /* MCUPLL, 528 MHz, /2 = 264 MHz */ |
251 | { 0x00082407, 0xff841e5b, 1, 7 }, /* MCUPLL, 528 MHz, /4 = 132 MHz */ | 224 | { 0x00082407, 0xff841e5b, 1, 7 }, /* MCUPLL, 528 MHz, /4 = 132 MHz */ |
225 | { 0x00082407, 0xff841e5b, 1, 7 }, /* MCUPLL, 528 MHz, /4 = 132 MHz */ | ||
252 | }; | 226 | }; |
253 | 227 | ||
254 | 228 | ||