diff options
author | Len Brown <len.brown@intel.com> | 2016-04-06 17:00:47 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-04-08 20:17:43 -0400 |
commit | 5dcef694860100fd16885f052591b1268b764d21 (patch) | |
tree | 7c083237a14697091466b2506f039e8d45363daa | |
parent | c998c07836f985b24361629dc98506ec7893e7a0 (diff) |
intel_idle: add BXT support
Broxton has all the HSW C-states, except C3.
BXT C-state timing is slightly different.
Here we trust the IRTL MSRs as authority
on maximum C-state latency, and override the driver's tables
with the values found in the associated IRTL MSRs.
Further we set the target_residency to 1x maximum latency,
trusting the hardware demotion logic.
Signed-off-by: Len Brown <len.brown@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | arch/x86/include/asm/msr-index.h | 8 | ||||
-rw-r--r-- | drivers/idle/intel_idle.c | 137 |
2 files changed, 145 insertions, 0 deletions
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b05402ef3b84..73d66fa48638 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
@@ -162,6 +162,14 @@ | |||
162 | #define MSR_PKG_C9_RESIDENCY 0x00000631 | 162 | #define MSR_PKG_C9_RESIDENCY 0x00000631 |
163 | #define MSR_PKG_C10_RESIDENCY 0x00000632 | 163 | #define MSR_PKG_C10_RESIDENCY 0x00000632 |
164 | 164 | ||
165 | /* Interrupt Response Limit */ | ||
166 | #define MSR_PKGC3_IRTL 0x0000060a | ||
167 | #define MSR_PKGC6_IRTL 0x0000060b | ||
168 | #define MSR_PKGC7_IRTL 0x0000060c | ||
169 | #define MSR_PKGC8_IRTL 0x00000633 | ||
170 | #define MSR_PKGC9_IRTL 0x00000634 | ||
171 | #define MSR_PKGC10_IRTL 0x00000635 | ||
172 | |||
165 | /* Run Time Average Power Limiting (RAPL) Interface */ | 173 | /* Run Time Average Power Limiting (RAPL) Interface */ |
166 | 174 | ||
167 | #define MSR_RAPL_POWER_UNIT 0x00000606 | 175 | #define MSR_RAPL_POWER_UNIT 0x00000606 |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index c6935de425fa..c96649292b55 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -766,6 +766,67 @@ static struct cpuidle_state knl_cstates[] = { | |||
766 | .enter = NULL } | 766 | .enter = NULL } |
767 | }; | 767 | }; |
768 | 768 | ||
769 | static struct cpuidle_state bxt_cstates[] = { | ||
770 | { | ||
771 | .name = "C1-BXT", | ||
772 | .desc = "MWAIT 0x00", | ||
773 | .flags = MWAIT2flg(0x00), | ||
774 | .exit_latency = 2, | ||
775 | .target_residency = 2, | ||
776 | .enter = &intel_idle, | ||
777 | .enter_freeze = intel_idle_freeze, }, | ||
778 | { | ||
779 | .name = "C1E-BXT", | ||
780 | .desc = "MWAIT 0x01", | ||
781 | .flags = MWAIT2flg(0x01), | ||
782 | .exit_latency = 10, | ||
783 | .target_residency = 20, | ||
784 | .enter = &intel_idle, | ||
785 | .enter_freeze = intel_idle_freeze, }, | ||
786 | { | ||
787 | .name = "C6-BXT", | ||
788 | .desc = "MWAIT 0x20", | ||
789 | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
790 | .exit_latency = 133, | ||
791 | .target_residency = 133, | ||
792 | .enter = &intel_idle, | ||
793 | .enter_freeze = intel_idle_freeze, }, | ||
794 | { | ||
795 | .name = "C7s-BXT", | ||
796 | .desc = "MWAIT 0x31", | ||
797 | .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
798 | .exit_latency = 155, | ||
799 | .target_residency = 155, | ||
800 | .enter = &intel_idle, | ||
801 | .enter_freeze = intel_idle_freeze, }, | ||
802 | { | ||
803 | .name = "C8-BXT", | ||
804 | .desc = "MWAIT 0x40", | ||
805 | .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
806 | .exit_latency = 1000, | ||
807 | .target_residency = 1000, | ||
808 | .enter = &intel_idle, | ||
809 | .enter_freeze = intel_idle_freeze, }, | ||
810 | { | ||
811 | .name = "C9-BXT", | ||
812 | .desc = "MWAIT 0x50", | ||
813 | .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
814 | .exit_latency = 2000, | ||
815 | .target_residency = 2000, | ||
816 | .enter = &intel_idle, | ||
817 | .enter_freeze = intel_idle_freeze, }, | ||
818 | { | ||
819 | .name = "C10-BXT", | ||
820 | .desc = "MWAIT 0x60", | ||
821 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | ||
822 | .exit_latency = 10000, | ||
823 | .target_residency = 10000, | ||
824 | .enter = &intel_idle, | ||
825 | .enter_freeze = intel_idle_freeze, }, | ||
826 | { | ||
827 | .enter = NULL } | ||
828 | }; | ||
829 | |||
769 | /** | 830 | /** |
770 | * intel_idle | 831 | * intel_idle |
771 | * @dev: cpuidle_device | 832 | * @dev: cpuidle_device |
@@ -950,6 +1011,11 @@ static const struct idle_cpu idle_cpu_knl = { | |||
950 | .state_table = knl_cstates, | 1011 | .state_table = knl_cstates, |
951 | }; | 1012 | }; |
952 | 1013 | ||
1014 | static const struct idle_cpu idle_cpu_bxt = { | ||
1015 | .state_table = bxt_cstates, | ||
1016 | .disable_promotion_to_c1e = true, | ||
1017 | }; | ||
1018 | |||
953 | #define ICPU(model, cpu) \ | 1019 | #define ICPU(model, cpu) \ |
954 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } | 1020 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } |
955 | 1021 | ||
@@ -985,6 +1051,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { | |||
985 | ICPU(0x9e, idle_cpu_skl), | 1051 | ICPU(0x9e, idle_cpu_skl), |
986 | ICPU(0x55, idle_cpu_skx), | 1052 | ICPU(0x55, idle_cpu_skx), |
987 | ICPU(0x57, idle_cpu_knl), | 1053 | ICPU(0x57, idle_cpu_knl), |
1054 | ICPU(0x5c, idle_cpu_bxt), | ||
988 | {} | 1055 | {} |
989 | }; | 1056 | }; |
990 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); | 1057 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); |
@@ -1075,6 +1142,73 @@ static void ivt_idle_state_table_update(void) | |||
1075 | 1142 | ||
1076 | /* else, 1 and 2 socket systems use default ivt_cstates */ | 1143 | /* else, 1 and 2 socket systems use default ivt_cstates */ |
1077 | } | 1144 | } |
1145 | |||
1146 | /* | ||
1147 | * Translate IRTL (Interrupt Response Time Limit) MSR to usec | ||
1148 | */ | ||
1149 | |||
1150 | static unsigned int irtl_ns_units[] = { | ||
1151 | 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 }; | ||
1152 | |||
1153 | static unsigned long long irtl_2_usec(unsigned long long irtl) | ||
1154 | { | ||
1155 | unsigned long long ns; | ||
1156 | |||
1157 | ns = irtl_ns_units[(irtl >> 10) & 0x3]; | ||
1158 | |||
1159 | return div64_u64((irtl & 0x3FF) * ns, 1000); | ||
1160 | } | ||
1161 | /* | ||
1162 | * bxt_idle_state_table_update(void) | ||
1163 | * | ||
1164 | * On BXT, we trust the IRTL to show the definitive maximum latency | ||
1165 | * We use the same value for target_residency. | ||
1166 | */ | ||
1167 | static void bxt_idle_state_table_update(void) | ||
1168 | { | ||
1169 | unsigned long long msr; | ||
1170 | |||
1171 | rdmsrl(MSR_PKGC6_IRTL, msr); | ||
1172 | if (msr) { | ||
1173 | unsigned int usec = irtl_2_usec(msr); | ||
1174 | |||
1175 | bxt_cstates[2].exit_latency = usec; | ||
1176 | bxt_cstates[2].target_residency = usec; | ||
1177 | } | ||
1178 | |||
1179 | rdmsrl(MSR_PKGC7_IRTL, msr); | ||
1180 | if (msr) { | ||
1181 | unsigned int usec = irtl_2_usec(msr); | ||
1182 | |||
1183 | bxt_cstates[3].exit_latency = usec; | ||
1184 | bxt_cstates[3].target_residency = usec; | ||
1185 | } | ||
1186 | |||
1187 | rdmsrl(MSR_PKGC8_IRTL, msr); | ||
1188 | if (msr) { | ||
1189 | unsigned int usec = irtl_2_usec(msr); | ||
1190 | |||
1191 | bxt_cstates[4].exit_latency = usec; | ||
1192 | bxt_cstates[4].target_residency = usec; | ||
1193 | } | ||
1194 | |||
1195 | rdmsrl(MSR_PKGC9_IRTL, msr); | ||
1196 | if (msr) { | ||
1197 | unsigned int usec = irtl_2_usec(msr); | ||
1198 | |||
1199 | bxt_cstates[5].exit_latency = usec; | ||
1200 | bxt_cstates[5].target_residency = usec; | ||
1201 | } | ||
1202 | |||
1203 | rdmsrl(MSR_PKGC10_IRTL, msr); | ||
1204 | if (msr) { | ||
1205 | unsigned int usec = irtl_2_usec(msr); | ||
1206 | |||
1207 | bxt_cstates[6].exit_latency = usec; | ||
1208 | bxt_cstates[6].target_residency = usec; | ||
1209 | } | ||
1210 | |||
1211 | } | ||
1078 | /* | 1212 | /* |
1079 | * sklh_idle_state_table_update(void) | 1213 | * sklh_idle_state_table_update(void) |
1080 | * | 1214 | * |
@@ -1130,6 +1264,9 @@ static void intel_idle_state_table_update(void) | |||
1130 | case 0x3e: /* IVT */ | 1264 | case 0x3e: /* IVT */ |
1131 | ivt_idle_state_table_update(); | 1265 | ivt_idle_state_table_update(); |
1132 | break; | 1266 | break; |
1267 | case 0x5c: /* BXT */ | ||
1268 | bxt_idle_state_table_update(); | ||
1269 | break; | ||
1133 | case 0x5e: /* SKL-H */ | 1270 | case 0x5e: /* SKL-H */ |
1134 | sklh_idle_state_table_update(); | 1271 | sklh_idle_state_table_update(); |
1135 | break; | 1272 | break; |