Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[TIP] CPU frequency scaling con AMD Barton mobile su desktop
View unanswered posts
View posts from last 24 hours
View posts from last 7 days

 
Reply to topic    Gentoo Forums Forum Index Forum italiano (Italian) Risorse italiane (documentazione e tools)
View previous topic :: View next topic  
Author Message
skakz
Guru
Guru


Joined: 03 Jul 2004
Posts: 380
Location: Ischia/Napoli/Italia/Terra

PostPosted: Sat May 28, 2005 3:14 pm    Post subject: [TIP] CPU frequency scaling con AMD Barton mobile su desktop Reply with quote

ATTENZIONE: leggete più in basso per la soluzione!!!!!
ps: se il vostro barton non è un "mobile" non vi preoccupate!!!!
ecco come renderlo "mobile"
http://fab51.com/cpu/barton/athlon-e24.html

-----------------------------------------------------------------------------------------------------------
vai direttamente qui https://forums.gentoo.org/viewtopic-p-2451332-highlight-.html#2451332
-----------------------------------------------------------------------------------------------------------



ultimamente sto avendo problemi di temperature elevate con la mia cpu, un 2500+ Mobile Barton montato su una asus a7v600-x. questo'inverno l'ho tenuto a 2900+ (2000mhz) senza alcun problema tra i 40/45 gradi. ora con il caldo mi raggiunge anche i 55 gradi a riposo e non overclockato! Ho ottimi dissipatori e ventole quindi per risolvere mi sono indirizzato verso il cpu frequency scaling. ora la questione è questa: come faccio a sapere se la mia scheda madre la supporta? (il processore è sicuro perchè un mobile) se la supporta cosa devo fare per abilitarlo? dal bios? dal kernel?


grazie a tutti
_________________
Linux Registered User n.340423
Linux User Group Ischia
www.tush.it


Last edited by skakz on Sun May 29, 2005 7:01 pm; edited 5 times in total
Back to top
View user's profile Send private message
Ciccio Bueo
l33t
l33t


Joined: 19 Oct 2004
Posts: 834
Location: Treviso

PostPosted: Sat May 28, 2005 3:54 pm    Post subject: Reply with quote

che io sappia la scheda madre deve essere dotata di chiset via per fare lo scaling, quelle basate sull'nforce non lo permettono, per il resto non so aiutarti, mi spiace. :wink:
Back to top
View user's profile Send private message
skakz
Guru
Guru


Joined: 03 Jul 2004
Posts: 380
Location: Ischia/Napoli/Italia/Terra

PostPosted: Sat May 28, 2005 4:10 pm    Post subject: Reply with quote

questa ha chip via kt600...
ma non ho trovato da nessuna parte info a riguardo...
_________________
Linux Registered User n.340423
Linux User Group Ischia
www.tush.it
Back to top
View user's profile Send private message
btbbass
Apprentice
Apprentice


Joined: 15 Feb 2005
Posts: 287
Location: Asti o Torino

PostPosted: Sat May 28, 2005 4:21 pm    Post subject: Re: [OT] CPU frequency scaling su desktop Reply with quote

darkdude wrote:
ultimamente sto avendo problemi di temperature elevate con la mia cpu, un 2500+ Mobile Barton montato su una asus a7v600-x. questo'inverno l'ho tenuto a 2900+ (2000mhz) senza alcun problema tra i 40/45 gradi. ora con il caldo mi raggiunge anche i 55 gradi a riposo e non overclockato! Ho ottimi dissipatori e ventole quindi per risolvere mi sono indirizzato verso il cpu frequency scaling. ora la questione è questa: come faccio a sapere se la mia scheda madre la supporta? (il processore è sicuro perchè un mobile) se la supporta cosa devo fare per abilitarlo? dal bios? dal kernel?


grazie a tutti


Mah, io credo che la teperatura a riposo non sia del tutto indicativa... L'importante è che non ti superi i 70-75 C quando ad esempio compili... Il mio centrino arriva comodo comodo ai 73 C, ma è normale, perlomeno se compili...
A riposo non scende sotto i 50, sempre con il caldo, naturalmente...
_________________
Chi dice che è impossibile non interrompa chi lo sta facendo

-Proverbio Cinese -
___________________________________
Back to top
View user's profile Send private message
Sparker
l33t
l33t


Joined: 28 Aug 2003
Posts: 992

PostPosted: Sat May 28, 2005 5:54 pm    Post subject: Reply with quote

[errore]Alcune MoBo con nforce2 supportano il cambiamento al volo del FSB ed anche della tensione del core:
https://forums.gentoo.org/viewtopic-t-273047-highlight-nforce2+scaling.html[/errore]
edit: non so dove ho letto che hai una nforce2 :roll:


Puoi usare athcool che mette in idle la cpu se non utilizzata
(la mia sconosciuta npap2-ultra lo fa direttamente via BIOS :twisted: )

Athcool funziona anche con i kt600
Back to top
View user's profile Send private message
skakz
Guru
Guru


Joined: 03 Jul 2004
Posts: 380
Location: Ischia/Napoli/Italia/Terra

PostPosted: Sat May 28, 2005 6:00 pm    Post subject: Reply with quote

@btbbass: in effetti 55 gradi non è troppo però sai a volte capita che resti acceso per giorni o settimane in casi in cui assolutamente non servono tutti e 2000mhz quindi ci avevo fatto un pensierino serio.

@Sparker: la mia scheda è una asus con chip via kt600

grazie a tutti in ogni caso
_________________
Linux Registered User n.340423
Linux User Group Ischia
www.tush.it
Back to top
View user's profile Send private message
Sparker
l33t
l33t


Joined: 28 Aug 2003
Posts: 992

PostPosted: Sat May 28, 2005 6:04 pm    Post subject: Reply with quote

darkdude wrote:
@Sparker: la mia scheda è una asus con chip via kt600

Si si, prova athcool (è in portage), sul sito c'è scritto che supporta anche i chipset kt600
Back to top
View user's profile Send private message
skakz
Guru
Guru


