379536e3abd1f52d2543386a9d3c5e8cca6c602d
[deliverable/linux.git] / arch / mips / alchemy / devboards / db1200 / setup.c
1 /*
2 * Alchemy/AMD/RMI DB1200 board setup.
3 *
4 * Licensed under the terms outlined in the file COPYING in the root of
5 * this source archive.
6 */
7
8 #include <linux/init.h>
9 #include <linux/interrupt.h>
10 #include <linux/io.h>
11 #include <linux/kernel.h>
12 #include <asm/mach-au1x00/au1000.h>
13 #include <asm/mach-db1x00/bcsr.h>
14 #include <asm/mach-db1x00/db1200.h>
15
16 const char *get_system_type(void)
17 {
18 return "Alchemy Db1200";
19 }
20
21 void __init board_setup(void)
22 {
23 unsigned long freq0, clksrc, div, pfc;
24 unsigned short whoami;
25
26 bcsr_init(DB1200_BCSR_PHYS_ADDR,
27 DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
28
29 whoami = bcsr_read(BCSR_WHOAMI);
30 printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
31 " Board-ID %d Daughtercard ID %d\n",
32 (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
33
34 /* SMBus/SPI on PSC0, Audio on PSC1 */
35 pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
36 pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
37 pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
38 pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
39 __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
40 wmb();
41
42 /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
43 * CPU clock; all other clock generators off/unused.
44 */
45 div = (get_au1x00_speed() + 25000000) / 50000000;
46 if (div & 1)
47 div++;
48 div = ((div >> 1) - 1) & 0xff;
49
50 freq0 = div << SYS_FC_FRDIV0_BIT;
51 __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
52 wmb();
53 freq0 |= SYS_FC_FE0; /* enable F0 */
54 __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
55 wmb();
56
57 /* psc0_intclk comes 1:1 from F0 */
58 clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
59 __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
60 wmb();
61 }
62
63 /* use the hexleds to count the number of times the cpu has entered
64 * wait, the dots to indicate whether the CPU is currently idle or
65 * active (dots off = sleeping, dots on = working) for cases where
66 * the number doesn't change for a long(er) period of time.
67 */
68 static void db1200_wait(void)
69 {
70 __asm__(" .set push \n"
71 " .set mips3 \n"
72 " .set noreorder \n"
73 " cache 0x14, 0(%0) \n"
74 " cache 0x14, 32(%0) \n"
75 " cache 0x14, 64(%0) \n"
76 /* dots off: we're about to call wait */
77 " lui $26, 0xb980 \n"
78 " ori $27, $0, 3 \n"
79 " sb $27, 0x18($26) \n"
80 " sync \n"
81 " nop \n"
82 " wait \n"
83 " nop \n"
84 " nop \n"
85 " nop \n"
86 " nop \n"
87 " nop \n"
88 /* dots on: there's work to do, increment cntr */
89 " lui $26, 0xb980 \n"
90 " sb $0, 0x18($26) \n"
91 " lui $26, 0xb9c0 \n"
92 " lb $27, 0($26) \n"
93 " addiu $27, $27, 1 \n"
94 " sb $27, 0($26) \n"
95 " sync \n"
96 " .set pop \n"
97 : : "r" (db1200_wait));
98 }
99
100 static int __init db1200_arch_init(void)
101 {
102 /* GPIO7 is low-level triggered CPLD cascade */
103 set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
104 bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
105
106 /* do not autoenable these: CPLD has broken edge int handling,
107 * and the CD handler setup requires manual enabling to work
108 * around that.
109 */
110 irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
111 irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
112
113 if (cpu_wait)
114 cpu_wait = db1200_wait;
115
116 return 0;
117 }
118 arch_initcall(db1200_arch_init);
This page took 0.033103 seconds and 4 git commands to generate.