Bugzilla – Attachment 69318 Details for
Bug 150318
Powersave interferes with DMA on VIA C3 Nehemiah
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
IDP Log In
|
Forgot Password
[patch]
diff between via's version and mainline
delme (text/plain), 11.77 KB, created by
Pavel Machek
on 2006-02-20 13:56:22 UTC
(
hide
)
Description:
diff between via's version and mainline
Filename:
MIME Type:
Creator:
Pavel Machek
Created:
2006-02-20 13:56:22 UTC
Size:
11.77 KB
patch
obsolete
>--- /data/l/linux/arch/i386/kernel/cpu/cpufreq/longhaul.c 2005-09-26 21:20:44.000000000 +0200 >+++ /tmp/delme_longhaul.c 2006-02-20 14:53:56.000000000 +0100 >@@ -14,7 +14,7 @@ > * until we have code that gets it right. > * Version 3 of longhaul got renamed to Powersaver and redesigned > * to use the POWERSAVER MSR at 0x110a. >- * It is present in Ezra-T (C5M), Nehemiah (C5X) and above. >+ * It is present in Ezra-T (C5N), Nehemiah (C5XLOE/C5XLOH/C5P) and above. > * It's pretty much the same feature wise to longhaul v2, though > * there is provision for scaling FSB too, but this doesn't work > * too well in practice so we don't even try to use this. >@@ -29,7 +29,9 @@ > #include <linux/cpufreq.h> > #include <linux/slab.h> > #include <linux/string.h> >-#include <linux/pci.h> >+ >+#include <linux/ide.h> >+#include <linux/delay.h> > > #include <asm/msr.h> > #include <asm/timex.h> >@@ -59,9 +61,24 @@ > > /* Module parameters */ > static int dont_scale_voltage; >+static int debug; >+ >+static void dprintk(const char *fmt, ...) >+{ >+ char s[256]; >+ va_list args; >+ >+ if (debug == 0) >+ return; >+ >+ va_start(args, fmt); >+ vsprintf(s, fmt, args); >+ printk(s); >+ va_end(args); >+} > > >-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) >+#define __hlt() __asm__ __volatile__("hlt": : :"memory") > > > /* Clock ratios multiplied by 10 */ >@@ -72,22 +89,23 @@ > static int longhaul_version; > static struct cpufreq_frequency_table *longhaul_table; > >-#ifdef CONFIG_CPU_FREQ_DEBUG >-static char speedbuffer[8]; > >-static char *print_speed(int speed) >-{ >- if (speed > 1000) { >- if (speed%1000 == 0) >- sprintf (speedbuffer, "%dGHz", speed/1000); >- else >- sprintf (speedbuffer, "%d.%dGHz", speed/1000, (speed%1000)/100); >- } else >- sprintf (speedbuffer, "%dMHz", speed); >+void ide_idle(void) { >+ int i; >+ ide_hwif_t *hwif = ide_hwifs; >+ ide_drive_t *drive; > >- return speedbuffer; >+ i = 0; >+ do { >+ drive = &hwif->drives[i]; >+ i++; >+ if (strncmp(drive->name,"hd",2) == 0) { >+ while (drive->waiting_for_dma) udelay(10) ; >+ } else { >+ i = 0; >+ } >+ } while (i != 0); > } >-#endif > > > static unsigned int calc_speed(int mult) >@@ -118,10 +136,10 @@ > static void do_powersaver(union msr_longhaul *longhaul, > unsigned int clock_ratio_index) > { >- struct pci_dev *dev; >+ int version; > unsigned long flags; > unsigned int tmp_mask; >- int version; >+ struct pci_dev *dev; > int i; > u16 pci_cmd; > u16 cmd_state[64]; >@@ -138,18 +156,20 @@ > } > > rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); >+ > longhaul->bits.SoftBusRatio = clock_ratio_index & 0xf; > longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; > longhaul->bits.EnableSoftBusRatio = 1; > longhaul->bits.RevisionKey = 0; > >+ /* Begin critical section */ > preempt_disable(); >+ ide_idle(); /* avoid ide timeouts when bus master off */ > local_irq_save(flags); > >- /* >- * get current pci bus master state for all devices >- * and clear bus master bit >- */ >+ /* get current pci bus master state for all devices */ >+ /* and clear bus master bit */ >+ > dev = NULL; > i = 0; > do { >@@ -162,19 +182,26 @@ > } > } while (dev != NULL); > >+ /* disabling INT2 takes care of ints 8-15 (cascaded) */ >+ > tmp_mask=inb(0x21); /* works on C3. save mask. */ >- outb(0xFE,0x21); /* TMR0 only */ >- outb(0xFF,0x80); /* delay */ >+ outb(0xFE,0x21); /* TMR0 only */ >+ outb(0xFF,0x80); /* delay */ >+ >+ local_irq_enable(); /* sti */ >+ >+ __hlt(); /* make sure we've got a full tick */ > >- safe_halt(); > wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); >- halt(); > >- local_irq_disable(); >+ __hlt(); >+ >+ local_irq_disable(); /* cli */ > >- outb(tmp_mask,0x21); /* restore mask */ >+ outb(tmp_mask,0x21); /* restore mask */ > > /* restore pci bus master state for all devices */ >+ > dev = NULL; > i = 0; > do { >@@ -184,14 +211,22 @@ > pci_write_config_byte(dev, PCI_COMMAND, pci_cmd); > } > } while (dev != NULL); >+ > local_irq_restore(flags); >+ > preempt_enable(); > >+ /* END CRITICAL SECTION */ >+ > /* disable bus ratio bit */ >+ > rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); >+ > longhaul->bits.EnableSoftBusRatio = 0; > longhaul->bits.RevisionKey = version; >+ > wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); >+ > } > > /** >@@ -227,8 +262,8 @@ > > cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); > >- dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", >- fsb, mult/10, mult%10, print_speed(speed/1000)); >+ dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%d)\n", >+ fsb, mult/10, mult%10, speed/1000); > > switch (longhaul_version) { > >@@ -247,7 +282,9 @@ > bcr2.bits.CLOCKMUL = clock_ratio_index; > local_irq_disable(); > wrmsrl (MSR_VIA_BCR2, bcr2.val); >- safe_halt(); >+ local_irq_enable(); >+ >+ __hlt(); > > /* Disable software clock multiplier */ > rdmsrl (MSR_VIA_BCR2, bcr2.val); >@@ -258,7 +295,8 @@ > break; > > /* >- * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N]) >+ * Longhaul v3 (aka Powersaver). (Ezra-T [C5N] & Nehemiah >+ * [C5XLOE/C5XLOH/C5P]) > * We can scale voltage with this too, but that's currently > * disabled until we come up with a decent 'match freq to voltage' > * algorithm. >@@ -328,7 +366,7 @@ > unsigned long lo, hi; > unsigned int eblcr_fsb_table_v1[] = { 66, 133, 100, -1 }; > unsigned int eblcr_fsb_table_v2[] = { 133, 100, -1, 66 }; >- >+ unsigned long deviceid=0,cpufreqdiv=0; // FSB 200 MHz > switch (longhaul_version) { > case TYPE_LONGHAUL_V1: > case TYPE_LONGHAUL_V2: >@@ -363,9 +401,8 @@ > } > > /* Nehemiah */ >- if (cpu_model==CPU_NEHEMIAH) { >- rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); >- >+ if (cpu_model==CPU_NEHEMIAH) >+ { > /* > * TODO: This code works, but raises a lot of questions. > * - Some Nehemiah's seem to have broken Min/MaxMHzBR's. >@@ -377,38 +414,77 @@ > * We're possibly using something undocumented and unsupported, > * But it works, so we don't grumble. > */ >- minmult=40; >- maxmult=longhaul_get_cpu_mult(); > >- /* Starting with the 1.2GHz parts, theres a 200MHz bus. */ >- if ((cpu_khz/1000) > 1200) >- fsb = 200; >- else >- fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB]; >- break; >- } >+ >+/* VIA improved the 200MHz FSB by Eddy Fu (2005-05-18) */ >+ // started >+ __asm__ ( >+ "movl $0x80000200, %%eax\n\r" >+ "movl $0x0cf8, %%edx\n\r" >+ "outl %%eax, %%dx\n\r" >+ >+ "movl $0x0cfc, %%edx\n\r" >+ "inl %%dx, %%eax\n\r" >+ "movl %%eax, %0\n\r" >+ :"=m" (deviceid) >+ ); >+ // printk("deviceid=%lx\n",deviceid); >+ if (deviceid == 0x22591106) { >+ // Read System Frequency Divider Rx54[7:5] >+ >+ __asm__ ( >+ "movl $0x80000254, %%eax\n\r" >+ "movl $0x0cf8, %%edx\n\r" >+ "outl %%eax, %%dx\n\r" >+ >+ "movl $0x0cfc, %%edx\n\r" >+ "inl %%dx, %%eax\n\r" >+ "andl $0x000000e0, %%eax\n\r" >+ "movl %%eax, %0\n\r" >+ :"=m" (cpufreqdiv) >+ ); >+ // dprintk("cpufreqdiv = %lx\n", cpufreqdiv); >+ if (cpufreqdiv == 0x00) >+ fsb = 100; >+ if (cpufreqdiv == 0x20) >+ fsb = 133; >+ if (cpufreqdiv == 0x40) >+ fsb = 200; >+ // dprintk ("VIA Nehemiah CPU's FSB=%d.\n", fsb); >+ } >+ else >+ { >+ rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); >+ fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB]; >+ } >+ minmult=40; >+ maxmult=longhaul_get_cpu_mult(); >+ // dprintk ("VIA Nehemiah CPU's maxmult = %d .\n", maxmult); >+ // dprintk ("VIA Nehemiah CPU's FSB = %d .\n", fsb); >+ // finished >+ break; >+ } > } > >- dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n", >+ printk (KERN_INFO PFX "MinMult: %d.%d x MaxMult: %d.%d x\n", > minmult/10, minmult%10, maxmult/10, maxmult%10); > > if (fsb == -1) { >- printk (KERN_INFO PFX "Invalid (reserved) FSB!\n"); >+ dprintk (KERN_INFO PFX "Invalid (reserved) FSB!\n"); > return -EINVAL; > } >- > highest_speed = calc_speed(maxmult); > lowest_speed = calc_speed(minmult); >- dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, >- print_speed(lowest_speed/1000), >- print_speed(highest_speed/1000)); >+ printk (KERN_INFO PFX "FSB: %d MHz Lowest speed: %d Highest speed: %d\n", fsb, >+ lowest_speed/1000, >+ highest_speed/1000); > > if (lowest_speed == highest_speed) { >- printk (KERN_INFO PFX "highestspeed == lowest, aborting.\n"); >+ dprintk (KERN_INFO PFX "highestspeed == lowest, aborting.\n"); > return -EINVAL; > } > if (lowest_speed > highest_speed) { >- printk (KERN_INFO PFX "nonsense! lowest (%d > %d) !\n", >+ dprintk (KERN_INFO PFX "nonsense! lowest (%d > %d) !\n", > lowest_speed, highest_speed); > return -EINVAL; > } >@@ -453,25 +529,25 @@ > vrmrev = longhaul.bits.VRMRev; > > if (minvid == 0 || maxvid == 0) { >- printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " >+ dprintk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " > "Voltage scaling disabled.\n", > minvid/1000, minvid%1000, maxvid/1000, maxvid%1000); > return; > } > > if (minvid == maxvid) { >- printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are " >+ dprintk (KERN_INFO PFX "Claims to support voltage scaling but min & max are " > "both %d.%03d. Voltage scaling disabled\n", > maxvid/1000, maxvid%1000); > return; > } > > if (vrmrev==0) { >- dprintk ("VRM 8.5\n"); >+ dprintk ("VRM 8.5 \n"); > memcpy (voltage_table, vrm85scales, sizeof(voltage_table)); > numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25; > } else { >- dprintk ("Mobile VRM\n"); >+ dprintk ("Mobile VRM \n"); > memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table)); > numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5; > } >@@ -565,7 +641,7 @@ > > case 8: > cpu_model = CPU_EZRA_T; >- cpuname = "C3 'Ezra-T' [C5M]"; >+ cpuname = "C3 'Ezra-T' [C5N]"; > longhaul_version = TYPE_POWERSAVER; > numscales=32; > memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio)); >@@ -578,17 +654,17 @@ > numscales=32; > switch (c->x86_mask) { > case 0 ... 1: >- cpuname = "C3 'Nehemiah A' [C5N]"; >+ cpuname = "C3 'Nehemiah A' [C5XLOE]"; > memcpy (clock_ratio, nehemiah_a_clock_ratio, sizeof(nehemiah_a_clock_ratio)); > memcpy (eblcr_table, nehemiah_a_eblcr, sizeof(nehemiah_a_eblcr)); > break; > case 2 ... 4: >- cpuname = "C3 'Nehemiah B' [C5N]"; >+ cpuname = "C3 'Nehemiah B' [C5XLOH]"; > memcpy (clock_ratio, nehemiah_b_clock_ratio, sizeof(nehemiah_b_clock_ratio)); > memcpy (eblcr_table, nehemiah_b_eblcr, sizeof(nehemiah_b_eblcr)); > break; > case 5 ... 15: >- cpuname = "C3 'Nehemiah C' [C5N]"; >+ cpuname = "C3 'Nehemiah C' [C5P]"; > memcpy (clock_ratio, nehemiah_c_clock_ratio, sizeof(nehemiah_c_clock_ratio)); > memcpy (eblcr_table, nehemiah_c_eblcr, sizeof(nehemiah_c_eblcr)); > break; >@@ -691,6 +767,9 @@ > module_param (dont_scale_voltage, int, 0644); > MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor"); > >+module_param (debug, int, 0644); >+MODULE_PARM_DESC(debug, "Dump debugging information."); >+ > MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); > MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); > MODULE_LICENSE ("GPL");
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 150318
:
69196
| 69318