aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac/feature.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-12-13 21:10:10 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:03:17 -0500
commit1beb6a7d6cbed3ac03500ce9b5b9bb632c512039 (patch)
tree727aa76da5a82fca449dadf3cebbadc414ad6555 /arch/powerpc/platforms/powermac/feature.c
parentcd0c7f06803be06a5cf4564aa5a900f4b6aea603 (diff)
[PATCH] powerpc: Experimental support for new G5 Macs (#2)
This adds some very basic support for the new machines, including the Quad G5 (tested), and other new dual core based machines and iMac G5 iSight (untested). This is still experimental ! There is no thermal control yet, there is no proper handing of MSIs, etc.. but it boots, I have all 4 cores up on my machine. Compared to the previous version of this patch, this one adds DART IOMMU support for the U4 chipset and thus should work fine on setups with more than 2Gb of RAM. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac/feature.c')
-rw-r--r--arch/powerpc/platforms/powermac/feature.c65
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[] =
119static struct device_node *uninorth_node; 120static struct device_node *uninorth_node;
120static u32 __iomem *uninorth_base; 121static u32 __iomem *uninorth_base;
121static u32 uninorth_rev; 122static u32 uninorth_rev;
122static int uninorth_u3; 123static int uninorth_maj;
123static void __iomem *u3_ht; 124static 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)
1399static long g5_mpic_enable(struct device_node *node, long param, long value) 1400static 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 */
1548void g5_phy_disable_cpu1(void) 1554void 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