| @@ -833,6 +833,11 @@ static int rapl_write_data_raw(struct rapl_domain *rd, · 832 unmodified lines |
| 833 | 833 | return 0; |
| 834 | 834 | } |
| 835 | 835 | |
| 836 | +static const struct x86_cpu_id energy_unit_quirk_ids[] = { |
| 837 | + { X86_VENDOR_INTEL, 6, 0x37},/* VLV */ |
| 838 | + {} |
| 839 | +}; |
| 840 | + |
| 836 | 841 | static int rapl_check_unit(struct rapl_package *rp, int cpu) |
| 837 | 842 | { |
| 838 | 843 | u64 msr_val; |
| @@ -853,8 +858,11 @@ static int rapl_check_unit(struct rapl_package *rp, int cpu) · 14 unmodified lines |
| 853 | 858 | * time unit: 1/time_unit_divisor Seconds |
| 854 | 859 | */ |
| 855 | 860 | value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; |
| 856 | | − rp->energy_unit_divisor = 1 << value; |
| 857 | | − |
| 861 | + /* some CPUs have different way to calculate energy unit */ |
| 862 | + if (x86_match_cpu(energy_unit_quirk_ids)) |
| 863 | + rp->energy_unit_divisor = 1000000 / (1 << value); |
| 864 | + else |
| 865 | + rp->energy_unit_divisor = 1 << value; |
| 858 | 866 | |
| 859 | 867 | value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; |
| 860 | 868 | rp->power_unit_divisor = 1 << value; |
| @@ -941,6 +949,7 @@ static void package_power_limit_irq_restore(int package_id) · 80 unmodified lines |
| 941 | 949 | static const struct x86_cpu_id rapl_ids[] = { |
| 942 | 950 | { X86_VENDOR_INTEL, 6, 0x2a},/* SNB */ |
| 943 | 951 | { X86_VENDOR_INTEL, 6, 0x2d},/* SNB EP */ |
| 952 | + { X86_VENDOR_INTEL, 6, 0x37},/* VLV */ |
| 944 | 953 | { X86_VENDOR_INTEL, 6, 0x3a},/* IVB */ |
| 945 | 954 | { X86_VENDOR_INTEL, 6, 0x45},/* HSW */ |
| 946 | 955 | /* TODO: Add more CPU IDs after testing */ |