aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2012-07-23 16:43:32 -0400
committerKumar Gala <galak@kernel.crashing.org>2012-07-26 14:26:05 -0400
commit896c01cb4bb3cfc2c0ea9873fa7a9f8bd0a7c8d8 (patch)
tree8be5534f24ac4b930b1b0b3b43d5ccbf72aa4fc4 /arch/powerpc
parent6269f2584a359766f53005c676daff8aee60cbed (diff)
powerpc/85xx: p1022ds: fix DIU/LBC switching with NAND enabled
In order for indirect mode on the PIXIS to work properly, both chip selects need to be set to GPCM mode, otherwise writes to the chip select base addresses will not actually post to the local bus -- they'll go to the NAND controller instead. Therefore, we need to set BR0 and BR1 to GPCM mode before switching to indirect mode. Signed-off-by: Timur Tabi <timur@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
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) !=