Joined: 03 Jul 2004
Posts: 380
Location: Ischia/Napoli/Italia/Terra

PostPosted: Sat May 28, 2005 6:49 pm    Post subject: Reply with quote

Sparker wrote:
darkdude wrote:
@Sparker: la mia scheda è una asus con chip via kt600

Si si, prova athcool (è in portage), sul sito c'è scritto che supporta anche i chipset kt600


ottimo tool !!! grazie :wink:


edit: naturalmente se qualcuno mi auita con il cpu freq scaling gliene sarei mooooolto grato
_________________
Linux Registered User n.340423
Linux User Group Ischia
www.tush.it
Back to top
View user's profile Send private message
johnnystuff
Tux's lil' helper
Tux's lil' helper


Joined: 28 Aug 2003
Posts: 141

PostPosted: Sat May 28, 2005 10:58 pm    Post subject: Reply with quote

hai letto questo ?
Verso metà se non ti interessa la questione sul runlevel e sull'acpi ci sono un bel po' di informazioni interessanti sul cpu frequency scaling on gentoo!
:wink:
Back to top
View user's profile Send private message
skakz
Guru
Guru


Joined: 03 Jul 2004
Posts: 380
Location: Ischia/Napoli/Italia/Terra

PostPosted: Sun May 29, 2005 9:36 am    Post subject: Reply with quote

Code:

omega root # modprobe powernow-k7
FATAL: Error inserting powernow_k7 (/lib/modules/2.6.11-gentoo-r9/kernel/arch/i386/kernel/cpu/cpufreq/powernow-k7.ko): No such device
omega root #


queste il mio config del kernel...
Code:

#
# Power management options (ACPI, APM)
#
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
# CONFIG_SOFTWARE_SUSPEND is not set

#
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
CONFIG_ACPI_BOOT=y
CONFIG_ACPI_INTERPRETER=y
# CONFIG_ACPI_SLEEP is not set
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_VIDEO=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_THERMAL=m
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_IBM is not set
# CONFIG_ACPI_TOSHIBA is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_BUS=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_X86_PM_TIMER is not set
CONFIG_ACPI_CONTAINER=m

#
# APM (Advanced Power Management) BIOS Support
#
CONFIG_APM=y
# CONFIG_APM_IGNORE_USER_SUSPEND is not set
# CONFIG_APM_DO_ENABLE is not set
# CONFIG_APM_CPU_IDLE is not set
# CONFIG_APM_DISPLAY_BLANK is not set
# CONFIG_APM_RTC_IS_GMT is not set
# CONFIG_APM_ALLOW_INTS is not set
CONFIG_APM_REAL_MODE_POWER_OFF=y

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
# CONFIG_CPU_FREQ_DEBUG is not set
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_TABLE=y

#
# CPUFreq processor drivers
#
CONFIG_X86_ACPI_CPUFREQ=m
CONFIG_X86_POWERNOW_K6=m
CONFIG_X86_POWERNOW_K7=m
CONFIG_X86_POWERNOW_K7_ACPI=y
CONFIG_X86_POWERNOW_K8=m
CONFIG_X86_POWERNOW_K8_ACPI=y
CONFIG_X86_GX_SUSPMOD=m
CONFIG_X86_SPEEDSTEP_CENTRINO=m
# CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI is not set
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_ICH=m
CONFIG_X86_SPEEDSTEP_SMI=m
CONFIG_X86_P4_CLOCKMOD=m
CONFIG_X86_CPUFREQ_NFORCE2=m
CONFIG_X86_LONGRUN=m
CONFIG_X86_LONGHAUL=m

#
# shared options
#
CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
CONFIG_X86_SPEEDSTEP_LIB=m
# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set


penso allora che non sia supportato.. giusto??


EDIT: quando faccio modprobe powernow-k7 in dmesg esce:
Code:

powernow: PowerNOW! Technology present. Can scale: frequency and voltage.
powernow: No PST tables match this cpuid (0x7a0)
powernow: This is indicative of a broken BIOS.
powernow: Trying ACPI perflib
powernow: ACPI perflib can not be used in this platform
powernow: ACPI and legacy methods failed
powernow: See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml


e poi:
Code:

omega linux # ls /sys/devices/system/cpu/cpu0/cpufreq/
ls: /sys/devices/system/cpu/cpu0/cpufreq/: No such file or directory
omega linux #

_________________
Linux Registered User n.340423
Linux User Group Ischia
www.tush.it
Back to top
View user's profile Send private message
skakz
Guru
Guru


Joined: 03 Jul 2004
Posts: 380
Location: Ischia/Napoli/Italia/Terra

PostPosted: Sun May 29, 2005 5:32 pm    Post subject: Reply with quote

solved:

ho dovuto modificare questi due file:

Code:

arch/i386/kernel/cpu/cpufreq/Kconfig

#
# CPU Frequency scaling
#

menu "CPU Frequency scaling"

source "drivers/cpufreq/Kconfig"

config CPU_FREQ_TABLE
       tristate "CPU frequency table helpers"
       depends on CPU_FREQ
       default y
       help
         Many CPUFreq drivers use these helpers, so only say N here if
         the CPUFreq driver of your choice doesn't need these helpers.

         If in doubt, say Y.

comment "CPUFreq processor drivers"
       depends on CPU_FREQ

config X86_ACPI_CPUFREQ
        tristate "ACPI Processor P-States driver"
        depends on CPU_FREQ_TABLE && ACPI_PROCESSOR
        help
          This driver adds a CPUFreq driver which utilizes the ACPI
          Processor Performance States.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config ELAN_CPUFREQ
        tristate "AMD Elan"
        depends on CPU_FREQ_TABLE && X86_ELAN
        ---help---
          This adds the CPUFreq driver for AMD Elan SC400 and SC410
          processors.

          You need to specify the processor maximum speed as boot
          parameter: elanfreq=maxspeed (in kHz) or as module
          parameter "max_freq".

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_POWERNOW_K6
        tristate "AMD Mobile K6-2/K6-3 PowerNow!"
        depends on CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
          AMD K6-3+ processors.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_POWERNOW_K7
        tristate "AMD Mobile Athlon/Duron PowerNow!"
        depends on CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for mobile AMD K7 mobile processors.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_POWERNOW_K7_ACPI
        bool
        depends on ((X86_POWERNOW_K7 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K7 = "y" && ACPI_PROCESSOR = "y"))
        default y

