[CPUFREQ] Powernow-k8: support family 0xf with 2 low p-states
authorMark Langsdorf <mark.langsdorf@amd.com>
Sun, 26 Jul 2009 15:55:25 +0000 (10:55 -0500)
committerDave Jones <davej@redhat.com>
Tue, 7 Jul 2009 01:38:29 +0000 (21:38 -0400)
Provide support for family 0xf processors with 2 P-states
below the elevator voltage.  Remove the checks that prevent
this configuration from being supported and increase the
transition voltage to prevent errors during the transition.

Signed-off-by: Mark Langsdorf <mark.langsdorf@amd.com>
Signed-off-by: Dave Jones <davej@redhat.com>
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.h

index 81cbe64ed6b49a79e8e3aa8b339a6a8b4cf2d202..ae068f59603f48f6bd5ebee5fd9a8f6a3bf152fc 100644 (file)
@@ -299,7 +299,7 @@ static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
 static int transition_fid_vid(struct powernow_k8_data *data,
                u32 reqfid, u32 reqvid)
 {
-       if (core_voltage_pre_transition(data, reqvid))
+       if (core_voltage_pre_transition(data, reqvid, reqfid))
                return 1;
 
        if (core_frequency_transition(data, reqfid))
@@ -327,17 +327,20 @@ static int transition_fid_vid(struct powernow_k8_data *data,
 
 /* Phase 1 - core voltage transition ... setup voltage */
 static int core_voltage_pre_transition(struct powernow_k8_data *data,
-               u32 reqvid)
+               u32 reqvid, u32 reqfid)
 {
        u32 rvosteps = data->rvo;
        u32 savefid = data->currfid;
-       u32 maxvid, lo;
+       u32 maxvid, lo, rvomult = 1;
 
        dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
                "reqvid 0x%x, rvo 0x%x\n",
                smp_processor_id(),
                data->currfid, data->currvid, reqvid, data->rvo);
 
+       if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP))
+               rvomult = 2;
+       rvosteps *= rvomult;
        rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
        maxvid = 0x1f & (maxvid >> 16);
        dprintk("ph1 maxvid=0x%x\n", maxvid);
@@ -351,7 +354,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data,
                        return 1;
        }
 
-       while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) {
+       while ((rvosteps > 0) &&
+                       ((rvomult * data->rvo + data->currvid) > reqvid)) {
                if (data->currvid == maxvid) {
                        rvosteps = 0;
                } else {
@@ -384,13 +388,6 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
        u32 vcoreqfid, vcocurrfid, vcofiddiff;
        u32 fid_interval, savevid = data->currvid;
 
-       if ((reqfid < HI_FID_TABLE_BOTTOM) &&
-           (data->currfid < HI_FID_TABLE_BOTTOM)) {
-               printk(KERN_ERR PFX "ph2: illegal lo-lo transition "
-                               "0x%x 0x%x\n", reqfid, data->currfid);
-               return 1;
-       }
-
        if (data->currfid == reqfid) {
                printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
                                data->currfid);
@@ -407,6 +404,9 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
        vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
            : vcoreqfid - vcocurrfid;
 
+       if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP))
+               vcofiddiff = 0;
+
        while (vcofiddiff > 2) {
                (data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
 
@@ -1081,14 +1081,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
                return 0;
        }
 
-       if ((fid < HI_FID_TABLE_BOTTOM) &&
-           (data->currfid < HI_FID_TABLE_BOTTOM)) {
-               printk(KERN_ERR PFX
-                      "ignoring illegal change in lo freq table-%x to 0x%x\n",
-                      data->currfid, fid);
-               return 1;
-       }
-
        dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n",
                smp_processor_id(), fid, vid);
        freqs.old = find_khz_freq_from_fid(data->currfid);
index c9c1190b5e1f057fb30652132225443c2ba2da58..02ce824073cb9463e33e0fb5a32d7f7e60814b2f 100644 (file)
@@ -215,7 +215,8 @@ struct pst_s {
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg)
 
-static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid);
+static int core_voltage_pre_transition(struct powernow_k8_data *data,
+       u32 reqvid, u32 regfid);
 static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid);
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);