Skip to contentSkip to conversation

ppc32: pmac sleep support update

PATCH In review Benjamin Herrenschmidt 4 participants 15 messages Jan 18, 2005 – Feb 27, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ppc32: pmac sleep support update

Hi !

This patch updates the PowerMac sleep support. The ability to sleep is now broken into 2 different flags, one, "may sleep" is set for all motherboards that we know how to put to sleep and wakeup. It gets turned into "can sleep" upon a call from the video driver indicating the ability to wakeup the video card. This doesn't deal with head-less machines, but this can be improved later. It also adds better cache flush code, which improves stability with cpufreq as well as sleep.

This patch actually breaks sleep support until the video drivers for the affected machines have been updated. This will come as separate patches.

arch/ppc/platforms/pmac_cache.S new file +325 -0
Index: linux-work/arch/ppc/platforms/pmac_cache.S
===================================================================
@@ -0,0 +1,325 @@
+/*
+ * This file contains low-level cache management functions
+ * used for sleep and CPU speed changes on Apple machines.
+ * (In fact the only thing that is Apple-specific is that we assume
+ * that we can read from ROM at physical address 0xfff00000.)
+ *
+ *    Copyright (C) 2004 Paul Mackerras ([email protected]) and
+ *                       Benjamin Herrenschmidt ([email protected])
+ *
+ * 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 <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/cputable.h>
+
+/*
+ * Flush and disable all data caches (dL1, L2, L3). This is used
+ * when going to sleep, when doing a PMU based cpufreq transition,
+ * or when "offlining" a CPU on SMP machines. This code is over
+ * paranoid, but I've had enough issues with various CPU revs and
+ * bugs that I decided it was worth beeing over cautious
+ */
+
+_GLOBAL(flush_disable_caches)
+BEGIN_FTR_SECTION
+	b	flush_disable_745x
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
+BEGIN_FTR_SECTION
+	b	flush_disable_75x
+END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
+	b	__flush_disable_L1
+
+/* This is the code for G3 and 74[01]0 */
+flush_disable_75x:
+	mflr	r10
+
+	/* Turn off EE and DR in MSR */
+	mfmsr	r11
+	rlwinm	r0,r11,0,~MSR_EE
+	rlwinm	r0,r0,0,~MSR_DR
+	sync
+	mtmsr	r0
+	isync
+
+	/* Stop DST streams */
+BEGIN_FTR_SECTION
+	DSSALL
+	sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+
+	/* Stop DPM */
+	mfspr	r8,SPRN_HID0		/* Save HID0 in r8 */
+	rlwinm	r4,r8,0,12,10		/* Turn off HID0[DPM] */
+	sync
+	mtspr	SPRN_HID0,r4		/* Disable DPM */
+	sync
+
+	/* disp-flush L1 */
+	li	r4,0x4000
+	mtctr	r4
+	lis	r4,0xfff0
+1:	lwzx	r0,r0,r4
+	addi	r4,r4,32
+	bdnz	1b
+	sync
+	isync
+	
+	/* disable / invalidate / enable L1 data */
+	mfspr	r3,SPRN_HID0
+	rlwinm	r0,r0,0,~HID0_DCE
+	mtspr	SPRN_HID0,r3
+	sync
+	isync
+	ori	r3,r3,HID0_DCE|HID0_DCI
+	sync
+	isync
+	mtspr	SPRN_HID0,r3
+	xori	r3,r3,HID0_DCI
+	mtspr	SPRN_HID0,r3
+	sync
+
+	/* Get the current enable bit of the L2CR into r4 */
+	mfspr	r5,L2CR
+	/* Set to data-only (pre-745x bit) */
+	oris	r3,r5,L2CR_L2DO@h
+	b	2f
+	/* When disabling L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r3
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	/* disp-flush L2. The interesting thing here is that the L2 can be
+	 * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
+	 * but that is probbaly fine. We disp-flush over 4Mb to be safe
+	 */
+	lis	r4,2
+	mtctr	r4
+	lis	r4,0xfff0
+1:	lwzx	r0,r0,r4
+	addi	r4,r4,32
+	bdnz	1b
+	sync
+	isync
+	/* now disable L2 */	
+	rlwinm	r5,r5,0,~L2CR_L2E
+	b	2f
+	/* When disabling L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r5
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	sync
+	isync
+	/* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
+	oris	r4,r5,L2CR_L2I@h
+	mtspr	L2CR,r4
+	sync
+	isync
+	xoris	r4,r4,L2CR_L2I@h
+	sync
+	mtspr	L2CR,r4
+	sync
+	
+	/* now disable the L1 data cache */
+	mfspr	r0,HID0
+	rlwinm	r0,r0,0,~HID0_DCE
+	mtspr	HID0,r0
+	sync
+	isync
+
+	/* Restore HID0[DPM] to whatever it was before */
+	sync
+	mtspr	SPRN_HID0,r8
+	sync
+
+	/* restore DR and EE */
+	sync
+	mtmsr	r11
+	isync
+
+	mtlr	r10
+	blr
+
+/* This code is for 745x processors */
+flush_disable_745x:
+	/* Turn off EE and DR in MSR */
+	mfmsr	r11
+	rlwinm	r0,r11,0,~MSR_EE
+	rlwinm	r0,r0,0,~MSR_DR
+	sync
+	mtmsr	r0
+	isync
+
+	/* Stop prefetch streams */
+	DSSALL
+	sync
+
+	/* Disable L2 prefetching */
+	mfspr	r0,SPRN_MSSCR0
+	rlwinm	r0,r0,0,0,29
+	mtspr	SPRN_MSSCR0,r0
+	sync
+	isync
+	lis	r4,0
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+
+	/* Due to a bug with the HW flush on some CPU revs, we occasionally
+	 * experience data corruption. I'm adding a displacement flush along
+	 * with a dcbf loop over a few Mb to "help". The problem isn't totally
+	 * fixed by this in theory, but at least, in practice, I couldn't reproduce
+	 * it even with a big hammer...
+	 */
+	 
+        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
+        isync
+
+        /* Now, flush the first 4MB of memory */
+        lis     r4,0x0002
+        mtctr   r4
+	li      r4,0
+        sync
+1:
+        dcbf    0,r4
+        addi    r4,r4,32                /* Go to start of next cache line */
+        bdnz    1b
+
+	/* Flush and disable the L1 data cache */
+	mfspr	r6,SPRN_LDSTCR
+	lis	r3,0xfff0	/* read from ROM for displacement flush */
+	li	r4,0xfe		/* start with only way 0 unlocked */
+	li	r5,128		/* 128 lines in each way */
+1:	mtctr	r5
+	rlwimi	r6,r4,0,24,31
+	mtspr	SPRN_LDSTCR,r6
+	sync
+	isync
+2:	lwz	r0,0(r3)	/* touch each cache line */
+	addi	r3,r3,32
+	bdnz	2b
+	rlwinm	r4,r4,1,24,30	/* move on to the next way */
+	ori	r4,r4,1
+	cmpwi	r4,0xff		/* all done? */
+	bne	1b
+	/* now unlock the L1 data cache */
+	li	r4,0
+	rlwimi	r6,r4,0,24,31
+	sync
+	mtspr	SPRN_LDSTCR,r6
+	sync
+	isync
+
+	/* Flush the L2 cache using the hardware assist */
+	mfspr	r3,L2CR
+	cmpwi	r3,0		/* check if it is enabled first */
+	bge	4f
+	oris	r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
+	b	2f
+	/* When disabling/locking L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r0		/* lock the L2 cache */
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	sync
+	isync
+	ori	r0,r3,L2CR_L2HWF_745x
+	sync
+	mtspr	L2CR,r0		/* set the hardware flush bit */
+3:	mfspr	r0,L2CR		/* wait for it to go to 0 */
+	andi.	r0,r0,L2CR_L2HWF_745x
+	bne	3b
+	sync
+	rlwinm	r3,r3,0,~L2CR_L2E
+	b	2f
+	/* When disabling L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r3		/* disable the L2 cache */
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	sync
+	isync
+	oris	r4,r3,L2CR_L2I@h
+	mtspr	L2CR,r4
+	sync
+	isync
+1:	mfspr	r4,L2CR
+	andis.	r0,r4,L2CR_L2I@h
+	bne	1b
+	sync
+
+BEGIN_FTR_SECTION
+	/* Flush the L3 cache using the hardware assist */
+4:	mfspr	r3,L3CR
+	cmpwi	r3,0		/* check if it is enabled */
+	bge	6f
+	oris	r0,r3,L3CR_L3IO@h
+	ori	r0,r0,L3CR_L3DO
+	sync
+	mtspr	L3CR,r0		/* lock the L3 cache */
+	sync
+	isync
+	ori	r0,r0,L3CR_L3HWF
+	sync
+	mtspr	L3CR,r0		/* set the hardware flush bit */
+5:	mfspr	r0,L3CR		/* wait for it to go to zero */
+	andi.	r0,r0,L3CR_L3HWF
+	bne	5b
+	rlwinm	r3,r3,0,~L3CR_L3E
+	sync
+	mtspr	L3CR,r3		/* disable the L3 cache */
+	sync
+	ori	r4,r3,L3CR_L3I
+	mtspr	SPRN_L3CR,r4
+1:	mfspr	r4,SPRN_L3CR
+	andi.	r0,r4,L3CR_L3I
+	bne	1b
+	sync
+END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
+
+6:	mfspr	r0,HID0		/* now disable the L1 data cache */
+	rlwinm	r0,r0,0,~HID0_DCE
+	mtspr	HID0,r0
+	sync
+	isync
+	mtmsr	r11		/* restore DR and EE */
+	isync
+	blr
include/asm-ppc/uninorth.h +49 -0