config X86_POWERNOW_K7_MANUAL
        bool "Manual setting of PowerNow! table for AMD Mobile Athlon/Duron."
        depends on X86_POWERNOW_K7
        default n
        help
          This adds the possibility to manual change the PST table.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_POWERNOW_K8
        tristate "AMD Opteron/Athlon64 PowerNow!"
        depends on CPU_FREQ_TABLE && EXPERIMENTAL
        help
          This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_POWERNOW_K8_ACPI
        bool
        depends on ((X86_POWERNOW_K8 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K8 = "y" && ACPI_PROCESSOR = "y"))
        default y

config X86_GX_SUSPMOD
        tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
        depends on CPU_FREQ
        help
         This add the CPUFreq driver for NatSemi Geode processors which
         support suspend modulation.

         For details, take a look at <file:Documentation/cpu-freq/>.

         If in doubt, say N.

config X86_SPEEDSTEP_CENTRINO
        tristate "Intel Enhanced SpeedStep"
        depends on CPU_FREQ_TABLE
        select X86_SPEEDSTEP_CENTRINO_TABLE if (!X86_SPEEDSTEP_CENTRINO_ACPI)
        help
          This adds the CPUFreq driver for Enhanced SpeedStep enabled
          mobile CPUs.  This means Intel Pentium M (Centrino) CPUs. However,
          you also need to say Y to "Use ACPI tables to decode..." below
          [which might imply enabling ACPI] if you want to use this driver
          on non-Banias CPUs.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_SPEEDSTEP_CENTRINO_ACPI
        bool "Use ACPI tables to decode valid frequency/voltage pairs"
        depends on X86_SPEEDSTEP_CENTRINO
        depends on ((X86_SPEEDSTEP_CENTRINO = "m" && ACPI_PROCESSOR) || (X86_SPEEDSTEP_CENTRINO = "y" && ACPI_PROCESSOR = "y"))
        default y
        help
          Use primarily the information provided in the BIOS ACPI tables
          to determine valid CPU frequency and voltage pairings. It is
          required for the driver to work on non-Banias CPUs.

          If in doubt, say Y.

config X86_SPEEDSTEP_CENTRINO_TABLE
        bool "Built-in tables for Banias CPUs"
        depends on X86_SPEEDSTEP_CENTRINO
        default y
        help
          Use built-in tables for Banias CPUs if ACPI encoding
          is not available.

          If in doubt, say N.

config X86_SPEEDSTEP_ICH
        tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
        depends on CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for certain mobile Intel Pentium III
          (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all
          mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2,
          ICH3 or ICH4 southbridge.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_SPEEDSTEP_SMI
        tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)"
        depends on CPU_FREQ_TABLE && EXPERIMENTAL
        help
          This adds the CPUFreq driver for certain mobile Intel Pentium III
          (Coppermine), all mobile Intel Pentium III-M (Tualatin)
          on systems which have an Intel 440BX/ZX/MX southbridge.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_P4_CLOCKMOD
        tristate "Intel Pentium 4 clock modulation"
        depends on CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for Intel Pentium 4 / XEON
          processors.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_CPUFREQ_NFORCE2
        tristate "nVidia nForce2 FSB changing"
        depends on CPU_FREQ && EXPERIMENTAL
        help
          This adds the CPUFreq driver for FSB changing on nVidia nForce2
          platforms.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_LONGRUN
        tristate "Transmeta LongRun"
        depends on CPU_FREQ
        help
          This adds the CPUFreq driver for Transmeta Crusoe and Efficeon processors
          which support LongRun.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

config X86_LONGHAUL
        tristate "VIA Cyrix III Longhaul"
        depends on CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for VIA Samuel/CyrixIII,
          VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
          processors.

          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.

comment "shared options"
        depends on CPU_FREQ

config X86_ACPI_CPUFREQ_PROC_INTF
        bool "/proc/acpi/processor/../performance interface (deprecated)"
        depends on PROC_FS
        depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI
        help
          This enables the deprecated /proc/acpi/processor/../performance
          interface. While it is helpful for debugging, the generic,
          cross-architecture cpufreq interfaces should be used.

          If in doubt, say N.

config X86_SPEEDSTEP_LIB
        tristate
        depends on (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD)
        default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD)

config X86_SPEEDSTEP_RELAXED_CAP_CHECK
        bool "Relaxed speedstep capability checks"
        depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH)
        help
          Don't perform all checks for a speedstep capable system which would
          normally be done. Some ancient or strange systems, though speedstep
          capable, don't always indicate that they are speedstep capable. This
          option lets the probing code bypass some of those checks if the
          parameter "relaxed_check=1" is passed to the module.


endmenu



e



Code:

arch/i386/kernel/cpu/cpufreq/powernow-k7.c

/*
 *  AMD K7 Powernow driver.
 *  (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs.
 *  (C) 2003-2004 Dave Jones <davej@redhat.com>
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *  Based upon datasheets & sample CPUs kindly provided by AMD.
 *
 * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
 * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
 * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
 * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/dmi.h>

#include <asm/msr.h>
#include <asm/timex.h>
#include <asm/io.h>
#include <asm/system.h>

#ifdef CONFIG_X86_POWERNOW_K7_ACPI
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif

#include "powernow-k7.h"

#define PFX "powernow: "


struct psb_s {
        u8 signature[10];
        u8 tableversion;
        u8 flags;
        u16 settlingtime;
        u8 reserved1;
        u8 numpst;
};

struct pst_s {
        u32 cpuid;
        u8 fsbspeed;
        u8 maxfid;
        u8 startvid;
        u8 numpstates;
};

#ifdef CONFIG_X86_POWERNOW_K7_ACPI
union powernow_acpi_control_t {
        struct {
                unsigned long fid:5,
                vid:5,
                sgtc:20,
                res1:2;
        } bits;
        unsigned long val;
};
#endif

#if defined CONFIG_CPU_FREQ_DEBUG || defined CONFIG_X86_POWERNOW_K7_MANUAL
 /* divide by 1000 to get VCore voltage in V. */
 static int mobile_vid_table[32] = {
    2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
    1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
    1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
    1075, 1050, 1025, 1000, 975, 950, 925, 0,
};
#endif

