diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-07-31 01:18:31 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-07-31 01:18:31 -0400 |
commit | b6965f7967a64b185d7ff4cc4bcf15c380c1348f (patch) | |
tree | e8d8b25b54288b3b5ffbdf40c59c637abee4a86b /arch/powerpc/platforms/85xx | |
parent | 1fad1e9a747687a7399bf58e87974f9b1bbcae06 (diff) | |
parent | 896c01cb4bb3cfc2c0ea9873fa7a9f8bd0a7c8d8 (diff) |
Merge remote-tracking branch 'kumar/merge' into merge
Kumar says:
"A few patches that missed the initial 3.6 window. These are bug fixes at
this point."
Diffstat (limited to 'arch/powerpc/platforms/85xx')
-rw-r--r-- | arch/powerpc/platforms/85xx/p1022_ds.c | 122 |
1 files changed, 100 insertions, 22 deletions
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 89ee02c54561..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) != |
@@ -419,18 +479,6 @@ void __init p1022_ds_pic_init(void) | |||
419 | 479 | ||
420 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) | 480 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) |
421 | 481 | ||
422 | /* | ||
423 | * Disables a node in the device tree. | ||
424 | * | ||
425 | * This function is called before kmalloc() is available, so the 'new' object | ||
426 | * should be allocated in the global area. The easiest way is to do that is | ||
427 | * to allocate one static local variable for each call to this function. | ||
428 | */ | ||
429 | static void __init disable_one_node(struct device_node *np, struct property *new) | ||
430 | { | ||
431 | prom_update_property(np, new); | ||
432 | } | ||
433 | |||
434 | /* TRUE if there is a "video=fslfb" command-line parameter. */ | 482 | /* TRUE if there is a "video=fslfb" command-line parameter. */ |
435 | static bool fslfb; | 483 | static bool fslfb; |
436 | 484 | ||
@@ -493,28 +541,58 @@ static void __init p1022_ds_setup_arch(void) | |||
493 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; | 541 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; |
494 | 542 | ||
495 | /* | 543 | /* |
496 | * Disable the NOR flash node if there is video=fslfb... command-line | 544 | * Disable the NOR and NAND flash nodes if there is video=fslfb... |
497 | * parameter. When the DIU is active, NOR flash is unavailable, so we | 545 | * command-line parameter. When the DIU is active, the localbus is |
498 | * have to disable the node before the MTD driver loads. | 546 | * unavailable, so we have to disable these nodes before the MTD |
547 | * driver loads. | ||
499 | */ | 548 | */ |
500 | if (fslfb) { | 549 | if (fslfb) { |
501 | struct device_node *np = | 550 | struct device_node *np = |
502 | of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); | 551 | of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); |
503 | 552 | ||
504 | if (np) { | 553 | if (np) { |
505 | np = of_find_compatible_node(np, NULL, "cfi-flash"); | 554 | struct device_node *np2; |
506 | if (np) { | 555 | |
556 | of_node_get(np); | ||
557 | np2 = of_find_compatible_node(np, NULL, "cfi-flash"); | ||
558 | if (np2) { | ||
507 | static struct property nor_status = { | 559 | static struct property nor_status = { |
508 | .name = "status", | 560 | .name = "status", |
509 | .value = "disabled", | 561 | .value = "disabled", |
510 | .length = sizeof("disabled"), | 562 | .length = sizeof("disabled"), |
511 | }; | 563 | }; |
512 | 564 | ||
565 | /* | ||
566 | * prom_update_property() is called before | ||
567 | * kmalloc() is available, so the 'new' object | ||
568 | * should be allocated in the global area. | ||
569 | * The easiest way is to do that is to | ||
570 | * allocate one static local variable for each | ||
571 | * call to this function. | ||
572 | */ | ||
513 | pr_info("p1022ds: disabling %s node", | 573 | pr_info("p1022ds: disabling %s node", |
514 | np->full_name); | 574 | np2->full_name); |
515 | disable_one_node(np, &nor_status); | 575 | prom_update_property(np2, &nor_status); |
516 | of_node_put(np); | 576 | of_node_put(np2); |
517 | } | 577 | } |
578 | |||
579 | of_node_get(np); | ||
580 | np2 = of_find_compatible_node(np, NULL, | ||
581 | "fsl,elbc-fcm-nand"); | ||
582 | if (np2) { | ||
583 | static struct property nand_status = { | ||
584 | .name = "status", | ||
585 | .value = "disabled", | ||
586 | .length = sizeof("disabled"), | ||
587 | }; | ||
588 | |||
589 | pr_info("p1022ds: disabling %s node", | ||
590 | np2->full_name); | ||
591 | prom_update_property(np2, &nand_status); | ||
592 | of_node_put(np2); | ||
593 | } | ||
594 | |||
595 | of_node_put(np); | ||
518 | } | 596 | } |
519 | 597 | ||
520 | } | 598 | } |