55 lines not on this page · raw message

arch/ppc/platforms/pmac_feature.c +153 -42

383 lines not on this page · raw message

arch/ppc/platforms/pmac_cpufreq.c +11 -8
Index: linux-work/arch/ppc/platforms/pmac_cpufreq.c
===================================================================
@@ -154,6 +154,14 @@
 	return 0;
 }
 
+static unsigned int __pmac dfs_get_cpu_speed(unsigned int cpu)
+{
+	if (mfspr(HID1) & HID1_DFS)
+		return low_freq;
+	else
+		return hi_freq;
+}
+
 
 /* Switch CPU speed using slewing GPIOs
  */
@@ -229,10 +237,6 @@
 	/* Save & disable L2 and L3 caches */
 	save_l3cr = _get_L3CR();	/* (returns -1 if not available) */
 	save_l2cr = _get_L2CR();	/* (returns -1 if not available) */
-	if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
-		_set_L3CR(save_l3cr & 0x7fffffff);
-	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
-		_set_L2CR(save_l2cr & 0x7fffffff);
 
 	/* Send the new speed command. My assumption is that this command
 	 * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
@@ -458,14 +462,13 @@
 {
 	struct device_node *volt_gpio_np;
 	u32 *reg;
+	struct cpufreq_driver *driver = &pmac_cpufreq_driver;
 
 	/* OF only reports the high frequency */
 	hi_freq = cur_freq;
 	low_freq = cur_freq/2;
