Evgeni Golov <[EMAIL PROTECTED]> writes:

Hi,

> On Fri, 1 Jun 2007 17:13:14 +0100 Stephen Bridges wrote:
>
>> Ah, didn't realise there was a difference.  I think my laptop is ICH4 rather 
>> than 4M, but I'd better check now.
>
> Your X31 should have an ICH4-M (so does mine...) ;)
>
>> > you can't use the same patch. afaik on ich4m/ich5 you have to poke the
>> > pci registers. I've a ich4m test box where I can force enable the hpet but
>> > the patch is breaking resume :(
>
> Could you please share the patch? (As I understand it's not the
> standard force hpet patch from linuxpowertop.org...)
> Maybe it won't break suspend on other hardware...

Sorry for the delay, but I was busy on other things. The good news is
that I'm now able to resume with the patch :)
I've tested on 2.6.21 and 2.6.22rc4 on ICH4M chipsets. ICH5 owner should
add their pci ids and report if it's working for them too.

According to http://lkml.org/lkml/2007/5/21/267, ICH4M and ICH5 chipset have 
hpet and they can be force enable by a different method than ICH6 and later
chipsets. This patch implements such feature.
As I didn't test it on ICH5, I didn't add the chipsets PCI IDs.

[ This patch needs that the previous force hpet patch is applied
 http://www.linuxpowertop.org/patches/hpet_patches_45.patch ]

Signed-off-by: Arnaud Patard <[EMAIL PROTECTED]>

---
 arch/i386/kernel/quirks.c |   61 	59 +	2 -	0 !
 1 file changed, 59 insertions(+), 2 deletions(-)

Index: linux-2.6.21/arch/i386/kernel/quirks.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/quirks.c	2007-06-06 00:45:33.000000000 +0200
+++ linux-2.6.21/arch/i386/kernel/quirks.c	2007-06-06 00:48:26.000000000 +0200
@@ -104,6 +104,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
 unsigned long force_hpet_address;
 
 static void __iomem *rcba_base;
+static struct pci_dev *lpc_device;
+
+static void ich4m_force_hpet_resume(void)
+{
+	u32 val;
+
+	if (lpc_device == NULL)
+		BUG();
+
+	pci_read_config_dword(lpc_device, 0xD0, &val);
+	pci_write_config_dword(lpc_device, 0xD0, val | (1<<17));
+
+	pci_read_config_dword(lpc_device, 0xD0, &val);
+	if (!((val>>17) & 1))
+		BUG();
+	else
+		printk(KERN_DEBUG "Force enabled HPET at resume\n");
+
+}
 
 void ich_force_hpet_resume(void)
 {
@@ -112,8 +131,10 @@ void ich_force_hpet_resume(void)
 	if (!force_hpet_address)
 		return;
 
-	if (rcba_base == NULL)
-		BUG();
+	if (rcba_base == NULL) {
+		ich4m_force_hpet_resume();
+		return;
+	}
 
 	/* read the Function Disable register, dword mode only */
 	val = readl(rcba_base + 0x3404);
@@ -131,6 +152,42 @@ void ich_force_hpet_resume(void)
 	return;
 }
 
+
+static void ich4m_force_enable_hpet(struct pci_dev *dev)
+{
+	u32 val, gen_ctl;
+
+	if (hpet_address || force_hpet_address)
+		return;
+
+	pci_read_config_dword(dev, 0xD0, &gen_ctl);
+	if ((gen_ctl>>17) & 1) {
+		val = (gen_ctl>>15) & 3;
+		force_hpet_address = 0xFED00000 | (val << 12);
+		lpc_device = dev;
+		printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+				force_hpet_address);
+		return;
+	}
+
+	pci_write_config_dword(dev, 0xD0, gen_ctl | (1<<17));
+	pci_read_config_dword(dev, 0xD0, &gen_ctl);
+	if ((gen_ctl>>17) & 1) {
+		val = (gen_ctl>>15) & 3;
+		force_hpet_address = 0xFED00000 | (val << 12);
+		lpc_device = dev;
+		printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+				force_hpet_address);
+		return;
+	}
+
+	force_hpet_address = 0;
+	printk(KERN_DEBUG "Failed to force enable HPET\n");
+	return;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
+		ich4m_force_enable_hpet);
+
 static void ich_force_enable_hpet(struct pci_dev *dev)
 {
 	u32 val, rcba;
_______________________________________________
Power mailing list
[email protected]
http://www.bughost.org/mailman/listinfo/power

Reply via email to