/* divide by 10 to get multiplier. */
static int fid_codes[32] = {
    110, 115, 120, 125, 50, 55, 60, 65,
    70, 75, 80, 85, 90, 95, 100, 105,
    30, 190, 40, 200, 130, 135, 140, 210,
    150, 225, 160, 165, 170, 180, -1, -1,
};

#ifdef CONFIG_X86_POWERNOW_K7_MANUAL
/* translation table for even multiplier to fid */
static int even_multiplier[20] = {
       16, 18, 4, 6, 8, 10, 12, 14,    // 3, 4, 5, 6, 7 ,8 , 9, 10
       0, 2, 20, 22, 24, 26, 28, 29,   // 11, 12, 13, 14, 15, 16, 17, 18
       17, 19, 23, 25,         // 19, 20, 21, 22
};

/* translation table for odd multiplier to fid*/
static int odd_multiplier[9] = {
       5, 7, 9, 11, 13, 15, 1, 3,      // 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5
       21,                     // 13.5
};

/* This parameters can be used to manually overwrite the tables */
static int overwrite_table = 0;
#define MAX_PST 10
static int multiplier_arr_size = MAX_PST;
static int voltage_arr_size = MAX_PST;
static int multiplier[MAX_PST] = {[0 ... (MAX_PST - 1)] = 0 };
static int voltage[MAX_PST] = {[0 ... (MAX_PST - 1)] = 0 };
static int switch_latency = 0;
#endif /* CONFIG_X86_POWERNOW_K7_MANUAL */

/* This parameter is used in order to force ACPI instead of legacy method for
 * configuration purpose.
 */

static int acpi_force;

static struct cpufreq_frequency_table *powernow_table;

static unsigned int can_scale_bus;
static unsigned int can_scale_vid;
static unsigned int minimum_speed=-1;
static unsigned int maximum_speed;
static unsigned int number_scales;
static unsigned int fsb=0;
static unsigned int latency;
static char have_a0;

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k7", msg)

static int check_fsb(unsigned int fsbspeed)
{
        int delta;
        unsigned int f = fsb / 1000;

        delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
        return (delta < 5);
}

static int check_powernow(void)
{
        struct cpuinfo_x86 *c = cpu_data;
        unsigned int maxei, eax, ebx, ecx, edx;

        if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
#ifdef MODULE
                printk (KERN_INFO PFX "This module only works with AMD K7 CPUs\n");
#endif
                return 0;
        }

        /* Get maximum capabilities */
        maxei = cpuid_eax (0x80000000);
        if (maxei < 0x80000007) {       /* Any powernow info ? */
#ifdef MODULE
                printk (KERN_INFO PFX "No powernow capabilities detected\n");
#endif
                return 0;
        }

        if ((c->x86_model == 6) && (c->x86_mask == 0)) {
                printk (KERN_INFO PFX "K7 660[A0] core detected, enabling errata workarounds\n");
                have_a0 = 1;
        }

        cpuid(0x80000007, &eax, &ebx, &ecx, &edx);

        /* Check we can actually do something before we say anything.*/
        if (!(edx & (1 << 1 | 1 << 2)))
                return 0;

        printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");

        if (edx & 1 << 1) {
                printk ("frequency");
                can_scale_bus=1;
        }

        if ((edx & (1 << 1 | 1 << 2)) == 0x6)
                printk (" and ");

        if (edx & 1 << 2) {
                printk ("voltage");
                can_scale_vid=1;
        }

        printk (".\n");
        return 1;
}


static int get_ranges (unsigned char *pst)
{
        unsigned int j;
        unsigned int speed;
        u8 fid, vid;

        powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
        if (!powernow_table)
                return -ENOMEM;
        memset(powernow_table, 0, (sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));

        for (j=0 ; j < number_scales; j++) {
                fid = *pst++;

                powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
                powernow_table[j].index = fid; /* lower 8 bits */

                speed = powernow_table[j].frequency;

                if ((fid_codes[fid] % 10)==5) {
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
                        if (have_a0 == 1)
                                powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID;
#endif
                }

                if (speed < minimum_speed)
                        minimum_speed = speed;
                if (speed > maximum_speed)
                        maximum_speed = speed;

                vid = *pst++;
                powernow_table[j].index |= (vid << 8); /* upper 8 bits */

                dprintk ("   FID: 0x%x (%d.%dx [%dMHz])  "
                         "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
                         fid_codes[fid] % 10, speed/1000, vid,
                         mobile_vid_table[vid]/1000,
                         mobile_vid_table[vid]%1000);
        }
        powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
        powernow_table[number_scales].index = 0;

        return 0;
}


static void change_FID(int fid)
{
        union msr_fidvidctl fidvidctl;

        rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
        if (fidvidctl.bits.FID != fid) {
                fidvidctl.bits.SGTC = latency;
                fidvidctl.bits.FID = fid;
                fidvidctl.bits.VIDC = 0;
                fidvidctl.bits.FIDC = 1;
                wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
        }
}


static void change_VID(int vid)
{
        union msr_fidvidctl fidvidctl;

        rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
        if (fidvidctl.bits.VID != vid) {
                fidvidctl.bits.SGTC = latency;
                fidvidctl.bits.VID = vid;
                fidvidctl.bits.FIDC = 0;
                fidvidctl.bits.VIDC = 1;
                wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
        }
}


static void change_speed (unsigned int index)
{
        u8 fid, vid;
        struct cpufreq_freqs freqs;
        union msr_fidvidstatus fidvidstatus;
        int cfid;

        /* fid are the lower 8 bits of the index we stored into
         * the cpufreq frequency table in powernow_decode_bios,
         * vid are the upper 8 bits.
         */

        fid = powernow_table[index].index & 0xFF;
        vid = (powernow_table[index].index & 0xFF00) >> 8;

        freqs.cpu = 0;

        rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
        cfid = fidvidstatus.bits.CFID;
        freqs.old = fsb * fid_codes[cfid] / 10;

        freqs.new = powernow_table[index].frequency;

        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);

        /* Now do the magic poking into the MSRs.  */

        if (have_a0 == 1)       /* A0 errata 5 */
                local_irq_disable();

        if (freqs.old > freqs.new) {
                /* Going down, so change FID first */
                change_FID(fid);
                change_VID(vid);
        } else {
                /* Going up, so change VID first */
                change_VID(vid);
                change_FID(fid);
        }


        if (have_a0 == 1)
                local_irq_enable();

        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}


#ifdef CONFIG_X86_POWERNOW_K7_ACPI

static struct acpi_processor_performance *acpi_processor_perf;

static int powernow_acpi_init(void)
{
        int i;
        int retval = 0;
        union powernow_acpi_control_t pc;

        if (acpi_processor_perf != NULL && powernow_table != NULL) {
                retval = -EINVAL;
                goto err0;
        }

        acpi_processor_perf = kmalloc(sizeof(struct acpi_processor_performance),                                      GFP_KERNEL);

        if (!acpi_processor_perf) {
                retval = -ENOMEM;
                goto err0;
        }

        memset(acpi_processor_perf, 0, sizeof(struct acpi_processor_performance));

        if (acpi_processor_register_performance(acpi_processor_perf, 0)) {
                retval = -EIO;
                goto err1;
        }

        if (acpi_processor_perf->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) {
                retval = -ENODEV;
                goto err2;
        }

        if (acpi_processor_perf->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) {
                retval = -ENODEV;
                goto err2;
        }

        number_scales = acpi_processor_perf->state_count;

        if (number_scales < 2) {
                retval = -ENODEV;
                goto err2;
        }

        powernow_table = kmalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL);
        if (!powernow_table) {
                retval = -ENOMEM;
                goto err2;
        }

        memset(powernow_table, 0, ((number_scales + 1) * sizeof(struct cpufreq_frequency_table)));

        pc.val = (unsigned long) acpi_processor_perf->states[0].control;
        for (i = 0; i < number_scales; i++) {
                u8 fid, vid;
                unsigned int speed;

                pc.val = (unsigned long) acpi_processor_perf->states[i].control;                dprintk ("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
                         i,
                         (u32) acpi_processor_perf->states[i].core_frequency,
                         (u32) acpi_processor_perf->states[i].power,
                         (u32) acpi_processor_perf->states[i].transition_latency,
                         (u32) acpi_processor_perf->states[i].control,
                         pc.bits.sgtc);

                vid = pc.bits.vid;
                fid = pc.bits.fid;

                powernow_table[i].frequency = fsb * fid_codes[fid] / 10;
                powernow_table[i].index = fid; /* lower 8 bits */
                powernow_table[i].index |= (vid << 8); /* upper 8 bits */

                speed = powernow_table[i].frequency;

                if ((fid_codes[fid] % 10)==5) {
                        if (have_a0 == 1)
                                powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
                }

                dprintk ("   FID: 0x%x (%d.%dx [%dMHz])  "
                         "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
                         fid_codes[fid] % 10, speed/1000, vid,
                         mobile_vid_table[vid]/1000,
                         mobile_vid_table[vid]%1000);

                if (latency < pc.bits.sgtc)
                        latency = pc.bits.sgtc;

                if (speed < minimum_speed)
                        minimum_speed = speed;
                if (speed > maximum_speed)
                        maximum_speed = speed;
        }

        powernow_table[i].frequency = CPUFREQ_TABLE_END;
        powernow_table[i].index = 0;

        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);

        return 0;

err2:
        acpi_processor_unregister_performance(acpi_processor_perf, 0);
err1:
        kfree(acpi_processor_perf);
err0:
        printk(KERN_WARNING PFX "ACPI perflib can not be used in this platform\n");
        acpi_processor_perf = NULL;
        return retval;
}
#else
static int powernow_acpi_init(void)
{
        printk(KERN_INFO PFX "no support for ACPI processor found."
               "  Please recompile your kernel with ACPI processor\n");
        return -EINVAL;
}
#endif