-	if (mfspr(HID1) & HID1_DFS)
-		cur_freq = low_freq;
-	else
-		cur_freq = hi_freq;
+	driver->get = dfs_get_cpu_speed;
+	cur_freq = driver->get(0);
 
 	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
 	if (!volt_gpio_np){
arch/ppc/platforms/pmac_sleep.S +18 -17
Index: linux-work/arch/ppc/platforms/pmac_sleep.S
===================================================================
@@ -161,12 +161,8 @@
 	addi r3,r3,sleep_storage@l
 	stw r5,0(r3)
 
-	/* Disable DPM during cache flush */
-	mfspr	r3, SPRN_HID0
-	rlwinm	r3,r3,0,12,10
-	sync
-	mtspr	SPRN_HID0,r3
-	sync
+	/* Flush & disable all caches */
+	bl	flush_disable_caches
 
 	/* Turn off data relocation. */
 	mfmsr	r3		/* Save MSR in r7 */
@@ -175,8 +171,13 @@
 	mtmsr	r3
 	isync
 
-	/* Flush & disable L1 cache */
-	bl	__flush_disable_L1
+BEGIN_FTR_SECTION
+	/* Flush any pending L2 data prefetches to work around HW bug */
+	sync
+	lis	r3,0xfff0
+	lwz	r0,0(r3)	/* perform cache-inhibited load to ROM */
+	sync			/* (caches are disabled at this point) */
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
 
 /*
  * Set the HID0 and MSR for sleep.
@@ -212,17 +213,16 @@
  * r4 has the physical address of SL_PC(sp) (unused)
  */
 _GLOBAL(core99_wake_up)
-	/* Make sure HID0 no longer contains any sleep bit */
+	/* Make sure HID0 no longer contains any sleep bit and that data cache
+	 * is disabled
+	 */
 	mfspr	r3,HID0
 	rlwinm	r3,r3,0,11,7		/* clear SLEEP, NAP, DOZE bits */
+	rlwinm	3,r3,0,18,15		/* clear DCE, ICE */
 	mtspr	HID0,r3
 	sync
 	isync
 
-	/* Won't that cause problems on CPU that doesn't support it ? */
-	lis	r3, 0
-	mtspr	SPRN_MMCR0, r3
-
 	/* sanitize MSR */
 	mfmsr	r3
 	ori	r3,r3,MSR_EE|MSR_IP
@@ -246,10 +246,6 @@
  */
 
 grackle_wake_up:
-	/* Invalidate & enable L1 cache, we don't care about
-	 * whatever the ROM may have tried to write to memory
-	 */
-	bl	__inval_enable_L1
 
 	/* Restore the kernel's segment registers before
 	 * we do any r1 memory access as we are not sure they
@@ -271,6 +267,11 @@
 	/* Restore various CPU config stuffs */
 	bl	__restore_cpu_setup
 
+	/* Invalidate & enable L1 cache, we don't care about
+	 * whatever the ROM may have tried to write to memory
+	 */
+	bl	__inval_enable_L1
+
 	/* Restore the BATs, and SDR1.  Then we can turn on the MMU. */
 	lwz	r4,SL_SDR1(r1)
 	mtsdr1	r4
arch/ppc/kernel/l2cr.S +5 -4
Index: linux-work/arch/ppc/kernel/l2cr.S
===================================================================
@@ -45,6 +45,7 @@
 #include <asm/cputable.h>
 #include <asm/ppc_asm.h>
 #include <asm/cache.h>
+#include <asm/page.h>
 
 /* Usage:
 
@@ -284,7 +285,7 @@
 	/* 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,2,31		/* Turn off the enable & PE bits */
 	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
@@ -379,7 +380,7 @@
 /* flush_disable_L1()	- Flush and disable L1 cache
  *
  * clobbers r0, r3, ctr, cr0
- *
+ * Must be called with interrupts disabled and MMU enabled.
  */
 _GLOBAL(__flush_disable_L1)
 	/* Stop pending alitvec streams and memory accesses */
@@ -393,7 +394,7 @@
 	 */
 	li	r3,0x4000	/* 512kB / 32B */
 	mtctr	r3
-	li	r3, 0
+	lis	r3,KERNELBASE@h
 1:
 	lwz	r0,0(r3)
 	addi	r3,r3,0x0020	/* Go to start of next cache line */
@@ -404,7 +405,7 @@
 	/* Now flush those cache lines */
 	li	r3,0x4000	/* 512kB / 32B */
 	mtctr	r3
-	li	r3, 0
+	lis	r3,KERNELBASE@h
 1:
 	dcbf	0,r3
 	addi	r3,r3,0x0020	/* Go to start of next cache line */
drivers/macintosh/via-pmu.c +28 -36

178 lines not on this page · raw message

arch/ppc/platforms/Makefile +1 -1
Index: linux-work/arch/ppc/platforms/Makefile
===================================================================
@@ -11,7 +11,7 @@
 endif
 obj-$(CONFIG_PPC_PMAC)		+= pmac_pic.o pmac_setup.o pmac_time.o \
 					pmac_feature.o pmac_pci.o pmac_sleep.o \
-					pmac_low_i2c.o
+					pmac_low_i2c.o pmac_cache.o
 obj-$(CONFIG_PPC_CHRP)		+= chrp_setup.o chrp_time.o chrp_pci.o
 obj-$(CONFIG_PPC_PREP)		+= prep_pci.o prep_setup.o
 ifeq ($(CONFIG_PPC_PMAC),y)
include/asm-ppc/reg.h +4 -0
Index: linux-work/include/asm-ppc/reg.h
===================================================================
@@ -244,6 +244,10 @@
 #define L2CR_L2DF		0x00004000	/* L2 differential clock */
 #define L2CR_L2BYP		0x00002000	/* L2 DLL bypass */
 #define L2CR_L2IP		0x00000001	/* L2 GI in progress */
+#define L2CR_L2IO_745x		0x00100000	/* L2 instr. only (745x) */
+#define L2CR_L2DO_745x		0x00010000	/* L2 data only (745x) */
+#define L2CR_L2REP_745x		0x00001000	/* L2 repl. algorithm (745x) */
+#define L2CR_L2HWF_745x		0x00000800	/* L2 hardware flush (745x) */
 #define SPRN_L3CR		0x3FA	/* Level 3 Cache Control Regsiter */
 #define L3CR_L3E		0x80000000	/* L3 enable */
 #define L3CR_L3PE		0x40000000	/* L3 data parity enable */
include/asm-ppc/pmac_feature.h +15 -0
Index: linux-work/include/asm-ppc/pmac_feature.h
===================================================================
@@ -125,6 +125,7 @@
 #define PMAC_MB_HAS_FW_POWER		0x00000002
 #define PMAC_MB_OLD_CORE99		0x00000004
 #define PMAC_MB_MOBILE			0x00000008
+#define PMAC_MB_MAY_SLEEP		0x00000010
 
 /*
  * Feature calls supported on pmac
@@ -238,7 +239,10 @@
 
 /* PMAC_FTR_SLEEP_STATE		(struct device_node* node, 0, int value)
  * set the sleep state of the motherboard.
+ * 
  * Pass -1 as value to query for sleep capability
+ * Pass 1 to set IOs to sleep
+ * Pass 0 to set IOs to wake
  */
 #define PMAC_FTR_SLEEP_STATE		PMAC_FTR_DEF(15)
 
@@ -279,11 +283,22 @@
  */
 #define PMAC_FTR_AACK_DELAY_ENABLE     	PMAC_FTR_DEF(20)
 
+/* PMAC_FTR_DEVICE_CAN_WAKE
+ *
+ * Used by video drivers to inform system that they can actually perform
+ * wakeup from sleep
+ */
+#define PMAC_FTR_DEVICE_CAN_WAKE	PMAC_FTR_DEF(22)
+
 
 /* Don't use those directly, they are for the sake of pmac_setup.c */
 extern long pmac_do_feature_call(unsigned int selector, ...);
 extern void pmac_feature_init(void);
 
+/* Video suspend tweak */
+extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data);
+extern void pmac_call_early_video_resume(void);
+
 #define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x))
 
 
