aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 5ca2823ab7f2..3c732acf331d 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -208,6 +208,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
208 u8 __iomem *lbc_lcs0_ba = NULL; 208 u8 __iomem *lbc_lcs0_ba = NULL;
209 u8 __iomem *lbc_lcs1_ba = NULL; 209 u8 __iomem *lbc_lcs1_ba = NULL;
210 phys_addr_t cs0_addr, cs1_addr; 210 phys_addr_t cs0_addr, cs1_addr;
211 u32 br0, or0, br1, or1;
211 const __be32 *iprop; 212 const __be32 *iprop;
212 unsigned int num_laws; 213 unsigned int num_laws;
213 u8 b; 214 u8 b;
@@ -256,11 +257,70 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
256 } 257 }
257 num_laws = be32_to_cpup(iprop); 258 num_laws = be32_to_cpup(iprop);
258 259
259 cs0_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[0].br)); 260 /*
260 cs1_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[1].br)); 261 * Indirect mode requires both BR0 and BR1 to be set to "GPCM",
262 * otherwise writes to these addresses won't actually appear on the
263 * local bus, and so the PIXIS won't see them.
264 *
265 * In FCM mode, writes go to the NAND controller, which does not pass
266 * them to the localbus directly. So we force BR0 and BR1 into GPCM
267 * mode, since we don't care about what's behind the localbus any
268 * more.
269 */
270 br0 = in_be32(&lbc->bank[0].br);
271 br1 = in_be32(&lbc->bank[1].br);
272 or0 = in_be32(&lbc->bank[0].or);
273 or1 = in_be32(&lbc->bank[1].or);
274
275 /* Make sure CS0 and CS1 are programmed */
276 if (!(br0 & BR_V) || !(br1 & BR_V)) {
277 pr_err("p1022ds: CS0 and/or CS1 is not programmed\n");
278 goto exit;
279 }
280
281 /*
282 * Use the existing BRx/ORx values if it's already GPCM. Otherwise,
283 * force the values to simple 32KB GPCM windows with the most
284 * conservative timing.
285 */
286 if ((br0 & BR_MSEL) != BR_MS_GPCM) {
287 br0 = (br0 & BR_BA) | BR_V;
288 or0 = 0xFFFF8000 | 0xFF7;
289 out_be32(&lbc->bank[0].br, br0);
290 out_be32(&lbc->bank[0].or, or0);
291 }
292 if ((br1 & BR_MSEL) != BR_MS_GPCM) {
293 br1 = (br1 & BR_BA) | BR_V;
294 or1 = 0xFFFF8000 | 0xFF7;
295 out_be32(&lbc->bank[1].br, br1);
296 out_be32(&lbc->bank[1].or, or1);
297 }
298
299 cs0_addr = lbc_br_to_phys(ecm, num_laws, br0);
300 if (!cs0_addr) {
301 pr_err("p1022ds: could not determine physical address for CS0"
302 " (BR0=%08x)\n", br0);
303 goto exit;
304 }
305 cs1_addr = lbc_br_to_phys(ecm, num_laws, br1);
306 if (!cs0_addr) {
307 pr_err("p1022ds: could not determine physical address for CS1"
308 " (BR1=%08x)\n", br1);
309 goto exit;
310 }
261 311
262 lbc_lcs0_ba = ioremap(cs0_addr, 1); 312 lbc_lcs0_ba = ioremap(cs0_addr, 1);
313 if (!lbc_lcs0_ba) {
314 pr_err("p1022ds: could not ioremap CS0 address %llx\n",
315 (unsigned long long)cs0_addr);
316 goto exit;
317 }
263 lbc_lcs1_ba = ioremap(cs1_addr, 1); 318 lbc_lcs1_ba = ioremap(cs1_addr, 1);
319 if (!lbc_lcs1_ba) {
320 pr_err("p1022ds: could not ioremap CS1 address %llx\n",
321 (unsigned long long)cs1_addr);
322 goto exit;
323 }
264 324
265 /* Make sure we're in indirect mode first. */ 325 /* Make sure we're in indirect mode first. */
266 if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != 326 if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=