Yes, I know this has been NACKed several times. Yes, I know this isn't ever going into mainline. But likely I'm not the only one whose BIOS completely lacks any ACPI voltage tables, so posting the patch here gives fellow sufferers the chance to stumble over it. I took one of the several patches floating around that implement Intel Pentium-M Dothan support in speedstep-centrino (don't know who wrote it originally), and after some maintanance tried to add the C0 stepping and the LV/ULV models. I got the tables from a datasheet available on Intel's homepage. It's been said > It's not as if the bios people remove random states... that's work. > They only change such things if they really really have to... and > It's a BAD IDEA to then add that state back via the back door! but if your BIOS lacks any P-states at all, this seems the only way (until you get a better BIOS). It's been said > [...] great if your system is wired up to use VID#C, > but what if it isn't ? It's got a 1 in 4 chance [...] but as I understand it those VID#X columns in Intel's tables are different power profiles depending on CPU and other component tolerances. If always using the highest voltage i.e. worst case profile, this may draw more power than necassary, but I guess it should be the safe choice. Quote from Intel's datasheet >> Individual processor VID values may be calibrated during >> manufacturing such that two devices at the same speed may >> have different VID settings. Besides selecting the highest voltage per default, made it depend on CONFIG_EXPERIMENTAL so not to > "give people semi-automatic weapons to shoot their feet off with" I'll still reject all responsibility if you manage to blow up your hardware with this. I even retain the right to laugh at you. :-) GPL, provided "as is", use at own risk. --- --- linux-2.6.27.28/arch/x86/kernel/cpu/cpufreq/Kconfig +++ speedstep-centrino_for_dothan/arch/x86/kernel/cpu/cpufreq/Kconfig @@ -143,12 +143,14 @@ If in doubt, say N. config X86_SPEEDSTEP_CENTRINO_TABLE - bool "Built-in tables for Banias CPUs" - depends on X86_32 && X86_SPEEDSTEP_CENTRINO - default y + bool "Built-in tables for Banias/Dothan CPUs (EXPERIMENTAL)" + depends on X86_32 && X86_SPEEDSTEP_CENTRINO && EXPERIMENTAL + default n help - Use built-in tables for Banias CPUs if ACPI encoding + Use built-in tables for Banias and Dothan CPUs if ACPI encoding is not available. + As this is highly hardware dependent, enabling this may make your + system unstable. Use at your own risk. If in doubt, say N. --- linux-2.6.27.28/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ speedstep-centrino_for_dothan/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -44,7 +44,8 @@ CPU_BANIAS, CPU_DOTHAN_A1, CPU_DOTHAN_A2, - CPU_DOTHAN_B0, + CPU_DOTHAN_Bx, + CPU_DOTHAN_C0, CPU_MP4HT_D0, CPU_MP4HT_E0, }; @@ -53,7 +54,8 @@ [CPU_BANIAS] = { 6, 9, 5 }, [CPU_DOTHAN_A1] = { 6, 13, 1 }, [CPU_DOTHAN_A2] = { 6, 13, 2 }, - [CPU_DOTHAN_B0] = { 6, 13, 6 }, + [CPU_DOTHAN_Bx] = { 6, 13, 6 }, + [CPU_DOTHAN_C0] = { 6, 13, 8 }, [CPU_MP4HT_D0] = {15, 3, 4 }, [CPU_MP4HT_E0] = {15, 4, 1 }, }; @@ -194,6 +196,198 @@ OP(1700, 1484), { .frequency = CPUFREQ_TABLE_END } }; + +#undef OP + +/* Dothan processor datasheet 30218908.pdf defines 4 voltages for most + frequencies (usually VID#A - VID#D) - this macro allows us to define all + of these but we only use the highest voltages at compile time - this may + need some work if we want to select the voltage profile at runtime. */ + +#define OP(mhz, mva, mvb, mvc, mvd) \ + { \ + .frequency = (mhz) * 1000, \ + .index = (((mhz)/100) << 8) | ((mva - 700) / 16) \ + } + +/* Intel Pentium M processor 723 (Ultra Low Voltage) / 1.00GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_723[] = +{ + OP( 600, 812, 812, 812, 812), + OP( 800, 876, 876, 876, 876), + OP( 900, 908, 908, 908, 908), + OP(1000, 940, 940, 940, 940), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 733 (Ultra Low Voltage) / 1.10GHz (Dothan B1) */ +static struct cpufreq_frequency_table dothan_733[] = +{ + OP( 600, 812, 812, 812, 812), + OP( 800, 876, 876, 876, 876), + OP( 900, 892, 892, 892, 892), + OP(1000, 924, 924, 924, 924), + OP(1100, 940, 940, 940, 940), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 733J (Ultra Low Voltage) / 1.10GHz (Dothan C0) */ +static struct cpufreq_frequency_table dothan_733J[] = +{ /* VID#G VID#H VID#J VID#L */ + OP( 600, 812, 812, 812, 812), + OP( 800, 876, 876, 860, 844), + OP( 900, 908, 892, 876, 860), + OP(1000, 940, 924, 892, 876), + OP(1100, 956, 940, 908, 876), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 753 (Ultra Low Voltage) / 1.20GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_753[] = +{ /* VID#G VID#H VID#J VID#L */ + OP( 600, 812, 812, 812, 812), + OP( 800, 860, 860, 844, 844), + OP( 900, 892, 876, 860, 844), + OP(1000, 908, 908, 876, 860), + OP(1100, 940, 924, 892, 876), + OP(1200, 956, 940, 908, 876), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 773 (Ultra Low Voltage) / 1.30GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_773[] = +{ /* VID#G VID#H VID#J VID#L */ + OP( 600, 812, 812, 812, 812), + OP( 800, 860, 860, 844, 844), + OP( 900, 876, 876, 860, 844), + OP(1000, 908, 892, 876, 860), + OP(1100, 924, 908, 892, 860), + OP(1200, 940, 924, 908, 876), + OP(1300, 956, 940, 908, 876), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 738 (Low Voltage) / 1.40GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_738[] = +{ + OP( 600, 988, 988, 988, 988), + OP( 800, 1020, 1020, 1020, 1020), + OP( 900, 1036, 1036, 1036, 1036), + OP(1000, 1052, 1052, 1052, 1052), + OP(1100, 1068, 1068, 1068, 1068), + OP(1200, 1100, 1100, 1100, 1100), + OP(1300, 1116, 1116, 1116, 1116), + OP(1400, 1116, 1116, 1116, 1116), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 758 (Low Voltage) / 1.50GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_758[] = +{ + OP( 600, 988, 988, 988, 988), + OP( 800, 1020, 1020, 1020, 1020), + OP( 900, 1036, 1036, 1036, 1036), + OP(1000, 1052, 1052, 1052, 1052), + OP(1100, 1068, 1068, 1068, 1068), + OP(1200, 1084, 1084, 1084, 1084), + OP(1300, 1100, 1100, 1100, 1100), + OP(1400, 1116, 1116, 1116, 1116), + OP(1500, 1116, 1116, 1116, 1116), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 778 (Low Voltage) / 1.60GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_778[] = +{ + OP( 600, 988, 988, 988, 988), + OP( 800, 1020, 1020, 1020, 1020), + OP( 900, 1036, 1036, 1036, 1036), + OP(1000, 1052, 1052, 1052, 1052), + OP(1100, 1052, 1052, 1052, 1052), + OP(1200, 1068, 1068, 1068, 1068), + OP(1300, 1084, 1084, 1084, 1084), + OP(1400, 1100, 1100, 1100, 1100), + OP(1500, 1116, 1116, 1116, 1116), + OP(1600, 1116, 1116, 1116, 1116), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 715 / 1.50GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_715[] = +{ /* VID#A VID#B VID#C VID#D */ + OP( 600, 988, 988, 988, 988), + OP( 800, 1068, 1068, 1068, 1052), + OP(1000, 1148, 1148, 1132, 1116), + OP(1200, 1228, 1212, 1212, 1180), + OP(1500, 1340, 1324, 1308, 1276), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 725 / 1.60GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_725[] = +{ /* VID#A VID#B VID#C VID#D */ + OP( 600, 988, 988, 988, 988), + OP( 800, 1068, 1068, 1052, 1052), + OP(1000, 1132, 1132, 1116, 1116), + OP(1200, 1212, 1196, 1180, 1164), + OP(1400, 1276, 1260, 1244, 1228), + OP(1600, 1340, 1324, 1308, 1276), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 735 / 1.70GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_735[] = +{ /* VID#A VID#B VID#C VID#D */ + OP( 600, 988, 988, 988, 988), + OP( 800, 1052, 1052, 1052, 1052), + OP(1000, 1116, 1116, 1116, 1100), + OP(1200, 1180, 1180, 1164, 1148), + OP(1400, 1244, 1244, 1228, 1212), + OP(1700, 1340, 1324, 1308, 1276), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 745 / 1.80GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_745[] = +{ /* VID#A VID#B VID#C VID#D */ + OP( 600, 988, 988, 988, 988), + OP( 800, 1052, 1052, 1052, 1036), + OP(1000, 1116, 1100, 1100, 1084), + OP(1200, 1164, 1164, 1148, 1132), + OP(1400, 1228, 1212, 1212, 1180), + OP(1600, 1292, 1276, 1260, 1228), + OP(1800, 1340, 1324, 1308, 1276), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 755 / 2.00GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_755[] = +{ /* VID#A VID#B VID#C VID#D */ + OP( 600, 988, 988, 988, 988), + OP( 800, 1052, 1036, 1036, 1036), + OP(1000, 1100, 1084, 1084, 1084), + OP(1200, 1148, 1132, 1132, 1116), + OP(1400, 1196, 1180, 1180, 1164), + OP(1600, 1244, 1228, 1228, 1196), + OP(1800, 1292, 1276, 1276, 1244), + OP(2000, 1340, 1324, 1308, 1276), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 765 / 2.10GHz (Dothan) */ +static struct cpufreq_frequency_table dothan_765[] = +{ /* VID#E VID#A VID#B VID#C */ + OP( 600, 988, 988, 988, 988), + OP( 800, 1052, 1036, 1036, 1036), + OP(1000, 1100, 1084, 1084, 1084), + OP(1200, 1148, 1132, 1132, 1116), + OP(1400, 1196, 1180, 1180, 1164), + OP(1600, 1244, 1228, 1212, 1212), + OP(1800, 1292, 1276, 1260, 1244), + OP(2100, 1356, 1340, 1324, 1308), + { .frequency = CPUFREQ_TABLE_END } +}; + #undef OP #define _BANIAS(cpuid, max, name) \ @@ -204,6 +398,16 @@ } #define BANIAS(max) _BANIAS(&cpu_ids[CPU_BANIAS], max, #max) +#define _DOTHAN(cpuid, max, name) \ +{ .cpu_id = cpuid, \ + .model_name = "Intel(R) Pentium(R) M processor " #max "GHz", \ + .max_freq = (max)*1000000,\ + .op_points = dothan_##name,\ +} +#define DOTHAN(max, name) \ + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], max, name), \ + _DOTHAN(&cpu_ids[CPU_DOTHAN_C0], max, name) + /* CPU models, their operating frequency range, and freq/voltage operating points */ static struct cpu_model models[] = @@ -217,11 +421,24 @@ BANIAS(1500), BANIAS(1600), BANIAS(1700), + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], 1.00, 723), + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], 1.10, 733), + _DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1.10, 733J), + _DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1.20, 753), + _DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1.30, 773), + DOTHAN(1.40, 738), + _DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1.50, 758), + _DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1.60, 778), + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], 1.50, 715), + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], 1.60, 725), + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], 1.70, 735), + DOTHAN(1.80, 745), + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], 2.00, 755), + _DOTHAN(&cpu_ids[CPU_DOTHAN_Bx], 2.10, 765), /* NULL model_name is a wildcard */ { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, - { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, @@ -229,6 +446,8 @@ }; #undef _BANIAS #undef BANIAS +#undef _DOTHAN +#undef DOTHAN static int centrino_cpu_init_table(struct cpufreq_policy *policy) { @@ -294,7 +513,9 @@ */ if ((per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_BANIAS]) || (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_A1]) || - (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_B0])) { + (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_A2]) || + (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_Bx]) || + (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_C0])) { msr = (msr >> 8) & 0xff; return msr * 100000; } _ -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html