arch/ppc/platforms/pmac_pci.c +5 -1
Index: linux-work/arch/ppc/platforms/pmac_pci.c
===================================================================
@@ -915,8 +915,12 @@
 	 * (iBook second controller)
 	 */
 	if (dev->vendor == PCI_VENDOR_ID_APPLE
-	    && dev->device == PCI_DEVICE_ID_APPLE_KL_USB && !node)
+	    && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
+	    && !node) {
+		printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
+		       pci_name(dev));
 		return -EINVAL;
+	}
 
 	if (!node)
 		return 0;
drivers/serial/pmac_zilog.c +2 -0
Index: linux-work/drivers/serial/pmac_zilog.c
===================================================================
@@ -1946,6 +1946,8 @@
 	unsigned long flags;
 	int i;
 
+	if (ZS_IS_ASLEEP(uap))
+		return;
 	spin_lock_irqsave(&uap->port.lock, flags);
 
 	/* Turn of interrupts and enable the transmitter. */
#1 lore raw
Quoted 11 lines · Benjamin Herrenschmidt

Hi !

This patch updates the PowerMac sleep support. The ability to sleep is now broken into 2 different flags, one, "may sleep" is set for all motherboards that we know how to put to sleep and wakeup. It gets turned into "can sleep" upon a call from the video driver indicating the ability to wakeup the video card. This doesn't deal with head-less machines, but this can be improved later. It also adds better cache flush code, which improves stability with cpufreq as well as sleep.