#ifdef CONFIG_X86_POWERNOW_K7_MANUAL
static int powernow_manual_settings(union msr_fidvidstatus *fidvidstatus)
{
       int i, k, validentry;
       unsigned int max_multiplier, max_voltage;
       unsigned int speed, cm;
       u8 vid, fid;
       static struct cpufreq_frequency_table *powernow_table_tmp;

       if (switch_latency > 0) {
               if (switch_latency < 100) {
                       printk(KERN_INFO PFX
                              "Settling time passed as %d microseconds."
                              "Should be at least 100. Correcting.\n",
                              switch_latency);
                       switch_latency = 100;
               }
               latency = switch_latency;
       } else {
               latency = 200;
       }
       dprintk("Settling Time: %d microseconds.\n", latency);

       /* get number of specified multipliers */
       number_scales = multiplier_arr_size;
       for (i = 0; i < multiplier_arr_size; i++) {
               if (multiplier[i] == 0) {
                       number_scales = i;
                       break;
               }
       }

       /* get maximum values */
       max_multiplier = fid_codes[fidvidstatus->bits.MFID];
       max_voltage = mobile_vid_table[fidvidstatus->bits.MVID];

       /* allocate memory */
       powernow_table =
           kmalloc((sizeof(struct cpufreq_frequency_table) *
                    (number_scales + 1)), GFP_KERNEL);
       if (!powernow_table)
               return -ENOMEM;
       memset(powernow_table, 0,
              (sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));

       k = 0;
       for (i = 0; i < number_scales; i++) {
               validentry = 0;
               if (multiplier[i] != 0) {
                       /* fix multiplier */
                       if (multiplier[i] < 30)
                               multiplier[i] = multiplier[i] * 10;
                       if (multiplier[i] < max_multiplier) {
                               cm = (multiplier[i] / 10);

                               /* check if odd or even muliplier */
                               if (multiplier[i] % 10) {
                                       /* odd multiplier */
                                       if (cm == 16) {
                                               /* hardcoded because 14.5 and 15.5 fids not possible */
                                               fid = 27;
                                               validentry = 1;
                                       } else if ((cm > 4) && (cm < 14)) {
                                               fid = odd_multiplier[cm - 5];
                                               validentry = 1;
                                       }
                               } else {
                                       /* even_multiplier */
                                       if ((cm < 23) && (cm > 2)) {
                                               fid = even_multiplier[cm - 3];
                                               validentry = 1;
                                       }
                               }
                       }
               }

               if (validentry) {
                       /* if no voltage specified use CPU default */
                       if (voltage[i] == 0)
                               voltage[i] = max_voltage;
                       /* we do not allow higher voltages than the CPU's maximum 925 mV is the minimum */
                       if ((voltage[i] <= max_voltage) && (voltage[i] >= 925)) {                               if (voltage[i] >= 1300) {
                                       vid = 40 - (voltage[i] / 50);
                               } else {
                                       vid = 67 - (voltage[i] / 25);
                               }
                               /* calculate speed */
                               speed = fsb * fid_codes[fid] / 10;
                               powernow_table[k].frequency = speed;
                               powernow_table[k].index = fid;  /*lower 8 bits */                               powernow_table[k].index |= (vid << 8);  /*upper 8 bits */

                               if (speed < minimum_speed)
                                       minimum_speed = speed;
                               if (speed > maximum_speed)
                                       maximum_speed = speed;

                               dprintk("   FID: 0x%x (%d.%dx [%dMHz])\t", fid,
                                       fid_codes[fid] / 10,
                                       fid_codes[fid] % 10, speed / 1000);
                               dprintk("VID: 0x%x (%d.%03dV)\n", vid,
                                       mobile_vid_table[vid] / 1000,
                                       mobile_vid_table[vid] % 1000);
                               k++;
                       }
               } else {
                       // invalid entry
                       dprintk("Entry %d is invalid\n", i + 1);
               }
       }
       if (k < number_scales) {
               /* some entrys were invalid need to realloc table */
               number_scales = k;
               powernow_table_tmp =
                   kmalloc((sizeof(struct cpufreq_frequency_table) *
                            (number_scales + 1)), GFP_KERNEL);
               if (!powernow_table_tmp) {
                       kfree(powernow_table);
                       return -ENOMEM;
               }
               memcpy(powernow_table_tmp, powernow_table,(sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));
               kfree(powernow_table);
               powernow_table = powernow_table_tmp;
       }

       /* Terminate frequency list */
       powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
       powernow_table[number_scales].index = 0;

       return 0;
}
#endif /* CONFIG_X86_POWERNOW_K7_MANUAL */





static int powernow_decode_bios (int maxfid, int startvid)
{
        struct psb_s *psb;
        struct pst_s *pst;
        unsigned int i, j;
        unsigned char *p;
        unsigned int etuple;
        unsigned int ret;

        etuple = cpuid_eax(0x80000001);

        for (i=0xC0000; i < 0xffff0 ; i+=16) {

                p = phys_to_virt(i);

                if (memcmp(p, "AMDK7PNOW!",  10) == 0){
                        dprintk ("Found PSB header at %p\n", p);
                        psb = (struct psb_s *) p;
                        dprintk ("Table version: 0x%x\n", psb->tableversion);
                        if (psb->tableversion != 0x12) {
                                printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n");
                                return -ENODEV;
                        }

                        dprintk ("Flags: 0x%x\n", psb->flags);
                        if ((psb->flags & 1)==0) {
                                dprintk ("Mobile voltage regulator\n");
                        } else {
                                dprintk ("Desktop voltage regulator\n");
                        }

                        latency = psb->settlingtime;
                        if (latency < 100) {
                                printk (KERN_INFO PFX "BIOS set settling time to %d microseconds."
                                                "Should be at least 100. Correcting.\n", latency);
                                latency = 100;
                        }
                        dprintk ("Settling Time: %d microseconds.\n", psb->settlingtime);
                        dprintk ("Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);

                        p += sizeof (struct psb_s);

                        pst = (struct pst_s *) p;

                        for (i = 0 ; i <psb->numpst; i++) {
                                pst = (struct pst_s *) p;
                                number_scales = pst->numpstates;

                                if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) &&
                                    (maxfid==pst->maxfid) && (startvid==pst->startvid))
                                {
                                        dprintk ("PST:%d (@%p)\n", i, pst);
                                        dprintk (" cpuid: 0x%x  fsb: %d  maxFID: 0x%x  startvid: 0x%x\n",
                                                 pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);

                                        ret = get_ranges ((char *) pst + sizeof (struct pst_s));
                                        return ret;

                                } else {
                                        p = (char *) pst + sizeof (struct pst_s);
                                        for (j=0 ; j < number_scales; j++)
                                                p+=2;
                                }
                        }
                        printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple);
                        printk (KERN_INFO PFX "This is indicative of a broken BIOS.\n");

                        return -EINVAL;
                }
                p++;
        }

        return -ENODEV;
}


static int powernow_target (struct cpufreq_policy *policy,
                            unsigned int target_freq,
                            unsigned int relation)
{
        unsigned int newstate;

        if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, relation, &newstate))
                return -EINVAL;

        change_speed(newstate);

        return 0;
}


static int powernow_verify (struct cpufreq_policy *policy)
{
        return cpufreq_frequency_table_verify(policy, powernow_table);
}

/*
 * We use the fact that the bus frequency is somehow
 * a multiple of 100000/3 khz, then we compute sgtc according
 * to this multiple.
 * That way, we match more how AMD thinks all of that work.
 * We will then get the same kind of behaviour already tested under
 * the "well-known" other OS.
 */
