change danube 2 ifxmips
[openwrt/svn-archive/archive.git] / target / linux / ifxmips / files / arch / mips / danube / setup.c
1 /*
2 * arch/mips/danube/setup.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) 2004 peng.liu@infineon.com
19 *
20 * Rewrite of Infineon Danube code, thanks to infineon for the support,
21 * software and hardware
22 *
23 * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
24 *
25 */
26
27 #include <linux/init.h>
28
29 #include <asm/time.h>
30 #include <asm/traps.h>
31 #include <asm/cpu.h>
32 #include <asm/irq.h>
33 #include <asm/danube/danube.h>
34 #include <asm/danube/danube_irq.h>
35 #include <asm/danube/danube_pmu.h>
36
37 static unsigned int r4k_offset; /* Amount to increment compare reg each time */
38 static unsigned int r4k_cur; /* What counter should be at next timer irq */
39
40 extern void danube_reboot_setup (void);
41 void prom_printf (const char * fmt, ...);
42
43 void
44 __init bus_error_init (void)
45 {
46 /* nothing yet */
47 }
48
49 unsigned int
50 danube_get_ddr_hz (void)
51 {
52 switch (readl(IFXMIPS_CGU_SYS) & 0x3)
53 {
54 case 0:
55 return CLOCK_167M;
56 case 1:
57 return CLOCK_133M;
58 case 2:
59 return CLOCK_111M;
60 }
61 return CLOCK_83M;
62 }
63 EXPORT_SYMBOL(danube_get_ddr_hz);
64
65 unsigned int
66 danube_get_cpu_hz (void)
67 {
68 unsigned int ddr_clock = danube_get_ddr_hz();
69 switch (readl(IFXMIPS_CGU_SYS) & 0xc)
70 {
71 case 0:
72 return CLOCK_333M;
73 case 4:
74 return ddr_clock;
75 }
76 return ddr_clock << 1;
77 }
78 EXPORT_SYMBOL(danube_get_cpu_hz);
79
80 unsigned int
81 danube_get_fpi_hz (void)
82 {
83 unsigned int ddr_clock = danube_get_ddr_hz();
84 if (readl(IFXMIPS_CGU_SYS) & 0x40)
85 {
86 return ddr_clock >> 1;
87 }
88 return ddr_clock;
89 }
90 EXPORT_SYMBOL(danube_get_fpi_hz);
91
92 unsigned int
93 danube_get_cpu_ver (void)
94 {
95 return readl(IFXMIPS_MCD_CHIPID) & 0xFFFFF000;
96 }
97 EXPORT_SYMBOL(danube_get_cpu_ver);
98
99 void
100 danube_time_init (void)
101 {
102 mips_hpt_frequency = danube_get_cpu_hz() / 2;
103 r4k_offset = mips_hpt_frequency / HZ;
104 printk("mips_hpt_frequency:%d\n", mips_hpt_frequency);
105 printk("r4k_offset: %08x(%d)\n", r4k_offset, r4k_offset);
106 }
107
108 int
109 danube_be_handler(struct pt_regs *regs, int is_fixup)
110 {
111 /*TODO*/
112 printk(KERN_ERR "TODO: BUS error\n");
113
114 return MIPS_BE_FATAL;
115 }
116
117 /* ISR GPTU Timer 6 for high resolution timer */
118 static irqreturn_t
119 danube_timer6_interrupt(int irq, void *dev_id)
120 {
121 timer_interrupt(IFXMIPS_TIMER6_INT, NULL);
122
123 return IRQ_HANDLED;
124 }
125
126 static struct irqaction hrt_irqaction = {
127 .handler = danube_timer6_interrupt,
128 .flags = IRQF_DISABLED,
129 .name = "hrt",
130 };
131
132 void __init
133 plat_timer_setup (struct irqaction *irq)
134 {
135 unsigned int retval;
136
137 setup_irq(MIPS_CPU_TIMER_IRQ, irq);
138
139 r4k_cur = (read_c0_count() + r4k_offset);
140 write_c0_compare(r4k_cur);
141
142 danube_pmu_enable(IFXMIPS_PMU_PWDCR_GPT | IFXMIPS_PMU_PWDCR_FPI);
143
144 writel(0x100, IFXMIPS_GPTU_GPT_CLC);
145
146 writel(0xffff, IFXMIPS_GPTU_GPT_CAPREL);
147 writel(0x80C0, IFXMIPS_GPTU_GPT_T6CON);
148
149 retval = setup_irq(IFXMIPS_TIMER6_INT, &hrt_irqaction);
150
151 if (retval)
152 {
153 prom_printf("reqeust_irq failed %d. HIGH_RES_TIMER is diabled\n", IFXMIPS_TIMER6_INT);
154 }
155 }
156
157 void __init
158 plat_mem_setup (void)
159 {
160 u32 status;
161 prom_printf("This %s has a cpu rev of 0x%X\n", BOARD_SYSTEM_TYPE, danube_get_cpu_ver());
162
163 //TODO WHY ???
164 /* clear RE bit*/
165 status = read_c0_status();
166 status &= (~(1<<25));
167 write_c0_status(status);
168
169 danube_reboot_setup();
170 board_time_init = danube_time_init;
171 board_be_handler = &danube_be_handler;
172
173 ioport_resource.start = IOPORT_RESOURCE_START;
174 ioport_resource.end = IOPORT_RESOURCE_END;
175 iomem_resource.start = IOMEM_RESOURCE_START;
176 iomem_resource.end = IOMEM_RESOURCE_END;
177 }