This patch actually breaks sleep support until the video drivers for the affected machines have been updated. This will come as separate patches.

With all your patches applied I'm getting an oops during wakeup inside pci_bus_read_config_word on my iBook/G3. Call trace: pci_set_master, pci_device_resume, resume_device, dpm_resume, device_resume, pmac_wakeup_devices, pmu_ioctl, sys_ioctl.

Andreas.

Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
#2 lore raw
Quoted 11 lines · Andreas Schwab
Quoted 9 lines · Benjamin Herrenschmidt

Hi !

This patch updates the PowerMac sleep support. The ability to sleep is now broken into 2 different flags, one, "may sleep" is set for all motherboards that we know how to put to sleep and wakeup. It gets turned into "can sleep" upon a call from the video driver indicating the ability to wakeup the video card. This doesn't deal with head-less machines, but this can be improved later. It also adds better cache flush code, which improves stability with cpufreq as well as sleep.

Quoted 7 lines
Quoted 2 lines

This patch actually breaks sleep support until the video drivers for the affected machines have been updated. This will come as separate patches.

With all your patches applied I'm getting an oops during wakeup inside pci_bus_read_config_word on my iBook/G3. Call trace: pci_set_master, pci_device_resume, resume_device, dpm_resume, device_resume, pmac_wakeup_devices, pmu_ioctl, sys_ioctl.

