diff options
Diffstat (limited to 'arch/powerpc/platforms/powermac/feature.c')
-rw-r--r-- | arch/powerpc/platforms/powermac/feature.c | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index b1f896952b1..d2915d64d45 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -101,7 +101,8 @@ static const char *macio_names[] = | |||
101 | "Keylargo", | 101 | "Keylargo", |
102 | "Pangea", | 102 | "Pangea", |
103 | "Intrepid", | 103 | "Intrepid", |
104 | "K2" | 104 | "K2", |
105 | "Shasta", | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | 108 | ||
@@ -119,7 +120,7 @@ static const char *macio_names[] = | |||
119 | static struct device_node *uninorth_node; | 120 | static struct device_node *uninorth_node; |
120 | static u32 __iomem *uninorth_base; | 121 | static u32 __iomem *uninorth_base; |
121 | static u32 uninorth_rev; | 122 | static u32 uninorth_rev; |
122 | static int uninorth_u3; | 123 | static int uninorth_maj; |
123 | static void __iomem *u3_ht; | 124 | static void __iomem *u3_ht; |
124 | 125 | ||
125 | /* | 126 | /* |
@@ -1399,8 +1400,15 @@ static long g5_fw_enable(struct device_node *node, long param, long value) | |||
1399 | static long g5_mpic_enable(struct device_node *node, long param, long value) | 1400 | static long g5_mpic_enable(struct device_node *node, long param, long value) |
1400 | { | 1401 | { |
1401 | unsigned long flags; | 1402 | unsigned long flags; |
1403 | struct device_node *parent = of_get_parent(node); | ||
1404 | int is_u3; | ||
1402 | 1405 | ||
1403 | if (node->parent == NULL || strcmp(node->parent->name, "u3")) | 1406 | if (parent == NULL) |
1407 | return 0; | ||
1408 | is_u3 = strcmp(parent->name, "u3") == 0 || | ||
1409 | strcmp(parent->name, "u4") == 0; | ||
1410 | of_node_put(parent); | ||
1411 | if (!is_u3) | ||
1404 | return 0; | 1412 | return 0; |
1405 | 1413 | ||
1406 | LOCK(flags); | 1414 | LOCK(flags); |
@@ -1464,7 +1472,7 @@ static long g5_i2s_enable(struct device_node *node, long param, long value) | |||
1464 | }, | 1472 | }, |
1465 | }; | 1473 | }; |
1466 | 1474 | ||
1467 | if (macio->type != macio_keylargo2 /* && macio->type != macio_shasta*/) | 1475 | if (macio->type != macio_keylargo2 && macio->type != macio_shasta) |
1468 | return -ENODEV; | 1476 | return -ENODEV; |
1469 | if (strncmp(node->name, "i2s-", 4)) | 1477 | if (strncmp(node->name, "i2s-", 4)) |
1470 | return -ENODEV; | 1478 | return -ENODEV; |
@@ -1473,11 +1481,9 @@ static long g5_i2s_enable(struct device_node *node, long param, long value) | |||
1473 | case 0: | 1481 | case 0: |
1474 | case 1: | 1482 | case 1: |
1475 | break; | 1483 | break; |
1476 | #if 0 | ||
1477 | case 2: | 1484 | case 2: |
1478 | if (macio->type == macio_shasta) | 1485 | if (macio->type == macio_shasta) |
1479 | break; | 1486 | break; |
1480 | #endif | ||
1481 | default: | 1487 | default: |
1482 | return -ENODEV; | 1488 | return -ENODEV; |
1483 | } | 1489 | } |
@@ -1508,7 +1514,7 @@ static long g5_reset_cpu(struct device_node *node, long param, long value) | |||
1508 | struct device_node *np; | 1514 | struct device_node *np; |
1509 | 1515 | ||
1510 | macio = &macio_chips[0]; | 1516 | macio = &macio_chips[0]; |
1511 | if (macio->type != macio_keylargo2) | 1517 | if (macio->type != macio_keylargo2 && macio->type != macio_shasta) |
1512 | return -ENODEV; | 1518 | return -ENODEV; |
1513 | 1519 | ||
1514 | np = find_path_device("/cpus"); | 1520 | np = find_path_device("/cpus"); |
@@ -1547,7 +1553,8 @@ static long g5_reset_cpu(struct device_node *node, long param, long value) | |||
1547 | */ | 1553 | */ |
1548 | void g5_phy_disable_cpu1(void) | 1554 | void g5_phy_disable_cpu1(void) |
1549 | { | 1555 | { |
1550 | UN_OUT(U3_API_PHY_CONFIG_1, 0); | 1556 | if (uninorth_maj == 3) |
1557 | UN_OUT(U3_API_PHY_CONFIG_1, 0); | ||
1551 | } | 1558 | } |
1552 | #endif /* CONFIG_POWER4 */ | 1559 | #endif /* CONFIG_POWER4 */ |
1553 | 1560 | ||
@@ -2462,6 +2469,14 @@ static struct pmac_mb_def pmac_mb_defs[] = { | |||
2462 | PMAC_TYPE_POWERMAC_G5_U3L, g5_features, | 2469 | PMAC_TYPE_POWERMAC_G5_U3L, g5_features, |
2463 | 0, | 2470 | 0, |
2464 | }, | 2471 | }, |
2472 | { "PowerMac11,2", "PowerMac G5 Dual Core", | ||
2473 | PMAC_TYPE_POWERMAC_G5_U3L, g5_features, | ||
2474 | 0, | ||
2475 | }, | ||
2476 | { "PowerMac12,1", "iMac G5 (iSight)", | ||
2477 | PMAC_TYPE_POWERMAC_G5_U3L, g5_features, | ||
2478 | 0, | ||
2479 | }, | ||
2465 | { "RackMac3,1", "XServe G5", | 2480 | { "RackMac3,1", "XServe G5", |
2466 | PMAC_TYPE_XSERVE_G5, g5_features, | 2481 | PMAC_TYPE_XSERVE_G5, g5_features, |
2467 | 0, | 2482 | 0, |
@@ -2574,6 +2589,11 @@ static int __init probe_motherboard(void) | |||
2574 | pmac_mb.model_name = "Unknown K2-based"; | 2589 | pmac_mb.model_name = "Unknown K2-based"; |
2575 | pmac_mb.features = g5_features; | 2590 | pmac_mb.features = g5_features; |
2576 | break; | 2591 | break; |
2592 | case macio_shasta: | ||
2593 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_SHASTA; | ||
2594 | pmac_mb.model_name = "Unknown Shasta-based"; | ||
2595 | pmac_mb.features = g5_features; | ||
2596 | break; | ||
2577 | #endif /* CONFIG_POWER4 */ | 2597 | #endif /* CONFIG_POWER4 */ |
2578 | default: | 2598 | default: |
2579 | return -ENODEV; | 2599 | return -ENODEV; |
@@ -2651,7 +2671,12 @@ static void __init probe_uninorth(void) | |||
2651 | /* Locate G5 u3 */ | 2671 | /* Locate G5 u3 */ |
2652 | if (uninorth_node == NULL) { | 2672 | if (uninorth_node == NULL) { |
2653 | uninorth_node = of_find_node_by_name(NULL, "u3"); | 2673 | uninorth_node = of_find_node_by_name(NULL, "u3"); |
2654 | uninorth_u3 = 1; | 2674 | uninorth_maj = 3; |
2675 | } | ||
2676 | /* Locate G5 u4 */ | ||
2677 | if (uninorth_node == NULL) { | ||
2678 | uninorth_node = of_find_node_by_name(NULL, "u4"); | ||
2679 | uninorth_maj = 4; | ||
2655 | } | 2680 | } |
2656 | if (uninorth_node == NULL) | 2681 | if (uninorth_node == NULL) |
2657 | return; | 2682 | return; |
@@ -2664,12 +2689,13 @@ static void __init probe_uninorth(void) | |||
2664 | return; | 2689 | return; |
2665 | uninorth_base = ioremap(address, 0x40000); | 2690 | uninorth_base = ioremap(address, 0x40000); |
2666 | uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); | 2691 | uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); |
2667 | if (uninorth_u3) | 2692 | if (uninorth_maj == 3 || uninorth_maj == 4) |
2668 | u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); | 2693 | u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); |
2669 | 2694 | ||
2670 | printk(KERN_INFO "Found %s memory controller & host bridge," | 2695 | printk(KERN_INFO "Found %s memory controller & host bridge" |
2671 | " revision: %d\n", uninorth_u3 ? "U3" : "UniNorth", | 2696 | " @ 0x%08x revision: 0x%02x\n", uninorth_maj == 3 ? "U3" : |
2672 | uninorth_rev); | 2697 | uninorth_maj == 4 ? "U4" : "UniNorth", |
2698 | (unsigned int)address, uninorth_rev); | ||
2673 | printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); | 2699 | printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); |
2674 | 2700 | ||
2675 | /* Set the arbitrer QAck delay according to what Apple does | 2701 | /* Set the arbitrer QAck delay according to what Apple does |
@@ -2677,7 +2703,8 @@ static void __init probe_uninorth(void) | |||
2677 | if (uninorth_rev < 0x11) { | 2703 | if (uninorth_rev < 0x11) { |
2678 | actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; | 2704 | actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; |
2679 | actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : | 2705 | actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : |
2680 | UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; | 2706 | UNI_N_ARB_CTRL_QACK_DELAY) << |
2707 | UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; | ||
2681 | UN_OUT(UNI_N_ARB_CTRL, actrl); | 2708 | UN_OUT(UNI_N_ARB_CTRL, actrl); |
2682 | } | 2709 | } |
2683 | 2710 | ||
@@ -2685,7 +2712,8 @@ static void __init probe_uninorth(void) | |||
2685 | * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI | 2712 | * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI |
2686 | * memory timeout | 2713 | * memory timeout |
2687 | */ | 2714 | */ |
2688 | if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0) | 2715 | if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || |
2716 | uninorth_rev == 0xc0) | ||
2689 | UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); | 2717 | UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); |
2690 | } | 2718 | } |
2691 | 2719 | ||
@@ -2736,12 +2764,14 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ | |||
2736 | node->full_name); | 2764 | node->full_name); |
2737 | return; | 2765 | return; |
2738 | } | 2766 | } |
2739 | if (type == macio_keylargo) { | 2767 | if (type == macio_keylargo || type == macio_keylargo2) { |
2740 | u32 *did = (u32 *)get_property(node, "device-id", NULL); | 2768 | u32 *did = (u32 *)get_property(node, "device-id", NULL); |
2741 | if (*did == 0x00000025) | 2769 | if (*did == 0x00000025) |
2742 | type = macio_pangea; | 2770 | type = macio_pangea; |
2743 | if (*did == 0x0000003e) | 2771 | if (*did == 0x0000003e) |
2744 | type = macio_intrepid; | 2772 | type = macio_intrepid; |
2773 | if (*did == 0x0000004f) | ||
2774 | type = macio_shasta; | ||
2745 | } | 2775 | } |
2746 | macio_chips[i].of_node = node; | 2776 | macio_chips[i].of_node = node; |
2747 | macio_chips[i].type = type; | 2777 | macio_chips[i].type = type; |
@@ -2840,7 +2870,8 @@ set_initial_features(void) | |||
2840 | } | 2870 | } |
2841 | 2871 | ||
2842 | #ifdef CONFIG_POWER4 | 2872 | #ifdef CONFIG_POWER4 |
2843 | if (macio_chips[0].type == macio_keylargo2) { | 2873 | if (macio_chips[0].type == macio_keylargo2 || |
2874 | macio_chips[0].type == macio_shasta) { | ||
2844 | #ifndef CONFIG_SMP | 2875 | #ifndef CONFIG_SMP |
2845 | /* On SMP machines running UP, we have the second CPU eating | 2876 | /* On SMP machines running UP, we have the second CPU eating |
2846 | * bus cycles. We need to take it off the bus. This is done | 2877 | * bus cycles. We need to take it off the bus. This is done |