static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) { u32 l, h; if ((newstate > DC_DISABLE) || (newstate == DC_RESV)) return -EINVAL; rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h); if (l & 0x01) pr_debug("CPU#%d currently thermal throttled\n", cpu); if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT)) newstate = DC_38PT; rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); if (newstate == DC_DISABLE) { pr_debug("CPU#%d disabling modulation\n", cpu); wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); } else { pr_debug("CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10)); /* bits 63 - 5 : reserved * bit 4 : enable/disable * bits 3-1 : duty cycle * bit 0 : reserved */ l = (l & ~14); l = l | (1<<4) | ((newstate & 0x7)<<1); wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l, h); } return 0; }
static void enable_soc_dts(void) { int i; u32 val, eax, edx; rdmsr_on_cpu(0, MSR_THERM_CFG1, &eax, &edx); /* B[11:13] C2H Hyst */ eax = (eax & ~(0x7 << 11)) | (DEFAULT_C2H_HYST << 11); /* B[8:10] H2C Hyst */ eax = (eax & ~(0x7 << 8)) | (DEFAULT_H2C_HYST << 8); /* Set the Hysteresis value */ wrmsr_on_cpu(0, MSR_THERM_CFG1, eax, edx); /* Enable the DTS */ write_soc_reg(DTS_ENABLE_REG, DTS_ENABLE); val = read_soc_reg(SOC_DTS_CONTROL); write_soc_reg(SOC_DTS_CONTROL, val | ENABLE_AUX_INTRPT | ENABLE_CPU0); /* Enable Interrupts for all the AUX trips for the DTS */ for (i = 0; i < SOC_THERMAL_TRIPS; i++) { val = read_soc_reg(TE_AUX0 + i); write_soc_reg(TE_AUX0 + i, (val | RTE_ENABLE)); } }
static void one_msr_wr(RegRec * r) { uint32_t hi, lo; if (! (r->box & VLD)) return; hi = r->reg >> 32; lo = r->reg & 0xffffffff; switch(r->box & 0xf) { case GMSR: wrmsr(r->ofs, lo, hi); break; #if RAS_SAVE_CPU_MSR case LMSR: wrmsr_on_cpu(r->num, r->ofs, lo, hi); break; #endif } r->box &= ~VLD; #if PM_VERBOSE printk("msr_wr: box %d, idx %3d, ofs %04x <- %llx\n", r->box & 0xf, r->num, r->ofs, r->reg); #endif }
static ssize_t store_tmin(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct platform_data *pdata = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct temp_data *tdata = pdata->core_data[attr->index]; u32 eax, edx; unsigned long val; int diff; if (strict_strtoul(buf, 10, &val)) return -EINVAL; /* * THERM_MASK_THRESHOLD0 is 7 bits wide. Values are entered in terms * of milli degree celsius. Hence don't accept val > (127 * 1000) */ if (val > tdata->tjmax || val > 127000) return -EINVAL; diff = (tdata->tjmax - val) / 1000; mutex_lock(&tdata->update_lock); rdmsr_on_cpu(tdata->cpu, tdata->intrpt_reg, &eax, &edx); eax = (eax & ~THERM_MASK_THRESHOLD0) | (diff << THERM_SHIFT_THRESHOLD0); wrmsr_on_cpu(tdata->cpu, tdata->intrpt_reg, eax, edx); tdata->tmin = val; mutex_unlock(&tdata->update_lock); return count; }
int main(int argc, char *argv[]) { uint32_t reg; int c; int cpu = 0; unsigned long arg; char *endarg; program = argv[0]; while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (c) { case 'h': usage(); exit(0); case 'V': fprintf(stderr, "%s: version %s\n", program, VERSION_STRING); exit(0); case 'a': cpu = -1; break; case 'p': arg = strtoul(optarg, &endarg, 0); if (*endarg || arg > 5119) { usage(); exit(127); } cpu = (int)arg; break; default: usage(); exit(127); } } if (optind > argc - 2) { /* Should have at least two arguments */ usage(); exit(127); } reg = strtoul(argv[optind++], NULL, 0); if (cpu == -1) { doing_for_all = 1; wrmsr_on_all_cpus(reg, argc - optind, &argv[optind]); } else { wrmsr_on_cpu(reg, cpu, argc - optind, &argv[optind]); } exit(0); }
void wrmsr_on_all_cpus(uint32_t reg, int valcnt, char *regvals[]) { struct dirent **namelist; int dir_entries; dir_entries = scandir("/dev/cpu", &namelist, dir_filter, 0); while (dir_entries--) { wrmsr_on_cpu(reg, atoi(namelist[dir_entries]->d_name), valcnt, regvals); free(namelist[dir_entries]); } free(namelist); }
static int sfi_cpufreq_target(struct cpufreq_policy *policy, unsigned int index) { unsigned int next_perf_state = 0; /* Index into perf table */ u32 lo, hi; next_perf_state = policy->freq_table[index].driver_data; rdmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, &lo, &hi); lo = (lo & ~INTEL_PERF_CTL_MASK) | ((u32) sfi_cpufreq_array[next_perf_state].ctrl_val & INTEL_PERF_CTL_MASK); wrmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, lo, hi); return 0; }