It would be useful to get some more infos, what is the actual oops text (what error), and if you could add some printk's to figure out what is the culprit PCI device, that would be useful as well...

Ben.

#3 lore raw
Quoted 8 lines · Benjamin Herrenschmidt
Quoted 4 lines

With all your patches applied I'm getting an oops during wakeup inside pci_bus_read_config_word on my iBook/G3. Call trace: pci_set_master, pci_device_resume, resume_device, dpm_resume, device_resume, pmac_wakeup_devices, pmu_ioctl, sys_ioctl.

It would be useful to get some more infos, what is the actual oops text (what error), and if you could add some printk's to figure out what is the culprit PCI device, that would be useful as well...

I was unable to reproduce the exact oops I got yesterday. Now I'm getting a heap of oopses scrolling by, ending with a panic due to killing interrupt handler, without any way to capture them.

Andreas.

Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
#4 lore raw
Quoted 7 lines · Andreas Schwab
Quoted 5 lines · Benjamin Herrenschmidt
Quoted 4 lines

With all your patches applied I'm getting an oops during wakeup inside pci_bus_read_config_word on my iBook/G3. Call trace: pci_set_master, pci_device_resume, resume_device, dpm_resume, device_resume, pmac_wakeup_devices, pmu_ioctl, sys_ioctl.