static int __init fixup_sgtc(void)
{
        unsigned int sgtc;
        unsigned int m;

        m = fsb / 3333;
        if ((m % 10) >= 5)
                m += 5;

        m /= 10;

        sgtc = 100 * m * latency;
        sgtc = sgtc / 3;
        if (sgtc > 0xfffff) {
                printk(KERN_WARNING PFX "SGTC too large %d\n", sgtc);
                sgtc = 0xfffff;
        }
        return sgtc;
}

static unsigned int powernow_get(unsigned int cpu)
{
        union msr_fidvidstatus fidvidstatus;
        unsigned int cfid;

        if (cpu)
                return 0;
        rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
        cfid = fidvidstatus.bits.CFID;

        return (fsb * fid_codes[cfid] / 10);
}


static int __init acer_cpufreq_pst(struct dmi_system_id *d)
{
        printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident);
        printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
        printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n");
        return 0;
}

/*
 * Some Athlon laptops have really fucked PST tables.
 * A BIOS update is all that can save them.
 * Mention this, and disable cpufreq.
 */
static struct dmi_system_id __initdata powernow_dmi_table[] = {
        {
                .callback = acer_cpufreq_pst,
                .ident = "Acer Aspire",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"),
                        DMI_MATCH(DMI_BIOS_VERSION, "3A71"),
                },
        },
        { }
};

static int __init powernow_cpu_init (struct cpufreq_policy *policy)
{
        union msr_fidvidstatus fidvidstatus;
        int result;

        if (policy->cpu != 0)
                return -ENODEV;

        rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);

#ifdef CONFIG_X86_POWERNOW_K7_MANUAL
       if (fsb) {
               if (fsb < 1000)
                       fsb *= 1000;

               if (fsb < 1000 || fsb > 1000000) {
                       printk(KERN_WARNING PFX "FSB %ukhz out of range\n",
                              fsb);
                       return -EINVAL;
               }
       } else
#endif


        /* A K7 with powernow technology is set to max frequency by BIOS */
        fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];
        if (!fsb) {
                printk(KERN_WARNING PFX "can not determine bus frequency\n");
                return -EINVAL;
        }
        dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000);

        if (dmi_check_system(powernow_dmi_table) || acpi_force) {
                printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
                result = powernow_acpi_init();
#ifdef CONFIG_X86_POWERNOW_K7_MANUAL
        } else if (overwrite_table) {
                printk(KERN_INFO PFX
                       "Overwriting PST table with manual settings\n");
                result = powernow_manual_settings(&fidvidstatus);
#endif
        } else {
                result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
                if (result) {
                        printk (KERN_INFO PFX "Trying ACPI perflib\n");
                        maximum_speed = 0;
                        minimum_speed = -1;
                        latency = 0;
                        result = powernow_acpi_init();
                        if (result) {
                                printk (KERN_INFO PFX "ACPI and legacy methods failed\n");
                                printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml\n");
                        }
                } else {
                        /* SGTC use the bus clock as timer */
                        latency = fixup_sgtc();
                        printk(KERN_INFO PFX "SGTC: %d\n", latency);
                }
        }

        if (result)
                return result;

        printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
                                minimum_speed/1000, maximum_speed/1000);

        policy->governor = CPUFREQ_DEFAULT_GOVERNOR;

        policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency);

        policy->cur = powernow_get(0);

        cpufreq_frequency_table_get_attr(powernow_table, policy->cpu);

        return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
}

static int powernow_cpu_exit (struct cpufreq_policy *policy) {
        cpufreq_frequency_table_put_attr(policy->cpu);

#ifdef CONFIG_X86_POWERNOW_K7_ACPI
        if (acpi_processor_perf) {
                acpi_processor_unregister_performance(acpi_processor_perf, 0);
                kfree(acpi_processor_perf);
        }
#endif

        if (powernow_table)
                kfree(powernow_table);

        return 0;
}

static struct freq_attr* powernow_table_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
        NULL,
};

static struct cpufreq_driver powernow_driver = {
        .verify = powernow_verify,
        .target = powernow_target,
        .get    = powernow_get,
        .init   = powernow_cpu_init,
        .exit   = powernow_cpu_exit,
        .name   = "powernow-k7",
        .owner  = THIS_MODULE,
        .attr   = powernow_table_attr,
};

static int __init powernow_init (void)
{
        if (check_powernow()==0)
                return -ENODEV;
        return cpufreq_register_driver(&powernow_driver);
}


static void __exit powernow_exit (void)
{
        cpufreq_unregister_driver(&powernow_driver);
}

module_param(acpi_force,  int, 0444);
MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");

#ifdef CONFIG_X86_POWERNOW_K7_MANUAL
module_param(overwrite_table, int, 0444);
MODULE_PARM_DESC(overwrite_table, "overwrite table with manually settings");
module_param(fsb, uint, 0444);
MODULE_PARM_DESC(fsb, "(MHz) overrides the calculated FSB");
module_param_array(multiplier, int, &multiplier_arr_size, 0444);
MODULE_PARM_DESC(multiplier,
                "Specifiy up to 10 multipliers, multiply them by 10: 5->50, 5.5->55");
module_param_array(voltage, int, &voltage_arr_size, 0444);
MODULE_PARM_DESC(voltage,
                "Specify voltages in respect to the given multipliers, specify them in mV: 1.275V -> 1275");
module_param(switch_latency, int, 0444);
MODULE_PARM_DESC(switch_latency,
                "Set state transition latency in microseconds (default 200us)");#endif


MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
MODULE_LICENSE ("GPL");

late_initcall(powernow_init);
module_exit(powernow_exit);


scusate se posto i file interni.. però magari possono tornare utili a qualcuno
(tra l'altro le patch si trovano solo per kernel vecchi mentre questo funziona sull'ultima versione 2.6.11-gentoo-r9)

poi dal menuconfig:
Code:

                       <M> AMD Mobile Athlon/Duron PowerNow!                                                     
                       [*] Manual setting of PowerNow! table for AMD Mobile Athlon/Duron.   


