This adds support for recent powermac models and fixes a few bugs.
extern void __setup_cpu_7400(int cpu_nr);
extern void __setup_cpu_7410(int cpu_nr);
extern void __setup_cpu_7450(int cpu_nr);
+extern void __setup_cpu_7450_23(int cpu_nr);
+extern void __setup_cpu_7455(int cpu_nr);
extern void __setup_cpu_power3(int cpu_nr);
extern void __setup_cpu_8xx(int cpu_nr);
extern void __setup_cpu_generic(int cpu_nr);
},
{ /* 603 */
0xffff0000, 0x00030000, "603",
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_603
},
{ /* 603e */
0xffff0000, 0x00060000, "603e",
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_603
},
{ /* 603ev */
0xffff0000, 0x00070000, "603ev",
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_603
{ /* 740/750 (0x4202, don't support TAU ?) */
0xffffffff, 0x00084202, "740/750",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_750
{ /* 745/755 */
0xfffff000, 0x00083000, "745/755",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_750
{ /* 750CX (80100 and 8010x?) */
0xfffffff0, 0x00080100, "750CX",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_750
{ /* 750CX (82201 and 82202) */
0xfffffff0, 0x00082200, "750CX",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_750
{ /* 750CXe (82214) */
0xfffffff0, 0x00082210, "750CXe",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
COMMON_PPC,
32, 32,
__setup_cpu_750
{ /* 7400 rev 1.1 ? (no TAU) */
0xffffffff, 0x000c1101, "7400 (1.1)",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7400
{ /* 7400 */
0xffff0000, 0x000c0000, "7400",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7400
{ /* 7410 */
0xffff0000, 0x800c0000, "7410",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7410
{ /* 7450 2.0 - no doze/nap */
0xffffffff, 0x80000200, "7450",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7450
},
- { /* 7450 others */
- 0xffff0000, 0x80000000, "7450",
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP |
+ { /* 7450 2.1 */
+ 0xffffffff, 0x80000201, "7450",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7450
},
+ { /* 7450 2.3 and newer */
+ 0xffff0000, 0x80000000, "7450",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
+ COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+ 32, 32,
+ __setup_cpu_7450_23
+ },
+ { /* 7455 */
+ 0xffff0000, 0x80010000, "7455",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
+ COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
+ 32, 32,
+ __setup_cpu_7455
+ },
{ /* 82xx (8240, 8245, 8260 are all 603e cores) */
0x7fff0000, 0x00810000, "82xx",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
{
int do_power_save = 0;
- if (cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_CAN_DOZE)
+ /* Check if CPU can powersave */
+ if (cur_cpu_spec[smp_processor_id()]->cpu_features &
+ (CPU_FTR_CAN_DOZE | CPU_FTR_CAN_NAP))
do_power_save = 1;
#ifdef CONFIG_PPC_ISERIES
/* 7450 has no DOZE mode mode, we return if powersave_nap
* isn't enabled
*/
- if (!nap && cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_SPEC7450)
+ if (!(nap || (cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_CAN_DOZE)))
return;
/*
* Disable interrupts to prevent a lost wakeup
The bit moved on the 7450.....
****/
+ /* TODO: use HW flush assist when available */
+
lis r4,0x0002
mtctr r4
li r4,0
2:
/* Set up the L2CR configuration bits (and switch L2 off) */
+ /* CPU errata: Make sure the mtspr below is already in the
+ * L1 icache
+ */
+ b 20f
+21:
sync
mtspr L2CR,r3
sync
-
+ b 22f
+20:
+ b 21b
+22:
/* Before we perform the global invalidation, we must disable dynamic
* power management via HID0[DPM] to work around a processor bug where
* DPM can possibly interfere with the state machine in the processor
END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
blr
+
+/*
+ * Here is a similar routine for dealing with the L3 cache
+ * on the 745x family of chips
+ */
+
+_GLOBAL(_set_L3CR)
+ /* Make sure this is a 745x chip */
+BEGIN_FTR_SECTION
+ li r3,-1
+ blr
+END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
+
+ /* Turn off interrupts and data relocation. */
+ mfmsr r7 /* Save MSR in r7 */
+ rlwinm r4,r7,0,17,15
+ rlwinm r4,r4,0,28,26 /* Turn off DR bit */
+ sync
+ mtmsr r4
+ isync
+
+ /* Stop DST streams */
+ dssall 0
+
+ /* Get the current enable bit of the L3CR into r4 */
+ mfspr r4,SPRN_L3CR
+
+ /* Tweak some bits */
+ rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
+ rlwinm r3,r3,0,22,20 /* Turn off the invalidate bit */
+ rlwinm r3,r3,0,1,31 /* Turn off the enable bit */
+ rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
+ /* Check to see if we need to flush */
+ rlwinm. r4,r4,0,0,0
+ beq 2f
+
+ /* Flush the cache. First, read the first 4MB of memory (physical) to
+ * put new data in the cache. (Actually we only need
+ * the size of the L3 cache plus the size of the L1+L2 cache, but 4MB will
+ * cover everything just to be safe).
+ */
+
+ /* TODO: use HW flush assist */
+
+ lis r4,0x0002
+ mtctr r4
+ li r4,0
+1:
+ lwzx r0,r0,r4
+ addi r4,r4,32 /* Go to start of next cache line */
+ bdnz 1b
+
+ /* Now, flush the first 4MB of memory */
+ lis r4,0x0002
+ mtctr r4
+ li r4,0
+ sync
+1:
+ dcbf r0,r4
+ addi r4,r4,32 /* Go to start of next cache line */
+ bdnz 1b
+
+2:
+ /* Set up the L3CR configuration bits (and switch L3 off) */
+ sync
+ mtspr SPRN_L3CR,r3
+ sync
+
+ /* Before we perform the global invalidation, we must disable dynamic
+ * power management via HID0[DPM] to work around a processor bug where
+ * DPM can possibly interfere with the state machine in the processor
+ * that invalidates the L3 cache tags. Hrm... This is necessary for L2,
+ * is it for L3 as well ? --BenH.
+ */
+ mfspr r8,HID0 /* Save HID0 in r8 */
+ rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
+ sync
+ mtspr HID0,r4 /* Disable DPM */
+ sync
+
+ oris r3,r3,L3CR_L3RES@h /* Set reserved bit 5 */
+ mtspr SPRN_L3CR,r3
+ sync
+ oris r3,r3,L3CR_L3CLKEN@h /* Set clken */
+ mtspr SPRN_L3CR,r3
+ sync
+
+ /* Wait for stabilize */
+ li r0,128
+ mtctr r0
+1: bdnz 1b
+
+ /* Perform a global invalidation */
+ ori r3,r3,0x0400
+ sync
+ mtspr SPRN_L3CR,r3
+ sync
+ isync
+
+ /* We wait for the L3I bit to clear...... */
+10: mfspr r3,SPRN_L3CR
+ andi. r4,r3,0x0400
+ bne 10b
+
+ /* Clear CLKEN */
+ rlwinm r3,r3,0,5,3 /* Turn off the clken bit */
+ mtspr SPRN_L3CR,r3
+ sync
+
+ /* Wait for stabilize */
+ li r0,128
+ mtctr r0
+1: bdnz 1b
+
+ /* Restore HID0[DPM] to whatever it was before */
+ sync
+ mtspr 1008,r8
+ sync
+
+ /* See if we need to enable the cache */
+ cmplwi r5,0
+ beq 4f
+
+ /* Enable the cache */
+ oris r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
+ mtspr SPRN_L3CR,r3
+ sync
+
+ /* Restore MSR (restores EE and DR bits to original state) */
+4: SYNC
+ mtmsr r7
+ isync
+ blr
+
+_GLOBAL(_get_L3CR)
+ /* Return the L3CR contents */
+ li r3,0
+BEGIN_FTR_SECTION
+ mfspr r3,SPRN_L3CR
+END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
+ blr
+
/* --- End of PowerLogix code ---
*/
if (_machine != _MACH_Pmac)
return;
/*
- * Fix the interrupt routing on the TI1211 chip on the 1999
- * G3 powerbook, which doesn't get initialized properly by OF.
- * Same problem with the 1410 of the new titanium pbook which
- * has the same register.
+ * Fix the interrupt routing on the various cardbus bridges
+ * used on powerbooks
*/
- if (dev->vendor == PCI_VENDOR_ID_TI
- && (dev->device == PCI_DEVICE_ID_TI_1211 ||
- dev->device == PCI_DEVICE_ID_TI_1410)) {
+ if (dev->vendor != PCI_VENDOR_ID_TI)
+ return;
+ if (dev->device == PCI_DEVICE_ID_TI_1130 ||
+ dev->device == PCI_DEVICE_ID_TI_1131) {
+ u8 val;
+ /* Enable PCI interrupt */
+ if (pci_read_config_byte(dev, 0x91, &val) == 0)
+ pci_write_config_byte(dev, 0x91, val | 0x30);
+ /* Disable ISA interrupt mode */
+ if (pci_read_config_byte(dev, 0x92, &val) == 0)
+ pci_write_config_byte(dev, 0x92, val & ~0x06);
+ }
+ if (dev->device == PCI_DEVICE_ID_TI_1210 ||
+ dev->device == PCI_DEVICE_ID_TI_1211 ||
+ dev->device == PCI_DEVICE_ID_TI_1410) {
u8 val;
/* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
signal out the MFUNC0 pin */
* which might have be mirrored at 0x0100-0x03ff..
*/
void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+ unsigned long align)
{
struct pci_dev *dev = data;
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/pmac_feature.h>
+#include <asm/sections.h>
#if defined CONFIG_KGDB
#include <asm/kgdb.h>
return 0;
}
-
static void *c_start(struct seq_file *m, loff_t *pos)
{
int i = *pos;
}
#ifdef CONFIG_ALL_PPC
+/*
+ * Assume here that all clock rates are the same in a
+ * smp system. -- Cort
+ */
+int __openfirmware
+of_show_percpuinfo(struct seq_file *m, int i)
+{
+ struct device_node *cpu_node;
+ int *fp, s;
+
+ cpu_node = find_type_devices("cpu");
+ if (!cpu_node)
+ return 0;
+ for (s = 0; s < i && cpu_node->next; s++)
+ cpu_node = cpu_node->next;
+ fp = (int *) get_property(cpu_node, "clock-frequency", NULL);
+ if (fp)
+ seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000);
+ return 0;
+}
+
void __init
intuit_machine_type(void)
{
if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) {
unsigned long val = simple_strtoul(str, NULL, 0);
printk(KERN_INFO "l2cr set to %lx\n", val);
- _set_L2CR(0); /* force invalidate by disable cache */
- _set_L2CR(val); /* and enable it */
+ _set_L2CR(0); /* force invalidate by disable cache */
+ _set_L2CR(val); /* and enable it */
}
return 1;
}
__setup("l2cr=", ppc_setup_l2cr);
+#ifdef CONFIG_NVRAM
+/* Generic nvram hooks we now look into ppc_md.nvram_read_val
+ * on pmac too ;)
+ * //XX Those 2 could be moved to headers
+ */
+unsigned char
+nvram_read_byte(int addr)
+{
+ if (ppc_md.nvram_read_val)
+ return ppc_md.nvram_read_val(addr);
+ return 0xff;
+}
+
+void
+nvram_write_byte(unsigned char val, int addr)
+{
+ if (ppc_md.nvram_write_val)
+ ppc_md.nvram_write_val(val, addr);
+}
+#endif /* CONFIG_NVRAM */
+
int __init ppc_init(void)
{
/* clear the progress line */
chrp_init2(void)
{
#ifdef CONFIG_NVRAM
- pmac_nvram_init();
+// XX replace this in a more saner way
+// pmac_nvram_init();
#endif
request_region(0x20,0x20,"pic1");
}
static int __pmac
-generic_scc_enable(struct device_node* node, u32 enable_mask, u32 reset_mask,
- int param, int value)
+ohare_htw_scc_enable(struct device_node* node, int param, int value)
{
struct macio_chip* macio;
unsigned long chan_mask;
unsigned long fcr;
unsigned long flags;
+ int htw;
+ unsigned long rmask;
macio = macio_find(node, 0);
if (!macio)
else
return -ENODEV;
+ htw = (macio->type == macio_heathrow || macio->type == macio_paddington
+ || macio->type == macio_gatwick);
if (value) {
+#ifdef CONFIG_ADB_PMU
+ if ((param & 0xfff) == PMAC_SCC_IRDA)
+ pmu_enable_irled(1);
+#endif /* CONFIG_ADB_PMU */
LOCK(flags);
fcr = MACIO_IN32(OHARE_FCR);
/* Check if scc cell need enabling */
if (!(fcr & OH_SCC_ENABLE)) {
- fcr |= enable_mask;
- MACIO_OUT32(OHARE_FCR, fcr);
- fcr |= reset_mask;
- MACIO_OUT32(OHARE_FCR, fcr);
+ fcr |= OH_SCC_ENABLE;
+ if (htw) {
+ fcr &= ~HRW_SCC_TRANS_EN_N;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ fcr |= (rmask = HRW_RESET_SCC);
+ MACIO_OUT32(OHARE_FCR, fcr);
+ } else {
+ fcr |= (rmask = OH_SCC_RESET);
+ MACIO_OUT32(OHARE_FCR, fcr);
+ }
UNLOCK(flags);
(void)MACIO_IN32(OHARE_FCR);
mdelay(15);
LOCK(flags);
- fcr &= ~reset_mask;
+ fcr &= ~rmask;
MACIO_OUT32(OHARE_FCR, fcr);
}
if (chan_mask & MACIO_FLAG_SCCA_ON)
fcr &= ~OH_SCCB_IO;
MACIO_OUT32(OHARE_FCR, fcr);
if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
- fcr &= ~enable_mask;
+ fcr &= ~OH_SCC_ENABLE;
+ if (htw)
+ fcr |= HRW_SCC_TRANS_EN_N;
MACIO_OUT32(OHARE_FCR, fcr);
}
macio->flags &= ~(chan_mask);
UNLOCK(flags);
mdelay(10);
- }
- return 0;
-}
-
-static int __pmac
-ohare_scc_enable(struct device_node* node, int param, int value)
-{
- int rc;
-
#ifdef CONFIG_ADB_PMU
- if (value && (param & 0xfff) == PMAC_SCC_IRDA)
- pmu_enable_irled(1);
+ if ((param & 0xfff) == PMAC_SCC_IRDA)
+ pmu_enable_irled(0);
#endif /* CONFIG_ADB_PMU */
- rc = generic_scc_enable(node, OH_SCC_ENABLE, OH_SCC_RESET, param, value);
-#ifdef CONFIG_ADB_PMU
- if ((param & 0xfff) == PMAC_SCC_IRDA && (rc || !value))
- pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */
- return rc;
+ }
+ return 0;
}
static int __pmac
return 0;
}
-static int __pmac
-heathrow_scc_enable(struct device_node* node, int param, int value)
-{
- int rc;
-
-#ifdef CONFIG_ADB_PMU
- if (value && param == PMAC_SCC_IRDA)
- pmu_enable_irled(1);
-#endif /* CONFIG_ADB_PMU */
- /* Fixme: It's possible that wallstreet (heathrow) is different
- * than other paddington machines. I still have to figure that
- * out exactly, for now, the paddington values are used
- */
- rc = generic_scc_enable(node, HRW_SCC_ENABLE, PADD_RESET_SCC, param, value);
-#ifdef CONFIG_ADB_PMU
- if (param == PMAC_SCC_IRDA && (rc || !value))
- pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */
- return rc;
-}
-
static int __pmac
heathrow_modem_enable(struct device_node* node, int param, int value)
{
if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
pmac_mb.model_id != PMAC_TYPE_YIKES) {
LOCK(flags);
- /* We use the paddington values as they seem to work properly
- * on the wallstreet (heathrow) as well. I can't tell why we
- * had to flip them on older feature.c, the fact is that new
- * code uses the paddington values which are also the ones used
- * in Darwin, and that works on wallstreet !
- */
if (value)
- MACIO_BIC(HEATHROW_FCR, PADD_MODEM_POWER_N);
+ MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
else
- MACIO_BIS(HEATHROW_FCR, PADD_MODEM_POWER_N);
+ MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
UNLOCK(flags);
(void)MACIO_IN32(HEATHROW_FCR);
mdelay(250);
LOCK(flags);
MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags);
- mdelay(250);
- LOCK(flags);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags);
- mdelay(250);
- LOCK(flags);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
(void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags);
+ UNLOCK(flags); mdelay(250);
}
return 0;
}
/* This seems to be necessary as well or the fan
* keeps coming up and battery drains fast */
MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
+ /* Make sure eth is down even if module or sleep
+ * won't work properly */
+ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
}
/* Make sure modem is shut down */
MACIO_OUT8(HRW_GPIO_MODEM_RESET,
MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
- MACIO_BIS(HEATHROW_FCR, PADD_MODEM_POWER_N);
+ MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
/* Let things settle */
UNLOCK(flags); mdelay(250); LOCK(flags);
MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
+ UNLOCK(flags); mdelay(250);
}
return 0;
}
UNLOCK(flags); mdelay(250); LOCK(flags);
MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
(void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
+ UNLOCK(flags); mdelay(250);
}
return 0;
}
return pmac_mb.board_flags;
case PMAC_MB_INFO_NAME:
/* hack hack hack... but should work */
- return (int)pmac_mb.model_name;
+ *((const char **)value) = pmac_mb.model_name;
+ break;
}
return 0;
}
* to have issues with turning on/off those asic cells
*/
static struct feature_table_entry ohare_features[] __pmacdata = {
- { PMAC_FTR_SCC_ENABLE, ohare_scc_enable },
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
{ PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
{ PMAC_FTR_IDE_ENABLE, ohare_ide_enable},
* powerbooks.
*/
static struct feature_table_entry heathrow_laptop_features[] __pmacdata = {
- { PMAC_FTR_SCC_ENABLE, heathrow_scc_enable },
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
{ PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
* The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
*/
static struct feature_table_entry paddington_features[] __pmacdata = {
- { PMAC_FTR_SCC_ENABLE, heathrow_scc_enable },
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
{ PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
PMAC_TYPE_PSURGE, NULL,
0
},
+ { "AAPL,ShinerESB", "Apple Network Server",
+ PMAC_TYPE_ANS, NULL,
+ 0
+ },
{ "AAPL,e407", "Alchemy",
PMAC_TYPE_ALCHEMY, NULL,
0
PMAC_TYPE_PANGEA_IMAC, pangea_features,
PMAC_MB_CAN_SLEEP
},
+ { "PowerBook4,2", "iBook 2 with 14\" LCD",
+ PMAC_TYPE_IBOOK2, pangea_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ },
{ "PowerBook4,1", "iBook 2",
PMAC_TYPE_IBOOK2, pangea_features,
PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
PMAC_TYPE_TITANIUM2, core99_features,
PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
},
+ { "PowerBook3,4", "PowerBook Titanium III",
+ PMAC_TYPE_TITANIUM3, core99_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ },
};
/*
feature_call func = NULL;
va_list args;
- if (!pmac_mb.features)
- return -ENODEV;
- for (i=0; pmac_mb.features[i].function; i++)
- if (pmac_mb.features[i].selector == selector) {
- func = pmac_mb.features[i].function;
- break;
- }
+ if (pmac_mb.features)
+ for (i=0; pmac_mb.features[i].function; i++)
+ if (pmac_mb.features[i].selector == selector) {
+ func = pmac_mb.features[i].function;
+ break;
+ }
if (!func)
for (i=0; any_features[i].function; i++)
if (any_features[i].selector == selector) {
}
}
- /* On all machines, switch sound off */
+ /* On all machines that support sound PM, switch sound off */
if (macio_chips[0].of_node)
pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
macio_chips[0].of_node, 0, 0);
+ /* While on some desktop G3s, we turn it back on */
+ if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
+ && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
+ pmac_mb.model_id == PMAC_TYPE_SILK)) {
+ struct macio_chip* macio = &macio_chips[0];
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ }
+
+
/* On all machines, switch modem & serial ports off */
np = find_devices("ch-a");
while(np) {
set_initial_features();
}
-void __init
+int __init
pmac_feature_late_init(void)
{
struct device_node* np;
np = find_devices("interrupt-controller");
if (np)
request_OF_resource(np, 0, NULL);
+ return 0;
}
+
+device_initcall(pmac_feature_late_init);
* BK Id: %F% %I% %G% %U% %#%
*/
/*
- * Miscellaneous procedures for dealing with the PowerMac hardware.
+ * arch/ppc/platforms/pmac_nvram.c
+ *
+ * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Todo: - cleanup some coding horrors in the flash code
+ * - add support for the OF persistent properties
*/
#include <linux/config.h>
#include <linux/module.h>
extern int pmac_newworld;
-static u8 __openfirmware
+static u8 __pmac
chrp_checksum(struct chrp_header* hdr)
{
u8 *ptr;
printk("nvram: Error writing bank %d\n", core99_bank);
}
-unsigned char __openfirmware
-nvram_read_byte(int addr)
+unsigned char __pmac
+pmac_nvram_read_byte(int addr)
{
switch (nvram_naddrs) {
#ifdef CONFIG_ADB_PMU
return 0;
}
-void __openfirmware
-nvram_write_byte(unsigned char val, int addr)
+void __pmac
+pmac_nvram_write_byte(int addr, unsigned char val)
{
switch (nvram_naddrs) {
#ifdef CONFIG_ADB_PMU
if (offset < 0)
return 0;
- return nvram_read_byte(xpaddr + offset);
+ return pmac_nvram_read_byte(xpaddr + offset);
}
void __pmac
if (offset < 0)
return;
- nvram_write_byte(xpaddr + offset, data);
+ pmac_nvram_write_byte(data, xpaddr + offset);
}
*/
/*
* Support for PCI bridges found on Power Macintoshes.
- * At present the "bandit" and "chaos" bridges are supported.
- * Fortunately you access configuration space in the same
- * way with either bridge.
+ *
+ * This includes support for bandit, chaos, grackle (motorola
+ * MPC106), and uninorth
*
* Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
*
+ * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
rev = in_8(bp->cfg_data);
if (rev != BANDIT_REVID)
printk(KERN_WARNING
- "Unknown revision %d for bandit at %08lx\n",
- rev, bp->io_base_phys);
+ "Unknown revision %d for bandit\n", rev);
} else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
return;
}
- /* read the revision id */
- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
- udelay(2);
- rev = in_8(bp->cfg_data);
- if (rev != BANDIT_REVID)
- printk(KERN_WARNING "Unknown revision %d for bandit at %08lx\n",
- rev, bp->io_base_phys);
-
/* read the word at offset 0x50 */
out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
udelay(2);
magic |= BANDIT_COHERENT;
udelay(2);
out_le32((volatile unsigned int *)bp->cfg_data, magic);
- printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %08lx\n",
- bp->io_base_phys);
+ printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
}
{
struct pci_dev* dev;
- pci_for_each_dev(dev)
- {
- /*
- * Open Firmware often doesn't initialize the,
- * PCI_INTERRUPT_LINE config register properly, so we
- * should find the device node and se if it has an
- * AAPL,interrupts property.
- */
- unsigned char pin;
- struct device_node* node;
-
- if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || !pin)
- continue; /* No interrupt generated -> no fixup */
- node = pci_device_to_OF_node(dev);
- if (!node) {
- printk("No OF node for device %x:%x\n", dev->bus->number, dev->devfn >> 3);
- continue;
- }
+ /*
+ * Open Firmware often doesn't initialize the
+ * PCI_INTERRUPT_LINE config register properly, so we
+ * should find the device node and apply the interrupt
+ * obtained from the OF device-tree
+ */
+ pci_for_each_dev(dev) {
+ struct device_node* node = pci_device_to_OF_node(dev);
/* this is the node, see if it has interrupts */
- if (node->n_intrs > 0)
+ if (node && node->n_intrs > 0)
dev->irq = node->intrs[0].line;
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
/*
* BK Id: %F% %I% %G% %U% %#%
*/
+/*
+ * Support for the interrupt controllers found on Power Macintosh,
+ * currently Apple's "Grand Central" interrupt controller in all
+ * it's incarnations. OpenPIC support used on newer machines is
+ * in a separate file
+ *
+ * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
#include <linux/config.h>
#include <linux/stddef.h>
#include <linux/init.h>
* Derived from "arch/alpha/kernel/setup.c"
* Copyright (C) 1995 Linus Torvalds
*
+ * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
extern char pckbd_unexpected_up(unsigned char keycode);
extern int keyboard_sends_linux_keycodes;
extern void pmac_nvram_update(void);
-
+extern unsigned char pmac_nvram_read_byte(int addr);
+extern void pmac_nvram_write_byte(int addr, unsigned char val);
extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
extern void pmac_pcibios_after_init(void);
+extern int of_show_percpuinfo(struct seq_file *m, int i);
extern kdev_t sd_find_target(void *host, int tgt);
#ifdef CONFIG_SMP
extern struct smp_ops_t psurge_smp_ops;
extern struct smp_ops_t core99_smp_ops;
-
-volatile static long int core99_l2_cache;
-void __init
-core99_init_l2(void)
-{
- int cpu = smp_processor_id();
-
- if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
- return;
-
- if (cpu == 0){
- core99_l2_cache = _get_L2CR();
- printk("CPU0: L2CR is %lx\n", core99_l2_cache);
- } else {
- printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
- _set_L2CR(0);
- _set_L2CR(core99_l2_cache);
- printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
- }
-}
#endif /* CONFIG_SMP */
-/*
- * Assume here that all clock rates are the same in a
- * smp system. -- Cort
- */
-int __openfirmware
-of_show_percpuinfo(struct seq_file *m, int i)
-{
- struct device_node *cpu_node;
- int *fp, s;
-
- cpu_node = find_type_devices("cpu");
- if (!cpu_node)
- return 0;
- for (s = 0; s < i && cpu_node->next; s++)
- cpu_node = cpu_node->next;
- fp = (int *) get_property(cpu_node, "clock-frequency", NULL);
- if (fp)
- seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000);
- return 0;
-}
-
int __pmac
pmac_show_cpuinfo(struct seq_file *m)
{
struct device_node *np;
char *pp;
int plen;
-
+ int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+ NULL, PMAC_MB_INFO_MODEL, 0);
+ unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+ NULL, PMAC_MB_INFO_FLAGS, 0);
+ char* mbname;
+
+ if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
+ mbname = "Unknown";
+
/* find motherboard type */
seq_printf(m, "machine\t\t: ");
np = find_devices("device-tree");
} else
seq_printf(m, "PowerMac\n");
+ /* print parsed model */
+ seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
+ seq_printf(m, "pmac flags\t: %08x\n", mbflags);
+
/* find l2 cache info */
np = find_devices("l2-cache");
if (np == 0)
printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
? "enabled" : "disabled");
-
-#ifdef CONFIG_SMP
- /* somewhat of a hack */
- core99_init_l2();
-#endif
#ifdef CONFIG_KGDB
zs_kgdb_hook(0);
int boot_part;
extern kdev_t boot_dev;
-void __init
-pmac_init2(void)
-{
-#ifdef CONFIG_ADB_PMU
- via_pmu_start();
-#endif
-#ifdef CONFIG_ADB_CUDA
- via_cuda_start();
-#endif
-#ifdef CONFIG_PMAC_PBOOK
- media_bay_init();
-#endif
- pmac_feature_late_init();
-}
-
#ifdef CONFIG_SCSI
void __init
note_scsi_host(struct device_node *node, void *host)
ppc_md.irq_cannonicalize = NULL;
ppc_md.init_IRQ = pmac_pic_init;
ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */
- ppc_md.init = pmac_init2;
ppc_md.pcibios_fixup = pmac_pcibios_fixup;
ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
ppc_md.get_rtc_time = pmac_get_rtc_time;
ppc_md.calibrate_decr = pmac_calibrate_decr;
+#ifdef CONFIG_NVRAM
+ ppc_md.nvram_read_val = pmac_nvram_read_byte;
+ ppc_md.nvram_write_val = pmac_nvram_write_byte;
+#endif
+
ppc_md.find_end_of_memory = pmac_find_end_of_memory;
ppc_md.feature_call = pmac_do_feature_call;
#define PSURGE_QUAD_COTTON 2
#define PSURGE_QUAD_ICEGRASS 3
-/* l2 cache stuff for dual G4 macs */
-extern void core99_init_l2(void);
+volatile static long int core99_l2_cache;
+volatile static long int core99_l3_cache;
+
+static void __init
+core99_init_caches(void)
+{
+ int cpu = smp_processor_id();
+
+ if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
+ return;
+
+ if (cpu == 0){
+ core99_l2_cache = _get_L2CR();
+ printk("CPU0: L2CR is %lx\n", core99_l2_cache);
+ } else {
+ printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
+ _set_L2CR(0);
+ _set_L2CR(core99_l2_cache);
+ printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
+ }
+
+ if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
+ return;
+
+ if (cpu == 0){
+ core99_l3_cache = _get_L3CR();
+ printk("CPU0: L3CR is %lx\n", core99_l3_cache);
+ } else {
+ printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
+ _set_L3CR(0);
+ _set_L3CR(core99_l3_cache);
+ printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
+ }
+}
+
+/* Some CPU registers have to be saved from the first CPU and
+ * applied to others. Note that we override what is setup by
+ * the cputable intentionally.
+ */
+
+#define reg_hid0 0
+#define reg_hid1 1
+#define reg_msscr0 2
+#define reg_msssr0 3
+#define reg_ictrl 4
+#define reg_ldstcr 5
+#define reg_ldstdb 6
+#define reg_count 7
+
+static unsigned long cpu_regs[reg_count];
+
+static void __pmac
+cpu_setup_grab(void)
+{
+ unsigned int pvers = mfspr(SPRN_PVR)>>16;
+
+ /* Read cache setting of CPU 0 */
+ core99_init_caches();
+
+ /* 7400/7410/7450 */
+ if (pvers == 0x8000 || pvers == 0x000c || pvers == 0x800c) {
+ cpu_regs[reg_hid0] = mfspr(SPRN_HID0);
+ cpu_regs[reg_msscr0] = mfspr(SPRN_MSSCR0);
+ cpu_regs[reg_msssr0] = mfspr(SPRN_MSSSR0);
+ }
+ /* 7450 only */
+ if (pvers == 0x8000) {
+ cpu_regs[reg_hid1] = mfspr(SPRN_HID1);
+ cpu_regs[reg_ictrl] = mfspr(SPRN_ICTRL);
+ cpu_regs[reg_ldstcr] = mfspr(SPRN_LDSTCR);
+ cpu_regs[reg_ldstdb] = mfspr(SPRN_LDSTDB);
+ }
+ flush_dcache_range((unsigned long)cpu_regs, (unsigned long)&cpu_regs[reg_count]);
+}
+
+static void __pmac
+cpu_setup_apply(int cpu_nr)
+{
+ unsigned int pvers = mfspr(SPRN_PVR)>>16;
+
+ /* Apply cache setting from CPU 0 */
+ core99_init_caches();
+
+ /* 7400/7410/7450 */
+ if (pvers == 0x8000 || pvers == 0x000c || pvers == 0x800c) {
+ unsigned long tmp;
+ __asm__ __volatile__ (
+ "lwz %0,4*"stringify(reg_hid0)"(%1)\n"
+ "sync\n"
+ "mtspr "stringify(SPRN_HID0)", %0\n"
+ "isync;sync\n"
+ "lwz %0, 4*"stringify(reg_msscr0)"(%1)\n"
+ "sync\n"
+ "mtspr "stringify(SPRN_MSSCR0)", %0\n"
+ "isync;sync\n"
+// "lwz %0, "stringify(reg_msssr0)"(%1)\n"
+// "sync\n"
+// "mtspr "stringify(SPRN_MSSSR0)", %0\n"
+// "isync;sync\n"
+ : "=&r" (tmp) : "r" (cpu_regs));
+ }
+ /* 7410 only */
+ if (pvers == 0x800c) {
+ unsigned long tmp;
+ __asm__ __volatile__ (
+ "li %0, 0\n"
+ "sync\n"
+ "mtspr "stringify(SPRN_L2CR2)", %0\n"
+ "isync;sync\n"
+ : "=&r" (tmp));
+ }
+ /* 7450 only */
+ if (pvers == 0x8000) {
+ unsigned long tmp;
+ __asm__ __volatile__ (
+ "lwz %0, 4*"stringify(reg_hid1)"(%1)\n"
+ "sync\n"
+ "mtspr "stringify(SPRN_HID1)", %0\n"
+ "isync;sync\n"
+ "lwz %0, 4*"stringify(reg_ictrl)"(%1)\n"
+ "sync\n"
+ "mtspr "stringify(SPRN_ICTRL)", %0\n"
+ "isync;sync\n"
+ "lwz %0, 4*"stringify(reg_ldstcr)"(%1)\n"
+ "sync\n"
+ "mtspr "stringify(SPRN_LDSTCR)", %0\n"
+ "isync;sync\n"
+ "lwz %0, 4*"stringify(reg_ldstdb)"(%1)\n"
+ "sync\n"
+ "mtspr "stringify(SPRN_LDSTDB)", %0\n"
+ "isync;sync\n"
+ : "=&r" (tmp) : "r" (cpu_regs));
+ }
+}
/*
* Set and clear IPIs for powersurge.
{
struct device_node *cpus;
int i, ncpus = 1;
+ extern int powersave_nap;
if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
cpus = find_type_devices("cpu");
openpic_request_IPIs();
for (i = 1; i < ncpus; ++i)
smp_hw_index[i] = i;
+ powersave_nap = 0;
+ cpu_setup_grab();
}
return ncpus;
{
unsigned long save_vector, new_vector;
unsigned long flags;
-#if 1 /* New way... */
+
volatile unsigned long *vector
= ((volatile unsigned long *)(KERNELBASE+0x100));
if (nr < 1 || nr > 3)
return;
-#else
- volatile unsigned long *vector
- = ((volatile unsigned long *)(KERNELBASE+0x500));
- if (nr != 1)
- return;
-#endif
if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
local_irq_save(flags);
static void __init
smp_core99_setup_cpu(int cpu_nr)
{
+ /* Setup some registers */
+ if (cpu_nr != 0)
+ cpu_setup_apply(cpu_nr);
+
/* Setup openpic */
do_openpic_setup_cpu();
- /* Setup L2 */
- if (cpu_nr != 0)
- core99_init_l2();
- else
+ /* Setup L2/L3 */
+ if (cpu_nr == 0)
if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
}
#define CPU_FTR_604_PERF_MON 0x00000080
#define CPU_FTR_601 0x00000100
#define CPU_FTR_HPTE_TABLE 0x00000200
+#define CPU_FTR_CAN_NAP 0x00000400
+#define CPU_FTR_L3CR 0x00000800
#ifdef __ASSEMBLY__
* Bits in feature control register.
* Bits postfixed with a _N are in inverse logic
*/
-#define HRW_RESET_SCC 0x00000001 /* actually controls transceiver... */
+#define HRW_SCC_TRANS_EN_N 0x00000001 /* Also controls modem power */
#define HRW_BAY_POWER_N 0x00000002
#define HRW_BAY_PCI_ENABLE 0x00000004
#define HRW_BAY_IDE_ENABLE 0x00000008
#define HRW_ARB_BYPASS 0x00400000 /* Disable internal PCI arbitrer */
#define HRW_IDE1_RESET_N 0x00800000 /* Media bay */
#define HRW_SLOW_SCC_PCLK 0x01000000 /* ??? (0) */
-#define HRW_MODEM_POWER_N 0x02000000 /* Used by internal modem on wallstreet */
+#define HRW_RESET_SCC 0x02000000
#define HRW_MFDC_CELL_ENABLE 0x04000000 /* ??? (0) */
#define HRW_USE_MFDC 0x08000000 /* ??? (0) */
#define HRW_BMAC_IO_ENABLE 0x60000000 /* two bits, not documented in OF */
/* We OR those features at boot on desktop G3s */
#define HRW_DEFAULTS (HRW_SCCA_IO | HRW_SCCB_IO | HRW_SCC_ENABLE)
-/* Those seem to be different on paddington */
-#define PADD_MODEM_POWER_N 0x00000001 /* modem power on paddington */
-#define PADD_RESET_SCC 0x02000000 /* check this please */
-
/* Looks like Heathrow has some sort of GPIOs as well... */
#define HRW_GPIO_MODEM_RESET 0x6d
#define MB_POWER 6 /* media bay contains a Power device (???) */
#define MB_NO 7 /* media bay contains nothing */
-void media_bay_init(void);
int check_media_bay(struct device_node *which_bay, int what);
int check_media_bay_by_base(unsigned long base, int what);
*/
/* PowerSurge are the first generation of PCI Pmacs. This include
- * all of the Grand-Central based machines
+ * all of the Grand-Central based machines. We currently don't
+ * differenciate most of them.
*/
#define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */
+#define PMAC_TYPE_ANS 0x11 /* Apple Network Server */
/* Here is the infamous serie of OHare based machines
*/
#define PMAC_TYPE_PISMO 0x46 /* Pismo PowerBook */
#define PMAC_TYPE_TITANIUM 0x47 /* Titanium PowerBook */
#define PMAC_TYPE_TITANIUM2 0x48 /* Titanium II PowerBook */
+#define PMAC_TYPE_TITANIUM3 0x49 /* Titanium III PowerBook (with L3) */
#define PMAC_TYPE_UNKNOWN_CORE99 0x5f
/* MacRISC2 machines based on the Pangea chipset
/* Don't use those directly, they are for the sake of pmac_setup.c */
extern int pmac_do_feature_call(unsigned int selector, ...);
extern void pmac_feature_init(void);
-extern void pmac_feature_late_init(void);
#define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x))
#define HID0_EBD (1<<28) /* Enable Bus Data Parity */
#define HID0_SBCLK (1<<27)
#define HID0_EICE (1<<26)
-#define HID0_TBEN (1<<26) /* Timebase enable - 7450 */
+#define HID0_TBEN (1<<26) /* Timebase enable - 745x */
#define HID0_ECLK (1<<25)
#define HID0_PAR (1<<24)
-#define HID0_STEN (1<<24) /* S/W Tablewalk enable - 7450 */
+#define HID0_STEN (1<<24) /* Software table search enable - 745x */
+#define HID0_HIGH_BAT (1<<23) /* Enable high BATs - 7455 */
#define HID0_DOZE (1<<23)
#define HID0_NAP (1<<22)
#define HID0_SLEEP (1<<21)
#define HID0_SGE (1<<7) /* Store Gathering Enable */
#define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */
#define HID0_DFCA (1<<6) /* Data Cache Flush Assist */
+#define HID0_LRSTK (1<<4) /* Link register stack - 745x */
#define HID0_BTIC (1<<5) /* Branch Target Instr Cache Enable */
-#define HID0_LRSTK (1<<4) /* Link Stack enable - 7450 */
#define HID0_ABE (1<<3) /* Address Broadcast Enable */
-#define HID0_FOLD (1<<3) /* Branch Folding enable - 7450 */
+#define HID0_FOLD (1<<3) /* Branch Folding enable - 745x */
#define HID0_BHTE (1<<2) /* Branch History Table Enable */
#define HID0_BTCD (1<<1) /* Branch target cache disable */
#define HID0_NOPDST (1<<1) /* No-op dst, dstt, etc. instr. */
#define SPRN_L2CR2 0x3f8
#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter (7450) */
#define L3CR_L3E 0x80000000 /* L3 enable */
+#define L3CR_L3PE 0x40000000 /* L3 data parity enable */
+#define L3CR_L3APE 0x20000000 /* L3 addr parity enable */
+#define L3CR_L3SIZ 0x10000000 /* L3 size */
+#define L3CR_L3CLKEN 0x08000000 /* L3 clock enable */
+#define L3CR_L3RES 0x04000000 /* L3 special reserved bit */
+#define L3CR_L3CLKDIV 0x03800000 /* L3 clock divisor */
+#define L3CR_L3IO 0x00400000 /* L3 instruction only */
+#define L3CR_L3SPO 0x00040000 /* L3 sample point override */
+#define L3CR_L3CKSP 0x00030000 /* L3 clock sample point */
+#define L3CR_L3PSP 0x0000e000 /* L3 P-clock sample point */
+#define L3CR_L3REP 0x00001000 /* L3 replacement algorithm */
+#define L3CR_L3HWF 0x00000800 /* L3 hardware flush */
+#define L3CR_L3I 0x00000400 /* L3 global invalidate */
+#define L3CR_L3RT 0x00000300 /* L3 SRAM type */
+#define L3CR_L3NIRCA 0x00000080 /* L3 non-integer ratio clock adj. */
+#define L3CR_L3DO 0x00000040 /* L3 data only mode */
+#define L3CR_PMEN 0x00000004 /* L3 private memory enable */
+#define L3CR_PMSIZ 0x00000001 /* L3 private memory size */
#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */
#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */
#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */
#define SPRG7 SPRN_SPRG7
#define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */
#define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */
+#define SRR2 SPRN_SRR2 /* Save and Restore Register 2 */
+#define SRR3 SPRN_SRR3 /* Save and Restore Register 3 */
#define TBRL SPRN_TBRL /* Time Base Read Lower Register */
#define TBRU SPRN_TBRU /* Time Base Read Upper Register */
#define TBWL SPRN_TBWL /* Time Base Write Lower Register */