Quoted 7 lines
Quoted 3 lines

It would be useful to get some more infos, what is the actual oops text (what error), and if you could add some printk's to figure out what is the culprit PCI device, that would be useful as well...

I was unable to reproduce the exact oops I got yesterday. Now I'm getting a heap of oopses scrolling by, ending with a panic due to killing interrupt handler, without any way to capture them.

Even when building xmon into the kernel ?

Ben.

#5 lore raw
Quoted 1 line · Benjamin Herrenschmidt

Even when building xmon into the kernel ?

Doh! I didn't think of that. This is what I get from xmon:

    <2>kernel BUG in unlock_page at mm/filemap.c:430!
    vector: 700 at pc = c003f098, lr = c0041654
    msr = 29032, sp = e71b1c80 [e71b1bd0]
    current = e7bbec70, pid = 2915, comm = syslogd

c0041654 = generic_file_buffered_write

Last kernel messages:

radeonfb: switching to D0 state...
HID1, after: 70000044
cpufreq: resume failed to assert current frequency is what timing core thinks it is.

Andreas.

Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
#6 lore raw
Quoted 11 lines · Andreas Schwab
Quoted 1 line · Benjamin Herrenschmidt

Even when building xmon into the kernel ?

Doh! I didn't think of that. This is what I get from xmon:

    <2>kernel BUG in unlock_page at mm/filemap.c:430!
    vector: 700 at pc = c003f098, lr = c0041654
    msr = 29032, sp = e71b1c80 [e71b1bd0]
    current = e7bbec70, pid = 2915, comm = syslogd
Quoted 7 lines

c0041654 = generic_file_buffered_write

Last kernel messages:

radeonfb: switching to D0 state...
HID1, after: 70000044
cpufreq: resume failed to assert current frequency is what timing core thinks it is.

Weird ... Can you try without cpufreq built in the kernel ? Also what is the exact CPU revision ? I think you are just experiencing memory corruption...

Ben.

#7 lore raw
Quoted 3 lines · Benjamin Herrenschmidt
Quoted 1 line

cpufreq: resume failed to assert current frequency is what timing core thinks it is.

Weird ... Can you try without cpufreq built in the kernel ?

I think this message is unrelated to the problem, it occurs with all kernels so far.

Quoted 1 line

Also what is the exact CPU revision ?

It's a 750FX revision 1.18.

Quoted 1 line

I think you are just experiencing memory corruption...

Yes, I agree, I get completely different crashes whenever I use a slightly different kernel.

Andreas.

Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
#8 lore raw
Quoted 9 lines · Andreas Schwab
Quoted 3 lines · Benjamin Herrenschmidt
Quoted 1 line

cpufreq: resume failed to assert current frequency is what timing core thinks it is.

Weird ... Can you try without cpufreq built in the kernel ?

I think this message is unrelated to the problem, it occurs with all kernels so far.

Quoted 8 lines
Quoted 1 line

Also what is the exact CPU revision ?

It's a 750FX revision 1.18.

Quoted 1 line

I think you are just experiencing memory corruption...

Yes, I agree, I get completely different crashes whenever I use a slightly different kernel.

It would be interesting to hack around pmac_cache.S and see if you get it more reliable ...

Ben.

#9 lore raw
In reply to Benjamin Herrenschmidt
Quoted 4 lines · Benjamin Herrenschmidt

This patch updates the PowerMac sleep support. The ability to sleep is now broken into 2 different flags, one, "may sleep" is set for all motherboards that we know how to put to sleep and wakeup. It gets turned into "can sleep" upon a call from the video driver indicating the ability to wakeup the video card.

Why do it like this? Drivers already have the ability to veto sleep requests, surely?

Signature · 1 line
dwmw2
#10 lore raw
Quoted 8 lines · David Woodhouse
Quoted 4 lines · Benjamin Herrenschmidt

