aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/4xx.c
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-08-20 08:30:32 -0400
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-08-20 08:30:32 -0400
commit2ba4573cdaf98b0f3acb8795a66f412c1c41284a (patch)
tree34e161751ed0192c5b1af1f2001d4b035b985f34 /arch/powerpc/boot/4xx.c
parent8c1449bdb4c7e9c4492ba18ded70fd8669eeffae (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.c82
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
113void 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}