1e6202907619cd29ad4afdf3d34262179dee5c1c
[openwrt/svn-archive/archive.git] / target / linux / ifxmips / files / arch / mips / ifxmips / setup.c
1 /*
2 * arch/mips/ifxmips/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 IFXMips 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/ifxmips/ifxmips.h>
34 #include <asm/ifxmips/ifxmips_irq.h>
35 #include <asm/ifxmips/ifxmips_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 ifxmips_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 ifxmips_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(ifxmips_get_ddr_hz);
64
65 unsigned int
66 ifxmips_get_cpu_hz (void)
67 {
68 unsigned int ddr_clock = ifxmips_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(ifxmips_get_cpu_hz);
79
80 unsigned int
81 ifxmips_get_fpi_hz (void)
82 {
83 unsigned int ddr_clock = ifxmips_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(ifxmips_get_fpi_hz);
91
92 unsigned int
93 ifxmips_get_cpu_ver (void)
94 {
95 return readl(IFXMIPS_MCD_CHIPID) & 0xFFFFF000;
96 }
97 EXPORT_SYMBOL(ifxmips_get_cpu_ver);
98
99 static __inline__ u32 get_counter_resolution(void)
100 {
101 u32 res;
102 __asm__ __volatile__(
103 ".set push\n"
104 ".set mips32r2\n"
105 ".set noreorder\n"
106 "rdhwr %0, $3\n"
107 "ehb\n"
108 ".set pop\n"
109 : "=&r" (res)
110 : /* no input */
111 : "memory");
112 instruction_hazard();
113 return res;
114 }
115
116 int
117 ifxmips_be_handler(struct pt_regs *regs, int is_fixup)
118 {
119 /*TODO*/
120 printk(KERN_ERR "TODO: BUS error\n");
121
122 return MIPS_BE_FATAL;
123 }
124
125 void __init
126 plat_time_init (void)
127 {
128 mips_hpt_frequency = ifxmips_get_cpu_hz()/get_counter_resolution();
129 r4k_cur = (read_c0_count() + r4k_offset);
130 write_c0_compare(r4k_cur);
131 ifxmips_pmu_enable(IFXMIPS_PMU_PWDCR_GPT | IFXMIPS_PMU_PWDCR_FPI);
132
133 writel(0x100, IFXMIPS_GPTU_GPT_CLC);
134
135 writel(0xffff, IFXMIPS_GPTU_GPT_CAPREL);
136 writel(0x80C0, IFXMIPS_GPTU_GPT_T6CON);
137 }
138
139 extern const char* get_system_type (void);
140
141 //void (*board_time_init)(void);
142 void __init
143 plat_mem_setup (void)
144 {
145 u32 status;
146 prom_printf("This %s has a cpu rev of 0x%X\n", get_system_type(), ifxmips_get_cpu_ver());
147
148 //TODO WHY ???
149 /* clear RE bit*/
150 status = read_c0_status();
151 status &= (~(1<<25));
152 write_c0_status(status);
153
154 ifxmips_reboot_setup();
155 // board_time_init = ifxmips_time_init;
156 board_be_handler = &ifxmips_be_handler;
157
158 ioport_resource.start = IOPORT_RESOURCE_START;
159 ioport_resource.end = IOPORT_RESOURCE_END;
160 iomem_resource.start = IOMEM_RESOURCE_START;
161 iomem_resource.end = IOMEM_RESOURCE_END;
162 }