e6ae3a4a5d256139ce0b135526ab5179aa0bf011
[kugel-rb.git] / firmware / target / arm / as3525 / debug-as3525.c
blobe6ae3a4a5d256139ce0b135526ab5179aa0bf011
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright © 2008 Rafaël Carré
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <stdbool.h>
23 #include "debug-target.h"
24 #include "button.h"
25 #include "lcd.h"
26 #include "font.h"
27 #include "system.h"
28 #include "cpu.h"
29 #include "pl180.h"
30 #include "ascodec-target.h"
31 #include "adc.h"
32 #include "storage.h"
34 #define ON "Enabled"
35 #define OFF "Disabled"
37 #define CP15_MMU (1<<0) /* mmu off/on */
38 #define CP15_DC (1<<2) /* dcache off/on */
39 #define CP15_IC (1<<12) /* icache off/on */
41 #define CLK_MAIN 24000000 /* 24 MHz */
43 #define CLK_PLLA 0
44 #define CLK_PLLB 1
45 #define CLK_PROC 2
46 #define CLK_FCLK 3
47 #define CLK_EXTMEM 4
48 #define CLK_PCLK 5
49 #define CLK_IDE 6
50 #define CLK_I2C 7
51 #define CLK_I2SI 8
52 #define CLK_I2SO 9
53 #define CLK_DBOP 10
54 #define CLK_SD_MCLK_NAND 11
55 #define CLK_SD_MCLK_MSD 12
56 #define CLK_USB 13
58 #define I2C2_CPSR0 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x1C))
59 #define I2C2_CPSR1 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x20))
60 #define MCI_NAND *((volatile unsigned long *)(NAND_FLASH_BASE + 0x04))
61 #define MCI_SD *((volatile unsigned long *)(SD_MCI_BASE + 0x04))
63 extern bool sd_enabled;
65 /* FIXME: target tree is including ./debug-target.h rather than the one in
66 * sansa-fuze/, even though deps contains the correct one
67 * if I put the below into a sansa-fuze/debug-target.h, it doesn't work*/
68 #if defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_C200V2)
69 #define DEBUG_DBOP
70 #include "dbop-as3525.h"
71 #endif
73 static inline unsigned read_cp15 (void)
75 unsigned cp15_value;
76 asm volatile (
77 "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" : "=r"(cp15_value));
78 return (cp15_value);
81 static int calc_freq(int clk)
83 unsigned int prediv = ((unsigned int)CGU_PROC>>2) & 0x3;
84 unsigned int postdiv = ((unsigned int)CGU_PROC>>4) & 0xf;
85 #if CONFIG_CPU == AS3525
86 int out_div;
88 switch(clk) {
89 /* clk_main = clk_int = 24MHz oscillator */
90 case CLK_PLLA:
91 if(CGU_PLLASUP & (1<<3))
92 return 0;
94 /*assume 24MHz oscillator only input available */
95 out_div = ((CGU_PLLA>>13) & 0x3); /* bits 13:14 */
96 if (out_div == 3) /* for 11 NO=4 */
97 out_div=4;
98 if(out_div) /* NO = 0 not allowed */
99 return ((2 * (CGU_PLLA & 0xff))*CLK_MAIN)/
100 (((CGU_PLLA>>8) & 0x1f)*out_div);
101 return 0;
102 case CLK_PLLB:
103 if(CGU_PLLBSUP & (1<<3))
104 return 0;
106 /*assume 24MHz oscillator only input available */
107 out_div = ((CGU_PLLB>>13) & 0x3); /* bits 13:14 */
108 if (out_div == 3) /* for 11 NO=4 */
109 out_div=4;
110 if(out_div) /* NO = 0 not allowed */
111 return ((2 * (CGU_PLLB & 0xff))*CLK_MAIN)/
112 (((CGU_PLLB>>8) & 0x1f)*out_div);
113 return 0;
114 #else
115 int od, f, r;
117 /* AS3525v2 */
118 switch(clk) {
119 case CLK_PLLA:
120 if(CGU_PLLASUP & (1<<3))
121 return 0;
123 f = (CGU_PLLA & 0x7F) + 1;
124 r = ((CGU_PLLA >> 7) & 0x7) + 1;
125 od = (CGU_PLLA >> 10) & 1 ? 2 : 1;
126 return (CLK_MAIN / 2) * f / (r * od);
128 case CLK_PLLB:
129 if(CGU_PLLBSUP & (1<<3))
130 return 0;
132 f = (CGU_PLLB & 0x7F) + 1;
133 r = ((CGU_PLLB >> 7) & 0x7) + 1;
134 od = (CGU_PLLB >> 10) & 1 ? 2 : 1;
135 return (CLK_MAIN / 2) * f / (r * od);
136 #endif
137 case CLK_PROC:
138 #if CONFIG_CPU == AS3525 /* not in arm926-ejs */
139 if (!(read_cp15()>>30)) /* fastbus */
140 return calc_freq(CLK_PCLK);
141 else /* Synch or Asynch bus*/
142 #endif /* CONFIG_CPU == AS3525 */
143 return calc_freq(CLK_FCLK);
144 case CLK_FCLK:
145 switch(CGU_PROC & 3) {
146 case 0:
147 return (CLK_MAIN * (8 - prediv)) / (8 * (postdiv + 1));
148 case 1:
149 return (calc_freq(CLK_PLLA) * (8 - prediv)) /
150 (8 * (postdiv + 1));
151 case 2:
152 return (calc_freq(CLK_PLLB) * (8 - prediv)) /
153 (8 * (postdiv + 1));
154 default:
155 return 0;
157 case CLK_EXTMEM:
158 #if CONFIG_CPU == AS3525
159 switch(CGU_PERI & 3) {
160 #else
161 /* bits 1:0 of CGU_PERI always read as 0 and source = FCLK */
162 switch(3) {
163 #endif
164 case 0:
165 return CLK_MAIN/(((CGU_PERI>>2)& 0xf)+1);
166 case 1:
167 return calc_freq(CLK_PLLA)/(((CGU_PERI>>2)& 0xf)+1);
168 case 2:
169 return calc_freq(CLK_PLLB)/(((CGU_PERI>>2)& 0xf)+1);
170 case 3:
171 default:
172 return calc_freq(CLK_FCLK)/(((CGU_PERI>>2)& 0xf)+1);
174 case CLK_PCLK:
175 return calc_freq(CLK_EXTMEM)/(((CGU_PERI>>6)& 0x1)+1);
176 case CLK_IDE:
177 switch(CGU_IDE & 3) {
178 case 0:
179 return CLK_MAIN/(((CGU_IDE>>2)& 0xf)+1);
180 case 1:
181 return calc_freq(CLK_PLLA)/(((CGU_IDE>>2)& 0xf)+1);
182 case 2:
183 return calc_freq(CLK_PLLB)/(((CGU_IDE>>2)& 0xf)+1);
184 default:
185 return 0;
187 case CLK_I2C:
188 return calc_freq(CLK_PCLK)/AS3525_I2C_PRESCALER;
189 case CLK_I2SI:
190 switch((CGU_AUDIO>>12) & 3) {
191 case 0:
192 return CLK_MAIN/(((CGU_AUDIO>>14) & 0x1ff)+1);
193 case 1:
194 return calc_freq(CLK_PLLA)/(((CGU_AUDIO>>14) & 0x1ff)+1);
195 case 2:
196 return calc_freq(CLK_PLLB)/(((CGU_AUDIO>>14) & 0x1ff)+1);
197 default:
198 return 0;
200 case CLK_I2SO:
201 switch(CGU_AUDIO & 3) {
202 case 0:
203 return CLK_MAIN/(((CGU_AUDIO>>2) & 0x1ff)+1);
204 case 1:
205 return calc_freq(CLK_PLLA)/(((CGU_AUDIO>>2) & 0x1ff)+1);
206 case 2:
207 return calc_freq(CLK_PLLB)/(((CGU_AUDIO>>2) & 0x1ff)+1);
208 default:
209 return 0;
211 case CLK_DBOP:
212 return calc_freq(CLK_PCLK)/((CGU_DBOP & 7)+1);
213 #if CONFIG_CPU == AS3525
214 case CLK_SD_MCLK_NAND:
215 if(!(MCI_NAND & (1<<8)))
216 return 0;
217 else if(MCI_NAND & (1<<10))
218 return calc_freq(CLK_IDE);
219 else
220 return calc_freq(CLK_IDE)/(((MCI_NAND & 0xff)+1)*2);
221 case CLK_SD_MCLK_MSD:
222 if(!(MCI_SD & (1<<8)))
223 return 0;
224 else if(MCI_SD & (1<<10))
225 return calc_freq(CLK_PCLK);
226 else
227 return calc_freq(CLK_PCLK)/(((MCI_SD & 0xff)+1)*2);
228 #endif
229 case CLK_USB:
230 switch(CGU_USB & 3) { /* 0-> div=1 other->div=1/(2*n) */
231 case 0:
232 if (!((CGU_USB>>2) & 0x7))
233 return CLK_MAIN;
234 else
235 return CLK_MAIN/(2*((CGU_USB>>2) & 0x7));
236 case 1:
237 if (!((CGU_USB>>2) & 0x7))
238 return calc_freq(CLK_PLLA);
239 else
240 return calc_freq(CLK_PLLA)/(2*((CGU_USB>>2) & 0x7));
241 case 2:
242 if (!((CGU_USB>>2) & 0x7))
243 return calc_freq(CLK_PLLB);
244 else
245 return calc_freq(CLK_PLLB)/(2*((CGU_USB>>2) & 0x7));
246 default:
247 return 0;
249 default:
250 return 0;
254 bool __dbg_hw_info(void)
256 int line;
257 #if CONFIG_CPU == AS3525
258 int last_nand = 0;
259 #ifdef HAVE_MULTIDRIVE
260 int last_sd = 0;
261 #endif
262 #endif /* CONFIG_CPU == AS3525 */
264 lcd_clear_display();
265 lcd_setfont(FONT_SYSFIXED);
267 while(1)
269 while(1)
271 #ifdef SANSA_C200V2
272 extern int dbop_denoise_accept;
273 extern int dbop_denoise_reject;
275 lcd_clear_display();
276 line = 0;
277 lcd_puts(0, line++, "[Submodel:]");
278 lcd_putsf(0, line++, "C200v2 variant %d", c200v2_variant);
279 if (dbop_denoise_accept) {
280 lcd_putsf(0, line++, "DBOP noise: %d%%",
281 (100*dbop_denoise_reject)/dbop_denoise_accept);
282 } else {
283 lcd_puts(0, line++, "DBOP noise: oo");
285 lcd_putsf(0, line++, "reject: %d", dbop_denoise_reject);
286 lcd_putsf(0, line++, "accept: %d", dbop_denoise_accept);
287 lcd_update();
288 int btn = button_get_w_tmo(HZ/10);
289 if(btn == (DEBUG_CANCEL|BUTTON_REL))
290 goto end;
291 else if(btn == (BUTTON_DOWN|BUTTON_REL))
292 break;
294 while(1)
296 #endif
297 lcd_clear_display();
298 line = 0;
299 lcd_puts(0, line++, "[Clock Frequencies:]");
300 lcd_puts(0, line++, " SET ACTUAL");
301 #if CONFIG_CPU == AS3525
302 lcd_putsf(0, line++, "922T:%s %3dMHz",
303 (!(read_cp15()>>30)) ? "FAST " :
304 (read_cp15()>>31) ? "ASYNC" : "SYNC ",
305 #else
306 lcd_putsf(0, line++, "926ejs: %3dMHz",
307 #endif
308 calc_freq(CLK_PROC)/1000000);
309 lcd_putsf(0, line++, "PLLA:%3dMHz %3dMHz", AS3525_PLLA_FREQ/1000000,
310 calc_freq(CLK_PLLA)/1000000);
311 lcd_putsf(0, line++, "PLLB: %3dMHz", calc_freq(CLK_PLLB)/1000000);
312 lcd_putsf(0, line++, "FCLK: %3dMHz", calc_freq(CLK_FCLK)/1000000);
313 lcd_putsf(0, line++, "DRAM:%3dMHz %3dMHz", AS3525_PCLK_FREQ/1000000,
314 calc_freq(CLK_EXTMEM)/1000000);
315 lcd_putsf(0, line++, "PCLK:%3dMHz %3dMHz", AS3525_PCLK_FREQ/1000000,
316 calc_freq(CLK_PCLK)/1000000);
318 #if LCD_HEIGHT < 176 /* clip */
319 lcd_update();
320 int btn = button_get_w_tmo(HZ/10);
321 if(btn == (DEBUG_CANCEL|BUTTON_REL))
322 goto end;
323 else if(btn == (BUTTON_DOWN|BUTTON_REL))
324 break;
326 while(1)
328 lcd_clear_display();
329 line = 0;
330 #endif /* LCD_HEIGHT < 176 */
332 lcd_putsf(0, line++, "IDE :%3dMHz %3dMHz", AS3525_IDE_FREQ/1000000,
333 calc_freq(CLK_IDE)/1000000);
334 lcd_putsf(0, line++, "DBOP:%3dMHz %3dMHz", AS3525_DBOP_FREQ/1000000,
335 calc_freq(CLK_DBOP)/1000000);
336 lcd_putsf(0, line++, "I2C :%3dkHz %3dkHz", AS3525_I2C_FREQ/1000,
337 calc_freq(CLK_I2C)/1000);
338 lcd_putsf(0, line++, "I2SI: %s %3dMHz", (CGU_AUDIO & (1<<23)) ?
339 "on " : "off" , calc_freq(CLK_I2SI)/1000000);
340 lcd_putsf(0, line++, "I2SO: %s %3dMHz", (CGU_AUDIO & (1<<11)) ?
341 "on " : "off", calc_freq(CLK_I2SO)/1000000);
342 #if CONFIG_CPU == AS3525
343 /* If disabled, enable SD cards so we can read the registers */
344 if(sd_enabled == false)
346 sd_enable(true);
347 last_nand = MCI_NAND;
348 #ifdef HAVE_MULTIDRIVE
349 last_sd = MCI_SD;
350 #endif
351 sd_enable(false);
354 lcd_putsf(0, line++, "SD :%3dMHz %3dMHz",
355 ((AS3525_IDE_FREQ/ 1000000) /
356 ((last_nand & MCI_CLOCK_BYPASS)? 1:(((last_nand & 0xff)+1) * 2))),
357 calc_freq(CLK_SD_MCLK_NAND)/1000000);
358 #ifdef HAVE_MULTIDRIVE
359 lcd_putsf(0, line++, "uSD :%3dMHz %3dMHz",
360 ((AS3525_PCLK_FREQ/ 1000000) /
361 ((last_sd & MCI_CLOCK_BYPASS) ? 1: (((last_sd & 0xff) + 1) * 2))),
362 calc_freq(CLK_SD_MCLK_MSD)/1000000);
363 #endif
364 #endif /* CONFIG_CPU == AS3525 */
365 lcd_putsf(0, line++, "USB : %3dMHz", calc_freq(CLK_USB)/1000000);
367 #if LCD_HEIGHT < 176 /* clip */
368 lcd_update();
369 int btn = button_get_w_tmo(HZ/10);
370 if(btn == (DEBUG_CANCEL|BUTTON_REL))
371 goto end;
372 else if(btn == (BUTTON_DOWN|BUTTON_REL))
373 break;
375 while(1)
377 lcd_clear_display();
378 line = 0;
379 #endif /* LCD_HEIGHT < 176 */
381 lcd_putsf(0, line++, "MMU : %s CVDDP:%4d", (read_cp15() & CP15_MMU) ?
382 " on" : "off", adc_read(ADC_CVDD) * 25);
383 lcd_putsf(0, line++, "Icache:%s Dcache:%s",
384 (read_cp15() & CP15_IC) ? " on" : "off",
385 (read_cp15() & CP15_DC) ? " on" : "off");
387 lcd_update();
388 int btn = button_get_w_tmo(HZ/10);
389 if(btn == (DEBUG_CANCEL|BUTTON_REL))
390 goto end;
391 else if(btn == (BUTTON_DOWN|BUTTON_REL))
392 break;
394 while(1)
396 lcd_clear_display();
397 line = 0;
399 lcd_putsf(0, line++, "CGU_PLLA :%8x", (unsigned int)(CGU_PLLA));
400 lcd_putsf(0, line++, "CGU_PLLB :%8x", (unsigned int)(CGU_PLLB));
401 lcd_putsf(0, line++, "CGU_PROC :%8x", (unsigned int)(CGU_PROC));
402 lcd_putsf(0, line++, "CGU_PERI :%8x", (unsigned int)(CGU_PERI));
403 lcd_putsf(0, line++, "CGU_IDE :%8x", (unsigned int)(CGU_IDE));
404 lcd_putsf(0, line++, "CGU_DBOP :%8x", (unsigned int)(CGU_DBOP));
405 lcd_putsf(0, line++, "CGU_AUDIO :%8x", (unsigned int)(CGU_AUDIO));
406 lcd_putsf(0, line++, "CGU_USB :%8x", (unsigned int)(CGU_USB));
408 #if LCD_HEIGHT < 176 /* clip */
409 lcd_update();
410 int btn = button_get_w_tmo(HZ/10);
411 if(btn == (DEBUG_CANCEL|BUTTON_REL))
412 goto end;
413 else if(btn == (BUTTON_DOWN|BUTTON_REL))
414 break;
416 while(1)
418 lcd_clear_display();
419 line = 0;
420 #endif /* LCD_HEIGHT < 176 */
422 lcd_putsf(0, line++, "I2C2_CPSR :%8x", (unsigned int)(I2C2_CPSR1<<8 |
423 I2C2_CPSR0));
424 #if CONFIG_CPU == AS3525
425 lcd_putsf(0, line++, "MCI_NAND :%8x", (unsigned int)(MCI_NAND));
426 lcd_putsf(0, line++, "MCI_SD :%8x", (unsigned int)(MCI_SD));
427 #else
428 lcd_putsf(0, line++, "CGU_MEMSTK:%8x", (unsigned int)(CGU_MEMSTICK));
429 lcd_putsf(0, line++, "CGU_SDSLOT:%8x", (unsigned int)(CGU_SDSLOT));
430 #endif
432 lcd_update();
433 int btn = button_get_w_tmo(HZ/10);
434 if(btn == (DEBUG_CANCEL|BUTTON_REL))
435 goto end;
436 else if(btn == (BUTTON_DOWN|BUTTON_REL))
437 break;
441 end:
442 lcd_setfont(FONT_UI);
443 return false;
446 bool __dbg_ports(void)
448 int line, btn, i;
450 lcd_setfont(FONT_SYSFIXED);
452 while(1)
454 lcd_clear_display();
456 while(1)
458 line = 0;
459 lcd_puts(0, line++, "[GPIO Vals and Dirs]");
460 lcd_putsf(0, line++, "GPIOA: %2x DIR: %2x", GPIOA_DATA, GPIOA_DIR);
461 lcd_putsf(0, line++, "GPIOB: %2x DIR: %2x", GPIOB_DATA, GPIOB_DIR);
462 lcd_putsf(0, line++, "GPIOC: %2x DIR: %2x", GPIOC_DATA, GPIOC_DIR);
463 lcd_putsf(0, line++, "GPIOD: %2x DIR: %2x", GPIOD_DATA, GPIOD_DIR);
464 #ifdef DEBUG_DBOP
465 line++;
466 lcd_puts(0, line++, "[DBOP_DIN]");
467 lcd_putsf(0, line++, "DBOP_DIN: %4x", dbop_debug());
468 #endif
469 line++;
470 lcd_puts(0, line++, "[CP15]");
471 lcd_putsf(0, line++, "CP15: 0x%8x", read_cp15());
472 lcd_update();
473 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
474 break;
476 btn = button_get_w_tmo(HZ/10);
477 if(btn == (DEBUG_CANCEL|BUTTON_REL))
478 goto end;
479 else if(btn == (BUTTON_DOWN|BUTTON_REL))
480 break;
483 #if CONFIG_CPU == AS3525 /* as3525v2 channels are different */
484 #define BATTEMP_UNIT 5/2 /* 2.5mV */
485 static const char *adc_name[13] = {
486 "CHG_OUT ",
487 "RTCSUP ",
488 "VBUS ",
489 "CHG_IN ",
490 "CVDD ",
491 "BatTemp ",
492 "MicSup1 ",
493 "MicSup2 ",
494 "VBE1 ",
495 "VBE2 ",
496 "I_MicSup1",
497 "I_MicSup2",
498 "VBAT ",
500 #elif CONFIG_CPU == AS3525v2
501 #define BATTEMP_UNIT 2 /* 2mV */
502 static const char *adc_name[16] = {
503 "BVDD ",
504 "BVDDR ",
505 "CHGIN ",
506 "CHGOUT ",
507 "VBUS ",
508 NULL,
509 "BatTemp ",
510 NULL,
511 "MicSup ",
512 NULL,
513 "I_MiSsup",
514 NULL,
515 "VBE_1uA ",
516 "VBE_2uA ",
517 "I_CHGact",
518 "I_CHGref",
520 #endif
522 lcd_clear_display();
524 while(1)
526 line = 0;
528 for(i=0; i<5; i++)
529 lcd_putsf(0, line++, "%s: %d mV", adc_name[i], adc_read(i) * 5);
530 for(; i<8; i++)
531 if(adc_name[i])
532 lcd_putsf(0, line++, "%s: %d mV", adc_name[i],
533 adc_read(i) * BATTEMP_UNIT);
534 #if LCD_HEIGHT < 176 /* clip */
535 lcd_update();
537 btn = button_get_w_tmo(HZ/10);
538 if(btn == (DEBUG_CANCEL|BUTTON_REL))
539 goto end;
540 else if(btn == (BUTTON_DOWN|BUTTON_REL))
541 break;
543 lcd_clear_display();
544 while(1)
546 line = 0;
547 #endif /* LCD_HEIGHT < 176 */
548 for(i=8; i<10; i++)
549 if(adc_name[i])
550 lcd_putsf(0, line++, "%s: %d mV", adc_name[i], adc_read(i));
551 for(; i<12; i++)
552 if(adc_name[i])
553 lcd_putsf(0, line++, "%s: %d uA", adc_name[i], adc_read(i));
554 #if CONFIG_CPU == AS3525 /* different units */
555 lcd_putsf(0, line++, "%s: %d mV", adc_name[i], adc_read(i)*5/2);
556 #elif CONFIG_CPU == AS3525v2
557 for(; i<16; i++)
558 lcd_putsf(0, line++, "%s: %d mV", adc_name[i], adc_read(i));
559 #endif
560 lcd_update();
562 btn = button_get_w_tmo(HZ/10);
563 if(btn == (DEBUG_CANCEL|BUTTON_REL))
564 goto end;
565 else if(btn == (BUTTON_DOWN|BUTTON_REL))
566 break;
570 end:
571 lcd_setfont(FONT_UI);
572 return false;