e poi basta richiamare il modulo con parametri del tipo
Code:

modprobe powernow-k7 overwrite_table=1 multiplier=6,7,8,9,10 fsb=200


le opzioni complete sono:
overwrite_table:
activates the manually settings, set it to >=1

multiplier:
specifies an array of multipliers

voltage:
specifies an array of VCore voltages (default BIOS settings)

switch_latency:
sets the state transition latency in microseconds (default 200us)

fsb:
sets the frontsidebus (default calculated from BIOS settings)


e... tadà:
Code:

omega linux # dmesg | grep powernow
powernow: PowerNOW! Technology present. Can scale: frequency and voltage.
powernow: Overwriting PST table with manual settings
powernow: Minimum speed 1200 MHz. Maximum speed 2000 MHz.
omega linux #


poi basta un qualsiasi programma per il dynamic cpu frequency scaling :twisted:
_________________
Linux Registered User n.340423
Linux User Group Ischia
www.tush.it
Back to top
View user's profile Send private message
federico
Advocate
Advocate


Joined: 18 Feb 2003
Posts: 3272
Location: Italy, Milano

PostPosted: Mon May 30, 2005 1:24 am    Post subject: Reply with quote

Mio fratello ha scritto ieri un demone che fa dello scaling governor basato anche sulla temperatura, se in compilazione il suo amd64 arriva a 90° allora scala la frequenza, poi rilascia la velocita' quando si e' un po' raffreddato, e via dicendo, con un controllo abbastanza intelligente sulla cosa che pero' ora non saprei spiegarlo bene come lo ha detto lui...
_________________
Sideralis www.sideralis.org
Pic http://blackman.amicofigo.com/gallery
Arduino http://www.arduino.cc
Chi aveva potuto aveva spaccato
2000 pezzi buttati là
Molti saluti,qualche domanda
Semplice come musica punk
Back to top
View user's profile Send private message
johnnystuff
Tux's lil' helper
Tux's lil' helper


Joined: 28 Aug 2003
Posts: 141

PostPosted: Fri Jun 03, 2005 8:50 pm    Post subject: Reply with quote

ehi federico nessuna novità da tuo fratello? Mi sembra una cosa interessante....famme sapè.
:wink:
Back to top
View user's profile Send private message
federico
Advocate
Advocate


Joined: 18 Feb 2003
Posts: 3272
Location: Italy, Milano

PostPosted: Fri Jun 03, 2005 8:57 pm    Post subject: Reply with quote

Come ha scritto mio fratello in un altro post qualche giorno fa:

Riquito wrote:

Ciao [starter del topic],
ho una acer1524wlmi, con processore AMD64 3400+ e da un po' di tempo a questa parte mi succeda la tua stessa cosa: in fase di compilazione medio/lunga o grosso sforzo si surriscalda e va in protezione. giusto due giorni fa ho scritto uno script in python, di buona fattura :) , che ti propongo.

Controlla il trip_point, e se la temperatura della cpu raggiunge trip_point-15 gradi passa in userspace e setta la frequenza alla prima più bassa disponibile. se dopo due secondi la temperatura e' ancora sopra il livello consentito, scala di nuovo, e così via sino a raggiungere eventualmente il minimo.
Quando la temperatura raggiunge i 65 gradi torna in ondemand, e se scende sotto i 52 la controlla ogni 20 secondi, e non piu' 2.
L'accesso ai file di proc avviene solo dopo averli lockati con fcntl, per non avere problemi con altre risorse che accedono agli stessi file.
Una volta lanciato l'applicativo principale, check_temp.py, diventa un demone conforme agli standard unix.

La libreria che usa, cpulib.py, puo' essere eseguita standalone per avere informazioni generiche sulla cpu.
(mmm, lanciala con "python cpulib.py", non ricordo se ho messo la shebang)

Prima di usare il programma, per sicurezza dato che non ho fatto 1000 controlli, lanciare cpulib.py e controllare che nell'output ci siano
trip_point
userspace e ondemand nei governor disponibili

Ah, io presuppongo che in generale sia ondemand il governor in uso, quindi quando la cpu e' "fredda" setto come governor ondemand.

Puoi trovare lo script a questo indirizzo.
http://www.sideralis.net/download/temp_proc.tar.bz2

Salva tutto in una directory e poi aggiungi la path di check_temp.py al tuo local.start

Ciao,
Riccardo

p.s.
ho modificato il programma: ora torna in ondemand facendo controlli incrociati tra average della cpu e temperatura

_________________
Sideralis www.sideralis.org
Pic http://blackman.amicofigo.com/gallery
Arduino http://www.arduino.cc
Chi aveva potuto aveva spaccato
2000 pezzi buttati là
Molti saluti,qualche domanda
Semplice come musica punk
Back to top
View user's profile Send private message
skakz
Guru
Guru


Joined: 03 Jul 2004
Posts: 380
Location: Ischia/Napoli/Italia/Terra

PostPosted: Fri Jun 03, 2005 9:23 pm    Post subject: Reply with quote

grazie,
io per ora sto usando speedfreq in modalità dynamic ossia alza la frequenza del processore solo quando richiesto,
però questo script mi sembra una vera furbata. lo provo subito e magari lascio anche un commento
ancora grazie
_________________
Linux Registered User n.340423
Linux User Group Ischia
www.tush.it
Back to top
View user's profile Send private message
newred
n00b
n00b


Joined: 24 Aug 2006
Posts: 25

PostPosted: Thu Aug 24, 2006 4:13 pm    Post subject: Reply with quote

Ciao a tutti ... sono nuovo del forum e di gentoo
Sto per allestire un serverino per casa e vorrei una conferma prima di stravolgere tutto....
Con una mb dfi infinity con nforce2 e un xp-m riesco ad avere una gestione dinamica del clock della cpu??
Sto per acquistare un xp-m 2400+ e prima di confermare vorrei essere sicuro che faccia al caso mio....

Grazie

Bye
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Forum italiano (Italian) Risorse italiane (documentazione e tools) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum