--- arch/i386/kernel/cpu/cpufreq/powernow-k8.c.orig 2008-07-06 04:24:21.000000000 +0900 +++ arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2008-07-06 14:38:27.000000000 +0900 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,15 @@ #define VERSION "version 2.20.00" #include "powernow-k8.h" +static int vcore_list[16] = { 1100,1050,1000,950,900,0 }; +static int vcore_list_count = 5; +//module_param_array(vcore_list, int, &vcore_list_count, 0644); +//MODULE_PARM_DESC(vcore_list, "List of new voltages to use, order must match freq_list"); + +static int freq_list[16] = { 2300,2200,2000,1800,1000,0 }; +static int freq_list_count = 5; +//module_param_array(freq_list, int, &freq_list_count, 0644); +//MODULE_PARM_DESC(freq_list, "List of new frequencies to use, order must match vcore_list"); /* serialize freq changes */ static DEFINE_MUTEX(fidvid_mutex); @@ -78,6 +88,12 @@ } +/* Return fid from a frequency in MHz */ +static u32 find_fid_from_freq(u32 freq) +{ + return (freq - 800) / 100; +} + /* Return a frequency in KHz, given an input fid */ static u32 find_khz_freq_from_fid(u32 fid) { @@ -89,6 +105,12 @@ return data[pstate].frequency; } +/* Return a vid from a voltage in mV */ +static u32 find_vid_from_millivolts(u32 vcore) +{ + return (1550-vcore)/25; +} + /* Return the vco fid for an input fid * * Each "low" fid has corresponding "high" fid, and you can get to "low" fids @@ -628,6 +650,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) { + printk(KERN_INFO PFX "fill_powernow_table() entry"); struct cpufreq_frequency_table *powernow_table; unsigned int j; @@ -651,13 +674,17 @@ if (check_pst_table(data, pst, maxvid)) return -EINVAL; - powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) - * (data->numps + 1)), GFP_KERNEL); + if ( freq_list_count > data->numps ) + data->numps = freq_list_count; + + powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (data->numps + 1)), GFP_KERNEL); + if (!powernow_table) { printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); return -ENOMEM; } + if ( ( vcore_list_count <= 1 ) || ( freq_list_count <= 1 ) ) { for (j = 0; j < data->numps; j++) { powernow_table[j].index = pst[j].fid; /* lower 8 bits */ powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */ @@ -665,13 +692,34 @@ } powernow_table[data->numps].frequency = CPUFREQ_TABLE_END; powernow_table[data->numps].index = 0; + printk(KERN_INFO PFX "Wrong fucking side of things vcore:%d, freq:%d.\n", + vcore_list_count, + freq_list_count); + } + else { + for (j = 0; j < freq_list_count ; j++) { + printk(KERN_INFO PFX "PTL: Requested %dMHz with %dmV\n", + freq_list[j], + vcore_list[j]); + powernow_table[j].index = find_fid_from_freq(freq_list[j]); + powernow_table[j].index |= (find_vid_from_millivolts(vcore_list[j]) << 8); + powernow_table[j].frequency = find_khz_freq_from_fid(find_fid_from_freq(freq_list[j])); + + + } /* for ( freq_list_count )*/ + printk(KERN_INFO PFX "PTL: Performed required adjustments.\n"); + powernow_table[freq_list_count].frequency = CPUFREQ_TABLE_END; + powernow_table[freq_list_count].index = 0; + } + + if (query_current_values_with_pending_wait(data)) { kfree(powernow_table); return -EIO; } - dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); + printk(KERN_INFO PFX "cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); data->powernow_table = powernow_table; print_basics(data); @@ -679,7 +727,7 @@ if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid)) return 0; - dprintk("currfid/vid do not match PST, ignoring\n"); + printk(KERN_INFO PFX "currfid/vid do not match PST, ignoring\n"); return 0; } @@ -841,8 +889,11 @@ } /* fill in data->powernow_table */ - powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) - * (data->acpi_data->state_count + 1)), GFP_KERNEL); + if ( freq_list_count > data->acpi_data->state_count ) + data->acpi_data->state_count = freq_list_count; + + powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (data->acpi_data->state_count + 1)), GFP_KERNEL); + if (!powernow_table) { dprintk("powernow_table memory alloc failure\n"); goto err_out; @@ -938,9 +989,15 @@ dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); - powernow_table[i].index = fid; /* lower 8 bits */ - powernow_table[i].index |= (vid << 8); /* upper 8 bits */ - powernow_table[i].frequency = find_khz_freq_from_fid(fid); + /* powernow_table[i].index = fid; lower 8 bits + powernow_table[i].index |= (vid << 8); upper 8 bits + powernow_table[i].frequency = find_khz_freq_from_fid(fid);*/ + printk(KERN_INFO PFX "Requested %dMHz with %dmV\n", + freq_list[i], + vcore_list[i]); + powernow_table[i].index = find_fid_from_freq(freq_list[i]); + powernow_table[i].index |= (find_vid_from_millivolts(vcore_list[i]) << 8); + powernow_table[i].frequency = find_khz_freq_from_fid(find_fid_from_freq(freq_list[i])); /* verify frequency is OK */ if ((powernow_table[i].frequency > (MAX_FREQ * 1000)) || @@ -978,6 +1035,7 @@ printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", powernow_table[i].frequency, (unsigned int) (data->acpi_data->states[i].core_frequency * 1000)); + if ( ( freq_list_count <= 1 ) || ( !freq_list_count ) ) powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; continue; }