* longhaul
@ 2004-05-03 8:27 Lars Täuber
0 siblings, 0 replies; 5+ messages in thread
From: Lars Täuber @ 2004-05-03 8:27 UTC (permalink / raw)
To: cpufreq
Hallo,
i got the address from the MAINTAINER file from Linux kernel source.
If this address is a list I'm not subscribed.
We've got two computers with the VIA Samuel2 CPU - one in revision 2 and one in revision 3.
The revision 2 works with the longaul v1 driver on 2.6.5 very good.
(It's a Elitegroup A900 Desknote)
The other one doesn't work, it says that the max cpufreq (6??) is higher than the one at boot time (598). This cpu is a 600MHz on an Epia CL6000. It runs 24x7 and is passively cooled end therefor we want it to slow down when nothing is to do.
There is a driver that works but only for the 2.4.x kernels.
http://www3.sympatico.ca/howlettfamily/epia/longhaul.html
Is there a solution for our problem?
Best Regards
Lars Täuber
^ permalink raw reply [flat|nested] 5+ messages in thread
* longhaul
@ 2005-04-12 5:46 ken_staton
2005-04-13 14:49 ` longhaul Bruno Ducrot
2005-04-13 14:54 ` longhaul Bruno Ducrot
0 siblings, 2 replies; 5+ messages in thread
From: ken_staton @ 2005-04-12 5:46 UTC (permalink / raw)
To: cpufreq
here's a partial fix for longhaul on a nehemiah c3-2.
the code in do_powersaver() is significantly changed.
frequency changes occur after the HLT instruction and there must
be more than 20 usec between HLT and the interrupt that brings
the cpu out of HLT. the only interrupt you have any chance of controlling
is the timer interrupt.
the algorithm for this:
1. disable all interrupts
2. mask all interrupts off except timer (irq0)
3. enable interrupts (i.e. just irq0)
4. HLT (so we know we've just had a tick before changing the MSR)
5. write the MSR
6. HLT (this changes the frequency)
7. disable all interrupts
8. restore the original interrupt mask
9. re-enable interrupts
the reason this is a partial fix:
external hardware signals (NMI, INIT, SMI, FLUSH) interferes with the
frequency change.
****> this is the hard one:
cache snooping interferes with the frequency change.
so if DMA is accessing memory, cache snooping is active.
my partial fix waits for the ide dma to be idle and then dives into the
frequency change.
other dma controllers (e.g. bus mastering pci card, legacy (isa) dma channels)
will cause the same problem.
---
ken
--- longhaul-2.6.11.7.c 2005-04-11 22:12:18.000000000 -0700
+++ longhaul.c 2005-04-11 22:13:51.000000000 -0700
@@ -30,6 +30,11 @@
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+#include <asm/irq.h>
+#include <linux/sched.h>
+
#include <asm/msr.h>
#include <asm/timex.h>
#include <asm/io.h>
@@ -58,13 +63,26 @@
/* 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;
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,
"longhaul", msg)
+ va_start(args, fmt);
+ vsprintf(s, fmt, args);
+ printk(s);
+ va_end(args);
+}
#define __hlt() __asm__ __volatile__("hlt": : :"memory")
+
/* Clock ratios multiplied by 10 */
static int clock_ratio[32];
static int eblcr_table[32];
@@ -72,10 +90,31 @@
static unsigned int highest_speed, lowest_speed; /* kHz */
static int longhaul_version;
static struct cpufreq_frequency_table *longhaul_table;
-
-#ifdef CONFIG_CPU_FREQ_DEBUG
static char speedbuffer[8];
+spinlock_t long_lock = SPIN_LOCK_UNLOCKED;
+
+
+void dma_idle(void) {
+ int i;
+ ide_hwif_t *hwif = ide_hwifs;
+ ide_drive_t *drive;
+
+ 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);
+}
+
+
+
static char *print_speed(int speed)
{
if (speed > 1000) {
@@ -88,7 +127,6 @@
return speedbuffer;
}
-#endif
static unsigned int calc_speed(int mult)
@@ -121,6 +159,13 @@
{
int version;
+ unsigned long flags;
+ unsigned int tmp_mask;
+
+
+ dprintk(KERN_INFO PFX " %d ",clock_ratio_index);
+
+
switch (cpu_model) {
case CPU_EZRA_T:
version = 3;
@@ -133,23 +178,54 @@
}
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;
- local_irq_disable();
+
+ dma_idle(); // ide dma only...
+
+// BEGIN CRITICAL SECTION
+
+// preempt_disable();
+ local_irq_save(flags);
+
+ // 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
+
+
+ local_irq_enable(); // sti
+
+ __hlt(); // wait to catch a full timer tick interval
+
wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
- local_irq_enable();
- __hlt();
+
+ __hlt(); // change PLL. wait for stable clock.
+
+ local_irq_disable(); // cli
+
+ outb(tmp_mask,0x21); // restore mask
+
+ 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;
- local_irq_disable();
+
wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
- local_irq_enable();
}
+
/**
* longhaul_set_cpu_frequency()
* @clock_ratio_index : bitpattern of the new multiplier.
@@ -183,7 +259,7 @@
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
+ dprintk (KERN_INFO PFX "Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
fsb, mult/10, mult%10, print_speed(speed/1000));
switch (longhaul_version) {
@@ -213,6 +289,7 @@
local_irq_disable();
wrmsrl (MSR_VIA_BCR2, bcr2.val);
local_irq_enable();
+
break;
/*
@@ -347,7 +424,7 @@
}
}
- dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n",
+ dprintk (KERN_INFO PFX "MinMult:%d.%dx MaxMult:%d.%dx\n",
minmult/10, minmult%10, maxmult/10, maxmult%10);
if (fsb == -1) {
@@ -357,9 +434,9 @@
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));
+ dprintk (KERN_INFO PFX "FSB:%dMHz ", fsb);
+ dprintk ("Lowest speed:%s ", print_speed(lowest_speed/1000));
+ dprintk ("Highest speed:%s\n", print_speed(highest_speed/1000));
if (lowest_speed == highest_speed) {
printk (KERN_INFO PFX "highestspeed == lowest, aborting.\n");
@@ -425,11 +502,11 @@
}
if (vrmrev==0) {
- dprintk ("VRM 8.5 \n");
+ dprintk (KERN_INFO PFX "VRM 8.5 : ");
memcpy (voltage_table, vrm85scales, sizeof(voltage_table));
numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25;
} else {
- dprintk ("Mobile VRM \n");
+ dprintk (KERN_INFO PFX "Mobile VRM : ");
memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table));
numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5;
}
@@ -578,7 +655,7 @@
longhaul_setup_voltagescaling();
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cpuinfo.transition_latency = 20000; // nSec = 20uS
policy->cur = calc_speed(longhaul_get_cpu_mult());
ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
@@ -631,6 +708,7 @@
}
+
static void __exit longhaul_exit(void)
{
int i=0;
@@ -649,6 +727,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");
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: longhaul
2005-04-12 5:46 longhaul ken_staton
@ 2005-04-13 14:49 ` Bruno Ducrot
2005-04-13 14:54 ` longhaul Bruno Ducrot
1 sibling, 0 replies; 5+ messages in thread
From: Bruno Ducrot @ 2005-04-13 14:49 UTC (permalink / raw)
To: ken_staton; +Cc: cpufreq
On Mon, Apr 11, 2005 at 10:46:56PM -0700, ken_staton@agilent.com wrote:
>
> here's a partial fix for longhaul on a nehemiah c3-2.
>
> the code in do_powersaver() is significantly changed.
>
> frequency changes occur after the HLT instruction and there must
> be more than 20 usec between HLT and the interrupt that brings
> the cpu out of HLT. the only interrupt you have any chance of controlling
> is the timer interrupt.
Do you have any pointer about this statement?
>
> the algorithm for this:
>
> 1. disable all interrupts
> 2. mask all interrupts off except timer (irq0)
> 3. enable interrupts (i.e. just irq0)
> 4. HLT (so we know we've just had a tick before changing the MSR)
> 5. write the MSR
> 6. HLT (this changes the frequency)
> 7. disable all interrupts
> 8. restore the original interrupt mask
> 9. re-enable interrupts
Since the clock timer is not disabled, how you achieve atomicity
in-between steps 3 to 7?
> the reason this is a partial fix:
>
> external hardware signals (NMI, INIT, SMI, FLUSH) interferes with the
> frequency change.
>
> ****> this is the hard one:
> cache snooping interferes with the frequency change.
> so if DMA is accessing memory, cache snooping is active.
>
> my partial fix waits for the ide dma to be idle and then dives into the
> frequency change.
> other dma controllers (e.g. bus mastering pci card, legacy (isa) dma channels)
> will cause the same problem.
>
>
>
> ---
> ken
>
>
>
>
>
> --- longhaul-2.6.11.7.c 2005-04-11 22:12:18.000000000 -0700
> +++ longhaul.c 2005-04-11 22:13:51.000000000 -0700
> @@ -30,6 +30,11 @@
> #include <linux/slab.h>
> #include <linux/string.h>
>
> +#include <linux/ide.h>
> +#include <linux/delay.h>
> +#include <asm/irq.h>
> +#include <linux/sched.h>
> +
> #include <asm/msr.h>
> #include <asm/timex.h>
> #include <asm/io.h>
> @@ -58,13 +63,26 @@
>
> /* 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;
>
> -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,
What's wrong with this version of dprintk?
> "longhaul", msg)
> + va_start(args, fmt);
> + vsprintf(s, fmt, args);
> + printk(s);
> + va_end(args);
> +}
>
>
> #define __hlt() __asm__ __volatile__("hlt": : :"memory")
>
> +
Why this line is added?
> /* Clock ratios multiplied by 10 */
> static int clock_ratio[32];
> static int eblcr_table[32];
> @@ -72,10 +90,31 @@
> static unsigned int highest_speed, lowest_speed; /* kHz */
> static int longhaul_version;
> static struct cpufreq_frequency_table *longhaul_table;
> -
> -#ifdef CONFIG_CPU_FREQ_DEBUG
> static char speedbuffer[8];
>
> +spinlock_t long_lock = SPIN_LOCK_UNLOCKED;
> +
> +
> +void dma_idle(void) {
> + int i;
> + ide_hwif_t *hwif = ide_hwifs;
> + ide_drive_t *drive;
> +
> + 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);
> +}
Could you please respect linux coding style?
...
> +
> + dma_idle(); // ide dma only...
ditto. Please don't use a comment a la C99.
> +
> +// BEGIN CRITICAL SECTION
ditto
> +
> +// preempt_disable();
> + local_irq_save(flags);
> +
> + // disabling INT2 takes care of ints 8-15 (cascaded)
> +
> + tmp_mask=inb(0x21); // works on C3. save mask.
Do you have any pointer stating that PIC is the only available
interrupt model for such architecture?
--
Bruno Ducrot
-- Which is worse: ignorance or apathy?
-- Don't know. Don't care.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: longhaul
2005-04-12 5:46 longhaul ken_staton
2005-04-13 14:49 ` longhaul Bruno Ducrot
@ 2005-04-13 14:54 ` Bruno Ducrot
1 sibling, 0 replies; 5+ messages in thread
From: Bruno Ducrot @ 2005-04-13 14:54 UTC (permalink / raw)
To: ken_staton; +Cc: cpufreq
On Mon, Apr 11, 2005 at 10:46:56PM -0700, ken_staton@agilent.com wrote:
>
> here's a partial fix for longhaul on a nehemiah c3-2.
>
> the code in do_powersaver() is significantly changed.
>
> frequency changes occur after the HLT instruction and there must
> be more than 20 usec between HLT and the interrupt that brings
> the cpu out of HLT. the only interrupt you have any chance of controlling
> is the timer interrupt.
BTW, what is the interrupt source in order to wakeup the processor in
this perticular case? I would said SMI or SCI, but not
the timer one. On the other hand I don't have hardware nor
specification so I cant tell for sure.
--
Bruno Ducrot
-- Which is worse: ignorance or apathy?
-- Don't know. Don't care.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Longhaul
@ 2007-01-03 17:59 Rafał Bilski
0 siblings, 0 replies; 5+ messages in thread
From: Rafał Bilski @ 2007-01-03 17:59 UTC (permalink / raw)
To: Dave Jones; +Cc: cpufreq
I have report that Longhaul is locking Epia CL-10000. Basicaly
it is older Epia M-10000 with dual LAN. ACPI nor northbridge
support isn't blocking disk DMA.
Feel free to mark Longhaul broken again.
Bye
Rafa³ Bilski
----------------------------------------------------------------------
Jestes kierowca? To poczytaj! >>> http://link.interia.pl/f199e
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-01-03 17:59 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-03 17:59 Longhaul Rafał Bilski
-- strict thread matches above, loose matches on Subject: below --
2005-04-12 5:46 longhaul ken_staton
2005-04-13 14:49 ` longhaul Bruno Ducrot
2005-04-13 14:54 ` longhaul Bruno Ducrot
2004-05-03 8:27 longhaul Lars Täuber
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.