This patch updates the PowerMac sleep support. The ability to sleep is now broken into 2 different flags, one, "may sleep" is set for all motherboards that we know how to put to sleep and wakeup. It gets turned into "can sleep" upon a call from the video driver indicating the ability to wakeup the video card.

Why do it like this? Drivers already have the ability to veto sleep requests, surely?

But they don't, besides, you may just not have a driver for the card (that is things like offb don't register as a pci_driver, etc...)

It's a mecanism that can/will be improved in the future, but for now, it suits my needs perfectly.

Ben.

#11 lore raw
In reply to Benjamin Herrenschmidt
Quoted 11 lines · Benjamin Herrenschmidt

Hi !

This patch updates the PowerMac sleep support. The ability to sleep is now broken into 2 different flags, one, "may sleep" is set for all motherboards that we know how to put to sleep and wakeup. It gets turned into "can sleep" upon a call from the video driver indicating the ability to wakeup the video card. This doesn't deal with head-less machines, but this can be improved later. It also adds better cache flush code, which improves stability with cpufreq as well as sleep.

This patch actually breaks sleep support until the video drivers for the affected machines have been updated. This will come as separate patches.

Is that supposed to work? 2.6.11-rc2-bk10 sleeps ok on a pismo, but -rc3 just does nothing when closing the lid.

#12 lore raw
Quoted 11 lines · Olaf Hering
Quoted 9 lines · Benjamin Herrenschmidt

Hi !

This patch updates the PowerMac sleep support. The ability to sleep is now broken into 2 different flags, one, "may sleep" is set for all motherboards that we know how to put to sleep and wakeup. It gets turned into "can sleep" upon a call from the video driver indicating the ability to wakeup the video card. This doesn't deal with head-less machines, but this can be improved later. It also adds better cache flush code, which improves stability with cpufreq as well as sleep.

Quoted 5 lines
Quoted 2 lines

This patch actually breaks sleep support until the video drivers for the affected machines have been updated. This will come as separate patches.

Is that supposed to work? 2.6.11-rc2-bk10 sleeps ok on a pismo, but -rc3 just does nothing when closing the lid.

It's normal, the kernel is waiting for the video driver to do a platform call to indicate it supports sleep/wakeup on this model. The video driver updates haven't been pushed yet. This concerns laptops with nVidia, r128 and radeon chips. The former, we don't know how to wake them up yet, the r128 patch is trivial and should go in, the radeonfb patch is still beeing debated on.

Ben.

#13 lore raw
In reply to Benjamin Herrenschmidt

arch/ppc/platforms/pmac_cache.S line 37

Quoted 3 lines · Benjamin Herrenschmidt

+++ linux-work/arch/ppc/platforms/pmac_cache.S 2005-01-18 12:01:49.000000000 +1100

arch/ppc/platforms/pmac_cache.S new file +1 -0
+	b	__flush_disable_L1

This one is only available for CONFIG_6xx, so g5 32bit users will scream. (not that I care)

arch/ppc/platforms/built-in.o(.text+0x1228): In function `flush_disable_caches':
: undefined reference to `__flush_disable_L1'

#14 lore raw
Quoted 9 lines · Olaf Hering

arch/ppc/platforms/pmac_cache.S line 37

Quoted 3 lines · Benjamin Herrenschmidt

+++ linux-work/arch/ppc/platforms/pmac_cache.S 2005-01-18 12:01:49.000000000 +1100

arch/ppc/platforms/pmac_cache.S new file +1 -0
+	b	__flush_disable_L1

This one is only available for CONFIG_6xx, so g5 32bit users will scream. (not that I care)

Me neither :) I don't support g5 32 bits, though I'll probably just fix it for this time as it's easy.

Quoted 2 lines

arch/ppc/platforms/built-in.o(.text+0x1228): In function `flush_disable_caches':
: undefined reference to `__flush_disable_L1'

Signature · 1 line
Benjamin Herrenschmidt <[email protected]>