diff options
author | Josh Boyer <jwboyer@linux.vnet.ibm.com> | 2007-08-20 08:30:32 -0400 |
---|---|---|
committer | Josh Boyer <jwboyer@linux.vnet.ibm.com> | 2007-08-20 08:30:32 -0400 |
commit | 2ba4573cdaf98b0f3acb8795a66f412c1c41284a (patch) | |
tree | 34e161751ed0192c5b1af1f2001d4b035b985f34 /arch/powerpc/boot/4xx.c | |
parent | 8c1449bdb4c7e9c4492ba18ded70fd8669eeffae (diff) |
[POWERPC] Bamboo zImage wrapper
Add a bootwrapper for the AMCC 440EP Bamboo Eval board. This also adds a
common fixup_clock function for all 440EP(x) chips.
Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'arch/powerpc/boot/4xx.c')
-rw-r--r-- | arch/powerpc/boot/4xx.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c index 59026e4585dc..642d8780bb31 100644 --- a/arch/powerpc/boot/4xx.c +++ b/arch/powerpc/boot/4xx.c | |||
@@ -108,3 +108,85 @@ void ibm4xx_fixup_ebc_ranges(const char *ebc) | |||
108 | 108 | ||
109 | setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32)); | 109 | setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32)); |
110 | } | 110 | } |
111 | |||
112 | #define SPRN_CCR1 0x378 | ||
113 | void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk) | ||
114 | { | ||
115 | u32 cpu, plb, opb, ebc, tb, uart0, m, vco; | ||
116 | u32 reg; | ||
117 | u32 fwdva, fwdvb, fbdv, lfbdv, opbdv0, perdv0, spcid0, prbdv0, tmp; | ||
118 | |||
119 | mtdcr(DCRN_CPR0_ADDR, CPR0_PLLD0); | ||
120 | reg = mfdcr(DCRN_CPR0_DATA); | ||
121 | tmp = (reg & 0x000F0000) >> 16; | ||
122 | fwdva = tmp ? tmp : 16; | ||
123 | tmp = (reg & 0x00000700) >> 8; | ||
124 | fwdvb = tmp ? tmp : 8; | ||
125 | tmp = (reg & 0x1F000000) >> 24; | ||
126 | fbdv = tmp ? tmp : 32; | ||
127 | lfbdv = (reg & 0x0000007F); | ||
128 | |||
129 | mtdcr(DCRN_CPR0_ADDR, CPR0_OPBD0); | ||
130 | reg = mfdcr(DCRN_CPR0_DATA); | ||
131 | tmp = (reg & 0x03000000) >> 24; | ||
132 | opbdv0 = tmp ? tmp : 4; | ||
133 | |||
134 | mtdcr(DCRN_CPR0_ADDR, CPR0_PERD0); | ||
135 | reg = mfdcr(DCRN_CPR0_DATA); | ||
136 | tmp = (reg & 0x07000000) >> 24; | ||
137 | perdv0 = tmp ? tmp : 8; | ||
138 | |||
139 | mtdcr(DCRN_CPR0_ADDR, CPR0_PRIMBD0); | ||
140 | reg = mfdcr(DCRN_CPR0_DATA); | ||
141 | tmp = (reg & 0x07000000) >> 24; | ||
142 | prbdv0 = tmp ? tmp : 8; | ||
143 | |||
144 | mtdcr(DCRN_CPR0_ADDR, CPR0_SCPID); | ||
145 | reg = mfdcr(DCRN_CPR0_DATA); | ||
146 | tmp = (reg & 0x03000000) >> 24; | ||
147 | spcid0 = tmp ? tmp : 4; | ||
148 | |||
149 | /* Calculate M */ | ||
150 | mtdcr(DCRN_CPR0_ADDR, CPR0_PLLC0); | ||
151 | reg = mfdcr(DCRN_CPR0_DATA); | ||
152 | tmp = (reg & 0x03000000) >> 24; | ||
153 | if (tmp == 0) { /* PLL output */ | ||
154 | tmp = (reg & 0x20000000) >> 29; | ||
155 | if (!tmp) /* PLLOUTA */ | ||
156 | m = fbdv * lfbdv * fwdva; | ||
157 | else | ||
158 | m = fbdv * lfbdv * fwdvb; | ||
159 | } | ||
160 | else if (tmp == 1) /* CPU output */ | ||
161 | m = fbdv * fwdva; | ||
162 | else | ||
163 | m = perdv0 * opbdv0 * fwdvb; | ||
164 | |||
165 | vco = (m * sysclk) + (m >> 1); | ||
166 | cpu = vco / fwdva; | ||
167 | plb = vco / fwdvb / prbdv0; | ||
168 | opb = plb / opbdv0; | ||
169 | ebc = plb / perdv0; | ||
170 | |||
171 | /* FIXME */ | ||
172 | uart0 = ser_clk; | ||
173 | |||
174 | /* Figure out timebase. Either CPU or default TmrClk */ | ||
175 | asm volatile ( | ||
176 | "mfspr %0,%1\n" | ||
177 | : | ||
178 | "=&r"(reg) : "i"(SPRN_CCR1)); | ||
179 | if (reg & 0x0080) | ||
180 | tb = 25000000; /* TmrClk is 25MHz */ | ||
181 | else | ||
182 | tb = cpu; | ||
183 | |||
184 | dt_fixup_cpu_clocks(cpu, tb, 0); | ||
185 | dt_fixup_clock("/plb", plb); | ||
186 | dt_fixup_clock("/plb/opb", opb); | ||
187 | dt_fixup_clock("/plb/opb/ebc", ebc); | ||
188 | dt_fixup_clock("/plb/opb/serial@ef600300", uart0); | ||
189 | dt_fixup_clock("/plb/opb/serial@ef600400", uart0); | ||
190 | dt_fixup_clock("/plb/opb/serial@ef600500", uart0); | ||
191 | dt_fixup_clock("/plb/opb/serial@ef600600", uart0); | ||
192 | } | ||