25 #include <linux/module.h>
26 #include <linux/pci.h>
27 #include <linux/bitops.h>
28 #include <asm/processor.h>
35 #define PCI_DEVICE_ID_AMD_16H_NB_F4 0x1534
38 #define REG_NORTHBRIDGE_CAP 0xe8
41 #define REG_PROCESSOR_TDP 0x1b8
44 #define REG_TDP_RUNNING_AVERAGE 0xe0
45 #define REG_TDP_LIMIT3 0xe8
57 u32 val, tdp_limit, running_avg_range;
58 s32 running_avg_capture;
65 running_avg_capture = (val >> 4) & 0x3fffff;
66 running_avg_capture = sign_extend32(running_avg_capture, 21);
67 running_avg_range = (val & 0xf) + 1;
72 tdp_limit = val >> 16;
73 curr_pwr_watts = ((
u64)(tdp_limit +
74 data->
base_tdp)) << running_avg_range;
75 curr_pwr_watts -= running_avg_capture;
85 curr_pwr_watts = (curr_pwr_watts * 15625) >> (10 + running_avg_range);
86 return sprintf(buf,
"%u\n", (
unsigned int) curr_pwr_watts);
102 return sprintf(buf,
"fam15h_power\n");
106 static struct attribute *fam15h_power_attrs[] = {
107 &dev_attr_power1_input.attr,
108 &dev_attr_power1_crit.attr,
114 .attrs = fam15h_power_attrs,
123 if ((val &
BIT(29)) && ((val >> 30) & 3))
140 static void tweak_runavg_range(
struct pci_dev *pdev)
151 pci_bus_read_config_dword(pdev->
bus,
154 if ((val & 0xf) != 0
xe)
159 pci_bus_write_config_dword(pdev->
bus,
167 tweak_runavg_range(pdev);
171 #define fam15h_power_resume NULL
187 data->
tdp_to_watts = ((val & 0x3ff) << 6) | ((val >> 10) & 0x3f);
191 if ((tmp >> 16) >= 256)
192 dev_warn(&f4->
dev,
"Bogus value for ProcessorPwrWatts "
193 "(processor_pwr_watts>=%u)\n",
194 (
unsigned int) (tmp >> 16));
212 tweak_runavg_range(pdev);
214 if (!fam15h_power_is_internal_node0(pdev))
221 fam15h_power_init_data(pdev, data);
231 goto exit_remove_group;
259 static struct pci_driver fam15h_power_driver = {
260 .name =
"fam15h_power",
261 .id_table = fam15h_power_id_table,
262 .probe = fam15h_power_probe,