Opteron revision F will support higher frequencies than
can be encoded in the current driver's 4 bit frequency field. This patch updates the driver to support Rev F including 6 bit FIDs and processor ID updates. This should apply cleanly whether or not the dual-core bugfix I sent out last week is applied. I'd prefer that both get applied, of course. Signed-off-by: David Keck <david.keck@amd.com> Signed-off-by: Mark Langsdorf <mark.langsdorf@amd.com> Signed-off-by: Dave Jones <davej@redhat.com>
This commit is contained in:
parent
03938c3f10
commit
841e40b380
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* (c) 2003, 2004 Advanced Micro Devices, Inc.
|
* (c) 2003, 2004, 2005 Advanced Micro Devices, Inc.
|
||||||
* Your use of this code is subject to the terms and conditions of the
|
* Your use of this code is subject to the terms and conditions of the
|
||||||
* GNU general public license version 2. See "COPYING" or
|
* GNU general public license version 2. See "COPYING" or
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
#define PFX "powernow-k8: "
|
#define PFX "powernow-k8: "
|
||||||
#define BFX PFX "BIOS error: "
|
#define BFX PFX "BIOS error: "
|
||||||
#define VERSION "version 1.40.4"
|
#define VERSION "version 1.50.3"
|
||||||
#include "powernow-k8.h"
|
#include "powernow-k8.h"
|
||||||
|
|
||||||
/* serialize freq changes */
|
/* serialize freq changes */
|
||||||
|
@ -232,7 +232,7 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
|
||||||
/*
|
/*
|
||||||
* Reduce the vid by the max of step or reqvid.
|
* Reduce the vid by the max of step or reqvid.
|
||||||
* Decreasing vid codes represent increasing voltages:
|
* Decreasing vid codes represent increasing voltages:
|
||||||
* vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of 0x1f is off.
|
* vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off.
|
||||||
*/
|
*/
|
||||||
static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step)
|
static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step)
|
||||||
{
|
{
|
||||||
|
@ -467,7 +467,7 @@ static int check_supported_cpu(unsigned int cpu)
|
||||||
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
|
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
|
||||||
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
|
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
|
||||||
((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
|
((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
|
||||||
((eax & CPUID_XMOD) > CPUID_XMOD_REV_E)) {
|
((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) {
|
||||||
printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
|
printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -696,6 +696,7 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned
|
||||||
|
|
||||||
data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
|
data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
|
||||||
data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK;
|
data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK;
|
||||||
|
data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
|
||||||
data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
|
data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
|
||||||
data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK);
|
data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK);
|
||||||
data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK;
|
data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK;
|
||||||
|
@ -735,8 +736,13 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < data->acpi_data.state_count; i++) {
|
for (i = 0; i < data->acpi_data.state_count; i++) {
|
||||||
u32 fid = data->acpi_data.states[i].control & FID_MASK;
|
if (data->exttype) {
|
||||||
u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
|
u32 fid = data->acpi_data.states[i].status & FID_MASK;
|
||||||
|
u32 vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK;
|
||||||
|
} else {
|
||||||
|
u32 fid = data->acpi_data.states[i].control & FID_MASK;
|
||||||
|
u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
|
dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
|
||||||
|
|
||||||
|
@ -753,7 +759,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* verify voltage is OK - BIOSs are using "off" to indicate invalid */
|
/* verify voltage is OK - BIOSs are using "off" to indicate invalid */
|
||||||
if (vid == 0x1f) {
|
if (vid == VID_OFF) {
|
||||||
dprintk("invalid vid %u, ignoring\n", vid);
|
dprintk("invalid vid %u, ignoring\n", vid);
|
||||||
powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
|
powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
|
||||||
continue;
|
continue;
|
||||||
|
@ -930,15 +936,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
|
||||||
|
|
||||||
down(&fidvid_sem);
|
down(&fidvid_sem);
|
||||||
|
|
||||||
for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
|
|
||||||
/* make sure the sibling is initialized */
|
|
||||||
if (!powernow_data[i]) {
|
|
||||||
ret = 0;
|
|
||||||
up(&fidvid_sem);
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
powernow_k8_acpi_pst_values(data, newstate);
|
powernow_k8_acpi_pst_values(data, newstate);
|
||||||
|
|
||||||
if (transition_frequency(data, newstate)) {
|
if (transition_frequency(data, newstate)) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* (c) 2003, 2004 Advanced Micro Devices, Inc.
|
* (c) 2003, 2004, 2005 Advanced Micro Devices, Inc.
|
||||||
* Your use of this code is subject to the terms and conditions of the
|
* Your use of this code is subject to the terms and conditions of the
|
||||||
* GNU general public license version 2. See "COPYING" or
|
* GNU general public license version 2. See "COPYING" or
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
@ -19,6 +19,7 @@ struct powernow_k8_data {
|
||||||
u32 vidmvs; /* usable value calculated from mvs */
|
u32 vidmvs; /* usable value calculated from mvs */
|
||||||
u32 vstable; /* voltage stabilization time, units 20 us */
|
u32 vstable; /* voltage stabilization time, units 20 us */
|
||||||
u32 plllock; /* pll lock time, units 1 us */
|
u32 plllock; /* pll lock time, units 1 us */
|
||||||
|
u32 exttype; /* extended interface = 1 */
|
||||||
|
|
||||||
/* keep track of the current fid / vid */
|
/* keep track of the current fid / vid */
|
||||||
u32 currvid, currfid;
|
u32 currvid, currfid;
|
||||||
|
@ -41,7 +42,7 @@ struct powernow_k8_data {
|
||||||
#define CPUID_XFAM 0x0ff00000 /* extended family */
|
#define CPUID_XFAM 0x0ff00000 /* extended family */
|
||||||
#define CPUID_XFAM_K8 0
|
#define CPUID_XFAM_K8 0
|
||||||
#define CPUID_XMOD 0x000f0000 /* extended model */
|
#define CPUID_XMOD 0x000f0000 /* extended model */
|
||||||
#define CPUID_XMOD_REV_E 0x00020000
|
#define CPUID_XMOD_REV_F 0x00040000
|
||||||
#define CPUID_USE_XFAM_XMOD 0x00000f00
|
#define CPUID_USE_XFAM_XMOD 0x00000f00
|
||||||
#define CPUID_GET_MAX_CAPABILITIES 0x80000000
|
#define CPUID_GET_MAX_CAPABILITIES 0x80000000
|
||||||
#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
|
#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
|
||||||
|
@ -57,25 +58,26 @@ struct powernow_k8_data {
|
||||||
|
|
||||||
/* Field definitions within the FID VID Low Control MSR : */
|
/* Field definitions within the FID VID Low Control MSR : */
|
||||||
#define MSR_C_LO_INIT_FID_VID 0x00010000
|
#define MSR_C_LO_INIT_FID_VID 0x00010000
|
||||||
#define MSR_C_LO_NEW_VID 0x00001f00
|
#define MSR_C_LO_NEW_VID 0x00003f00
|
||||||
#define MSR_C_LO_NEW_FID 0x0000002f
|
#define MSR_C_LO_NEW_FID 0x0000003f
|
||||||
#define MSR_C_LO_VID_SHIFT 8
|
#define MSR_C_LO_VID_SHIFT 8
|
||||||
|
|
||||||
/* Field definitions within the FID VID High Control MSR : */
|
/* Field definitions within the FID VID High Control MSR : */
|
||||||
#define MSR_C_HI_STP_GNT_TO 0x000fffff
|
#define MSR_C_HI_STP_GNT_TO 0x000fffff
|
||||||
|
|
||||||
/* Field definitions within the FID VID Low Status MSR : */
|
/* Field definitions within the FID VID Low Status MSR : */
|
||||||
#define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */
|
#define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */
|
||||||
#define MSR_S_LO_MAX_RAMP_VID 0x1f000000
|
#define MSR_S_LO_MAX_RAMP_VID 0x3f000000
|
||||||
#define MSR_S_LO_MAX_FID 0x003f0000
|
#define MSR_S_LO_MAX_FID 0x003f0000
|
||||||
#define MSR_S_LO_START_FID 0x00003f00
|
#define MSR_S_LO_START_FID 0x00003f00
|
||||||
#define MSR_S_LO_CURRENT_FID 0x0000003f
|
#define MSR_S_LO_CURRENT_FID 0x0000003f
|
||||||
|
|
||||||
/* Field definitions within the FID VID High Status MSR : */
|
/* Field definitions within the FID VID High Status MSR : */
|
||||||
#define MSR_S_HI_MAX_WORKING_VID 0x001f0000
|
#define MSR_S_HI_MIN_WORKING_VID 0x3f000000
|
||||||
#define MSR_S_HI_START_VID 0x00001f00
|
#define MSR_S_HI_MAX_WORKING_VID 0x003f0000
|
||||||
#define MSR_S_HI_CURRENT_VID 0x0000001f
|
#define MSR_S_HI_START_VID 0x00003f00
|
||||||
#define MSR_C_HI_STP_GNT_BENIGN 0x00000001
|
#define MSR_S_HI_CURRENT_VID 0x0000003f
|
||||||
|
#define MSR_C_HI_STP_GNT_BENIGN 0x00000001
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are restrictions frequencies have to follow:
|
* There are restrictions frequencies have to follow:
|
||||||
|
@ -99,13 +101,15 @@ struct powernow_k8_data {
|
||||||
#define MIN_FREQ_RESOLUTION 200 /* fids jump by 2 matching freq jumps by 200 */
|
#define MIN_FREQ_RESOLUTION 200 /* fids jump by 2 matching freq jumps by 200 */
|
||||||
|
|
||||||
#define MAX_FID 0x2a /* Spec only gives FID values as far as 5 GHz */
|
#define MAX_FID 0x2a /* Spec only gives FID values as far as 5 GHz */
|
||||||
#define LEAST_VID 0x1e /* Lowest (numerically highest) useful vid value */
|
#define LEAST_VID 0x3e /* Lowest (numerically highest) useful vid value */
|
||||||
|
|
||||||
#define MIN_FREQ 800 /* Min and max freqs, per spec */
|
#define MIN_FREQ 800 /* Min and max freqs, per spec */
|
||||||
#define MAX_FREQ 5000
|
#define MAX_FREQ 5000
|
||||||
|
|
||||||
#define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */
|
#define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */
|
||||||
#define INVALID_VID_MASK 0xffffffe0 /* not a valid vid if these bits are set */
|
#define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */
|
||||||
|
|
||||||
|
#define VID_OFF 0x3f
|
||||||
|
|
||||||
#define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */
|
#define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue