diff options
| -rw-r--r-- | arch/powerpc/platforms/85xx/p1022_ds.c | 64 |
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) != |
