History

Merge tag 'pm-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management updates from Rafael Wysocki: "These add support for 'artificial' Energy Models in which power numbers for different entities may be in different scales, add support for some new hardware, fix bugs and clean up code in multiple places. Specifics: - Update the Energy Model support code to allow the Energy Model to be artificial, which means that the power values may not be on a uniform scale with other devices providing power information, and update the cpufreq_cooling and devfreq_cooling thermal drivers to support artificial Energy Models (Lukasz Luba). - Make DTPM check the Energy Model type (Lukasz Luba). - Fix policy counter decrementation in cpufreq if Energy Model is in use (Pierre Gondois). - Add CPU-based scaling support to passive devfreq governor (Saravana Kannan, Chanwoo Choi). - Update the rk3399_dmc devfreq driver (Brian Norris). - Export dev_pm_ops instead of suspend() and resume() in the IIO chemical scd30 driver (Jonathan Cameron). - Add namespace variants of EXPORT[_GPL]_SIMPLE_DEV_PM_OPS and PM-runtime counterparts (Jonathan Cameron). - Move symbol exports in the IIO chemical scd30 driver into the IIO_SCD30 namespace (Jonathan Cameron). - Avoid device PM-runtime usage count underflows (Rafael Wysocki). - Allow dynamic debug to control printing of PM messages (David Cohen). - Fix some kernel-doc comments in hibernation code (Yang Li, Haowen Bai). - Preserve ACPI-table override during hibernation (Amadeusz Sławiński). - Improve support for suspend-to-RAM for PSCI OSI mode (Ulf Hansson). - Make Intel RAPL power capping driver support the RaptorLake and AlderLake N processors (Zhang Rui, Sumeet Pawnikar). - Remove redundant store to value after multiply in the RAPL power capping driver (Colin Ian King). - Add AlderLake processor support to the intel_idle driver (Zhang Rui). - Fix regression leading to no genpd governor in the PSCI cpuidle driver and fix the riscv-sbi cpuidle driver to allow a genpd governor to be used (Ulf Hansson). - Fix cpufreq governor clean up code to avoid using kfree() directly to free kobject-based items (Kevin Hao). - Prepare cpufreq for powerpc's asm/prom.h cleanup (Christophe Leroy). - Make intel_pstate notify frequency invariance code when no_turbo is turned on and off (Chen Yu). - Add Sapphire Rapids OOB mode support to intel_pstate (Srinivas Pandruvada). - Make cpufreq avoid unnecessary frequency updates due to mismatch between hardware and the frequency table (Viresh Kumar). - Make remove_cpu_dev_symlink() clear the real_cpus mask to simplify code (Viresh Kumar). - Rearrange cpufreq_offline() and cpufreq_remove_dev() to make the calling convention for some driver callbacks consistent (Rafael Wysocki). - Avoid accessing half-initialized cpufreq policies from the show() and store() sysfs functions (Schspa Shi). - Rearrange cpufreq_offline() to make the calling convention for some driver callbacks consistent (Schspa Shi). - Update CPPC handling in cpufreq (Pierre Gondois). - Extend dev_pm_domain_detach() doc (Krzysztof Kozlowski). - Move genpd's time-accounting to ktime_get_mono_fast_ns() (Ulf Hansson). - Improve the way genpd deals with its governors (Ulf Hansson). - Update the turbostat utility to version 2022.04.16 (Len Brown, Dan Merillat, Sumeet Pawnikar, Zephaniah E. Loss-Cutler-Hull, Chen Yu)" * tag 'pm-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (94 commits) PM: domains: Trust domain-idle-states from DT to be correct by genpd PM: domains: Measure power-on/off latencies in genpd based on a governor PM: domains: Allocate governor data dynamically based on a genpd governor PM: domains: Clean up some code in pm_genpd_init() and genpd_remove() PM: domains: Fix initialization of genpd's next_wakeup PM: domains: Fixup QoS latency measurements for IRQ safe devices in genpd PM: domains: Measure suspend/resume latencies in genpd based on governor PM: domains: Move the next_wakeup variable into the struct gpd_timing_data PM: domains: Allocate gpd_timing_data dynamically based on governor PM: domains: Skip another warning in irq_safe_dev_in_sleep_domain() PM: domains: Rename irq_safe_dev_in_no_sleep_domain() in genpd PM: domains: Don't check PM_QOS_FLAG_NO_POWER_OFF in genpd PM: domains: Drop redundant code for genpd always-on governor PM: domains: Add GENPD_FLAG_RPM_ALWAYS_ON for the always-on governor powercap: intel_rapl: remove redundant store to value after multiply cpufreq: CPPC: Enable dvfs_possible_from_any_cpu cpufreq: CPPC: Enable fast_switch ACPI: CPPC: Assume no transition latency if no PCCT ACPI: bus: Set CPPC _OSC bits for all and when CPPC_LIB is supported ACPI: CPPC: Check _OSC for flexible address space ...

Linus Torvalds committed 4 years ago

Commit 09583df2 parents 1961b06 0d6448260 files · +2463 −1005Browse files

Unified · Split

60 files
  1. Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt +0 −212
  2. Documentation/devicetree/bindings/memory-controllers/rockchip,rk3399-dmc.yaml +384 −0
  3. Documentation/power/energy-model.rst +22 −2
  4. arch/arm64/kernel/smp.c +1 −0
  5. arch/x86/include/asm/msr-index.h +1 −0
  6. arch/x86/kernel/acpi/boot.c +1 −1
  7. drivers/acpi/bus.c +26 −8
  8. drivers/acpi/cppc_acpi.c +43 −1
  9. drivers/base/power/common.c +4 −4
  10. drivers/base/power/domain.c +170 −108
  11. drivers/base/power/domain_governor.c +35 −30
  12. drivers/base/power/runtime.c +42 −11
  13. drivers/cpufreq/cppc_cpufreq.c +211 −0
  14. drivers/cpufreq/cpufreq.c +69 −43
  15. drivers/cpufreq/cpufreq_governor.c +13 −7
  16. drivers/cpufreq/cpufreq_governor.h +1 −0
  17. drivers/cpufreq/intel_pstate.c +2 −0
  18. drivers/cpufreq/mediatek-cpufreq-hw.c +2 −2
  19. drivers/cpufreq/pasemi-cpufreq.c +0 −1
  20. drivers/cpufreq/pmac32-cpufreq.c +1 −1
  21. drivers/cpufreq/pmac64-cpufreq.c +1 −1
  22. drivers/cpufreq/ppc_cbe_cpufreq.c +0 −1
  23. drivers/cpufreq/ppc_cbe_cpufreq_pmi.c +1 −1
  24. drivers/cpufreq/scmi-cpufreq.c +2 −2
  25. drivers/cpuidle/cpuidle-psci-domain.c +2 −2
  26. drivers/cpuidle/cpuidle-psci.c +46 −0
  27. drivers/cpuidle/cpuidle-riscv-sbi.c +2 −2
  28. drivers/devfreq/devfreq.c +12 −8
  29. drivers/devfreq/governor.h +27 −0
  30. drivers/devfreq/governor_passive.c +335 −68
  31. drivers/devfreq/rk3399_dmc.c +147 −165
  32. drivers/idle/intel_idle.c +133 −0
  33. drivers/iio/chemical/scd30.h +1 −4
  34. drivers/iio/chemical/scd30_core.c +5 −5
  35. drivers/iio/chemical/scd30_i2c.c +2 −1
  36. drivers/iio/chemical/scd30_serial.c +2 −1
  37. drivers/opp/of.c +3 −3
  38. drivers/powercap/dtpm_cpu.c +1 −1
  39. drivers/powercap/intel_rapl_common.c +3 −1
  40. drivers/powercap/intel_rapl_msr.c +1 −0
  41. drivers/soc/rockchip/pm_domains.c +118 −0
  42. drivers/thermal/cpufreq_cooling.c +1 −1
  43. drivers/thermal/devfreq_cooling.c +5 −3
  44. include/acpi/cppc_acpi.h +5 −0
  45. include/linux/acpi.h +2 −0
  46. include/linux/devfreq.h +15 −2
  47. include/linux/energy_model.h +31 −4
  48. include/linux/pm.h +9 −5
  49. include/linux/pm_domain.h +14 −10
  50. include/linux/pm_runtime.h +8 −2
  51. include/linux/suspend.h +39 −5
  52. include/soc/rockchip/pm_domains.h +25 −0
  53. kernel/power/Makefile +5 −1
  54. kernel/power/energy_model.c +36 −29
  55. kernel/power/main.c +0 −29
  56. kernel/power/process.c +0 −3
  57. kernel/power/snapshot.c +8 −4
  58. tools/power/x86/turbostat/Makefile +1 −1
  59. tools/power/x86/turbostat/turbostat.8 +1 −1
  60. tools/power/x86/turbostat/turbostat.c +386 −208
Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt+0−212
@@ -1,212 +0,0 @@
1* Rockchip rk3399 DMC (Dynamic Memory Controller) device
2
3Required properties:
4- compatible: Must be "rockchip,rk3399-dmc".
5- devfreq-events: Node to get DDR loading, Refer to
6 Documentation/devicetree/bindings/devfreq/event/
7 rockchip-dfi.txt
8- clocks: Phandles for clock specified in "clock-names" property
9- clock-names : The name of clock used by the DFI, must be
10 "pclk_ddr_mon";
11- operating-points-v2: Refer to Documentation/devicetree/bindings/opp/opp-v2.yaml
12 for details.
13- center-supply: DMC supply node.
14- status: Marks the node enabled/disabled.
15- rockchip,pmu: Phandle to the syscon managing the "PMU general register
16 files".
17
18Optional properties:
19- interrupts: The CPU interrupt number. The interrupt specifier
20 format depends on the interrupt controller.
21 It should be a DCF interrupt. When DDR DVFS finishes
22 a DCF interrupt is triggered.
23- rockchip,pmu: Phandle to the syscon managing the "PMU general register
24 files".
25
26Following properties relate to DDR timing:
27
28- rockchip,dram_speed_bin : Value reference include/dt-bindings/clock/rk3399-ddr.h,
29 it selects the DDR3 cl-trp-trcd type. It must be
30 set according to "Speed Bin" in DDR3 datasheet,
31 DO NOT use a smaller "Speed Bin" than specified
32 for the DDR3 being used.
33
34- rockchip,pd_idle : Configure the PD_IDLE value. Defines the
35 power-down idle period in which memories are
36 placed into power-down mode if bus is idle
37 for PD_IDLE DFI clock cycles.
38
39- rockchip,sr_idle : Configure the SR_IDLE value. Defines the
40 self-refresh idle period in which memories are
41 placed into self-refresh mode if bus is idle
42 for SR_IDLE * 1024 DFI clock cycles (DFI
43 clocks freq is half of DRAM clock), default
44 value is "0".
45
46- rockchip,sr_mc_gate_idle : Defines the memory self-refresh and controller
47 clock gating idle period. Memories are placed
48 into self-refresh mode and memory controller
49 clock arg gating started if bus is idle for
50 sr_mc_gate_idle*1024 DFI clock cycles.
51
52- rockchip,srpd_lite_idle : Defines the self-refresh power down idle
53 period in which memories are placed into
54 self-refresh power down mode if bus is idle
55 for srpd_lite_idle * 1024 DFI clock cycles.
56 This parameter is for LPDDR4 only.
57
58- rockchip,standby_idle : Defines the standby idle period in which
59 memories are placed into self-refresh mode.
60 The controller, pi, PHY and DRAM clock will
61 be gated if bus is idle for standby_idle * DFI
62 clock cycles.
63
64- rockchip,dram_dll_dis_freq : Defines the DDR3 DLL bypass frequency in MHz.
65 When DDR frequency is less than DRAM_DLL_DISB_FREQ,
66 DDR3 DLL will be bypassed. Note: if DLL was bypassed,
67 the odt will also stop working.
68
69- rockchip,phy_dll_dis_freq : Defines the PHY dll bypass frequency in
70 MHz (Mega Hz). When DDR frequency is less than
71 DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
72 Note: PHY DLL and PHY ODT are independent.
73
74- rockchip,ddr3_odt_dis_freq : When the DRAM type is DDR3, this parameter defines
75 the ODT disable frequency in MHz (Mega Hz).
76 when the DDR frequency is less then ddr3_odt_dis_freq,
77 the ODT on the DRAM side and controller side are
78 both disabled.
79
80- rockchip,ddr3_drv : When the DRAM type is DDR3, this parameter defines
81 the DRAM side driver strength in ohms. Default
82 value is 40.
83
84- rockchip,ddr3_odt : When the DRAM type is DDR3, this parameter defines
85 the DRAM side ODT strength in ohms. Default value
86 is 120.
87
88- rockchip,phy_ddr3_ca_drv : When the DRAM type is DDR3, this parameter defines
89 the phy side CA line (incluing command line,
90 address line and clock line) driver strength.
91 Default value is 40.
92
93- rockchip,phy_ddr3_dq_drv : When the DRAM type is DDR3, this parameter defines
94 the PHY side DQ line (including DQS/DQ/DM line)
95 driver strength. Default value is 40.
96
97- rockchip,phy_ddr3_odt : When the DRAM type is DDR3, this parameter defines
98 the PHY side ODT strength. Default value is 240.
99
100- rockchip,lpddr3_odt_dis_freq : When the DRAM type is LPDDR3, this parameter defines
101 then ODT disable frequency in MHz (Mega Hz).
102 When DDR frequency is less then ddr3_odt_dis_freq,
103 the ODT on the DRAM side and controller side are
104 both disabled.
105
106- rockchip,lpddr3_drv : When the DRAM type is LPDDR3, this parameter defines
107 the DRAM side driver strength in ohms. Default
108 value is 34.
109
110- rockchip,lpddr3_odt : When the DRAM type is LPDDR3, this parameter defines
111 the DRAM side ODT strength in ohms. Default value
112 is 240.
113
114- rockchip,phy_lpddr3_ca_drv : When the DRAM type is LPDDR3, this parameter defines
115 the PHY side CA line (including command line,
116 address line and clock line) driver strength.
117 Default value is 40.
118
119- rockchip,phy_lpddr3_dq_drv : When the DRAM type is LPDDR3, this parameter defines
120 the PHY side DQ line (including DQS/DQ/DM line)
121 driver strength. Default value is 40.
122
123- rockchip,phy_lpddr3_odt : When dram type is LPDDR3, this parameter define
124 the phy side odt strength, default value is 240.
125
126- rockchip,lpddr4_odt_dis_freq : When the DRAM type is LPDDR4, this parameter
127 defines the ODT disable frequency in
128 MHz (Mega Hz). When the DDR frequency is less then
129 ddr3_odt_dis_freq, the ODT on the DRAM side and
130 controller side are both disabled.
131
132- rockchip,lpddr4_drv : When the DRAM type is LPDDR4, this parameter defines
133 the DRAM side driver strength in ohms. Default
134 value is 60.
135
136- rockchip,lpddr4_dq_odt : When the DRAM type is LPDDR4, this parameter defines
137 the DRAM side ODT on DQS/DQ line strength in ohms.
138 Default value is 40.
139
140- rockchip,lpddr4_ca_odt : When the DRAM type is LPDDR4, this parameter defines
141 the DRAM side ODT on CA line strength in ohms.
142 Default value is 40.
143
144- rockchip,phy_lpddr4_ca_drv : When the DRAM type is LPDDR4, this parameter defines
145 the PHY side CA line (including command address
146 line) driver strength. Default value is 40.
147
148- rockchip,phy_lpddr4_ck_cs_drv : When the DRAM type is LPDDR4, this parameter defines
149 the PHY side clock line and CS line driver
150 strength. Default value is 80.
151
152- rockchip,phy_lpddr4_dq_drv : When the DRAM type is LPDDR4, this parameter defines
153 the PHY side DQ line (including DQS/DQ/DM line)
154 driver strength. Default value is 80.
155
156- rockchip,phy_lpddr4_odt : When the DRAM type is LPDDR4, this parameter defines
157 the PHY side ODT strength. Default value is 60.
158
159Example:
160 dmc_opp_table: dmc_opp_table {
161 compatible = "operating-points-v2";
162
163 opp00 {
164 opp-hz = /bits/ 64 <300000000>;
165 opp-microvolt = <900000>;
166 };
167 opp01 {
168 opp-hz = /bits/ 64 <666000000>;
169 opp-microvolt = <900000>;
170 };
171 };
172
173 dmc: dmc {
174 compatible = "rockchip,rk3399-dmc";
175 devfreq-events = <&dfi>;
176 interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
177 clocks = <&cru SCLK_DDRC>;
178 clock-names = "dmc_clk";
179 operating-points-v2 = <&dmc_opp_table>;
180 center-supply = <&ppvar_centerlogic>;
181 upthreshold = <15>;
182 downdifferential = <10>;
183 rockchip,ddr3_speed_bin = <21>;
184 rockchip,pd_idle = <0x40>;
185 rockchip,sr_idle = <0x2>;
186 rockchip,sr_mc_gate_idle = <0x3>;
187 rockchip,srpd_lite_idle = <0x4>;
188 rockchip,standby_idle = <0x2000>;
189 rockchip,dram_dll_dis_freq = <300>;
190 rockchip,phy_dll_dis_freq = <125>;
191 rockchip,auto_pd_dis_freq = <666>;
192 rockchip,ddr3_odt_dis_freq = <333>;
193 rockchip,ddr3_drv = <40>;
194 rockchip,ddr3_odt = <120>;
195 rockchip,phy_ddr3_ca_drv = <40>;
196 rockchip,phy_ddr3_dq_drv = <40>;
197 rockchip,phy_ddr3_odt = <240>;
198 rockchip,lpddr3_odt_dis_freq = <333>;
199 rockchip,lpddr3_drv = <34>;
200 rockchip,lpddr3_odt = <240>;
201 rockchip,phy_lpddr3_ca_drv = <40>;
202 rockchip,phy_lpddr3_dq_drv = <40>;
203 rockchip,phy_lpddr3_odt = <240>;
204 rockchip,lpddr4_odt_dis_freq = <333>;
205 rockchip,lpddr4_drv = <60>;
206 rockchip,lpddr4_dq_odt = <40>;
207 rockchip,lpddr4_ca_odt = <40>;
208 rockchip,phy_lpddr4_ca_drv = <40>;
209 rockchip,phy_lpddr4_ck_cs_drv = <80>;
210 rockchip,phy_lpddr4_dq_drv = <80>;
211 rockchip,phy_lpddr4_odt = <60>;
212 };
Documentation/devicetree/bindings/memory-controllers/rockchip,rk3399-dmc.yaml+384−0
@@ -0,0 +1,384 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2# %YAML 1.2
3---
4$id: http://devicetree.org/schemas/memory-controllers/rockchip,rk3399-dmc.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Rockchip rk3399 DMC (Dynamic Memory Controller) device
8
9maintainers:
10 - Brian Norris <briannorris@chromium.org>
11
12properties:
13 compatible:
14 enum:
15 - rockchip,rk3399-dmc
16
17 devfreq-events:
18 $ref: /schemas/types.yaml#/definitions/phandle
19 description:
20 Node to get DDR loading. Refer to
21 Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt.
22
23 clocks:
24 maxItems: 1
25
26 clock-names:
27 items:
28 - const: dmc_clk
29
30 operating-points-v2: true
31
32 center-supply:
33 description:
34 DMC regulator supply.
35
36 rockchip,pmu:
37 $ref: /schemas/types.yaml#/definitions/phandle
38 description:
39 Phandle to the syscon managing the "PMU general register files".
40
41 interrupts:
42 maxItems: 1
43 description:
44 The CPU interrupt number. It should be a DCF interrupt. When DDR DVFS
45 finishes, a DCF interrupt is triggered.
46
47 rockchip,ddr3_speed_bin:
48 deprecated: true
49 $ref: /schemas/types.yaml#/definitions/uint32
50 description:
51 For values, reference include/dt-bindings/clock/rk3399-ddr.h. Selects the
52 DDR3 cl-trp-trcd type. It must be set according to "Speed Bin" in DDR3
53 datasheet; DO NOT use a smaller "Speed Bin" than specified for the DDR3
54 being used.
55
56 rockchip,pd_idle:
57 deprecated: true
58 $ref: /schemas/types.yaml#/definitions/uint32
59 description:
60 Configure the PD_IDLE value. Defines the power-down idle period in which
61 memories are placed into power-down mode if bus is idle for PD_IDLE DFI
62 clock cycles.
63 See also rockchip,pd-idle-ns.
64
65 rockchip,sr_idle:
66 deprecated: true
67 $ref: /schemas/types.yaml#/definitions/uint32
68 description:
69 Configure the SR_IDLE value. Defines the self-refresh idle period in
70 which memories are placed into self-refresh mode if bus is idle for
71 SR_IDLE * 1024 DFI clock cycles (DFI clocks freq is half of DRAM clock).
72 See also rockchip,sr-idle-ns.
73 default: 0
74
75 rockchip,sr_mc_gate_idle:
76 deprecated: true
77 $ref: /schemas/types.yaml#/definitions/uint32
78 description:
79 Defines the memory self-refresh and controller clock gating idle period.
80 Memories are placed into self-refresh mode and memory controller clock
81 arg gating started if bus is idle for sr_mc_gate_idle*1024 DFI clock
82 cycles.
83 See also rockchip,sr-mc-gate-idle-ns.
84
85 rockchip,srpd_lite_idle:
86 deprecated: true
87 $ref: /schemas/types.yaml#/definitions/uint32
88 description:
89 Defines the self-refresh power down idle period in which memories are
90 placed into self-refresh power down mode if bus is idle for
91 srpd_lite_idle * 1024 DFI clock cycles. This parameter is for LPDDR4
92 only.
93 See also rockchip,srpd-lite-idle-ns.
94
95 rockchip,standby_idle:
96 deprecated: true
97 $ref: /schemas/types.yaml#/definitions/uint32
98 description:
99 Defines the standby idle period in which memories are placed into
100 self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
101 if bus is idle for standby_idle * DFI clock cycles.
102 See also rockchip,standby-idle-ns.
103
104 rockchip,dram_dll_dis_freq:
105 deprecated: true
106 $ref: /schemas/types.yaml#/definitions/uint32
107 description: |
108 Defines the DDR3 DLL bypass frequency in MHz. When DDR frequency is less
109 than DRAM_DLL_DISB_FREQ, DDR3 DLL will be bypassed.
110 Note: if DLL was bypassed, the odt will also stop working.
111
112 rockchip,phy_dll_dis_freq:
113 deprecated: true
114 $ref: /schemas/types.yaml#/definitions/uint32
115 description: |
116 Defines the PHY dll bypass frequency in MHz (Mega Hz). When DDR frequency
117 is less than DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
118 Note: PHY DLL and PHY ODT are independent.
119
120 rockchip,auto_pd_dis_freq:
121 deprecated: true
122 $ref: /schemas/types.yaml#/definitions/uint32
123 description:
124 Defines the auto PD disable frequency in MHz.
125
126 rockchip,ddr3_odt_dis_freq:
127 $ref: /schemas/types.yaml#/definitions/uint32
128 minimum: 1000000 # In case anyone thought this was MHz.
129 description:
130 When the DRAM type is DDR3, this parameter defines the ODT disable
131 frequency in Hz. When the DDR frequency is less then ddr3_odt_dis_freq,
132 the ODT on the DRAM side and controller side are both disabled.
133
134 rockchip,ddr3_drv:
135 deprecated: true
136 $ref: /schemas/types.yaml#/definitions/uint32
137 description:
138 When the DRAM type is DDR3, this parameter defines the DRAM side drive
139 strength in ohms.
140 default: 40
141
142 rockchip,ddr3_odt:
143 deprecated: true
144 $ref: /schemas/types.yaml#/definitions/uint32
145 description:
146 When the DRAM type is DDR3, this parameter defines the DRAM side ODT
147 strength in ohms.
148 default: 120
149
150 rockchip,phy_ddr3_ca_drv:
151 deprecated: true
152 $ref: /schemas/types.yaml#/definitions/uint32
153 description:
154 When the DRAM type is DDR3, this parameter defines the phy side CA line
155 (incluing command line, address line and clock line) drive strength.
156 default: 40
157
158 rockchip,phy_ddr3_dq_drv:
159 deprecated: true
160 $ref: /schemas/types.yaml#/definitions/uint32
161 description:
162 When the DRAM type is DDR3, this parameter defines the PHY side DQ line
163 (including DQS/DQ/DM line) drive strength.
164 default: 40
165
166 rockchip,phy_ddr3_odt:
167 deprecated: true
168 $ref: /schemas/types.yaml#/definitions/uint32
169 description:
170 When the DRAM type is DDR3, this parameter defines the PHY side ODT
171 strength.
172 default: 240
173
174 rockchip,lpddr3_odt_dis_freq:
175 $ref: /schemas/types.yaml#/definitions/uint32
176 minimum: 1000000 # In case anyone thought this was MHz.
177 description:
178 When the DRAM type is LPDDR3, this parameter defines then ODT disable
179 frequency in Hz. When DDR frequency is less then ddr3_odt_dis_freq, the
180 ODT on the DRAM side and controller side are both disabled.
181
182 rockchip,lpddr3_drv:
183 deprecated: true
184 $ref: /schemas/types.yaml#/definitions/uint32
185 description:
186 When the DRAM type is LPDDR3, this parameter defines the DRAM side drive
187 strength in ohms.
188 default: 34
189
190 rockchip,lpddr3_odt:
191 deprecated: true
192 $ref: /schemas/types.yaml#/definitions/uint32
193 description:
194 When the DRAM type is LPDDR3, this parameter defines the DRAM side ODT
195 strength in ohms.
196 default: 240
197
198 rockchip,phy_lpddr3_ca_drv:
199 deprecated: true
200 $ref: /schemas/types.yaml#/definitions/uint32
201 description:
202 When the DRAM type is LPDDR3, this parameter defines the PHY side CA line
203 (including command line, address line and clock line) drive strength.
204 default: 40
205
206 rockchip,phy_lpddr3_dq_drv:
207 deprecated: true
208 $ref: /schemas/types.yaml#/definitions/uint32
209 description:
210 When the DRAM type is LPDDR3, this parameter defines the PHY side DQ line
211 (including DQS/DQ/DM line) drive strength.
212 default: 40
213
214 rockchip,phy_lpddr3_odt:
215 deprecated: true
216 $ref: /schemas/types.yaml#/definitions/uint32
217 description:
218 When dram type is LPDDR3, this parameter define the phy side odt
219 strength, default value is 240.
220
221 rockchip,lpddr4_odt_dis_freq:
222 $ref: /schemas/types.yaml#/definitions/uint32
223 minimum: 1000000 # In case anyone thought this was MHz.
224 description:
225 When the DRAM type is LPDDR4, this parameter defines the ODT disable
226 frequency in Hz. When the DDR frequency is less then ddr3_odt_dis_freq,
227 the ODT on the DRAM side and controller side are both disabled.
228
229 rockchip,lpddr4_drv:
230 deprecated: true
231 $ref: /schemas/types.yaml#/definitions/uint32
232 description:
233 When the DRAM type is LPDDR4, this parameter defines the DRAM side drive
234 strength in ohms.
235 default: 60
236
237 rockchip,lpddr4_dq_odt:
238 deprecated: true
239 $ref: /schemas/types.yaml#/definitions/uint32
240 description:
241 When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
242 DQS/DQ line strength in ohms.
243 default: 40
244
245 rockchip,lpddr4_ca_odt:
246 deprecated: true
247 $ref: /schemas/types.yaml#/definitions/uint32
248 description:
249 When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
250 CA line strength in ohms.
251 default: 40
252
253 rockchip,phy_lpddr4_ca_drv:
254 deprecated: true
255 $ref: /schemas/types.yaml#/definitions/uint32
256 description:
257 When the DRAM type is LPDDR4, this parameter defines the PHY side CA line
258 (including command address line) drive strength.
259 default: 40
260
261 rockchip,phy_lpddr4_ck_cs_drv:
262 deprecated: true
263 $ref: /schemas/types.yaml#/definitions/uint32
264 description:
265 When the DRAM type is LPDDR4, this parameter defines the PHY side clock
266 line and CS line drive strength.
267 default: 80
268
269 rockchip,phy_lpddr4_dq_drv:
270 deprecated: true
271 $ref: /schemas/types.yaml#/definitions/uint32
272 description:
273 When the DRAM type is LPDDR4, this parameter defines the PHY side DQ line
274 (including DQS/DQ/DM line) drive strength.
275 default: 80
276
277 rockchip,phy_lpddr4_odt:
278 deprecated: true
279 $ref: /schemas/types.yaml#/definitions/uint32
280 description:
281 When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
282 strength.
283 default: 60
284
285 rockchip,pd-idle-ns:
286 description:
287 Configure the PD_IDLE value in nanoseconds. Defines the power-down idle
288 period in which memories are placed into power-down mode if bus is idle
289 for PD_IDLE nanoseconds.
290
291 rockchip,sr-idle-ns:
292 description:
293 Configure the SR_IDLE value in nanoseconds. Defines the self-refresh idle
294 period in which memories are placed into self-refresh mode if bus is idle
295 for SR_IDLE nanoseconds.
296 default: 0
297
298 rockchip,sr-mc-gate-idle-ns:
299 description:
300 Defines the memory self-refresh and controller clock gating idle period in nanoseconds.
301 Memories are placed into self-refresh mode and memory controller clock
302 arg gating started if bus is idle for sr_mc_gate_idle nanoseconds.
303
304 rockchip,srpd-lite-idle-ns:
305 description:
306 Defines the self-refresh power down idle period in which memories are
307 placed into self-refresh power down mode if bus is idle for
308 srpd_lite_idle nanoseonds. This parameter is for LPDDR4 only.
309
310 rockchip,standby-idle-ns:
311 description:
312 Defines the standby idle period in which memories are placed into
313 self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
314 if bus is idle for standby_idle nanoseconds.
315
316 rockchip,pd-idle-dis-freq-hz:
317 description:
318 Defines the power-down idle disable frequency in Hz. When the DDR
319 frequency is greater than pd-idle-dis-freq, power-down idle is disabled.
320 See also rockchip,pd-idle-ns.
321
322 rockchip,sr-idle-dis-freq-hz:
323 description:
324 Defines the self-refresh idle disable frequency in Hz. When the DDR
325 frequency is greater than sr-idle-dis-freq, self-refresh idle is
326 disabled. See also rockchip,sr-idle-ns.
327
328 rockchip,sr-mc-gate-idle-dis-freq-hz:
329 description:
330 Defines the self-refresh and memory-controller clock gating disable
331 frequency in Hz. When the DDR frequency is greater than
332 sr-mc-gate-idle-dis-freq, the clock will not be gated when idle. See also
333 rockchip,sr-mc-gate-idle-ns.
334
335 rockchip,srpd-lite-idle-dis-freq-hz:
336 description:
337 Defines the self-refresh power down idle disable frequency in Hz. When
338 the DDR frequency is greater than srpd-lite-idle-dis-freq, memory will
339 not be placed into self-refresh power down mode when idle. See also
340 rockchip,srpd-lite-idle-ns.
341
342 rockchip,standby-idle-dis-freq-hz:
343 description:
344 Defines the standby idle disable frequency in Hz. When the DDR frequency
345 is greater than standby-idle-dis-freq, standby idle is disabled. See also
346 rockchip,standby-idle-ns.
347
348required:
349 - compatible
350 - devfreq-events
351 - clocks
352 - clock-names
353 - operating-points-v2
354 - center-supply
355
356additionalProperties: false
357
358examples:
359 - |
360 #include <dt-bindings/clock/rk3399-cru.h>
361 #include <dt-bindings/interrupt-controller/arm-gic.h>
362 memory-controller {
363 compatible = "rockchip,rk3399-dmc";
364 devfreq-events = <&dfi>;
365 rockchip,pmu = <&pmu>;
366 interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
367 clocks = <&cru SCLK_DDRC>;
368 clock-names = "dmc_clk";
369 operating-points-v2 = <&dmc_opp_table>;
370 center-supply = <&ppvar_centerlogic>;
371 rockchip,pd-idle-ns = <160>;
372 rockchip,sr-idle-ns = <10240>;
373 rockchip,sr-mc-gate-idle-ns = <40960>;
374 rockchip,srpd-lite-idle-ns = <61440>;
375 rockchip,standby-idle-ns = <81920>;
376 rockchip,ddr3_odt_dis_freq = <333000000>;
377 rockchip,lpddr3_odt_dis_freq = <333000000>;
378 rockchip,lpddr4_odt_dis_freq = <333000000>;
379 rockchip,pd-idle-dis-freq-hz = <1000000000>;
380 rockchip,sr-idle-dis-freq-hz = <1000000000>;
381 rockchip,sr-mc-gate-idle-dis-freq-hz = <1000000000>;
382 rockchip,srpd-lite-idle-dis-freq-hz = <0>;
383 rockchip,standby-idle-dis-freq-hz = <928000000>;
384 };
Documentation/power/energy-model.rst+22−2
@@ -123,6 +123,26 @@ allows a platform to register EM power values which are reflecting total power · 122 unmodified lines
123(static + dynamic). These power values might be coming directly from123(static + dynamic). These power values might be coming directly from
124experiments and measurements.124experiments and measurements.
125 125
126Registration of 'artificial' EM
127~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128
129There is an option to provide a custom callback for drivers missing detailed
130knowledge about power value for each performance state. The callback
131.get_cost() is optional and provides the 'cost' values used by the EAS.
132This is useful for platforms that only provide information on relative
133efficiency between CPU types, where one could use the information to
134create an abstract power model. But even an abstract power model can
135sometimes be hard to fit in, given the input power value size restrictions.
136The .get_cost() allows to provide the 'cost' values which reflect the
137efficiency of the CPUs. This would allow to provide EAS information which
138has different relation than what would be forced by the EM internal
139formulas calculating 'cost' values. To register an EM for such platform, the
140driver must set the flag 'milliwatts' to 0, provide .get_power() callback
141and provide .get_cost() callback. The EM framework would handle such platform
142properly during registration. A flag EM_PERF_DOMAIN_ARTIFICIAL is set for such
143platform. Special care should be taken by other frameworks which are using EM
144to test and treat this flag properly.
145
126Registration of 'simple' EM146Registration of 'simple' EM
127~~~~~~~~~~~~~~~~~~~~~~~~~~~147~~~~~~~~~~~~~~~~~~~~~~~~~~~
128 148
@@ -181,8 +201,8 @@ EM framework:: · 52 unmodified lines
181 201
182 -> drivers/cpufreq/foo_cpufreq.c202 -> drivers/cpufreq/foo_cpufreq.c
183 203
184 01 static int est_power(unsigned long *mW, unsigned long *KHz,204 01 static int est_power(struct device *dev, unsigned long *mW,
185 02 struct device *dev)205 02 unsigned long *KHz)
186 03 {206 03 {
187 04 long freq, power;207 04 long freq, power;
188 05208 05
arch/arm64/kernel/smp.c+1−0
@@ -512,6 +512,7 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu) · 511 unmodified lines
512{512{
513 return &cpu_madt_gicc[cpu];513 return &cpu_madt_gicc[cpu];
514}514}
515EXPORT_SYMBOL_GPL(acpi_cpu_get_madt_gicc);
515 516
516/*517/*
517 * acpi_map_gic_cpu_interface - parse processor MADT entry518 * acpi_map_gic_cpu_interface - parse processor MADT entry
arch/x86/include/asm/msr-index.h+1−0
@@ -319,6 +319,7 @@ · 318 unmodified lines
319 319
320/* Run Time Average Power Limiting (RAPL) Interface */320/* Run Time Average Power Limiting (RAPL) Interface */
321 321
322#define MSR_VR_CURRENT_CONFIG 0x00000601
322#define MSR_RAPL_POWER_UNIT 0x00000606323#define MSR_RAPL_POWER_UNIT 0x00000606
323 324
324#define MSR_PKG_POWER_LIMIT 0x00000610325#define MSR_PKG_POWER_LIMIT 0x00000610
arch/x86/kernel/acpi/boot.c+1−1
@@ -1862,7 +1862,7 @@ int __acpi_release_global_lock(unsigned int *lock) · 1861 unmodified lines
1862 1862
1863void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)1863void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
1864{1864{
1865 e820__range_add(addr, size, E820_TYPE_ACPI);1865 e820__range_add(addr, size, E820_TYPE_NVS);
1866 e820__update_table_print();1866 e820__update_table_print();
1867}1867}
1868 1868
drivers/acpi/bus.c+26−8
@@ -278,6 +278,20 @@ bool osc_sb_apei_support_acked; · 277 unmodified lines
278bool osc_pc_lpi_support_confirmed;278bool osc_pc_lpi_support_confirmed;
279EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);279EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
280 280
281/*
282 * ACPI 6.2 Section 6.2.11.2 'Platform-Wide OSPM Capabilities':
283 * Starting with ACPI Specification 6.2, all _CPC registers can be in
284 * PCC, System Memory, System IO, or Functional Fixed Hardware address
285 * spaces. OSPM support for this more flexible register space scheme is
286 * indicated by the “Flexible Address Space for CPPC Registers” _OSC bit.
287 *
288 * Otherwise (cf ACPI 6.1, s8.4.7.1.1.X), _CPC registers must be in:
289 * - PCC or Functional Fixed Hardware address space if defined
290 * - SystemMemory address space (NULL register) if not defined
291 */
292bool osc_cpc_flexible_adr_space_confirmed;
293EXPORT_SYMBOL_GPL(osc_cpc_flexible_adr_space_confirmed);
294
281/*295/*
282 * ACPI 6.4 Operating System Capabilities for USB.296 * ACPI 6.4 Operating System Capabilities for USB.
283 */297 */
@@ -315,12 +329,15 @@ static void acpi_bus_osc_negotiate_platform_control(void) · 31 unmodified lines
315#endif329#endif
316#ifdef CONFIG_X86330#ifdef CONFIG_X86
317 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;331 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
318 if (boot_cpu_has(X86_FEATURE_HWP)) {
319 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
320 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
321 }
322#endif332#endif
323 333
334#ifdef CONFIG_ACPI_CPPC_LIB
335 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
336 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
337#endif
338
339 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
340
324 if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))341 if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
325 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;342 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
326 343
@@ -341,10 +358,9 @@ static void acpi_bus_osc_negotiate_platform_control(void) · 14 unmodified lines
341 return;358 return;
342 }359 }
343 360
344#ifdef CONFIG_X86361#ifdef CONFIG_ACPI_CPPC_LIB
345 if (boot_cpu_has(X86_FEATURE_HWP))362 osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] &
346 osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] &363 (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT));
347 (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT));
348#endif364#endif
349 365
350 /*366 /*
@@ -366,6 +382,8 @@ static void acpi_bus_osc_negotiate_platform_control(void) · 15 unmodified lines
366 capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;382 capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
367 osc_sb_native_usb4_support_confirmed =383 osc_sb_native_usb4_support_confirmed =
368 capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;384 capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
385 osc_cpc_flexible_adr_space_confirmed =
386 capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
369 }387 }
370 388
371 kfree(context.ret.pointer);389 kfree(context.ret.pointer);
drivers/acpi/cppc_acpi.c+43−1
@@ -100,6 +100,16 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); · 99 unmodified lines
100 (cpc)->cpc_entry.reg.space_id == \100 (cpc)->cpc_entry.reg.space_id == \
101 ACPI_ADR_SPACE_PLATFORM_COMM)101 ACPI_ADR_SPACE_PLATFORM_COMM)
102 102
103/* Check if a CPC register is in SystemMemory */
104#define CPC_IN_SYSTEM_MEMORY(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
105 (cpc)->cpc_entry.reg.space_id == \
106 ACPI_ADR_SPACE_SYSTEM_MEMORY)
107
108/* Check if a CPC register is in SystemIo */
109#define CPC_IN_SYSTEM_IO(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
110 (cpc)->cpc_entry.reg.space_id == \
111 ACPI_ADR_SPACE_SYSTEM_IO)
112
103/* Evaluates to True if reg is a NULL register descriptor */113/* Evaluates to True if reg is a NULL register descriptor */
104#define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \114#define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \
105 (reg)->address == 0 && \115 (reg)->address == 0 && \
@@ -424,6 +434,24 @@ bool acpi_cpc_valid(void) · 318 unmodified lines
424}434}
425EXPORT_SYMBOL_GPL(acpi_cpc_valid);435EXPORT_SYMBOL_GPL(acpi_cpc_valid);
426 436
437bool cppc_allow_fast_switch(void)
438{
439 struct cpc_register_resource *desired_reg;
440 struct cpc_desc *cpc_ptr;
441 int cpu;
442
443 for_each_possible_cpu(cpu) {
444 cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
445 desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
446 if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
447 !CPC_IN_SYSTEM_IO(desired_reg))
448 return false;
449 }
450
451 return true;
452}
453EXPORT_SYMBOL_GPL(cppc_allow_fast_switch);
454
427/**455/**
428 * acpi_get_psd_map - Map the CPUs in the freq domain of a given cpu456 * acpi_get_psd_map - Map the CPUs in the freq domain of a given cpu
429 * @cpu: Find all CPUs that share a domain with cpu.457 * @cpu: Find all CPUs that share a domain with cpu.
@@ -736,6 +764,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) · 306 unmodified lines
736 if (gas_t->address) {764 if (gas_t->address) {
737 void __iomem *addr;765 void __iomem *addr;
738 766
767 if (!osc_cpc_flexible_adr_space_confirmed) {
768 pr_debug("Flexible address space capability not supported\n");
769 goto out_free;
770 }
771
739 addr = ioremap(gas_t->address, gas_t->bit_width/8);772 addr = ioremap(gas_t->address, gas_t->bit_width/8);
740 if (!addr)773 if (!addr)
741 goto out_free;774 goto out_free;
@@ -758,6 +791,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) · 16 unmodified lines
758 gas_t->address);791 gas_t->address);
759 goto out_free;792 goto out_free;
760 }793 }
794 if (!osc_cpc_flexible_adr_space_confirmed) {
795 pr_debug("Flexible address space capability not supported\n");
796 goto out_free;
797 }
761 } else {798 } else {
762 if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {799 if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {
763 /* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */800 /* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */
@@ -1447,6 +1484,9 @@ EXPORT_SYMBOL_GPL(cppc_set_perf); · 683 unmodified lines
1447 * transition latency for performance change requests. The closest we have1484 * transition latency for performance change requests. The closest we have
1448 * is the timing information from the PCCT tables which provides the info1485 * is the timing information from the PCCT tables which provides the info
1449 * on the number and frequency of PCC commands the platform can handle.1486 * on the number and frequency of PCC commands the platform can handle.
1487 *
1488 * If desired_reg is in the SystemMemory or SystemIo ACPI address space,
1489 * then assume there is no latency.
1450 */1490 */
1451unsigned int cppc_get_transition_latency(int cpu_num)1491unsigned int cppc_get_transition_latency(int cpu_num)
1452{1492{
@@ -1472,7 +1512,9 @@ unsigned int cppc_get_transition_latency(int cpu_num) · 19 unmodified lines
1472 return CPUFREQ_ETERNAL;1512 return CPUFREQ_ETERNAL;
1473 1513
1474 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];1514 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
1475 if (!CPC_IN_PCC(desired_reg))1515 if (CPC_IN_SYSTEM_MEMORY(desired_reg) || CPC_IN_SYSTEM_IO(desired_reg))
1516 return 0;
1517 else if (!CPC_IN_PCC(desired_reg))
1476 return CPUFREQ_ETERNAL;1518 return CPUFREQ_ETERNAL;
1477 1519
1478 if (pcc_ss_id < 0)1520 if (pcc_ss_id < 0)
drivers/base/power/common.c+4−4
@@ -172,10 +172,10 @@ EXPORT_SYMBOL_GPL(dev_pm_domain_attach_by_name); · 171 unmodified lines
172 * @dev: Device to detach.172 * @dev: Device to detach.
173 * @power_off: Used to indicate whether we should power off the device.173 * @power_off: Used to indicate whether we should power off the device.
174 *174 *
175 * This functions will reverse the actions from dev_pm_domain_attach() and175 * This functions will reverse the actions from dev_pm_domain_attach(),
176 * dev_pm_domain_attach_by_id(), thus it detaches @dev from its PM domain.176 * dev_pm_domain_attach_by_id() and dev_pm_domain_attach_by_name(), thus it
177 * Typically it should be invoked during the remove phase, either from177 * detaches @dev from its PM domain. Typically it should be invoked during the
178 * subsystem level code or from drivers.178 * remove phase, either from subsystem level code or from drivers.
179 *179 *
180 * Callers must ensure proper synchronization of this function with power180 * Callers must ensure proper synchronization of this function with power
181 * management callbacks.181 * management callbacks.
drivers/base/power/domain.c+170−108
@@ -131,7 +131,7 @@ static const struct genpd_lock_ops genpd_spin_ops = { · 130 unmodified lines
131#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)131#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
132#define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)132#define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
133 133
134static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,134static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
135 const struct generic_pm_domain *genpd)135 const struct generic_pm_domain *genpd)
136{136{
137 bool ret;137 bool ret;
@@ -139,11 +139,14 @@ static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev, · 1 unmodified line
139 ret = pm_runtime_is_irq_safe(dev) && !genpd_is_irq_safe(genpd);139 ret = pm_runtime_is_irq_safe(dev) && !genpd_is_irq_safe(genpd);
140 140
141 /*141 /*
142 * Warn once if an IRQ safe device is attached to a no sleep domain, as142 * Warn once if an IRQ safe device is attached to a domain, which
143 * to indicate a suboptimal configuration for PM. For an always on143 * callbacks are allowed to sleep. This indicates a suboptimal
144 * domain this isn't case, thus don't warn.144 * configuration for PM, but it doesn't matter for an always on domain.
145 */145 */
146 if (ret && !genpd_is_always_on(genpd))146 if (genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd))
147 return ret;
148
149 if (ret)
147 dev_warn_once(dev, "PM domain %s will not be powered off\n",150 dev_warn_once(dev, "PM domain %s will not be powered off\n",
148 genpd->name);151 genpd->name);
149 152
@@ -225,24 +228,23 @@ static void genpd_debug_remove(struct generic_pm_domain *genpd) · 75 unmodified lines
225 228
226static void genpd_update_accounting(struct generic_pm_domain *genpd)229static void genpd_update_accounting(struct generic_pm_domain *genpd)
227{230{
228 ktime_t delta, now;231 u64 delta, now;
229 232
230 now = ktime_get();233 now = ktime_get_mono_fast_ns();
231 delta = ktime_sub(now, genpd->accounting_time);234 if (now <= genpd->accounting_time)
235 return;
236
237 delta = now - genpd->accounting_time;
232 238
233 /*239 /*
234 * If genpd->status is active, it means we are just240 * If genpd->status is active, it means we are just
235 * out of off and so update the idle time and vice241 * out of off and so update the idle time and vice
236 * versa.242 * versa.
237 */243 */
238 if (genpd->status == GENPD_STATE_ON) {244 if (genpd->status == GENPD_STATE_ON)
239 int state_idx = genpd->state_idx;245 genpd->states[genpd->state_idx].idle_time += delta;
240 246 else
241 genpd->states[state_idx].idle_time =247 genpd->on_time += delta;
242 ktime_add(genpd->states[state_idx].idle_time, delta);
243 } else {
244 genpd->on_time = ktime_add(genpd->on_time, delta);
245 }
246 248
247 genpd->accounting_time = now;249 genpd->accounting_time = now;
248}250}
@@ -476,15 +478,16 @@ EXPORT_SYMBOL_GPL(dev_pm_genpd_set_performance_state); · 227 unmodified lines
476 */478 */
477void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next)479void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next)
478{480{
479 struct generic_pm_domain_data *gpd_data;
480 struct generic_pm_domain *genpd;481 struct generic_pm_domain *genpd;
482 struct gpd_timing_data *td;
481 483
482 genpd = dev_to_genpd_safe(dev);484 genpd = dev_to_genpd_safe(dev);
483 if (!genpd)485 if (!genpd)
484 return;486 return;
485 487
486 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);488 td = to_gpd_data(dev->power.subsys_data->domain_data)->td;
487 gpd_data->next_wakeup = next;489 if (td)
490 td->next_wakeup = next;
488}491}
489EXPORT_SYMBOL_GPL(dev_pm_genpd_set_next_wakeup);492EXPORT_SYMBOL_GPL(dev_pm_genpd_set_next_wakeup);
490 493
@@ -506,6 +509,7 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) · 15 unmodified lines
506 if (!genpd->power_on)509 if (!genpd->power_on)
507 goto out;510 goto out;
508 511
512 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode;
509 if (!timed) {513 if (!timed) {
510 ret = genpd->power_on(genpd);514 ret = genpd->power_on(genpd);
511 if (ret)515 if (ret)
@@ -524,7 +528,7 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) · 12 unmodified lines
524 goto out;528 goto out;
525 529
526 genpd->states[state_idx].power_on_latency_ns = elapsed_ns;530 genpd->states[state_idx].power_on_latency_ns = elapsed_ns;
527 genpd->max_off_time_changed = true;531 genpd->gd->max_off_time_changed = true;
528 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",532 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
529 genpd->name, "on", elapsed_ns);533 genpd->name, "on", elapsed_ns);
530 534
@@ -555,6 +559,7 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed) · 24 unmodified lines
555 if (!genpd->power_off)559 if (!genpd->power_off)
556 goto out;560 goto out;
557 561
562 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode;
558 if (!timed) {563 if (!timed) {
559 ret = genpd->power_off(genpd);564 ret = genpd->power_off(genpd);
560 if (ret)565 if (ret)
@@ -573,7 +578,7 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed) · 12 unmodified lines
573 goto out;578 goto out;
574 579
575 genpd->states[state_idx].power_off_latency_ns = elapsed_ns;580 genpd->states[state_idx].power_off_latency_ns = elapsed_ns;
576 genpd->max_off_time_changed = true;581 genpd->gd->max_off_time_changed = true;
577 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",582 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
578 genpd->name, "off", elapsed_ns);583 genpd->name, "off", elapsed_ns);
579 584
@@ -649,18 +654,12 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, · 69 unmodified lines
649 }654 }
650 655
651 list_for_each_entry(pdd, &genpd->dev_list, list_node) {656 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
652 enum pm_qos_flags_status stat;
653
654 stat = dev_pm_qos_flags(pdd->dev, PM_QOS_FLAG_NO_POWER_OFF);
655 if (stat > PM_QOS_FLAGS_NONE)
656 return -EBUSY;
657
658 /*657 /*
659 * Do not allow PM domain to be powered off, when an IRQ safe658 * Do not allow PM domain to be powered off, when an IRQ safe
660 * device is part of a non-IRQ safe domain.659 * device is part of a non-IRQ safe domain.
661 */660 */
662 if (!pm_runtime_suspended(pdd->dev) ||661 if (!pm_runtime_suspended(pdd->dev) ||
663 irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd))662 irq_safe_dev_in_sleep_domain(pdd->dev, genpd))
664 not_suspended++;663 not_suspended++;
665 }664 }
666 665
@@ -775,25 +774,27 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, · 108 unmodified lines
775 dev = gpd_data->base.dev;774 dev = gpd_data->base.dev;
776 775
777 for (;;) {776 for (;;) {
778 struct generic_pm_domain *genpd;777 struct generic_pm_domain *genpd = ERR_PTR(-ENODATA);
779 struct pm_domain_data *pdd;778 struct pm_domain_data *pdd;
779 struct gpd_timing_data *td;
780 780
781 spin_lock_irq(&dev->power.lock);781 spin_lock_irq(&dev->power.lock);
782 782
783 pdd = dev->power.subsys_data ?783 pdd = dev->power.subsys_data ?
784 dev->power.subsys_data->domain_data : NULL;784 dev->power.subsys_data->domain_data : NULL;
785 if (pdd) {785 if (pdd) {
786 to_gpd_data(pdd)->td.constraint_changed = true;786 td = to_gpd_data(pdd)->td;
787 genpd = dev_to_genpd(dev);787 if (td) {
788 } else {788 td->constraint_changed = true;
789 genpd = ERR_PTR(-ENODATA);789 genpd = dev_to_genpd(dev);
790 }
790 }791 }
791 792
792 spin_unlock_irq(&dev->power.lock);793 spin_unlock_irq(&dev->power.lock);
793 794
794 if (!IS_ERR(genpd)) {795 if (!IS_ERR(genpd)) {
795 genpd_lock(genpd);796 genpd_lock(genpd);
796 genpd->max_off_time_changed = true;797 genpd->gd->max_off_time_changed = true;
797 genpd_unlock(genpd);798 genpd_unlock(genpd);
798 }799 }
799 800
@@ -879,9 +880,9 @@ static int genpd_runtime_suspend(struct device *dev) · 79 unmodified lines
879 struct generic_pm_domain *genpd;880 struct generic_pm_domain *genpd;
880 bool (*suspend_ok)(struct device *__dev);881 bool (*suspend_ok)(struct device *__dev);
881 struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);882 struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
882 struct gpd_timing_data *td = &gpd_data->td;883 struct gpd_timing_data *td = gpd_data->td;
883 bool runtime_pm = pm_runtime_enabled(dev);884 bool runtime_pm = pm_runtime_enabled(dev);
884 ktime_t time_start;885 ktime_t time_start = 0;
885 s64 elapsed_ns;886 s64 elapsed_ns;
886 int ret;887 int ret;
887 888
@@ -902,8 +903,7 @@ static int genpd_runtime_suspend(struct device *dev) · 14 unmodified lines
902 return -EBUSY;903 return -EBUSY;
903 904
904 /* Measure suspend latency. */905 /* Measure suspend latency. */
905 time_start = 0;906 if (td && runtime_pm)
906 if (runtime_pm)
907 time_start = ktime_get();907 time_start = ktime_get();
908 908
909 ret = __genpd_runtime_suspend(dev);909 ret = __genpd_runtime_suspend(dev);
@@ -917,13 +917,13 @@ static int genpd_runtime_suspend(struct device *dev) · 7 unmodified lines
917 }917 }
918 918
919 /* Update suspend latency value if the measured time exceeds it. */919 /* Update suspend latency value if the measured time exceeds it. */
920 if (runtime_pm) {920 if (td && runtime_pm) {
921 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));921 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
922 if (elapsed_ns > td->suspend_latency_ns) {922 if (elapsed_ns > td->suspend_latency_ns) {
923 td->suspend_latency_ns = elapsed_ns;923 td->suspend_latency_ns = elapsed_ns;
924 dev_dbg(dev, "suspend latency exceeded, %lld ns\n",924 dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
925 elapsed_ns);925 elapsed_ns);
926 genpd->max_off_time_changed = true;926 genpd->gd->max_off_time_changed = true;
927 td->constraint_changed = true;927 td->constraint_changed = true;
928 }928 }
929 }929 }
@@ -932,7 +932,7 @@ static int genpd_runtime_suspend(struct device *dev) · 2 unmodified lines
932 * If power.irq_safe is set, this routine may be run with932 * If power.irq_safe is set, this routine may be run with
933 * IRQs disabled, so suspend only if the PM domain also is irq_safe.933 * IRQs disabled, so suspend only if the PM domain also is irq_safe.
934 */934 */
935 if (irq_safe_dev_in_no_sleep_domain(dev, genpd))935 if (irq_safe_dev_in_sleep_domain(dev, genpd))
936 return 0;936 return 0;
937 937
938 genpd_lock(genpd);938 genpd_lock(genpd);
@@ -955,12 +955,11 @@ static int genpd_runtime_resume(struct device *dev) · 16 unmodified lines
955{955{
956 struct generic_pm_domain *genpd;956 struct generic_pm_domain *genpd;
957 struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);957 struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
958 struct gpd_timing_data *td = &gpd_data->td;958 struct gpd_timing_data *td = gpd_data->td;
959 bool runtime_pm = pm_runtime_enabled(dev);959 bool timed = td && pm_runtime_enabled(dev);
960 ktime_t time_start;960 ktime_t time_start = 0;
961 s64 elapsed_ns;961 s64 elapsed_ns;
962 int ret;962 int ret;
963 bool timed = true;
964 963
965 dev_dbg(dev, "%s()\n", __func__);964 dev_dbg(dev, "%s()\n", __func__);
966 965
@@ -972,10 +971,8 @@ static int genpd_runtime_resume(struct device *dev) · 5 unmodified lines
972 * As we don't power off a non IRQ safe domain, which holds971 * As we don't power off a non IRQ safe domain, which holds
973 * an IRQ safe device, we don't need to restore power to it.972 * an IRQ safe device, we don't need to restore power to it.
974 */973 */
975 if (irq_safe_dev_in_no_sleep_domain(dev, genpd)) {974 if (irq_safe_dev_in_sleep_domain(dev, genpd))
976 timed = false;
977 goto out;975 goto out;
978 }
979 976
980 genpd_lock(genpd);977 genpd_lock(genpd);
981 ret = genpd_power_on(genpd, 0);978 ret = genpd_power_on(genpd, 0);
@@ -988,8 +985,7 @@ static int genpd_runtime_resume(struct device *dev) · 6 unmodified lines
988 985
989 out:986 out:
990 /* Measure resume latency. */987 /* Measure resume latency. */
991 time_start = 0;988 if (timed)
992 if (timed && runtime_pm)
993 time_start = ktime_get();989 time_start = ktime_get();
994 990
995 ret = genpd_start_dev(genpd, dev);991 ret = genpd_start_dev(genpd, dev);
@@ -1001,13 +997,13 @@ static int genpd_runtime_resume(struct device *dev) · 5 unmodified lines
1001 goto err_stop;997 goto err_stop;
1002 998
1003 /* Update resume latency value if the measured time exceeds it. */999 /* Update resume latency value if the measured time exceeds it. */
1004 if (timed && runtime_pm) {1000 if (timed) {
1005 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));1001 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
1006 if (elapsed_ns > td->resume_latency_ns) {1002 if (elapsed_ns > td->resume_latency_ns) {
1007 td->resume_latency_ns = elapsed_ns;1003 td->resume_latency_ns = elapsed_ns;
1008 dev_dbg(dev, "resume latency exceeded, %lld ns\n",1004 dev_dbg(dev, "resume latency exceeded, %lld ns\n",
1009 elapsed_ns);1005 elapsed_ns);
1010 genpd->max_off_time_changed = true;1006 genpd->gd->max_off_time_changed = true;
1011 td->constraint_changed = true;1007 td->constraint_changed = true;
1012 }1008 }
1013 }1009 }
@@ -1500,9 +1496,11 @@ EXPORT_SYMBOL_GPL(dev_pm_genpd_resume); · 486 unmodified lines
1500 1496
1501#endif /* CONFIG_PM_SLEEP */1497#endif /* CONFIG_PM_SLEEP */
1502 1498
1503static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)1499static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
1500 bool has_governor)
1504{1501{
1505 struct generic_pm_domain_data *gpd_data;1502 struct generic_pm_domain_data *gpd_data;
1503 struct gpd_timing_data *td;
1506 int ret;1504 int ret;
1507 1505
1508 ret = dev_pm_get_subsys_data(dev);1506 ret = dev_pm_get_subsys_data(dev);
@@ -1516,26 +1514,38 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev) · 7 unmodified lines
1516 }1514 }
1517 1515
1518 gpd_data->base.dev = dev;1516 gpd_data->base.dev = dev;
1519 gpd_data->td.constraint_changed = true;
1520 gpd_data->td.effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS;
1521 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;1517 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
1522 gpd_data->next_wakeup = KTIME_MAX;
1523 1518
1524 spin_lock_irq(&dev->power.lock);1519 /* Allocate data used by a governor. */
1520 if (has_governor) {
1521 td = kzalloc(sizeof(*td), GFP_KERNEL);
1522 if (!td) {
1523 ret = -ENOMEM;
1524 goto err_free;
1525 }
1525 1526
1526 if (dev->power.subsys_data->domain_data) {1527 td->constraint_changed = true;
1527 ret = -EINVAL;1528 td->effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS;
1528 goto err_free;1529 td->next_wakeup = KTIME_MAX;
1530 gpd_data->td = td;
1529 }1531 }
1530 1532
1531 dev->power.subsys_data->domain_data = &gpd_data->base;1533 spin_lock_irq(&dev->power.lock);
1534
1535 if (dev->power.subsys_data->domain_data)
1536 ret = -EINVAL;
1537 else
1538 dev->power.subsys_data->domain_data = &gpd_data->base;
1532 1539
1533 spin_unlock_irq(&dev->power.lock);1540 spin_unlock_irq(&dev->power.lock);
1534 1541
1542 if (ret)
1543 goto err_free;
1544
1535 return gpd_data;1545 return gpd_data;
1536 1546
1537 err_free:1547 err_free:
1538 spin_unlock_irq(&dev->power.lock);1548 kfree(gpd_data->td);
1539 kfree(gpd_data);1549 kfree(gpd_data);
1540 err_put:1550 err_put:
1541 dev_pm_put_subsys_data(dev);1551 dev_pm_put_subsys_data(dev);
@@ -1551,6 +1561,7 @@ static void genpd_free_dev_data(struct device *dev, · 9 unmodified lines
1551 1561
1552 spin_unlock_irq(&dev->power.lock);1562 spin_unlock_irq(&dev->power.lock);
1553 1563
1564 kfree(gpd_data->td);
1554 kfree(gpd_data);1565 kfree(gpd_data);
1555 dev_pm_put_subsys_data(dev);1566 dev_pm_put_subsys_data(dev);
1556}1567}
@@ -1607,6 +1618,7 @@ static int genpd_get_cpu(struct generic_pm_domain *genpd, struct device *dev) · 50 unmodified lines
1607static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,1618static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1608 struct device *base_dev)1619 struct device *base_dev)
1609{1620{
1621 struct genpd_governor_data *gd = genpd->gd;
1610 struct generic_pm_domain_data *gpd_data;1622 struct generic_pm_domain_data *gpd_data;
1611 int ret;1623 int ret;
1612 1624
@@ -1615,7 +1627,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, · 2 unmodified lines
1615 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))1627 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1616 return -EINVAL;1628 return -EINVAL;
1617 1629
1618 gpd_data = genpd_alloc_dev_data(dev);1630 gpd_data = genpd_alloc_dev_data(dev, gd);
1619 if (IS_ERR(gpd_data))1631 if (IS_ERR(gpd_data))
1620 return PTR_ERR(gpd_data);1632 return PTR_ERR(gpd_data);
1621 1633
@@ -1631,7 +1643,8 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, · 9 unmodified lines
1631 dev_pm_domain_set(dev, &genpd->domain);1643 dev_pm_domain_set(dev, &genpd->domain);
1632 1644
1633 genpd->device_count++;1645 genpd->device_count++;
1634 genpd->max_off_time_changed = true;1646 if (gd)
1647 gd->max_off_time_changed = true;
1635 1648
1636 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);1649 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
1637 1650
@@ -1685,7 +1698,8 @@ static int genpd_remove_device(struct generic_pm_domain *genpd, · 47 unmodified lines
1685 }1698 }
1686 1699
1687 genpd->device_count--;1700 genpd->device_count--;
1688 genpd->max_off_time_changed = true;1701 if (genpd->gd)
1702 genpd->gd->max_off_time_changed = true;
1689 1703
1690 genpd_clear_cpumask(genpd, gpd_data->cpu);1704 genpd_clear_cpumask(genpd, gpd_data->cpu);
1691 dev_pm_domain_set(dev, NULL);1705 dev_pm_domain_set(dev, NULL);
@@ -1958,6 +1972,53 @@ static int genpd_set_default_power_state(struct generic_pm_domain *genpd) · 266 unmodified lines
1958 return 0;1972 return 0;
1959}1973}
1960 1974
1975static int genpd_alloc_data(struct generic_pm_domain *genpd)
1976{
1977 struct genpd_governor_data *gd = NULL;
1978 int ret;
1979
1980 if (genpd_is_cpu_domain(genpd) &&
1981 !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL))
1982 return -ENOMEM;
1983
1984 if (genpd->gov) {
1985 gd = kzalloc(sizeof(*gd), GFP_KERNEL);
1986 if (!gd) {
1987 ret = -ENOMEM;
1988 goto free;
1989 }
1990
1991 gd->max_off_time_ns = -1;
1992 gd->max_off_time_changed = true;
1993 gd->next_wakeup = KTIME_MAX;
1994 }
1995
1996 /* Use only one "off" state if there were no states declared */
1997 if (genpd->state_count == 0) {
1998 ret = genpd_set_default_power_state(genpd);
1999 if (ret)
2000 goto free;
2001 }
2002
2003 genpd->gd = gd;
2004 return 0;
2005
2006free:
2007 if (genpd_is_cpu_domain(genpd))
2008 free_cpumask_var(genpd->cpus);
2009 kfree(gd);
2010 return ret;
2011}
2012
2013static void genpd_free_data(struct generic_pm_domain *genpd)
2014{
2015 if (genpd_is_cpu_domain(genpd))
2016 free_cpumask_var(genpd->cpus);
2017 if (genpd->free_states)
2018 genpd->free_states(genpd->states, genpd->state_count);
2019 kfree(genpd->gd);
2020}
2021
1961static void genpd_lock_init(struct generic_pm_domain *genpd)2022static void genpd_lock_init(struct generic_pm_domain *genpd)
1962{2023{
1963 if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {2024 if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
@@ -1995,11 +2056,9 @@ int pm_genpd_init(struct generic_pm_domain *genpd, · 31 unmodified lines
1995 atomic_set(&genpd->sd_count, 0);2056 atomic_set(&genpd->sd_count, 0);
1996 genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON;2057 genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON;
1997 genpd->device_count = 0;2058 genpd->device_count = 0;
1998 genpd->max_off_time_ns = -1;
1999 genpd->max_off_time_changed = true;
2000 genpd->provider = NULL;2059 genpd->provider = NULL;
2001 genpd->has_provider = false;2060 genpd->has_provider = false;
2002 genpd->accounting_time = ktime_get();2061 genpd->accounting_time = ktime_get_mono_fast_ns();
2003 genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;2062 genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
2004 genpd->domain.ops.runtime_resume = genpd_runtime_resume;2063 genpd->domain.ops.runtime_resume = genpd_runtime_resume;
2005 genpd->domain.ops.prepare = genpd_prepare;2064 genpd->domain.ops.prepare = genpd_prepare;
@@ -2017,26 +2076,22 @@ int pm_genpd_init(struct generic_pm_domain *genpd, · 11 unmodified lines
2017 genpd->dev_ops.start = pm_clk_resume;2076 genpd->dev_ops.start = pm_clk_resume;
2018 }2077 }
2019 2078
2079 /* The always-on governor works better with the corresponding flag. */
2080 if (gov == &pm_domain_always_on_gov)
2081 genpd->flags |= GENPD_FLAG_RPM_ALWAYS_ON;
2082
2020 /* Always-on domains must be powered on at initialization. */2083 /* Always-on domains must be powered on at initialization. */
2021 if ((genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) &&2084 if ((genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) &&
2022 !genpd_status_on(genpd))2085 !genpd_status_on(genpd))
2023 return -EINVAL;2086 return -EINVAL;
2024 2087
2025 if (genpd_is_cpu_domain(genpd) &&2088 /* Multiple states but no governor doesn't make sense. */
2026 !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL))2089 if (!gov && genpd->state_count > 1)
2027 return -ENOMEM;
2028
2029 /* Use only one "off" state if there were no states declared */
2030 if (genpd->state_count == 0) {
2031 ret = genpd_set_default_power_state(genpd);
2032 if (ret) {
2033 if (genpd_is_cpu_domain(genpd))
2034 free_cpumask_var(genpd->cpus);
2035 return ret;
2036 }
2037 } else if (!gov && genpd->state_count > 1) {
2038 pr_warn("%s: no governor for states\n", genpd->name);2090 pr_warn("%s: no governor for states\n", genpd->name);
2039 }2091
2092 ret = genpd_alloc_data(genpd);
2093 if (ret)
2094 return ret;
2040 2095
2041 device_initialize(&genpd->dev);2096 device_initialize(&genpd->dev);
2042 dev_set_name(&genpd->dev, "%s", genpd->name);2097 dev_set_name(&genpd->dev, "%s", genpd->name);
@@ -2081,10 +2136,7 @@ static int genpd_remove(struct generic_pm_domain *genpd) · 38 unmodified lines
2081 genpd_unlock(genpd);2136 genpd_unlock(genpd);
2082 genpd_debug_remove(genpd);2137 genpd_debug_remove(genpd);
2083 cancel_work_sync(&genpd->power_off_work);2138 cancel_work_sync(&genpd->power_off_work);
2084 if (genpd_is_cpu_domain(genpd))2139 genpd_free_data(genpd);
2085 free_cpumask_var(genpd->cpus);
2086 if (genpd->free_states)
2087 genpd->free_states(genpd->states, genpd->state_count);
2088 2140
2089 pr_debug("%s: removed %s\n", __func__, genpd->name);2141 pr_debug("%s: removed %s\n", __func__, genpd->name);
2090 2142
@@ -3163,6 +3215,7 @@ static int sub_domains_show(struct seq_file *s, void *data) · 1072 unmodified lines
3163static int idle_states_show(struct seq_file *s, void *data)3215static int idle_states_show(struct seq_file *s, void *data)
3164{3216{
3165 struct generic_pm_domain *genpd = s->private;3217 struct generic_pm_domain *genpd = s->private;
3218 u64 now, delta, idle_time = 0;
3166 unsigned int i;3219 unsigned int i;
3167 int ret = 0;3220 int ret = 0;
3168 3221
@@ -3173,17 +3226,19 @@ static int idle_states_show(struct seq_file *s, void *data) · 4 unmodified lines
3173 seq_puts(s, "State Time Spent(ms) Usage Rejected\n");3226 seq_puts(s, "State Time Spent(ms) Usage Rejected\n");
3174 3227
3175 for (i = 0; i < genpd->state_count; i++) {3228 for (i = 0; i < genpd->state_count; i++) {
3176 ktime_t delta = 0;3229 idle_time += genpd->states[i].idle_time;
3177 s64 msecs;
3178 3230
3179 if ((genpd->status == GENPD_STATE_OFF) &&3231 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) {
3180 (genpd->state_idx == i))3232 now = ktime_get_mono_fast_ns();
3181 delta = ktime_sub(ktime_get(), genpd->accounting_time);3233 if (now > genpd->accounting_time) {
3234 delta = now - genpd->accounting_time;
3235 idle_time += delta;
3236 }
3237 }
3182 3238
3183 msecs = ktime_to_ms(3239 do_div(idle_time, NSEC_PER_MSEC);
3184 ktime_add(genpd->states[i].idle_time, delta));3240 seq_printf(s, "S%-13i %-14llu %-14llu %llu\n", i, idle_time,
3185 seq_printf(s, "S%-13i %-14lld %-14llu %llu\n", i, msecs,3241 genpd->states[i].usage, genpd->states[i].rejected);
3186 genpd->states[i].usage, genpd->states[i].rejected);
3187 }3242 }
3188 3243
3189 genpd_unlock(genpd);3244 genpd_unlock(genpd);
@@ -3193,18 +3248,22 @@ static int idle_states_show(struct seq_file *s, void *data) · 3 unmodified lines
3193static int active_time_show(struct seq_file *s, void *data)3248static int active_time_show(struct seq_file *s, void *data)
3194{3249{
3195 struct generic_pm_domain *genpd = s->private;3250 struct generic_pm_domain *genpd = s->private;
3196 ktime_t delta = 0;3251 u64 now, on_time, delta = 0;
3197 int ret = 0;3252 int ret = 0;
3198 3253
3199 ret = genpd_lock_interruptible(genpd);3254 ret = genpd_lock_interruptible(genpd);
3200 if (ret)3255 if (ret)
3201 return -ERESTARTSYS;3256 return -ERESTARTSYS;
3202 3257
3203 if (genpd->status == GENPD_STATE_ON)3258 if (genpd->status == GENPD_STATE_ON) {
3204 delta = ktime_sub(ktime_get(), genpd->accounting_time);3259 now = ktime_get_mono_fast_ns();
3260 if (now > genpd->accounting_time)
3261 delta = now - genpd->accounting_time;
3262 }
3205 3263
3206 seq_printf(s, "%lld ms\n", ktime_to_ms(3264 on_time = genpd->on_time + delta;
3207 ktime_add(genpd->on_time, delta)));3265 do_div(on_time, NSEC_PER_MSEC);
3266 seq_printf(s, "%llu ms\n", on_time);
3208 3267
3209 genpd_unlock(genpd);3268 genpd_unlock(genpd);
3210 return ret;3269 return ret;
@@ -3213,7 +3272,7 @@ static int active_time_show(struct seq_file *s, void *data) · 2 unmodified lines
3213static int total_idle_time_show(struct seq_file *s, void *data)3272static int total_idle_time_show(struct seq_file *s, void *data)
3214{3273{
3215 struct generic_pm_domain *genpd = s->private;3274 struct generic_pm_domain *genpd = s->private;
3216 ktime_t delta = 0, total = 0;3275 u64 now, delta, total = 0;
3217 unsigned int i;3276 unsigned int i;
3218 int ret = 0;3277 int ret = 0;
3219 3278
@@ -3222,16 +3281,19 @@ static int total_idle_time_show(struct seq_file *s, void *data) · 2 unmodified lines
3222 return -ERESTARTSYS;3281 return -ERESTARTSYS;
3223 3282
3224 for (i = 0; i < genpd->state_count; i++) {3283 for (i = 0; i < genpd->state_count; i++) {
3284 total += genpd->states[i].idle_time;
3225 3285
3226 if ((genpd->status == GENPD_STATE_OFF) &&3286 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) {
3227 (genpd->state_idx == i))3287 now = ktime_get_mono_fast_ns();
3228 delta = ktime_sub(ktime_get(), genpd->accounting_time);3288 if (now > genpd->accounting_time) {
3229 3289 delta = now - genpd->accounting_time;
3230 total = ktime_add(total, genpd->states[i].idle_time);3290 total += delta;
3291 }
3292 }
3231 }3293 }
3232 total = ktime_add(total, delta);
3233 3294
3234 seq_printf(s, "%lld ms\n", ktime_to_ms(total));3295 do_div(total, NSEC_PER_MSEC);
3296 seq_printf(s, "%llu ms\n", total);
3235 3297
3236 genpd_unlock(genpd);3298 genpd_unlock(genpd);
3237 return ret;3299 return ret;
drivers/base/power/domain_governor.c+35−30
@@ -18,6 +18,8 @@ static int dev_update_qos_constraint(struct device *dev, void *data) · 17 unmodified lines
18 s64 constraint_ns;18 s64 constraint_ns;
19 19
20 if (dev->power.subsys_data && dev->power.subsys_data->domain_data) {20 if (dev->power.subsys_data && dev->power.subsys_data->domain_data) {
21 struct gpd_timing_data *td = dev_gpd_data(dev)->td;
22
21 /*23 /*
22 * Only take suspend-time QoS constraints of devices into24 * Only take suspend-time QoS constraints of devices into
23 * account, because constraints updated after the device has25 * account, because constraints updated after the device has
@@ -25,7 +27,8 @@ static int dev_update_qos_constraint(struct device *dev, void *data) · 1 unmodified line
25 * anyway. In order for them to take effect, the device has to27 * anyway. In order for them to take effect, the device has to
26 * be resumed and suspended again.28 * be resumed and suspended again.
27 */29 */
28 constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns;30 constraint_ns = td ? td->effective_constraint_ns :
31 PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS;
29 } else {32 } else {
30 /*33 /*
31 * The child is not in a domain and there's no info on its34 * The child is not in a domain and there's no info on its
@@ -49,7 +52,7 @@ static int dev_update_qos_constraint(struct device *dev, void *data) · 17 unmodified lines
49 */52 */
50static bool default_suspend_ok(struct device *dev)53static bool default_suspend_ok(struct device *dev)
51{54{
52 struct gpd_timing_data *td = &dev_gpd_data(dev)->td;55 struct gpd_timing_data *td = dev_gpd_data(dev)->td;
53 unsigned long flags;56 unsigned long flags;
54 s64 constraint_ns;57 s64 constraint_ns;
55 58
@@ -136,26 +139,28 @@ static void update_domain_next_wakeup(struct generic_pm_domain *genpd, ktime_t n · 80 unmodified lines
136 * is able to enter its optimal idle state.139 * is able to enter its optimal idle state.
137 */140 */
138 list_for_each_entry(pdd, &genpd->dev_list, list_node) {141 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
139 next_wakeup = to_gpd_data(pdd)->next_wakeup;142 next_wakeup = to_gpd_data(pdd)->td->next_wakeup;
140 if (next_wakeup != KTIME_MAX && !ktime_before(next_wakeup, now))143 if (next_wakeup != KTIME_MAX && !ktime_before(next_wakeup, now))
141 if (ktime_before(next_wakeup, domain_wakeup))144 if (ktime_before(next_wakeup, domain_wakeup))
142 domain_wakeup = next_wakeup;145 domain_wakeup = next_wakeup;
143 }146 }
144 147
145 list_for_each_entry(link, &genpd->parent_links, parent_node) {148 list_for_each_entry(link, &genpd->parent_links, parent_node) {
146 next_wakeup = link->child->next_wakeup;149 struct genpd_governor_data *cgd = link->child->gd;
150
151 next_wakeup = cgd ? cgd->next_wakeup : KTIME_MAX;
147 if (next_wakeup != KTIME_MAX && !ktime_before(next_wakeup, now))152 if (next_wakeup != KTIME_MAX && !ktime_before(next_wakeup, now))
148 if (ktime_before(next_wakeup, domain_wakeup))153 if (ktime_before(next_wakeup, domain_wakeup))
149 domain_wakeup = next_wakeup;154 domain_wakeup = next_wakeup;
150 }155 }
151 156
152 genpd->next_wakeup = domain_wakeup;157 genpd->gd->next_wakeup = domain_wakeup;
153}158}
154 159
155static bool next_wakeup_allows_state(struct generic_pm_domain *genpd,160static bool next_wakeup_allows_state(struct generic_pm_domain *genpd,
156 unsigned int state, ktime_t now)161 unsigned int state, ktime_t now)
157{162{
158 ktime_t domain_wakeup = genpd->next_wakeup;163 ktime_t domain_wakeup = genpd->gd->next_wakeup;
159 s64 idle_time_ns, min_sleep_ns;164 s64 idle_time_ns, min_sleep_ns;
160 165
161 min_sleep_ns = genpd->states[state].power_off_latency_ns +166 min_sleep_ns = genpd->states[state].power_off_latency_ns +
@@ -185,8 +190,9 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, · 23 unmodified lines
185 * All subdomains have been powered off already at this point.190 * All subdomains have been powered off already at this point.
186 */191 */
187 list_for_each_entry(link, &genpd->parent_links, parent_node) {192 list_for_each_entry(link, &genpd->parent_links, parent_node) {
188 struct generic_pm_domain *sd = link->child;193 struct genpd_governor_data *cgd = link->child->gd;
189 s64 sd_max_off_ns = sd->max_off_time_ns;194
195 s64 sd_max_off_ns = cgd ? cgd->max_off_time_ns : -1;
190 196
191 if (sd_max_off_ns < 0)197 if (sd_max_off_ns < 0)
192 continue;198 continue;
@@ -215,7 +221,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, · 22 unmodified lines
215 * domain to turn off and on (that's how much time it will221 * domain to turn off and on (that's how much time it will
216 * have to wait worst case).222 * have to wait worst case).
217 */223 */
218 td = &to_gpd_data(pdd)->td;224 td = to_gpd_data(pdd)->td;
219 constraint_ns = td->effective_constraint_ns;225 constraint_ns = td->effective_constraint_ns;
220 /*226 /*
221 * Zero means "no suspend at all" and this runs only when all227 * Zero means "no suspend at all" and this runs only when all
@@ -244,7 +250,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, · 22 unmodified lines
244 * time and the time needed to turn the domain on is the maximum250 * time and the time needed to turn the domain on is the maximum
245 * theoretical time this domain can spend in the "off" state.251 * theoretical time this domain can spend in the "off" state.
246 */252 */
247 genpd->max_off_time_ns = min_off_time_ns -253 genpd->gd->max_off_time_ns = min_off_time_ns -
248 genpd->states[state].power_on_latency_ns;254 genpd->states[state].power_on_latency_ns;
249 return true;255 return true;
250}256}
@@ -259,6 +265,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, · 8 unmodified lines
259static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now)265static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now)
260{266{
261 struct generic_pm_domain *genpd = pd_to_genpd(pd);267 struct generic_pm_domain *genpd = pd_to_genpd(pd);
268 struct genpd_governor_data *gd = genpd->gd;
262 int state_idx = genpd->state_count - 1;269 int state_idx = genpd->state_count - 1;
263 struct gpd_link *link;270 struct gpd_link *link;
264 271
@@ -269,11 +276,11 @@ static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now) · 4 unmodified lines
269 * cannot be met.276 * cannot be met.
270 */277 */
271 update_domain_next_wakeup(genpd, now);278 update_domain_next_wakeup(genpd, now);
272 if ((genpd->flags & GENPD_FLAG_MIN_RESIDENCY) && (genpd->next_wakeup != KTIME_MAX)) {279 if ((genpd->flags & GENPD_FLAG_MIN_RESIDENCY) && (gd->next_wakeup != KTIME_MAX)) {
273 /* Let's find out the deepest domain idle state, the devices prefer */280 /* Let's find out the deepest domain idle state, the devices prefer */
274 while (state_idx >= 0) {281 while (state_idx >= 0) {
275 if (next_wakeup_allows_state(genpd, state_idx, now)) {282 if (next_wakeup_allows_state(genpd, state_idx, now)) {
276 genpd->max_off_time_changed = true;283 gd->max_off_time_changed = true;
277 break;284 break;
278 }285 }
279 state_idx--;286 state_idx--;
@@ -281,14 +288,14 @@ static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now) · 1 unmodified line
281 288
282 if (state_idx < 0) {289 if (state_idx < 0) {
283 state_idx = 0;290 state_idx = 0;
284 genpd->cached_power_down_ok = false;291 gd->cached_power_down_ok = false;
285 goto done;292 goto done;
286 }293 }
287 }294 }
288 295
289 if (!genpd->max_off_time_changed) {296 if (!gd->max_off_time_changed) {
290 genpd->state_idx = genpd->cached_power_down_state_idx;297 genpd->state_idx = gd->cached_power_down_state_idx;
291 return genpd->cached_power_down_ok;298 return gd->cached_power_down_ok;
292 }299 }
293 300
294 /*301 /*
@@ -297,12 +304,16 @@ static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now) · 2 unmodified lines
297 * going to be called for any parent until this instance304 * going to be called for any parent until this instance
298 * returns.305 * returns.
299 */306 */
300 list_for_each_entry(link, &genpd->child_links, child_node)307 list_for_each_entry(link, &genpd->child_links, child_node) {
301 link->parent->max_off_time_changed = true;308 struct genpd_governor_data *pgd = link->parent->gd;
309
310 if (pgd)
311 pgd->max_off_time_changed = true;
312 }
302 313
303 genpd->max_off_time_ns = -1;314 gd->max_off_time_ns = -1;
304 genpd->max_off_time_changed = false;315 gd->max_off_time_changed = false;
305 genpd->cached_power_down_ok = true;316 gd->cached_power_down_ok = true;
306 317
307 /*318 /*
308 * Find a state to power down to, starting from the state319 * Find a state to power down to, starting from the state
@@ -310,7 +321,7 @@ static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now) · 1 unmodified line
310 */321 */
311 while (!__default_power_down_ok(pd, state_idx)) {322 while (!__default_power_down_ok(pd, state_idx)) {
312 if (state_idx == 0) {323 if (state_idx == 0) {
313 genpd->cached_power_down_ok = false;324 gd->cached_power_down_ok = false;
314 break;325 break;
315 }326 }
316 state_idx--;327 state_idx--;
@@ -318,8 +329,8 @@ static bool _default_power_down_ok(struct dev_pm_domain *pd, ktime_t now) · 1 unmodified line
318 329
319done:330done:
320 genpd->state_idx = state_idx;331 genpd->state_idx = state_idx;
321 genpd->cached_power_down_state_idx = genpd->state_idx;332 gd->cached_power_down_state_idx = genpd->state_idx;
322 return genpd->cached_power_down_ok;333 return gd->cached_power_down_ok;
323}334}
324 335
325static bool default_power_down_ok(struct dev_pm_domain *pd)336static bool default_power_down_ok(struct dev_pm_domain *pd)
@@ -327,11 +338,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd) · 1 unmodified line
327 return _default_power_down_ok(pd, ktime_get());338 return _default_power_down_ok(pd, ktime_get());
328}339}
329 340
330static bool always_on_power_down_ok(struct dev_pm_domain *domain)
331{
332 return false;
333}
334
335#ifdef CONFIG_CPU_IDLE341#ifdef CONFIG_CPU_IDLE
336static bool cpu_power_down_ok(struct dev_pm_domain *pd)342static bool cpu_power_down_ok(struct dev_pm_domain *pd)
337{343{
@@ -401,6 +407,5 @@ struct dev_power_governor simple_qos_governor = { · 63 unmodified lines
401 * pm_genpd_gov_always_on - A governor implementing an always-on policy407 * pm_genpd_gov_always_on - A governor implementing an always-on policy
402 */408 */
403struct dev_power_governor pm_domain_always_on_gov = {409struct dev_power_governor pm_domain_always_on_gov = {
404 .power_down_ok = always_on_power_down_ok,
405 .suspend_ok = default_suspend_ok,410 .suspend_ok = default_suspend_ok,
406};411};
drivers/base/power/runtime.c+42−11
@@ -263,7 +263,7 @@ static int rpm_check_suspend_allowed(struct device *dev) · 262 unmodified lines
263 retval = -EINVAL;263 retval = -EINVAL;
264 else if (dev->power.disable_depth > 0)264 else if (dev->power.disable_depth > 0)
265 retval = -EACCES;265 retval = -EACCES;
266 else if (atomic_read(&dev->power.usage_count) > 0)266 else if (atomic_read(&dev->power.usage_count))
267 retval = -EAGAIN;267 retval = -EAGAIN;
268 else if (!dev->power.ignore_children &&268 else if (!dev->power.ignore_children &&
269 atomic_read(&dev->power.child_count))269 atomic_read(&dev->power.child_count))
@@ -1039,13 +1039,33 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay) · 769 unmodified lines
1039}1039}
1040EXPORT_SYMBOL_GPL(pm_schedule_suspend);1040EXPORT_SYMBOL_GPL(pm_schedule_suspend);
1041 1041
1042static int rpm_drop_usage_count(struct device *dev)
1043{
1044 int ret;
1045
1046 ret = atomic_sub_return(1, &dev->power.usage_count);
1047 if (ret >= 0)
1048 return ret;
1049
1050 /*
1051 * Because rpm_resume() does not check the usage counter, it will resume
1052 * the device even if the usage counter is 0 or negative, so it is
1053 * sufficient to increment the usage counter here to reverse the change
1054 * made above.
1055 */
1056 atomic_inc(&dev->power.usage_count);
1057 dev_warn(dev, "Runtime PM usage count underflow!\n");
1058 return -EINVAL;
1059}
1060
1042/**1061/**
1043 * __pm_runtime_idle - Entry point for runtime idle operations.1062 * __pm_runtime_idle - Entry point for runtime idle operations.
1044 * @dev: Device to send idle notification for.1063 * @dev: Device to send idle notification for.
1045 * @rpmflags: Flag bits.1064 * @rpmflags: Flag bits.
1046 *1065 *
1047 * If the RPM_GET_PUT flag is set, decrement the device's usage count and1066 * If the RPM_GET_PUT flag is set, decrement the device's usage count and
1048 * return immediately if it is larger than zero. Then carry out an idle1067 * return immediately if it is larger than zero (if it becomes negative, log a
1068 * warning, increment it, and return an error). Then carry out an idle
1049 * notification, either synchronous or asynchronous.1069 * notification, either synchronous or asynchronous.
1050 *1070 *
1051 * This routine may be called in atomic context if the RPM_ASYNC flag is set,1071 * This routine may be called in atomic context if the RPM_ASYNC flag is set,
@@ -1057,7 +1077,10 @@ int __pm_runtime_idle(struct device *dev, int rpmflags) · 5 unmodified lines
1057 int retval;1077 int retval;
1058 1078
1059 if (rpmflags & RPM_GET_PUT) {1079 if (rpmflags & RPM_GET_PUT) {
1060 if (!atomic_dec_and_test(&dev->power.usage_count)) {1080 retval = rpm_drop_usage_count(dev);
1081 if (retval < 0) {
1082 return retval;
1083 } else if (retval > 0) {
1061 trace_rpm_usage_rcuidle(dev, rpmflags);1084 trace_rpm_usage_rcuidle(dev, rpmflags);
1062 return 0;1085 return 0;
1063 }1086 }
@@ -1079,7 +1102,8 @@ EXPORT_SYMBOL_GPL(__pm_runtime_idle); · 15 unmodified lines
1079 * @rpmflags: Flag bits.1102 * @rpmflags: Flag bits.
1080 *1103 *
1081 * If the RPM_GET_PUT flag is set, decrement the device's usage count and1104 * If the RPM_GET_PUT flag is set, decrement the device's usage count and
1082 * return immediately if it is larger than zero. Then carry out a suspend,1105 * return immediately if it is larger than zero (if it becomes negative, log a
1106 * warning, increment it, and return an error). Then carry out a suspend,
1083 * either synchronous or asynchronous.1107 * either synchronous or asynchronous.
1084 *1108 *
1085 * This routine may be called in atomic context if the RPM_ASYNC flag is set,1109 * This routine may be called in atomic context if the RPM_ASYNC flag is set,
@@ -1091,7 +1115,10 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags) · 5 unmodified lines
1091 int retval;1115 int retval;
1092 1116
1093 if (rpmflags & RPM_GET_PUT) {1117 if (rpmflags & RPM_GET_PUT) {
1094 if (!atomic_dec_and_test(&dev->power.usage_count)) {1118 retval = rpm_drop_usage_count(dev);
1119 if (retval < 0) {
1120 return retval;
1121 } else if (retval > 0) {
1095 trace_rpm_usage_rcuidle(dev, rpmflags);1122 trace_rpm_usage_rcuidle(dev, rpmflags);
1096 return 0;1123 return 0;
1097 }1124 }
@@ -1210,12 +1237,13 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) · 112 unmodified lines
1210{1237{
1211 struct device *parent = dev->parent;1238 struct device *parent = dev->parent;
1212 bool notify_parent = false;1239 bool notify_parent = false;
1240 unsigned long flags;
1213 int error = 0;1241 int error = 0;
1214 1242
1215 if (status != RPM_ACTIVE && status != RPM_SUSPENDED)1243 if (status != RPM_ACTIVE && status != RPM_SUSPENDED)
1216 return -EINVAL;1244 return -EINVAL;
1217 1245
1218 spin_lock_irq(&dev->power.lock);1246 spin_lock_irqsave(&dev->power.lock, flags);
1219 1247
1220 /*1248 /*
1221 * Prevent PM-runtime from being enabled for the device or return an1249 * Prevent PM-runtime from being enabled for the device or return an
@@ -1226,7 +1254,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) · 4 unmodified lines
1226 else1254 else
1227 error = -EAGAIN;1255 error = -EAGAIN;
1228 1256
1229 spin_unlock_irq(&dev->power.lock);1257 spin_unlock_irqrestore(&dev->power.lock, flags);
1230 1258
1231 if (error)1259 if (error)
1232 return error;1260 return error;
@@ -1247,7 +1275,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) · 14 unmodified lines
1247 device_links_read_unlock(idx);1275 device_links_read_unlock(idx);
1248 }1276 }
1249 1277
1250 spin_lock_irq(&dev->power.lock);1278 spin_lock_irqsave(&dev->power.lock, flags);
1251 1279
1252 if (dev->power.runtime_status == status || !parent)1280 if (dev->power.runtime_status == status || !parent)
1253 goto out_set;1281 goto out_set;
@@ -1288,7 +1316,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) · 34 unmodified lines
1288 dev->power.runtime_error = 0;1316 dev->power.runtime_error = 0;
1289 1317
1290 out:1318 out:
1291 spin_unlock_irq(&dev->power.lock);1319 spin_unlock_irqrestore(&dev->power.lock, flags);
1292 1320
1293 if (notify_parent)1321 if (notify_parent)
1294 pm_request_idle(parent);1322 pm_request_idle(parent);
@@ -1527,14 +1555,17 @@ EXPORT_SYMBOL_GPL(pm_runtime_forbid); · 232 unmodified lines
1527 */1555 */
1528void pm_runtime_allow(struct device *dev)1556void pm_runtime_allow(struct device *dev)
1529{1557{
1558 int ret;
1559
1530 spin_lock_irq(&dev->power.lock);1560 spin_lock_irq(&dev->power.lock);
1531 if (dev->power.runtime_auto)1561 if (dev->power.runtime_auto)
1532 goto out;1562 goto out;
1533 1563
1534 dev->power.runtime_auto = true;1564 dev->power.runtime_auto = true;
1535 if (atomic_dec_and_test(&dev->power.usage_count))1565 ret = rpm_drop_usage_count(dev);
1566 if (ret == 0)
1536 rpm_idle(dev, RPM_AUTO | RPM_ASYNC);1567 rpm_idle(dev, RPM_AUTO | RPM_ASYNC);
1537 else1568 else if (ret > 0)
1538 trace_rpm_usage_rcuidle(dev, RPM_AUTO | RPM_ASYNC);1569 trace_rpm_usage_rcuidle(dev, RPM_AUTO | RPM_ASYNC);
1539 1570
1540 out:1571 out:
drivers/cpufreq/cppc_cpufreq.c+211−0
@@ -389,6 +389,27 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, · 388 unmodified lines
389 return ret;389 return ret;
390}390}
391 391
392static unsigned int cppc_cpufreq_fast_switch(struct cpufreq_policy *policy,
393 unsigned int target_freq)
394{
395 struct cppc_cpudata *cpu_data = policy->driver_data;
396 unsigned int cpu = policy->cpu;
397 u32 desired_perf;
398 int ret;
399
400 desired_perf = cppc_cpufreq_khz_to_perf(cpu_data, target_freq);
401 cpu_data->perf_ctrls.desired_perf = desired_perf;
402 ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls);
403
404 if (ret) {
405 pr_debug("Failed to set target on CPU:%d. ret:%d\n",
406 cpu, ret);
407 return 0;
408 }
409
410 return target_freq;
411}
412
392static int cppc_verify_policy(struct cpufreq_policy_data *policy)413static int cppc_verify_policy(struct cpufreq_policy_data *policy)
393{414{
394 cpufreq_verify_within_cpu_limits(policy);415 cpufreq_verify_within_cpu_limits(policy);
@@ -420,12 +441,197 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu) · 25 unmodified lines
420 return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;441 return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
421}442}
422 443
444static DEFINE_PER_CPU(unsigned int, efficiency_class);
445static void cppc_cpufreq_register_em(struct cpufreq_policy *policy);
446
447/* Create an artificial performance state every CPPC_EM_CAP_STEP capacity unit. */
448#define CPPC_EM_CAP_STEP (20)
449/* Increase the cost value by CPPC_EM_COST_STEP every performance state. */
450#define CPPC_EM_COST_STEP (1)
451/* Add a cost gap correspnding to the energy of 4 CPUs. */
452#define CPPC_EM_COST_GAP (4 * SCHED_CAPACITY_SCALE * CPPC_EM_COST_STEP \
453 / CPPC_EM_CAP_STEP)
454
455static unsigned int get_perf_level_count(struct cpufreq_policy *policy)
456{
457 struct cppc_perf_caps *perf_caps;
458 unsigned int min_cap, max_cap;
459 struct cppc_cpudata *cpu_data;
460 int cpu = policy->cpu;
461
462 cpu_data = policy->driver_data;
463 perf_caps = &cpu_data->perf_caps;
464 max_cap = arch_scale_cpu_capacity(cpu);
465 min_cap = div_u64(max_cap * perf_caps->lowest_perf, perf_caps->highest_perf);
466 if ((min_cap == 0) || (max_cap < min_cap))
467 return 0;
468 return 1 + max_cap / CPPC_EM_CAP_STEP - min_cap / CPPC_EM_CAP_STEP;
469}
470
471/*
472 * The cost is defined as:
473 * cost = power * max_frequency / frequency
474 */
475static inline unsigned long compute_cost(int cpu, int step)
476{
477 return CPPC_EM_COST_GAP * per_cpu(efficiency_class, cpu) +
478 step * CPPC_EM_COST_STEP;
479}
480
481static int cppc_get_cpu_power(struct device *cpu_dev,
482 unsigned long *power, unsigned long *KHz)
483{
484 unsigned long perf_step, perf_prev, perf, perf_check;
485 unsigned int min_step, max_step, step, step_check;
486 unsigned long prev_freq = *KHz;
487 unsigned int min_cap, max_cap;
488 struct cpufreq_policy *policy;
489
490 struct cppc_perf_caps *perf_caps;
491 struct cppc_cpudata *cpu_data;
492
493 policy = cpufreq_cpu_get_raw(cpu_dev->id);
494 cpu_data = policy->driver_data;
495 perf_caps = &cpu_data->perf_caps;
496 max_cap = arch_scale_cpu_capacity(cpu_dev->id);
497 min_cap = div_u64(max_cap * perf_caps->lowest_perf,
498 perf_caps->highest_perf);
499
500 perf_step = CPPC_EM_CAP_STEP * perf_caps->highest_perf / max_cap;
501 min_step = min_cap / CPPC_EM_CAP_STEP;
502 max_step = max_cap / CPPC_EM_CAP_STEP;
503
504 perf_prev = cppc_cpufreq_khz_to_perf(cpu_data, *KHz);
505 step = perf_prev / perf_step;
506
507 if (step > max_step)
508 return -EINVAL;
509
510 if (min_step == max_step) {
511 step = max_step;
512 perf = perf_caps->highest_perf;
513 } else if (step < min_step) {
514 step = min_step;
515 perf = perf_caps->lowest_perf;
516 } else {
517 step++;
518 if (step == max_step)
519 perf = perf_caps->highest_perf;
520 else
521 perf = step * perf_step;
522 }
523
524 *KHz = cppc_cpufreq_perf_to_khz(cpu_data, perf);
525 perf_check = cppc_cpufreq_khz_to_perf(cpu_data, *KHz);
526 step_check = perf_check / perf_step;
527
528 /*
529 * To avoid bad integer approximation, check that new frequency value
530 * increased and that the new frequency will be converted to the
531 * desired step value.
532 */
533 while ((*KHz == prev_freq) || (step_check != step)) {
534 perf++;
535 *KHz = cppc_cpufreq_perf_to_khz(cpu_data, perf);
536 perf_check = cppc_cpufreq_khz_to_perf(cpu_data, *KHz);
537 step_check = perf_check / perf_step;
538 }
539
540 /*
541 * With an artificial EM, only the cost value is used. Still the power
542 * is populated such as 0 < power < EM_MAX_POWER. This allows to add
543 * more sense to the artificial performance states.
544 */
545 *power = compute_cost(cpu_dev->id, step);
546
547 return 0;
548}
549
550static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz,
551 unsigned long *cost)
552{
553 unsigned long perf_step, perf_prev;
554 struct cppc_perf_caps *perf_caps;
555 struct cpufreq_policy *policy;
556 struct cppc_cpudata *cpu_data;
557 unsigned int max_cap;
558 int step;
559
560 policy = cpufreq_cpu_get_raw(cpu_dev->id);
561 cpu_data = policy->driver_data;
562 perf_caps = &cpu_data->perf_caps;
563 max_cap = arch_scale_cpu_capacity(cpu_dev->id);
564
565 perf_prev = cppc_cpufreq_khz_to_perf(cpu_data, KHz);
566 perf_step = CPPC_EM_CAP_STEP * perf_caps->highest_perf / max_cap;
567 step = perf_prev / perf_step;
568
569 *cost = compute_cost(cpu_dev->id, step);
570
571 return 0;
572}
573
574static int populate_efficiency_class(void)
575{
576 struct acpi_madt_generic_interrupt *gicc;
577 DECLARE_BITMAP(used_classes, 256) = {};
578 int class, cpu, index;
579
580 for_each_possible_cpu(cpu) {
581 gicc = acpi_cpu_get_madt_gicc(cpu);
582 class = gicc->efficiency_class;
583 bitmap_set(used_classes, class, 1);
584 }
585
586 if (bitmap_weight(used_classes, 256) <= 1) {
587 pr_debug("Efficiency classes are all equal (=%d). "
588 "No EM registered", class);
589 return -EINVAL;
590 }
591
592 /*
593 * Squeeze efficiency class values on [0:#efficiency_class-1].
594 * Values are per spec in [0:255].
595 */
596 index = 0;
597 for_each_set_bit(class, used_classes, 256) {
598 for_each_possible_cpu(cpu) {
599 gicc = acpi_cpu_get_madt_gicc(cpu);
600 if (gicc->efficiency_class == class)
601 per_cpu(efficiency_class, cpu) = index;
602 }
603 index++;
604 }
605 cppc_cpufreq_driver.register_em = cppc_cpufreq_register_em;
606
607 return 0;
608}
609
610static void cppc_cpufreq_register_em(struct cpufreq_policy *policy)
611{
612 struct cppc_cpudata *cpu_data;
613 struct em_data_callback em_cb =
614 EM_ADV_DATA_CB(cppc_get_cpu_power, cppc_get_cpu_cost);
615
616 cpu_data = policy->driver_data;
617 em_dev_register_perf_domain(get_cpu_device(policy->cpu),
618 get_perf_level_count(policy), &em_cb,
619 cpu_data->shared_cpu_map, 0);
620}
621
423#else622#else
424 623
425static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu)624static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu)
426{625{
427 return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;626 return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
428}627}
628static int populate_efficiency_class(void)
629{
630 return 0;
631}
632static void cppc_cpufreq_register_em(struct cpufreq_policy *policy)
633{
634}
429#endif635#endif
430 636
431 637
@@ -536,6 +742,9 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) · 104 unmodified lines
536 goto out;742 goto out;
537 }743 }
538 744
745 policy->fast_switch_possible = cppc_allow_fast_switch();
746 policy->dvfs_possible_from_any_cpu = true;
747
539 /*748 /*
540 * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost749 * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
541 * is supported.750 * is supported.
@@ -681,6 +890,7 @@ static struct cpufreq_driver cppc_cpufreq_driver = { · 139 unmodified lines
681 .verify = cppc_verify_policy,890 .verify = cppc_verify_policy,
682 .target = cppc_cpufreq_set_target,891 .target = cppc_cpufreq_set_target,
683 .get = cppc_cpufreq_get_rate,892 .get = cppc_cpufreq_get_rate,
893 .fast_switch = cppc_cpufreq_fast_switch,
684 .init = cppc_cpufreq_cpu_init,894 .init = cppc_cpufreq_cpu_init,
685 .exit = cppc_cpufreq_cpu_exit,895 .exit = cppc_cpufreq_cpu_exit,
686 .set_boost = cppc_cpufreq_set_boost,896 .set_boost = cppc_cpufreq_set_boost,
@@ -742,6 +952,7 @@ static int __init cppc_cpufreq_init(void) · 55 unmodified lines
742 952
743 cppc_check_hisi_workaround();953 cppc_check_hisi_workaround();
744 cppc_freq_invariance_init();954 cppc_freq_invariance_init();
955 populate_efficiency_class();
745 956
746 ret = cpufreq_register_driver(&cppc_cpufreq_driver);957 ret = cpufreq_register_driver(&cppc_cpufreq_driver);
747 if (ret)958 if (ret)
drivers/cpufreq/cpufreq.c+69−43
@@ -28,6 +28,7 @@ · 27 unmodified lines
28#include <linux/suspend.h>28#include <linux/suspend.h>
29#include <linux/syscore_ops.h>29#include <linux/syscore_ops.h>
30#include <linux/tick.h>30#include <linux/tick.h>
31#include <linux/units.h>
31#include <trace/events/power.h>32#include <trace/events/power.h>
32 33
33static LIST_HEAD(cpufreq_policy_list);34static LIST_HEAD(cpufreq_policy_list);
@@ -947,13 +948,14 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) · 913 unmodified lines
947{948{
948 struct cpufreq_policy *policy = to_policy(kobj);949 struct cpufreq_policy *policy = to_policy(kobj);
949 struct freq_attr *fattr = to_attr(attr);950 struct freq_attr *fattr = to_attr(attr);
950 ssize_t ret;951 ssize_t ret = -EBUSY;
951 952
952 if (!fattr->show)953 if (!fattr->show)
953 return -EIO;954 return -EIO;
954 955
955 down_read(&policy->rwsem);956 down_read(&policy->rwsem);
956 ret = fattr->show(policy, buf);957 if (likely(!policy_is_inactive(policy)))
958 ret = fattr->show(policy, buf);
957 up_read(&policy->rwsem);959 up_read(&policy->rwsem);
958 960
959 return ret;961 return ret;
@@ -964,7 +966,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, · 4 unmodified lines
964{966{
965 struct cpufreq_policy *policy = to_policy(kobj);967 struct cpufreq_policy *policy = to_policy(kobj);
966 struct freq_attr *fattr = to_attr(attr);968 struct freq_attr *fattr = to_attr(attr);
967 ssize_t ret = -EINVAL;969 ssize_t ret = -EBUSY;
968 970
969 if (!fattr->store)971 if (!fattr->store)
970 return -EIO;972 return -EIO;
@@ -978,7 +980,8 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, · 7 unmodified lines
978 980
979 if (cpu_online(policy->cpu)) {981 if (cpu_online(policy->cpu)) {
980 down_write(&policy->rwsem);982 down_write(&policy->rwsem);
981 ret = fattr->store(policy, buf, count);983 if (likely(!policy_is_inactive(policy)))
984 ret = fattr->store(policy, buf, count);
982 up_write(&policy->rwsem);985 up_write(&policy->rwsem);
983 }986 }
984 987
@@ -1019,11 +1022,12 @@ static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu, · 34 unmodified lines
1019 dev_err(dev, "cpufreq symlink creation failed\n");1022 dev_err(dev, "cpufreq symlink creation failed\n");
1020}1023}
1021 1024
1022static void remove_cpu_dev_symlink(struct cpufreq_policy *policy,1025static void remove_cpu_dev_symlink(struct cpufreq_policy *policy, int cpu,
1023 struct device *dev)1026 struct device *dev)
1024{1027{
1025 dev_dbg(dev, "%s: Removing symlink\n", __func__);1028 dev_dbg(dev, "%s: Removing symlink\n", __func__);
1026 sysfs_remove_link(&dev->kobj, "cpufreq");1029 sysfs_remove_link(&dev->kobj, "cpufreq");
1030 cpumask_clear_cpu(cpu, policy->real_cpus);
1027}1031}
1028 1032
1029static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)1033static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)
@@ -1337,12 +1341,12 @@ static int cpufreq_online(unsigned int cpu) · 307 unmodified lines
1337 down_write(&policy->rwsem);1341 down_write(&policy->rwsem);
1338 policy->cpu = cpu;1342 policy->cpu = cpu;
1339 policy->governor = NULL;1343 policy->governor = NULL;
1340 up_write(&policy->rwsem);
1341 } else {1344 } else {
1342 new_policy = true;1345 new_policy = true;
1343 policy = cpufreq_policy_alloc(cpu);1346 policy = cpufreq_policy_alloc(cpu);
1344 if (!policy)1347 if (!policy)
1345 return -ENOMEM;1348 return -ENOMEM;
1349 down_write(&policy->rwsem);
1346 }1350 }
1347 1351
1348 if (!new_policy && cpufreq_driver->online) {1352 if (!new_policy && cpufreq_driver->online) {
@@ -1382,7 +1386,6 @@ static int cpufreq_online(unsigned int cpu) · 33 unmodified lines
1382 cpumask_copy(policy->related_cpus, policy->cpus);1386 cpumask_copy(policy->related_cpus, policy->cpus);
1383 }1387 }
1384 1388
1385 down_write(&policy->rwsem);
1386 /*1389 /*
1387 * affected cpus must always be the one, which are online. We aren't1390 * affected cpus must always be the one, which are online. We aren't
1388 * managing offline cpus here.1391 * managing offline cpus here.
@@ -1531,9 +1534,9 @@ static int cpufreq_online(unsigned int cpu) · 142 unmodified lines
1531 1534
1532out_destroy_policy:1535out_destroy_policy:
1533 for_each_cpu(j, policy->real_cpus)1536 for_each_cpu(j, policy->real_cpus)
1534 remove_cpu_dev_symlink(policy, get_cpu_device(j));1537 remove_cpu_dev_symlink(policy, j, get_cpu_device(j));
1535 1538
1536 up_write(&policy->rwsem);1539 cpumask_clear(policy->cpus);
1537 1540
1538out_offline_policy:1541out_offline_policy:
1539 if (cpufreq_driver->offline)1542 if (cpufreq_driver->offline)
@@ -1544,6 +1547,8 @@ out_exit_policy: · 4 unmodified lines
1544 cpufreq_driver->exit(policy);1547 cpufreq_driver->exit(policy);
1545 1548
1546out_free_policy:1549out_free_policy:
1550 up_write(&policy->rwsem);
1551
1547 cpufreq_policy_free(policy);1552 cpufreq_policy_free(policy);
1548 return ret;1553 return ret;
1549}1554}
@@ -1575,47 +1580,36 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) · 25 unmodified lines
1575 return 0;1580 return 0;
1576}1581}
1577 1582
1578static int cpufreq_offline(unsigned int cpu)1583static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy)
1579{1584{
1580 struct cpufreq_policy *policy;
1581 int ret;1585 int ret;
1582 1586
1583 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
1584
1585 policy = cpufreq_cpu_get_raw(cpu);
1586 if (!policy) {
1587 pr_debug("%s: No cpu_data found\n", __func__);
1588 return 0;
1589 }
1590
1591 down_write(&policy->rwsem);
1592 if (has_target())1587 if (has_target())
1593 cpufreq_stop_governor(policy);1588 cpufreq_stop_governor(policy);
1594 1589
1595 cpumask_clear_cpu(cpu, policy->cpus);1590 cpumask_clear_cpu(cpu, policy->cpus);
1596 1591
1597 if (policy_is_inactive(policy)) {
1598 if (has_target())
1599 strncpy(policy->last_governor, policy->governor->name,
1600 CPUFREQ_NAME_LEN);
1601 else
1602 policy->last_policy = policy->policy;
1603 } else if (cpu == policy->cpu) {
1604 /* Nominate new CPU */
1605 policy->cpu = cpumask_any(policy->cpus);
1606 }
1607
1608 /* Start governor again for active policy */
1609 if (!policy_is_inactive(policy)) {1592 if (!policy_is_inactive(policy)) {
1593 /* Nominate a new CPU if necessary. */
1594 if (cpu == policy->cpu)
1595 policy->cpu = cpumask_any(policy->cpus);
1596
1597 /* Start the governor again for the active policy. */
1610 if (has_target()) {1598 if (has_target()) {
1611 ret = cpufreq_start_governor(policy);1599 ret = cpufreq_start_governor(policy);
1612 if (ret)1600 if (ret)
1613 pr_err("%s: Failed to start governor\n", __func__);1601 pr_err("%s: Failed to start governor\n", __func__);
1614 }1602 }
1615 1603
1616 goto unlock;1604 return;
1617 }1605 }
1618 1606
1607 if (has_target())
1608 strncpy(policy->last_governor, policy->governor->name,
1609 CPUFREQ_NAME_LEN);
1610 else
1611 policy->last_policy = policy->policy;
1612
1619 if (cpufreq_thermal_control_enabled(cpufreq_driver)) {1613 if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
1620 cpufreq_cooling_unregister(policy->cdev);1614 cpufreq_cooling_unregister(policy->cdev);
1621 policy->cdev = NULL;1615 policy->cdev = NULL;
@@ -1634,8 +1628,24 @@ static int cpufreq_offline(unsigned int cpu) · 12 unmodified lines
1634 cpufreq_driver->exit(policy);1628 cpufreq_driver->exit(policy);
1635 policy->freq_table = NULL;1629 policy->freq_table = NULL;
1636 }1630 }
1631}
1632
1633static int cpufreq_offline(unsigned int cpu)
1634{
1635 struct cpufreq_policy *policy;
1636
1637 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
1638
1639 policy = cpufreq_cpu_get_raw(cpu);
1640 if (!policy) {
1641 pr_debug("%s: No cpu_data found\n", __func__);
1642 return 0;
1643 }
1644
1645 down_write(&policy->rwsem);
1646
1647 __cpufreq_offline(cpu, policy);
1637 1648
1638unlock:
1639 up_write(&policy->rwsem);1649 up_write(&policy->rwsem);
1640 return 0;1650 return 0;
1641}1651}
@@ -1653,19 +1663,25 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) · 11 unmodified lines
1653 if (!policy)1663 if (!policy)
1654 return;1664 return;
1655 1665
1656 if (cpu_online(cpu))1666 down_write(&policy->rwsem);
1657 cpufreq_offline(cpu);
1658 1667
1659 cpumask_clear_cpu(cpu, policy->real_cpus);1668 if (cpu_online(cpu))
1660 remove_cpu_dev_symlink(policy, dev);1669 __cpufreq_offline(cpu, policy);
1661 1670
1662 if (cpumask_empty(policy->real_cpus)) {1671 remove_cpu_dev_symlink(policy, cpu, dev);
1663 /* We did light-weight exit earlier, do full tear down now */
1664 if (cpufreq_driver->offline)
1665 cpufreq_driver->exit(policy);
1666 1672
1667 cpufreq_policy_free(policy);1673 if (!cpumask_empty(policy->real_cpus)) {
1674 up_write(&policy->rwsem);
1675 return;
1668 }1676 }
1677
1678 /* We did light-weight exit earlier, do full tear down now */
1679 if (cpufreq_driver->offline)
1680 cpufreq_driver->exit(policy);
1681
1682 up_write(&policy->rwsem);
1683
1684 cpufreq_policy_free(policy);
1669}1685}
1670 1686
1671/**1687/**
@@ -1707,6 +1723,16 @@ static unsigned int cpufreq_verify_current_freq(struct cpufreq_policy *policy, b · 35 unmodified lines
1707 return new_freq;1723 return new_freq;
1708 1724
1709 if (policy->cur != new_freq) {1725 if (policy->cur != new_freq) {
1726 /*
1727 * For some platforms, the frequency returned by hardware may be
1728 * slightly different from what is provided in the frequency
1729 * table, for example hardware may return 499 MHz instead of 500
1730 * MHz. In such cases it is better to avoid getting into
1731 * unnecessary frequency updates.
1732 */
1733 if (abs(policy->cur - new_freq) < HZ_PER_MHZ)
1734 return policy->cur;
1735
1710 cpufreq_out_of_sync(policy, new_freq);1736 cpufreq_out_of_sync(policy, new_freq);
1711 if (update)1737 if (update)
1712 schedule_work(&policy->update);1738 schedule_work(&policy->update);
drivers/cpufreq/cpufreq_governor.c+13−7
@@ -388,6 +388,15 @@ static void free_policy_dbs_info(struct policy_dbs_info *policy_dbs, · 387 unmodified lines
388 gov->free(policy_dbs);388 gov->free(policy_dbs);
389}389}
390 390
391static void cpufreq_dbs_data_release(struct kobject *kobj)
392{
393 struct dbs_data *dbs_data = to_dbs_data(to_gov_attr_set(kobj));
394 struct dbs_governor *gov = dbs_data->gov;
395
396 gov->exit(dbs_data);
397 kfree(dbs_data);
398}
399
391int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)400int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
392{401{
393 struct dbs_governor *gov = dbs_governor_of(policy);402 struct dbs_governor *gov = dbs_governor_of(policy);
@@ -425,6 +434,7 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) · 31 unmodified lines
425 goto free_policy_dbs_info;434 goto free_policy_dbs_info;
426 }435 }
427 436
437 dbs_data->gov = gov;
428 gov_attr_set_init(&dbs_data->attr_set, &policy_dbs->list);438 gov_attr_set_init(&dbs_data->attr_set, &policy_dbs->list);
429 439
430 ret = gov->init(dbs_data);440 ret = gov->init(dbs_data);
@@ -447,6 +457,7 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) · 16 unmodified lines
447 policy->governor_data = policy_dbs;457 policy->governor_data = policy_dbs;
448 458
449 gov->kobj_type.sysfs_ops = &governor_sysfs_ops;459 gov->kobj_type.sysfs_ops = &governor_sysfs_ops;
460 gov->kobj_type.release = cpufreq_dbs_data_release;
450 ret = kobject_init_and_add(&dbs_data->attr_set.kobj, &gov->kobj_type,461 ret = kobject_init_and_add(&dbs_data->attr_set.kobj, &gov->kobj_type,
451 get_governor_parent_kobj(policy),462 get_governor_parent_kobj(policy),
452 "%s", gov->gov.name);463 "%s", gov->gov.name);
@@ -488,13 +499,8 @@ void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy) · 35 unmodified lines
488 499
489 policy->governor_data = NULL;500 policy->governor_data = NULL;
490 501
491 if (!count) {502 if (!count && !have_governor_per_policy())
492 if (!have_governor_per_policy())503 gov->gdbs_data = NULL;
493 gov->gdbs_data = NULL;
494
495 gov->exit(dbs_data);
496 kfree(dbs_data);
497 }
498 504
499 free_policy_dbs_info(policy_dbs, gov);505 free_policy_dbs_info(policy_dbs, gov);
500 506
drivers/cpufreq/cpufreq_governor.h+1−0
@@ -37,6 +37,7 @@ enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE}; · 36 unmodified lines
37/* Governor demand based switching data (per-policy or global). */37/* Governor demand based switching data (per-policy or global). */
38struct dbs_data {38struct dbs_data {
39 struct gov_attr_set attr_set;39 struct gov_attr_set attr_set;
40 struct dbs_governor *gov;
40 void *tuners;41 void *tuners;
41 unsigned int ignore_nice_load;42 unsigned int ignore_nice_load;
42 unsigned int sampling_rate;43 unsigned int sampling_rate;
drivers/cpufreq/intel_pstate.c+2−0
@@ -1322,6 +1322,7 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, · 1321 unmodified lines
1322 mutex_unlock(&intel_pstate_limits_lock);1322 mutex_unlock(&intel_pstate_limits_lock);
1323 1323
1324 intel_pstate_update_policies();1324 intel_pstate_update_policies();
1325 arch_set_max_freq_ratio(global.no_turbo);
1325 1326
1326 mutex_unlock(&intel_pstate_driver_lock);1327 mutex_unlock(&intel_pstate_driver_lock);
1327 1328
@@ -2424,6 +2425,7 @@ static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = { · 1096 unmodified lines
2424 X86_MATCH(BROADWELL_X, core_funcs),2425 X86_MATCH(BROADWELL_X, core_funcs),
2425 X86_MATCH(SKYLAKE_X, core_funcs),2426 X86_MATCH(SKYLAKE_X, core_funcs),
2426 X86_MATCH(ICELAKE_X, core_funcs),2427 X86_MATCH(ICELAKE_X, core_funcs),
2428 X86_MATCH(SAPPHIRERAPIDS_X, core_funcs),
2427 {}2429 {}
2428};2430};
2429 2431
drivers/cpufreq/mediatek-cpufreq-hw.c+2−2
@@ -51,8 +51,8 @@ static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = { · 50 unmodified lines
51};51};
52 52
53static int __maybe_unused53static int __maybe_unused
54mtk_cpufreq_get_cpu_power(unsigned long *mW,54mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *mW,
55 unsigned long *KHz, struct device *cpu_dev)55 unsigned long *KHz)
56{56{
57 struct mtk_cpufreq_data *data;57 struct mtk_cpufreq_data *data;
58 struct cpufreq_policy *policy;58 struct cpufreq_policy *policy;
drivers/cpufreq/pasemi-cpufreq.c+0−1
@@ -18,7 +18,6 @@ · 17 unmodified lines
18 18
19#include <asm/hw_irq.h>19#include <asm/hw_irq.h>
20#include <asm/io.h>20#include <asm/io.h>
21#include <asm/prom.h>
22#include <asm/time.h>21#include <asm/time.h>
23#include <asm/smp.h>22#include <asm/smp.h>
24 23
drivers/cpufreq/pmac32-cpufreq.c+1−1
@@ -24,7 +24,7 @@ · 23 unmodified lines
24#include <linux/device.h>24#include <linux/device.h>
25#include <linux/hardirq.h>25#include <linux/hardirq.h>
26#include <linux/of_device.h>26#include <linux/of_device.h>
27#include <asm/prom.h>27
28#include <asm/machdep.h>28#include <asm/machdep.h>
29#include <asm/irq.h>29#include <asm/irq.h>
30#include <asm/pmac_feature.h>30#include <asm/pmac_feature.h>
drivers/cpufreq/pmac64-cpufreq.c+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
22#include <linux/completion.h>22#include <linux/completion.h>
23#include <linux/mutex.h>23#include <linux/mutex.h>
24#include <linux/of_device.h>24#include <linux/of_device.h>
25#include <asm/prom.h>25
26#include <asm/machdep.h>26#include <asm/machdep.h>
27#include <asm/irq.h>27#include <asm/irq.h>
28#include <asm/sections.h>28#include <asm/sections.h>
drivers/cpufreq/ppc_cbe_cpufreq.c+0−1
@@ -12,7 +12,6 @@ · 11 unmodified lines
12#include <linux/of_platform.h>12#include <linux/of_platform.h>
13 13
14#include <asm/machdep.h>14#include <asm/machdep.h>
15#include <asm/prom.h>
16#include <asm/cell-regs.h>15#include <asm/cell-regs.h>
17 16
18#include "ppc_cbe_cpufreq.h"17#include "ppc_cbe_cpufreq.h"
drivers/cpufreq/ppc_cbe_cpufreq_pmi.c+1−1
@@ -13,9 +13,9 @@ · 12 unmodified lines
13#include <linux/init.h>13#include <linux/init.h>
14#include <linux/of_platform.h>14#include <linux/of_platform.h>
15#include <linux/pm_qos.h>15#include <linux/pm_qos.h>
16#include <linux/slab.h>
16 17
17#include <asm/processor.h>18#include <asm/processor.h>
18#include <asm/prom.h>
19#include <asm/pmi.h>19#include <asm/pmi.h>
20#include <asm/cell-regs.h>20#include <asm/cell-regs.h>
21 21
drivers/cpufreq/scmi-cpufreq.c+2−2
@@ -96,8 +96,8 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) · 95 unmodified lines
96}96}
97 97
98static int __maybe_unused98static int __maybe_unused
99scmi_get_cpu_power(unsigned long *power, unsigned long *KHz,99scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
100 struct device *cpu_dev)100 unsigned long *KHz)
101{101{
102 unsigned long Hz;102 unsigned long Hz;
103 int ret, domain;103 int ret, domain;
drivers/cpuidle/cpuidle-psci-domain.c+2−2
@@ -52,7 +52,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi) · 51 unmodified lines
52 struct generic_pm_domain *pd;52 struct generic_pm_domain *pd;
53 struct psci_pd_provider *pd_provider;53 struct psci_pd_provider *pd_provider;
54 struct dev_power_governor *pd_gov;54 struct dev_power_governor *pd_gov;
55 int ret = -ENOMEM, state_count = 0;55 int ret = -ENOMEM;
56 56
57 pd = dt_idle_pd_alloc(np, psci_dt_parse_state_node);57 pd = dt_idle_pd_alloc(np, psci_dt_parse_state_node);
58 if (!pd)58 if (!pd)
@@ -71,7 +71,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi) · 12 unmodified lines
71 pd->flags |= GENPD_FLAG_ALWAYS_ON;71 pd->flags |= GENPD_FLAG_ALWAYS_ON;
72 72
73 /* Use governor for CPU PM domains if it has some states to manage. */73 /* Use governor for CPU PM domains if it has some states to manage. */
74 pd_gov = state_count > 0 ? &pm_domain_cpu_gov : NULL;74 pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
75 75
76 ret = pm_genpd_init(pd, pd_gov, false);76 ret = pm_genpd_init(pd, pd_gov, false);
77 if (ret)77 if (ret)
drivers/cpuidle/cpuidle-psci.c+46−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
23#include <linux/pm_runtime.h>23#include <linux/pm_runtime.h>
24#include <linux/slab.h>24#include <linux/slab.h>
25#include <linux/string.h>25#include <linux/string.h>
26#include <linux/syscore_ops.h>
26 27
27#include <asm/cpuidle.h>28#include <asm/cpuidle.h>
28 29
@@ -131,6 +132,49 @@ static int psci_idle_cpuhp_down(unsigned int cpu) · 102 unmodified lines
131 return 0;132 return 0;
132}133}
133 134
135static void psci_idle_syscore_switch(bool suspend)
136{
137 bool cleared = false;
138 struct device *dev;
139 int cpu;
140
141 for_each_possible_cpu(cpu) {
142 dev = per_cpu_ptr(&psci_cpuidle_data, cpu)->dev;
143
144 if (dev && suspend) {
145 dev_pm_genpd_suspend(dev);
146 } else if (dev) {
147 dev_pm_genpd_resume(dev);
148
149 /* Account for userspace having offlined a CPU. */
150 if (pm_runtime_status_suspended(dev))
151 pm_runtime_set_active(dev);
152
153 /* Clear domain state to re-start fresh. */
154 if (!cleared) {
155 psci_set_domain_state(0);
156 cleared = true;
157 }
158 }
159 }
160}
161
162static int psci_idle_syscore_suspend(void)
163{
164 psci_idle_syscore_switch(true);
165 return 0;
166}
167
168static void psci_idle_syscore_resume(void)
169{
170 psci_idle_syscore_switch(false);
171}
172
173static struct syscore_ops psci_idle_syscore_ops = {
174 .suspend = psci_idle_syscore_suspend,
175 .resume = psci_idle_syscore_resume,
176};
177
134static void psci_idle_init_cpuhp(void)178static void psci_idle_init_cpuhp(void)
135{179{
136 int err;180 int err;
@@ -138,6 +182,8 @@ static void psci_idle_init_cpuhp(void) · 1 unmodified line
138 if (!psci_cpuidle_use_cpuhp)182 if (!psci_cpuidle_use_cpuhp)
139 return;183 return;
140 184
185 register_syscore_ops(&psci_idle_syscore_ops);
186
141 err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,187 err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
142 "cpuidle/psci:online",188 "cpuidle/psci:online",
143 psci_idle_cpuhp_up,189 psci_idle_cpuhp_up,
drivers/cpuidle/cpuidle-riscv-sbi.c+2−2
@@ -414,7 +414,7 @@ static int sbi_pd_init(struct device_node *np) · 413 unmodified lines
414 struct generic_pm_domain *pd;414 struct generic_pm_domain *pd;
415 struct sbi_pd_provider *pd_provider;415 struct sbi_pd_provider *pd_provider;
416 struct dev_power_governor *pd_gov;416 struct dev_power_governor *pd_gov;
417 int ret = -ENOMEM, state_count = 0;417 int ret = -ENOMEM;
418 418
419 pd = dt_idle_pd_alloc(np, sbi_dt_parse_state_node);419 pd = dt_idle_pd_alloc(np, sbi_dt_parse_state_node);
420 if (!pd)420 if (!pd)
@@ -433,7 +433,7 @@ static int sbi_pd_init(struct device_node *np) · 12 unmodified lines
433 pd->flags |= GENPD_FLAG_ALWAYS_ON;433 pd->flags |= GENPD_FLAG_ALWAYS_ON;
434 434
435 /* Use governor for CPU PM domains if it has some states to manage. */435 /* Use governor for CPU PM domains if it has some states to manage. */
436 pd_gov = state_count > 0 ? &pm_domain_cpu_gov : NULL;436 pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
437 437
438 ret = pm_genpd_init(pd, pd_gov, false);438 ret = pm_genpd_init(pd, pd_gov, false);
439 if (ret)439 if (ret)
drivers/devfreq/devfreq.c+12−8
@@ -112,16 +112,16 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq) · 111 unmodified lines
112}112}
113 113
114/**114/**
115 * get_freq_range() - Get the current freq range115 * devfreq_get_freq_range() - Get the current freq range
116 * @devfreq: the devfreq instance116 * @devfreq: the devfreq instance
117 * @min_freq: the min frequency117 * @min_freq: the min frequency
118 * @max_freq: the max frequency118 * @max_freq: the max frequency
119 *119 *
120 * This takes into consideration all constraints.120 * This takes into consideration all constraints.
121 */121 */
122static void get_freq_range(struct devfreq *devfreq,122void devfreq_get_freq_range(struct devfreq *devfreq,
123 unsigned long *min_freq,123 unsigned long *min_freq,
124 unsigned long *max_freq)124 unsigned long *max_freq)
125{125{
126 unsigned long *freq_table = devfreq->profile->freq_table;126 unsigned long *freq_table = devfreq->profile->freq_table;
127 s32 qos_min_freq, qos_max_freq;127 s32 qos_min_freq, qos_max_freq;
@@ -158,6 +158,7 @@ static void get_freq_range(struct devfreq *devfreq, · 30 unmodified lines
158 if (*min_freq > *max_freq)158 if (*min_freq > *max_freq)
159 *min_freq = *max_freq;159 *min_freq = *max_freq;
160}160}
161EXPORT_SYMBOL(devfreq_get_freq_range);
161 162
162/**163/**
163 * devfreq_get_freq_level() - Lookup freq_table for the frequency164 * devfreq_get_freq_level() - Lookup freq_table for the frequency
@@ -418,7 +419,7 @@ int devfreq_update_target(struct devfreq *devfreq, unsigned long freq) · 254 unmodified lines
418 err = devfreq->governor->get_target_freq(devfreq, &freq);419 err = devfreq->governor->get_target_freq(devfreq, &freq);
419 if (err)420 if (err)
420 return err;421 return err;
421 get_freq_range(devfreq, &min_freq, &max_freq);422 devfreq_get_freq_range(devfreq, &min_freq, &max_freq);
422 423
423 if (freq < min_freq) {424 if (freq < min_freq) {
424 freq = min_freq;425 freq = min_freq;
@@ -785,6 +786,7 @@ struct devfreq *devfreq_add_device(struct device *dev, · 360 unmodified lines
785{786{
786 struct devfreq *devfreq;787 struct devfreq *devfreq;
787 struct devfreq_governor *governor;788 struct devfreq_governor *governor;
789 unsigned long min_freq, max_freq;
788 int err = 0;790 int err = 0;
789 791
790 if (!dev || !profile || !governor_name) {792 if (!dev || !profile || !governor_name) {
@@ -849,6 +851,8 @@ struct devfreq *devfreq_add_device(struct device *dev, · 58 unmodified lines
849 goto err_dev;851 goto err_dev;
850 }852 }
851 853
854 devfreq_get_freq_range(devfreq, &min_freq, &max_freq);
855
852 devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev);856 devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev);
853 devfreq->opp_table = dev_pm_opp_get_opp_table(dev);857 devfreq->opp_table = dev_pm_opp_get_opp_table(dev);
854 if (IS_ERR(devfreq->opp_table))858 if (IS_ERR(devfreq->opp_table))
@@ -1587,7 +1591,7 @@ static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr, · 732 unmodified lines
1587 unsigned long min_freq, max_freq;1591 unsigned long min_freq, max_freq;
1588 1592
1589 mutex_lock(&df->lock);1593 mutex_lock(&df->lock);
1590 get_freq_range(df, &min_freq, &max_freq);1594 devfreq_get_freq_range(df, &min_freq, &max_freq);
1591 mutex_unlock(&df->lock);1595 mutex_unlock(&df->lock);
1592 1596
1593 return sprintf(buf, "%lu\n", min_freq);1597 return sprintf(buf, "%lu\n", min_freq);
@@ -1641,7 +1645,7 @@ static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr, · 47 unmodified lines
1641 unsigned long min_freq, max_freq;1645 unsigned long min_freq, max_freq;
1642 1646
1643 mutex_lock(&df->lock);1647 mutex_lock(&df->lock);
1644 get_freq_range(df, &min_freq, &max_freq);1648 devfreq_get_freq_range(df, &min_freq, &max_freq);
1645 mutex_unlock(&df->lock);1649 mutex_unlock(&df->lock);
1646 1650
1647 return sprintf(buf, "%lu\n", max_freq);1651 return sprintf(buf, "%lu\n", max_freq);
@@ -1955,7 +1959,7 @@ static int devfreq_summary_show(struct seq_file *s, void *data) · 307 unmodified lines
1955 1959
1956 mutex_lock(&devfreq->lock);1960 mutex_lock(&devfreq->lock);
1957 cur_freq = devfreq->previous_freq;1961 cur_freq = devfreq->previous_freq;
1958 get_freq_range(devfreq, &min_freq, &max_freq);1962 devfreq_get_freq_range(devfreq, &min_freq, &max_freq);
1959 timer = devfreq->profile->timer;1963 timer = devfreq->profile->timer;
1960 1964
1961 if (IS_SUPPORTED_ATTR(devfreq->governor->attrs, POLLING_INTERVAL))1965 if (IS_SUPPORTED_ATTR(devfreq->governor->attrs, POLLING_INTERVAL))
drivers/devfreq/governor.h+27−0
@@ -47,6 +47,31 @@ · 46 unmodified lines
47#define DEVFREQ_GOV_ATTR_POLLING_INTERVAL BIT(0)47#define DEVFREQ_GOV_ATTR_POLLING_INTERVAL BIT(0)
48#define DEVFREQ_GOV_ATTR_TIMER BIT(1)48#define DEVFREQ_GOV_ATTR_TIMER BIT(1)
49 49
50/**
51 * struct devfreq_cpu_data - Hold the per-cpu data
52 * @node: list node
53 * @dev: reference to cpu device.
54 * @first_cpu: the cpumask of the first cpu of a policy.
55 * @opp_table: reference to cpu opp table.
56 * @cur_freq: the current frequency of the cpu.
57 * @min_freq: the min frequency of the cpu.
58 * @max_freq: the max frequency of the cpu.
59 *
60 * This structure stores the required cpu_data of a cpu.
61 * This is auto-populated by the governor.
62 */
63struct devfreq_cpu_data {
64 struct list_head node;
65
66 struct device *dev;
67 unsigned int first_cpu;
68
69 struct opp_table *opp_table;
70 unsigned int cur_freq;
71 unsigned int min_freq;
72 unsigned int max_freq;
73};
74
50/**75/**
51 * struct devfreq_governor - Devfreq policy governor76 * struct devfreq_governor - Devfreq policy governor
52 * @node: list node - contains registered devfreq governors77 * @node: list node - contains registered devfreq governors
@@ -89,6 +114,8 @@ int devm_devfreq_add_governor(struct device *dev, · 36 unmodified lines
89 114
90int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);115int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
91int devfreq_update_target(struct devfreq *devfreq, unsigned long freq);116int devfreq_update_target(struct devfreq *devfreq, unsigned long freq);
117void devfreq_get_freq_range(struct devfreq *devfreq, unsigned long *min_freq,
118 unsigned long *max_freq);
92 119
93static inline int devfreq_update_stats(struct devfreq *df)120static inline int devfreq_update_stats(struct devfreq *df)
94{121{
drivers/devfreq/governor_passive.c+335−68
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0-only1 // SPDX-License-Identifier: GPL-2.0-only
2/*2/*
3 * linux/drivers/devfreq/governor_passive.c3 * linux/drivers/devfreq/governor_passive.c
4 *4 *
@@ -8,76 +8,129 @@ · 3 unmodified lines
8 */8 */
9 9
10#include <linux/module.h>10#include <linux/module.h>
11#include <linux/cpu.h>
12#include <linux/cpufreq.h>
13#include <linux/cpumask.h>
14#include <linux/slab.h>
11#include <linux/device.h>15#include <linux/device.h>
12#include <linux/devfreq.h>16#include <linux/devfreq.h>
13#include "governor.h"17#include "governor.h"
14 18
15static int devfreq_passive_get_target_freq(struct devfreq *devfreq,19#define HZ_PER_KHZ 1000
16 unsigned long *freq)20
21static struct devfreq_cpu_data *
22get_parent_cpu_data(struct devfreq_passive_data *p_data,
23 struct cpufreq_policy *policy)
17{24{
18 struct devfreq_passive_data *p_data25 struct devfreq_cpu_data *parent_cpu_data;
19 = (struct devfreq_passive_data *)devfreq->data;
20 struct devfreq *parent_devfreq = (struct devfreq *)p_data->parent;
21 unsigned long child_freq = ULONG_MAX;
22 struct dev_pm_opp *opp, *p_opp;
23 int i, count;
24 26
25 /*27 if (!p_data || !policy)
26 * If the devfreq device with passive governor has the specific method28 return NULL;
27 * to determine the next frequency, should use the get_target_freq()
28 * of struct devfreq_passive_data.
29 */
30 if (p_data->get_target_freq)
31 return p_data->get_target_freq(devfreq, freq);
32 29
33 /*30 list_for_each_entry(parent_cpu_data, &p_data->cpu_data_list, node)
34 * If the parent and passive devfreq device uses the OPP table,31 if (parent_cpu_data->first_cpu == cpumask_first(policy->related_cpus))
35 * get the next frequency by using the OPP table.32 return parent_cpu_data;
36 */
37 33
38 /*34 return NULL;
39 * - parent devfreq device uses the governors except for passive.35}
40 * - passive devfreq device uses the passive governor.
41 *
42 * Each devfreq has the OPP table. After deciding the new frequency
43 * from the governor of parent devfreq device, the passive governor
44 * need to get the index of new frequency on OPP table of parent
45 * device. And then the index is used for getting the suitable
46 * new frequency for passive devfreq device.
47 */
48 if (!devfreq->profile || !devfreq->profile->freq_table
49 || devfreq->profile->max_state <= 0)
50 return -EINVAL;
51 36
52 /*37static unsigned long get_target_freq_by_required_opp(struct device *p_dev,
53 * The passive governor have to get the correct frequency from OPP38 struct opp_table *p_opp_table,
54 * list of parent device. Because in this case, *freq is temporary39 struct opp_table *opp_table,
55 * value which is decided by ondemand governor.40 unsigned long *freq)
56 */41{
57 if (devfreq->opp_table && parent_devfreq->opp_table) {42 struct dev_pm_opp *opp = NULL, *p_opp = NULL;
58 p_opp = devfreq_recommended_opp(parent_devfreq->dev.parent,43 unsigned long target_freq;
59 freq, 0);
60 if (IS_ERR(p_opp))
61 return PTR_ERR(p_opp);
62 44
63 opp = dev_pm_opp_xlate_required_opp(parent_devfreq->opp_table,45 if (!p_dev || !p_opp_table || !opp_table || !freq)
64 devfreq->opp_table, p_opp);46 return 0;
65 dev_pm_opp_put(p_opp);
66 47
67 if (IS_ERR(opp))48 p_opp = devfreq_recommended_opp(p_dev, freq, 0);
68 goto no_required_opp;49 if (IS_ERR(p_opp))
50 return 0;
69 51
70 *freq = dev_pm_opp_get_freq(opp);52 opp = dev_pm_opp_xlate_required_opp(p_opp_table, opp_table, p_opp);
71 dev_pm_opp_put(opp);53 dev_pm_opp_put(p_opp);
72 54
55 if (IS_ERR(opp))
73 return 0;56 return 0;
57
58 target_freq = dev_pm_opp_get_freq(opp);
59 dev_pm_opp_put(opp);
60
61 return target_freq;
62}
63
64static int get_target_freq_with_cpufreq(struct devfreq *devfreq,
65 unsigned long *target_freq)
66{
67 struct devfreq_passive_data *p_data =
68 (struct devfreq_passive_data *)devfreq->data;
69 struct devfreq_cpu_data *parent_cpu_data;
70 struct cpufreq_policy *policy;
71 unsigned long cpu, cpu_cur, cpu_min, cpu_max, cpu_percent;
72 unsigned long dev_min, dev_max;
73 unsigned long freq = 0;
74 int ret = 0;
75
76 for_each_online_cpu(cpu) {
77 policy = cpufreq_cpu_get(cpu);
78 if (!policy) {
79 ret = -EINVAL;
80 continue;
81 }
82
83 parent_cpu_data = get_parent_cpu_data(p_data, policy);
84 if (!parent_cpu_data) {
85 cpufreq_cpu_put(policy);
86 continue;
87 }
88
89 /* Get target freq via required opps */
90 cpu_cur = parent_cpu_data->cur_freq * HZ_PER_KHZ;
91 freq = get_target_freq_by_required_opp(parent_cpu_data->dev,
92 parent_cpu_data->opp_table,
93 devfreq->opp_table, &cpu_cur);
94 if (freq) {
95 *target_freq = max(freq, *target_freq);
96 cpufreq_cpu_put(policy);
97 continue;
98 }
99
100 /* Use interpolation if required opps is not available */
101 devfreq_get_freq_range(devfreq, &dev_min, &dev_max);
102
103 cpu_min = parent_cpu_data->min_freq;
104 cpu_max = parent_cpu_data->max_freq;
105 cpu_cur = parent_cpu_data->cur_freq;
106
107 cpu_percent = ((cpu_cur - cpu_min) * 100) / (cpu_max - cpu_min);
108 freq = dev_min + mult_frac(dev_max - dev_min, cpu_percent, 100);
109
110 *target_freq = max(freq, *target_freq);
111 cpufreq_cpu_put(policy);
74 }112 }
75 113
76no_required_opp:114 return ret;
77 /*115}
78 * Get the OPP table's index of decided frequency by governor116
79 * of parent device.117static int get_target_freq_with_devfreq(struct devfreq *devfreq,
80 */118 unsigned long *freq)
119{
120 struct devfreq_passive_data *p_data
121 = (struct devfreq_passive_data *)devfreq->data;
122 struct devfreq *parent_devfreq = (struct devfreq *)p_data->parent;
123 unsigned long child_freq = ULONG_MAX;
124 int i, count;
125
126 /* Get target freq via required opps */
127 child_freq = get_target_freq_by_required_opp(parent_devfreq->dev.parent,
128 parent_devfreq->opp_table,
129 devfreq->opp_table, freq);
130 if (child_freq)
131 goto out;
132
133 /* Use interpolation if required opps is not available */
81 for (i = 0; i < parent_devfreq->profile->max_state; i++)134 for (i = 0; i < parent_devfreq->profile->max_state; i++)
82 if (parent_devfreq->profile->freq_table[i] == *freq)135 if (parent_devfreq->profile->freq_table[i] == *freq)
83 break;136 break;
@@ -85,7 +138,6 @@ no_required_opp: · 1 unmodified line
85 if (i == parent_devfreq->profile->max_state)138 if (i == parent_devfreq->profile->max_state)
86 return -EINVAL;139 return -EINVAL;
87 140
88 /* Get the suitable frequency by using index of parent device. */
89 if (i < devfreq->profile->max_state) {141 if (i < devfreq->profile->max_state) {
90 child_freq = devfreq->profile->freq_table[i];142 child_freq = devfreq->profile->freq_table[i];
91 } else {143 } else {
@@ -93,12 +145,202 @@ no_required_opp: · 1 unmodified line
93 child_freq = devfreq->profile->freq_table[count - 1];145 child_freq = devfreq->profile->freq_table[count - 1];
94 }146 }
95 147
96 /* Return the suitable frequency for passive device. */148out:
97 *freq = child_freq;149 *freq = child_freq;
98 150
99 return 0;151 return 0;
100}152}
101 153
154static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
155 unsigned long *freq)
156{
157 struct devfreq_passive_data *p_data =
158 (struct devfreq_passive_data *)devfreq->data;
159 int ret;
160
161 if (!p_data)
162 return -EINVAL;
163
164 /*
165 * If the devfreq device with passive governor has the specific method
166 * to determine the next frequency, should use the get_target_freq()
167 * of struct devfreq_passive_data.
168 */
169 if (p_data->get_target_freq)
170 return p_data->get_target_freq(devfreq, freq);
171
172 switch (p_data->parent_type) {
173 case DEVFREQ_PARENT_DEV:
174 ret = get_target_freq_with_devfreq(devfreq, freq);
175 break;
176 case CPUFREQ_PARENT_DEV:
177 ret = get_target_freq_with_cpufreq(devfreq, freq);
178 break;
179 default:
180 ret = -EINVAL;
181 dev_err(&devfreq->dev, "Invalid parent type\n");
182 break;
183 }
184
185 return ret;
186}
187
188static int cpufreq_passive_notifier_call(struct notifier_block *nb,
189 unsigned long event, void *ptr)
190{
191 struct devfreq_passive_data *p_data =
192 container_of(nb, struct devfreq_passive_data, nb);
193 struct devfreq *devfreq = (struct devfreq *)p_data->this;
194 struct devfreq_cpu_data *parent_cpu_data;
195 struct cpufreq_freqs *freqs = ptr;
196 unsigned int cur_freq;
197 int ret;
198
199 if (event != CPUFREQ_POSTCHANGE || !freqs)
200 return 0;
201
202 parent_cpu_data = get_parent_cpu_data(p_data, freqs->policy);
203 if (!parent_cpu_data || parent_cpu_data->cur_freq == freqs->new)
204 return 0;
205
206 cur_freq = parent_cpu_data->cur_freq;
207 parent_cpu_data->cur_freq = freqs->new;
208
209 mutex_lock(&devfreq->lock);
210 ret = devfreq_update_target(devfreq, freqs->new);
211 mutex_unlock(&devfreq->lock);
212 if (ret) {
213 parent_cpu_data->cur_freq = cur_freq;
214 dev_err(&devfreq->dev, "failed to update the frequency.\n");
215 return ret;
216 }
217
218 return 0;
219}
220
221static int cpufreq_passive_unregister_notifier(struct devfreq *devfreq)
222{
223 struct devfreq_passive_data *p_data
224 = (struct devfreq_passive_data *)devfreq->data;
225 struct devfreq_cpu_data *parent_cpu_data;
226 int cpu, ret = 0;
227
228 if (p_data->nb.notifier_call) {
229 ret = cpufreq_unregister_notifier(&p_data->nb,
230 CPUFREQ_TRANSITION_NOTIFIER);
231 if (ret < 0)
232 return ret;
233 }
234
235 for_each_possible_cpu(cpu) {
236 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
237 if (!policy) {
238 ret = -EINVAL;
239 continue;
240 }
241
242 parent_cpu_data = get_parent_cpu_data(p_data, policy);
243 if (!parent_cpu_data) {
244 cpufreq_cpu_put(policy);
245 continue;
246 }
247
248 list_del(&parent_cpu_data->node);
249 if (parent_cpu_data->opp_table)
250 dev_pm_opp_put_opp_table(parent_cpu_data->opp_table);
251 kfree(parent_cpu_data);
252 cpufreq_cpu_put(policy);
253 }
254
255 return ret;
256}
257
258static int cpufreq_passive_register_notifier(struct devfreq *devfreq)
259{
260 struct devfreq_passive_data *p_data
261 = (struct devfreq_passive_data *)devfreq->data;
262 struct device *dev = devfreq->dev.parent;
263 struct opp_table *opp_table = NULL;
264 struct devfreq_cpu_data *parent_cpu_data;
265 struct cpufreq_policy *policy;
266 struct device *cpu_dev;
267 unsigned int cpu;
268 int ret;
269
270 p_data->cpu_data_list
271 = (struct list_head)LIST_HEAD_INIT(p_data->cpu_data_list);
272
273 p_data->nb.notifier_call = cpufreq_passive_notifier_call;
274 ret = cpufreq_register_notifier(&p_data->nb, CPUFREQ_TRANSITION_NOTIFIER);
275 if (ret) {
276 dev_err(dev, "failed to register cpufreq notifier\n");
277 p_data->nb.notifier_call = NULL;
278 goto err;
279 }
280
281 for_each_possible_cpu(cpu) {
282 policy = cpufreq_cpu_get(cpu);
283 if (!policy) {
284 ret = -EPROBE_DEFER;
285 goto err;
286 }
287
288 parent_cpu_data = get_parent_cpu_data(p_data, policy);
289 if (parent_cpu_data) {
290 cpufreq_cpu_put(policy);
291 continue;
292 }
293
294 parent_cpu_data = kzalloc(sizeof(*parent_cpu_data),
295 GFP_KERNEL);
296 if (!parent_cpu_data) {
297 ret = -ENOMEM;
298 goto err_put_policy;
299 }
300
301 cpu_dev = get_cpu_device(cpu);
302 if (!cpu_dev) {
303 dev_err(dev, "failed to get cpu device\n");
304 ret = -ENODEV;
305 goto err_free_cpu_data;
306 }
307
308 opp_table = dev_pm_opp_get_opp_table(cpu_dev);
309 if (IS_ERR(opp_table)) {
310 dev_err(dev, "failed to get opp_table of cpu%d\n", cpu);
311 ret = PTR_ERR(opp_table);
312 goto err_free_cpu_data;
313 }
314
315 parent_cpu_data->dev = cpu_dev;
316 parent_cpu_data->opp_table = opp_table;
317 parent_cpu_data->first_cpu = cpumask_first(policy->related_cpus);
318 parent_cpu_data->cur_freq = policy->cur;
319 parent_cpu_data->min_freq = policy->cpuinfo.min_freq;
320 parent_cpu_data->max_freq = policy->cpuinfo.max_freq;
321
322 list_add_tail(&parent_cpu_data->node, &p_data->cpu_data_list);
323 cpufreq_cpu_put(policy);
324 }
325
326 mutex_lock(&devfreq->lock);
327 ret = devfreq_update_target(devfreq, 0L);
328 mutex_unlock(&devfreq->lock);
329 if (ret)
330 dev_err(dev, "failed to update the frequency\n");
331
332 return ret;
333
334err_free_cpu_data:
335 kfree(parent_cpu_data);
336err_put_policy:
337 cpufreq_cpu_put(policy);
338err:
339 WARN_ON(cpufreq_passive_unregister_notifier(devfreq));
340
341 return ret;
342}
343
102static int devfreq_passive_notifier_call(struct notifier_block *nb,344static int devfreq_passive_notifier_call(struct notifier_block *nb,
103 unsigned long event, void *ptr)345 unsigned long event, void *ptr)
104{346{
@@ -131,30 +373,55 @@ static int devfreq_passive_notifier_call(struct notifier_block *nb, · 26 unmodified lines
131 return NOTIFY_DONE;373 return NOTIFY_DONE;
132}374}
133 375
134static int devfreq_passive_event_handler(struct devfreq *devfreq,376static int devfreq_passive_unregister_notifier(struct devfreq *devfreq)
135 unsigned int event, void *data)377{
378 struct devfreq_passive_data *p_data
379 = (struct devfreq_passive_data *)devfreq->data;
380 struct devfreq *parent = (struct devfreq *)p_data->parent;
381 struct notifier_block *nb = &p_data->nb;
382
383 return devfreq_unregister_notifier(parent, nb, DEVFREQ_TRANSITION_NOTIFIER);
384}
385
386static int devfreq_passive_register_notifier(struct devfreq *devfreq)
136{387{
137 struct devfreq_passive_data *p_data388 struct devfreq_passive_data *p_data
138 = (struct devfreq_passive_data *)devfreq->data;389 = (struct devfreq_passive_data *)devfreq->data;
139 struct devfreq *parent = (struct devfreq *)p_data->parent;390 struct devfreq *parent = (struct devfreq *)p_data->parent;
140 struct notifier_block *nb = &p_data->nb;391 struct notifier_block *nb = &p_data->nb;
141 int ret = 0;
142 392
143 if (!parent)393 if (!parent)
144 return -EPROBE_DEFER;394 return -EPROBE_DEFER;
145 395
396 nb->notifier_call = devfreq_passive_notifier_call;
397 return devfreq_register_notifier(parent, nb, DEVFREQ_TRANSITION_NOTIFIER);
398}
399
400static int devfreq_passive_event_handler(struct devfreq *devfreq,
401 unsigned int event, void *data)
402{
403 struct devfreq_passive_data *p_data
404 = (struct devfreq_passive_data *)devfreq->data;
405 int ret = 0;
406
407 if (!p_data)
408 return -EINVAL;
409
410 if (!p_data->this)
411 p_data->this = devfreq;
412
146 switch (event) {413 switch (event) {
147 case DEVFREQ_GOV_START:414 case DEVFREQ_GOV_START:
148 if (!p_data->this)415 if (p_data->parent_type == DEVFREQ_PARENT_DEV)
149 p_data->this = devfreq;416 ret = devfreq_passive_register_notifier(devfreq);
150 417 else if (p_data->parent_type == CPUFREQ_PARENT_DEV)
151 nb->notifier_call = devfreq_passive_notifier_call;418 ret = cpufreq_passive_register_notifier(devfreq);
152 ret = devfreq_register_notifier(parent, nb,
153 DEVFREQ_TRANSITION_NOTIFIER);
154 break;419 break;
155 case DEVFREQ_GOV_STOP:420 case DEVFREQ_GOV_STOP:
156 WARN_ON(devfreq_unregister_notifier(parent, nb,421 if (p_data->parent_type == DEVFREQ_PARENT_DEV)
157 DEVFREQ_TRANSITION_NOTIFIER));422 WARN_ON(devfreq_passive_unregister_notifier(devfreq));
423 else if (p_data->parent_type == CPUFREQ_PARENT_DEV)
424 WARN_ON(cpufreq_passive_unregister_notifier(devfreq));
158 break;425 break;
159 default:426 default:
160 break;427 break;
drivers/devfreq/rk3399_dmc.c+147−165
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 */5 */
6 6
7#include <linux/arm-smccc.h>7#include <linux/arm-smccc.h>
8#include <linux/bitfield.h>
8#include <linux/clk.h>9#include <linux/clk.h>
9#include <linux/delay.h>10#include <linux/delay.h>
10#include <linux/devfreq.h>11#include <linux/devfreq.h>
@@ -20,55 +21,49 @@ · 9 unmodified lines
20#include <linux/rwsem.h>21#include <linux/rwsem.h>
21#include <linux/suspend.h>22#include <linux/suspend.h>
22 23
24#include <soc/rockchip/pm_domains.h>
23#include <soc/rockchip/rk3399_grf.h>25#include <soc/rockchip/rk3399_grf.h>
24#include <soc/rockchip/rockchip_sip.h>26#include <soc/rockchip/rockchip_sip.h>
25 27
26struct dram_timing {28#define NS_TO_CYCLE(NS, MHz) (((NS) * (MHz)) / NSEC_PER_USEC)
27 unsigned int ddr3_speed_bin;29
28 unsigned int pd_idle;30#define RK3399_SET_ODT_PD_0_SR_IDLE GENMASK(7, 0)
29 unsigned int sr_idle;31#define RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE GENMASK(15, 8)
30 unsigned int sr_mc_gate_idle;32#define RK3399_SET_ODT_PD_0_STANDBY_IDLE GENMASK(31, 16)
31 unsigned int srpd_lite_idle;33
32 unsigned int standby_idle;34#define RK3399_SET_ODT_PD_1_PD_IDLE GENMASK(11, 0)
33 unsigned int auto_pd_dis_freq;35#define RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE GENMASK(27, 16)
34 unsigned int dram_dll_dis_freq;36
35 unsigned int phy_dll_dis_freq;37#define RK3399_SET_ODT_PD_2_ODT_ENABLE BIT(0)
36 unsigned int ddr3_odt_dis_freq;
37 unsigned int ddr3_drv;
38 unsigned int ddr3_odt;
39 unsigned int phy_ddr3_ca_drv;
40 unsigned int phy_ddr3_dq_drv;
41 unsigned int phy_ddr3_odt;
42 unsigned int lpddr3_odt_dis_freq;
43 unsigned int lpddr3_drv;
44 unsigned int lpddr3_odt;
45 unsigned int phy_lpddr3_ca_drv;
46 unsigned int phy_lpddr3_dq_drv;
47 unsigned int phy_lpddr3_odt;
48 unsigned int lpddr4_odt_dis_freq;
49 unsigned int lpddr4_drv;
50 unsigned int lpddr4_dq_odt;
51 unsigned int lpddr4_ca_odt;
52 unsigned int phy_lpddr4_ca_drv;
53 unsigned int phy_lpddr4_ck_cs_drv;
54 unsigned int phy_lpddr4_dq_drv;
55 unsigned int phy_lpddr4_odt;
56};
57 38
58struct rk3399_dmcfreq {39struct rk3399_dmcfreq {
59 struct device *dev;40 struct device *dev;
60 struct devfreq *devfreq;41 struct devfreq *devfreq;
42 struct devfreq_dev_profile profile;
61 struct devfreq_simple_ondemand_data ondemand_data;43 struct devfreq_simple_ondemand_data ondemand_data;
62 struct clk *dmc_clk;44 struct clk *dmc_clk;
63 struct devfreq_event_dev *edev;45 struct devfreq_event_dev *edev;
64 struct mutex lock;46 struct mutex lock;
65 struct dram_timing timing;
66 struct regulator *vdd_center;47 struct regulator *vdd_center;
67 struct regmap *regmap_pmu;48 struct regmap *regmap_pmu;
68 unsigned long rate, target_rate;49 unsigned long rate, target_rate;
69 unsigned long volt, target_volt;50 unsigned long volt, target_volt;
70 unsigned int odt_dis_freq;51 unsigned int odt_dis_freq;
71 int odt_pd_arg0, odt_pd_arg1;52
53 unsigned int pd_idle_ns;
54 unsigned int sr_idle_ns;
55 unsigned int sr_mc_gate_idle_ns;
56 unsigned int srpd_lite_idle_ns;
57 unsigned int standby_idle_ns;
58 unsigned int ddr3_odt_dis_freq;
59 unsigned int lpddr3_odt_dis_freq;
60 unsigned int lpddr4_odt_dis_freq;
61
62 unsigned int pd_idle_dis_freq;
63 unsigned int sr_idle_dis_freq;
64 unsigned int sr_mc_gate_idle_dis_freq;
65 unsigned int srpd_lite_idle_dis_freq;
66 unsigned int standby_idle_dis_freq;
72};67};
73 68
74static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,69static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
@@ -78,10 +73,14 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq, · 3 unmodified lines
78 struct dev_pm_opp *opp;73 struct dev_pm_opp *opp;
79 unsigned long old_clk_rate = dmcfreq->rate;74 unsigned long old_clk_rate = dmcfreq->rate;
80 unsigned long target_volt, target_rate;75 unsigned long target_volt, target_rate;
76 unsigned int ddrcon_mhz;
81 struct arm_smccc_res res;77 struct arm_smccc_res res;
82 bool odt_enable = false;
83 int err;78 int err;
84 79
80 u32 odt_pd_arg0 = 0;
81 u32 odt_pd_arg1 = 0;
82 u32 odt_pd_arg2 = 0;
83
85 opp = devfreq_recommended_opp(dev, freq, flags);84 opp = devfreq_recommended_opp(dev, freq, flags);
86 if (IS_ERR(opp))85 if (IS_ERR(opp))
87 return PTR_ERR(opp);86 return PTR_ERR(opp);
@@ -95,19 +94,71 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq, · 7 unmodified lines
95 94
96 mutex_lock(&dmcfreq->lock);95 mutex_lock(&dmcfreq->lock);
97 96
97 /*
98 * Ensure power-domain transitions don't interfere with ARM Trusted
99 * Firmware power-domain idling.
100 */
101 err = rockchip_pmu_block();
102 if (err) {
103 dev_err(dev, "Failed to block PMU: %d\n", err);
104 goto out_unlock;
105 }
106
107 /*
108 * Some idle parameters may be based on the DDR controller clock, which
109 * is half of the DDR frequency.
110 * pd_idle and standby_idle are based on the controller clock cycle.
111 * sr_idle_cycle, sr_mc_gate_idle_cycle, and srpd_lite_idle_cycle
112 * are based on the 1024 controller clock cycle
113 */
114 ddrcon_mhz = target_rate / USEC_PER_SEC / 2;
115
116 u32p_replace_bits(&odt_pd_arg1,
117 NS_TO_CYCLE(dmcfreq->pd_idle_ns, ddrcon_mhz),
118 RK3399_SET_ODT_PD_1_PD_IDLE);
119 u32p_replace_bits(&odt_pd_arg0,
120 NS_TO_CYCLE(dmcfreq->standby_idle_ns, ddrcon_mhz),
121 RK3399_SET_ODT_PD_0_STANDBY_IDLE);
122 u32p_replace_bits(&odt_pd_arg0,
123 DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_idle_ns,
124 ddrcon_mhz), 1024),
125 RK3399_SET_ODT_PD_0_SR_IDLE);
126 u32p_replace_bits(&odt_pd_arg0,
127 DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_mc_gate_idle_ns,
128 ddrcon_mhz), 1024),
129 RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE);
130 u32p_replace_bits(&odt_pd_arg1,
131 DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->srpd_lite_idle_ns,
132 ddrcon_mhz), 1024),
133 RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE);
134
98 if (dmcfreq->regmap_pmu) {135 if (dmcfreq->regmap_pmu) {
136 if (target_rate >= dmcfreq->sr_idle_dis_freq)
137 odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_IDLE;
138
139 if (target_rate >= dmcfreq->sr_mc_gate_idle_dis_freq)
140 odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE;
141
142 if (target_rate >= dmcfreq->standby_idle_dis_freq)
143 odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_STANDBY_IDLE;
144
145 if (target_rate >= dmcfreq->pd_idle_dis_freq)
146 odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_PD_IDLE;
147
148 if (target_rate >= dmcfreq->srpd_lite_idle_dis_freq)
149 odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE;
150
99 if (target_rate >= dmcfreq->odt_dis_freq)151 if (target_rate >= dmcfreq->odt_dis_freq)
100 odt_enable = true;152 odt_pd_arg2 |= RK3399_SET_ODT_PD_2_ODT_ENABLE;
101 153
102 /*154 /*
103 * This makes a SMC call to the TF-A to set the DDR PD155 * This makes a SMC call to the TF-A to set the DDR PD
104 * (power-down) timings and to enable or disable the156 * (power-down) timings and to enable or disable the
105 * ODT (on-die termination) resistors.157 * ODT (on-die termination) resistors.
106 */158 */
107 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,159 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, odt_pd_arg0, odt_pd_arg1,
108 dmcfreq->odt_pd_arg1,160 ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, odt_pd_arg2,
109 ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,161 0, 0, 0, &res);
110 odt_enable, 0, 0, 0, &res);
111 }162 }
112 163
113 /*164 /*
@@ -158,6 +209,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq, · 44 unmodified lines
158 dmcfreq->volt = target_volt;209 dmcfreq->volt = target_volt;
159 210
160out:211out:
212 rockchip_pmu_unblock();
213out_unlock:
161 mutex_unlock(&dmcfreq->lock);214 mutex_unlock(&dmcfreq->lock);
162 return err;215 return err;
163}216}
@@ -189,13 +242,6 @@ static int rk3399_dmcfreq_get_cur_freq(struct device *dev, unsigned long *freq) · 25 unmodified lines
189 return 0;242 return 0;
190}243}
191 244
192static struct devfreq_dev_profile rk3399_devfreq_dmc_profile = {
193 .polling_ms = 200,
194 .target = rk3399_dmcfreq_target,
195 .get_dev_status = rk3399_dmcfreq_get_dev_status,
196 .get_cur_freq = rk3399_dmcfreq_get_cur_freq,
197};
198
199static __maybe_unused int rk3399_dmcfreq_suspend(struct device *dev)245static __maybe_unused int rk3399_dmcfreq_suspend(struct device *dev)
200{246{
201 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);247 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);
@@ -238,69 +284,48 @@ static __maybe_unused int rk3399_dmcfreq_resume(struct device *dev) · 36 unmodified lines
238static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm, rk3399_dmcfreq_suspend,284static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm, rk3399_dmcfreq_suspend,
239 rk3399_dmcfreq_resume);285 rk3399_dmcfreq_resume);
240 286
241static int of_get_ddr_timings(struct dram_timing *timing,287static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
242 struct device_node *np)288 struct device_node *np)
243{289{
244 int ret = 0;290 int ret = 0;
245 291
246 ret = of_property_read_u32(np, "rockchip,ddr3_speed_bin",292 /*
247 &timing->ddr3_speed_bin);293 * These are all optional, and serve as minimum bounds. Give them large
248 ret |= of_property_read_u32(np, "rockchip,pd_idle",294 * (i.e., never "disabled") values if the DT doesn't specify one.
249 &timing->pd_idle);295 */
250 ret |= of_property_read_u32(np, "rockchip,sr_idle",296 data->pd_idle_dis_freq =
251 &timing->sr_idle);297 data->sr_idle_dis_freq =
252 ret |= of_property_read_u32(np, "rockchip,sr_mc_gate_idle",298 data->sr_mc_gate_idle_dis_freq =
253 &timing->sr_mc_gate_idle);299 data->srpd_lite_idle_dis_freq =
254 ret |= of_property_read_u32(np, "rockchip,srpd_lite_idle",300 data->standby_idle_dis_freq = UINT_MAX;
255 &timing->srpd_lite_idle);301
256 ret |= of_property_read_u32(np, "rockchip,standby_idle",302 ret |= of_property_read_u32(np, "rockchip,pd-idle-ns",
257 &timing->standby_idle);303 &data->pd_idle_ns);
258 ret |= of_property_read_u32(np, "rockchip,auto_pd_dis_freq",304 ret |= of_property_read_u32(np, "rockchip,sr-idle-ns",
259 &timing->auto_pd_dis_freq);305 &data->sr_idle_ns);
260 ret |= of_property_read_u32(np, "rockchip,dram_dll_dis_freq",306 ret |= of_property_read_u32(np, "rockchip,sr-mc-gate-idle-ns",
261 &timing->dram_dll_dis_freq);307 &data->sr_mc_gate_idle_ns);
262 ret |= of_property_read_u32(np, "rockchip,phy_dll_dis_freq",308 ret |= of_property_read_u32(np, "rockchip,srpd-lite-idle-ns",
263 &timing->phy_dll_dis_freq);309 &data->srpd_lite_idle_ns);
310 ret |= of_property_read_u32(np, "rockchip,standby-idle-ns",
311 &data->standby_idle_ns);
264 ret |= of_property_read_u32(np, "rockchip,ddr3_odt_dis_freq",312 ret |= of_property_read_u32(np, "rockchip,ddr3_odt_dis_freq",
265 &timing->ddr3_odt_dis_freq);313 &data->ddr3_odt_dis_freq);
266 ret |= of_property_read_u32(np, "rockchip,ddr3_drv",
267 &timing->ddr3_drv);
268 ret |= of_property_read_u32(np, "rockchip,ddr3_odt",
269 &timing->ddr3_odt);
270 ret |= of_property_read_u32(np, "rockchip,phy_ddr3_ca_drv",
271 &timing->phy_ddr3_ca_drv);
272 ret |= of_property_read_u32(np, "rockchip,phy_ddr3_dq_drv",
273 &timing->phy_ddr3_dq_drv);
274 ret |= of_property_read_u32(np, "rockchip,phy_ddr3_odt",
275 &timing->phy_ddr3_odt);
276 ret |= of_property_read_u32(np, "rockchip,lpddr3_odt_dis_freq",314 ret |= of_property_read_u32(np, "rockchip,lpddr3_odt_dis_freq",
277 &timing->lpddr3_odt_dis_freq);315 &data->lpddr3_odt_dis_freq);
278 ret |= of_property_read_u32(np, "rockchip,lpddr3_drv",
279 &timing->lpddr3_drv);
280 ret |= of_property_read_u32(np, "rockchip,lpddr3_odt",
281 &timing->lpddr3_odt);
282 ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_ca_drv",
283 &timing->phy_lpddr3_ca_drv);
284 ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_dq_drv",
285 &timing->phy_lpddr3_dq_drv);
286 ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_odt",
287 &timing->phy_lpddr3_odt);
288 ret |= of_property_read_u32(np, "rockchip,lpddr4_odt_dis_freq",316 ret |= of_property_read_u32(np, "rockchip,lpddr4_odt_dis_freq",
289 &timing->lpddr4_odt_dis_freq);317 &data->lpddr4_odt_dis_freq);
290 ret |= of_property_read_u32(np, "rockchip,lpddr4_drv",318
291 &timing->lpddr4_drv);319 ret |= of_property_read_u32(np, "rockchip,pd-idle-dis-freq-hz",
292 ret |= of_property_read_u32(np, "rockchip,lpddr4_dq_odt",320 &data->pd_idle_dis_freq);
293 &timing->lpddr4_dq_odt);321 ret |= of_property_read_u32(np, "rockchip,sr-idle-dis-freq-hz",
294 ret |= of_property_read_u32(np, "rockchip,lpddr4_ca_odt",322 &data->sr_idle_dis_freq);
295 &timing->lpddr4_ca_odt);323 ret |= of_property_read_u32(np, "rockchip,sr-mc-gate-idle-dis-freq-hz",
296 ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_ca_drv",324 &data->sr_mc_gate_idle_dis_freq);
297 &timing->phy_lpddr4_ca_drv);325 ret |= of_property_read_u32(np, "rockchip,srpd-lite-idle-dis-freq-hz",
298 ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_ck_cs_drv",326 &data->srpd_lite_idle_dis_freq);
299 &timing->phy_lpddr4_ck_cs_drv);327 ret |= of_property_read_u32(np, "rockchip,standby-idle-dis-freq-hz",
300 ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_dq_drv",328 &data->standby_idle_dis_freq);
301 &timing->phy_lpddr4_dq_drv);
302 ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_odt",
303 &timing->phy_lpddr4_odt);
304 329
305 return ret;330 return ret;
306}331}
@@ -311,8 +336,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) · 4 unmodified lines
311 struct device *dev = &pdev->dev;336 struct device *dev = &pdev->dev;
312 struct device_node *np = pdev->dev.of_node, *node;337 struct device_node *np = pdev->dev.of_node, *node;
313 struct rk3399_dmcfreq *data;338 struct rk3399_dmcfreq *data;
314 int ret, index, size;339 int ret;
315 uint32_t *timing;
316 struct dev_pm_opp *opp;340 struct dev_pm_opp *opp;
317 u32 ddr_type;341 u32 ddr_type;
318 u32 val;342 u32 val;
@@ -343,26 +367,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) · 24 unmodified lines
343 return ret;367 return ret;
344 }368 }
345 369
346 /*370 rk3399_dmcfreq_of_props(data, np);
347 * Get dram timing and pass it to arm trust firmware,
348 * the dram driver in arm trust firmware will get these
349 * timing and to do dram initial.
350 */
351 if (!of_get_ddr_timings(&data->timing, np)) {
352 timing = &data->timing.ddr3_speed_bin;
353 size = sizeof(struct dram_timing) / 4;
354 for (index = 0; index < size; index++) {
355 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, *timing++, index,
356 ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM,
357 0, 0, 0, 0, &res);
358 if (res.a0) {
359 dev_err(dev, "Failed to set dram param: %ld\n",
360 res.a0);
361 ret = -EINVAL;
362 goto err_edev;
363 }
364 }
365 }
366 371
367 node = of_parse_phandle(np, "rockchip,pmu", 0);372 node = of_parse_phandle(np, "rockchip,pmu", 0);
368 if (!node)373 if (!node)
@@ -381,13 +386,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) · 12 unmodified lines
381 386
382 switch (ddr_type) {387 switch (ddr_type) {
383 case RK3399_PMUGRF_DDRTYPE_DDR3:388 case RK3399_PMUGRF_DDRTYPE_DDR3:
384 data->odt_dis_freq = data->timing.ddr3_odt_dis_freq;389 data->odt_dis_freq = data->ddr3_odt_dis_freq;
385 break;390 break;
386 case RK3399_PMUGRF_DDRTYPE_LPDDR3:391 case RK3399_PMUGRF_DDRTYPE_LPDDR3:
387 data->odt_dis_freq = data->timing.lpddr3_odt_dis_freq;392 data->odt_dis_freq = data->lpddr3_odt_dis_freq;
388 break;393 break;
389 case RK3399_PMUGRF_DDRTYPE_LPDDR4:394 case RK3399_PMUGRF_DDRTYPE_LPDDR4:
390 data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq;395 data->odt_dis_freq = data->lpddr4_odt_dis_freq;
391 break;396 break;
392 default:397 default:
393 ret = -EINVAL;398 ret = -EINVAL;
@@ -399,63 +404,46 @@ no_pmu: · 5 unmodified lines
399 ROCKCHIP_SIP_CONFIG_DRAM_INIT,404 ROCKCHIP_SIP_CONFIG_DRAM_INIT,
400 0, 0, 0, 0, &res);405 0, 0, 0, 0, &res);
401 406
402 /*
403 * In TF-A there is a platform SIP call to set the PD (power-down)
404 * timings and to enable or disable the ODT (on-die termination).
405 * This call needs three arguments as follows:
406 *
407 * arg0:
408 * bit[0-7] : sr_idle
409 * bit[8-15] : sr_mc_gate_idle
410 * bit[16-31] : standby idle
411 * arg1:
412 * bit[0-11] : pd_idle
413 * bit[16-27] : srpd_lite_idle
414 * arg2:
415 * bit[0] : odt enable
416 */
417 data->odt_pd_arg0 = (data->timing.sr_idle & 0xff) |
418 ((data->timing.sr_mc_gate_idle & 0xff) << 8) |
419 ((data->timing.standby_idle & 0xffff) << 16);
420 data->odt_pd_arg1 = (data->timing.pd_idle & 0xfff) |
421 ((data->timing.srpd_lite_idle & 0xfff) << 16);
422
423 /*407 /*
424 * We add a devfreq driver to our parent since it has a device tree node408 * We add a devfreq driver to our parent since it has a device tree node
425 * with operating points.409 * with operating points.
426 */410 */
427 if (dev_pm_opp_of_add_table(dev)) {411 if (devm_pm_opp_of_add_table(dev)) {
428 dev_err(dev, "Invalid operating-points in device tree.\n");412 dev_err(dev, "Invalid operating-points in device tree.\n");
429 ret = -EINVAL;413 ret = -EINVAL;
430 goto err_edev;414 goto err_edev;
431 }415 }
432 416
433 of_property_read_u32(np, "upthreshold",417 data->ondemand_data.upthreshold = 25;
434 &data->ondemand_data.upthreshold);418 data->ondemand_data.downdifferential = 15;
435 of_property_read_u32(np, "downdifferential",
436 &data->ondemand_data.downdifferential);
437 419
438 data->rate = clk_get_rate(data->dmc_clk);420 data->rate = clk_get_rate(data->dmc_clk);
439 421
440 opp = devfreq_recommended_opp(dev, &data->rate, 0);422 opp = devfreq_recommended_opp(dev, &data->rate, 0);
441 if (IS_ERR(opp)) {423 if (IS_ERR(opp)) {
442 ret = PTR_ERR(opp);424 ret = PTR_ERR(opp);
443 goto err_free_opp;425 goto err_edev;
444 }426 }
445 427
446 data->rate = dev_pm_opp_get_freq(opp);428 data->rate = dev_pm_opp_get_freq(opp);
447 data->volt = dev_pm_opp_get_voltage(opp);429 data->volt = dev_pm_opp_get_voltage(opp);
448 dev_pm_opp_put(opp);430 dev_pm_opp_put(opp);
449 431
450 rk3399_devfreq_dmc_profile.initial_freq = data->rate;432 data->profile = (struct devfreq_dev_profile) {
433 .polling_ms = 200,
434 .target = rk3399_dmcfreq_target,
435 .get_dev_status = rk3399_dmcfreq_get_dev_status,
436 .get_cur_freq = rk3399_dmcfreq_get_cur_freq,
437 .initial_freq = data->rate,
438 };
451 439
452 data->devfreq = devm_devfreq_add_device(dev,440 data->devfreq = devm_devfreq_add_device(dev,
453 &rk3399_devfreq_dmc_profile,441 &data->profile,
454 DEVFREQ_GOV_SIMPLE_ONDEMAND,442 DEVFREQ_GOV_SIMPLE_ONDEMAND,
455 &data->ondemand_data);443 &data->ondemand_data);
456 if (IS_ERR(data->devfreq)) {444 if (IS_ERR(data->devfreq)) {
457 ret = PTR_ERR(data->devfreq);445 ret = PTR_ERR(data->devfreq);
458 goto err_free_opp;446 goto err_edev;
459 }447 }
460 448
461 devm_devfreq_register_opp_notifier(dev, data->devfreq);449 devm_devfreq_register_opp_notifier(dev, data->devfreq);
@@ -465,8 +453,6 @@ no_pmu: · 3 unmodified lines
465 453
466 return 0;454 return 0;
467 455
468err_free_opp:
469 dev_pm_opp_of_remove_table(&pdev->dev);
470err_edev:456err_edev:
471 devfreq_event_disable_edev(data->edev);457 devfreq_event_disable_edev(data->edev);
472 458
@@ -477,11 +463,7 @@ static int rk3399_dmcfreq_remove(struct platform_device *pdev) · 4 unmodified lines
477{463{
478 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);464 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);
479 465
480 /*466 devfreq_event_disable_edev(dmcfreq->edev);
481 * Before remove the opp table we need to unregister the opp notifier.
482 */
483 devm_devfreq_unregister_opp_notifier(dmcfreq->dev, dmcfreq->devfreq);
484 dev_pm_opp_of_remove_table(dmcfreq->dev);
485 467
486 return 0;468 return 0;
487}469}
drivers/idle/intel_idle.c+133−0
@@ -764,6 +764,106 @@ static struct cpuidle_state icx_cstates[] __initdata = { · 763 unmodified lines
764 .enter = NULL }764 .enter = NULL }
765};765};
766 766
767/*
768 * On AlderLake C1 has to be disabled if C1E is enabled, and vice versa.
769 * C1E is enabled only if "C1E promotion" bit is set in MSR_IA32_POWER_CTL.
770 * But in this case there is effectively no C1, because C1 requests are
771 * promoted to C1E. If the "C1E promotion" bit is cleared, then both C1
772 * and C1E requests end up with C1, so there is effectively no C1E.
773 *
774 * By default we enable C1E and disable C1 by marking it with
775 * 'CPUIDLE_FLAG_UNUSABLE'.
776 */
777static struct cpuidle_state adl_cstates[] __initdata = {
778 {
779 .name = "C1",
780 .desc = "MWAIT 0x00",
781 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE,
782 .exit_latency = 1,
783 .target_residency = 1,
784 .enter = &intel_idle,
785 .enter_s2idle = intel_idle_s2idle, },
786 {
787 .name = "C1E",
788 .desc = "MWAIT 0x01",
789 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
790 .exit_latency = 2,
791 .target_residency = 4,
792 .enter = &intel_idle,
793 .enter_s2idle = intel_idle_s2idle, },
794 {
795 .name = "C6",
796 .desc = "MWAIT 0x20",
797 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
798 .exit_latency = 220,
799 .target_residency = 600,
800 .enter = &intel_idle,
801 .enter_s2idle = intel_idle_s2idle, },
802 {
803 .name = "C8",
804 .desc = "MWAIT 0x40",
805 .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
806 .exit_latency = 280,
807 .target_residency = 800,
808 .enter = &intel_idle,
809 .enter_s2idle = intel_idle_s2idle, },
810 {
811 .name = "C10",
812 .desc = "MWAIT 0x60",
813 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
814 .exit_latency = 680,
815 .target_residency = 2000,
816 .enter = &intel_idle,
817 .enter_s2idle = intel_idle_s2idle, },
818 {
819 .enter = NULL }
820};
821
822static struct cpuidle_state adl_l_cstates[] __initdata = {
823 {
824 .name = "C1",
825 .desc = "MWAIT 0x00",
826 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE,
827 .exit_latency = 1,
828 .target_residency = 1,
829 .enter = &intel_idle,
830 .enter_s2idle = intel_idle_s2idle, },
831 {
832 .name = "C1E",
833 .desc = "MWAIT 0x01",
834 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
835 .exit_latency = 2,
836 .target_residency = 4,
837 .enter = &intel_idle,
838 .enter_s2idle = intel_idle_s2idle, },
839 {
840 .name = "C6",
841 .desc = "MWAIT 0x20",
842 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
843 .exit_latency = 170,
844 .target_residency = 500,
845 .enter = &intel_idle,
846 .enter_s2idle = intel_idle_s2idle, },
847 {
848 .name = "C8",
849 .desc = "MWAIT 0x40",
850 .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
851 .exit_latency = 200,
852 .target_residency = 600,
853 .enter = &intel_idle,
854 .enter_s2idle = intel_idle_s2idle, },
855 {
856 .name = "C10",
857 .desc = "MWAIT 0x60",
858 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
859 .exit_latency = 230,
860 .target_residency = 700,
861 .enter = &intel_idle,
862 .enter_s2idle = intel_idle_s2idle, },
863 {
864 .enter = NULL }
865};
866
767/*867/*
768 * On Sapphire Rapids Xeon C1 has to be disabled if C1E is enabled, and vice868 * On Sapphire Rapids Xeon C1 has to be disabled if C1E is enabled, and vice
769 * versa. On SPR C1E is enabled only if "C1E promotion" bit is set in869 * versa. On SPR C1E is enabled only if "C1E promotion" bit is set in
@@ -1147,6 +1247,14 @@ static const struct idle_cpu idle_cpu_icx __initconst = { · 377 unmodified lines
1147 .use_acpi = true,1247 .use_acpi = true,
1148};1248};
1149 1249
1250static const struct idle_cpu idle_cpu_adl __initconst = {
1251 .state_table = adl_cstates,
1252};
1253
1254static const struct idle_cpu idle_cpu_adl_l __initconst = {
1255 .state_table = adl_l_cstates,
1256};
1257
1150static const struct idle_cpu idle_cpu_spr __initconst = {1258static const struct idle_cpu idle_cpu_spr __initconst = {
1151 .state_table = spr_cstates,1259 .state_table = spr_cstates,
1152 .disable_promotion_to_c1e = true,1260 .disable_promotion_to_c1e = true,
@@ -1215,6 +1323,8 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { · 62 unmodified lines
1215 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx),1323 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx),
1216 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx),1324 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx),
1217 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx),1325 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx),
1326 X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &idle_cpu_adl),
1327 X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &idle_cpu_adl_l),
1218 X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr),1328 X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr),
1219 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl),1329 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl),
1220 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl),1330 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl),
@@ -1573,6 +1683,25 @@ static void __init skx_idle_state_table_update(void) · 352 unmodified lines
1573 }1683 }
1574}1684}
1575 1685
1686/**
1687 * adl_idle_state_table_update - Adjust AlderLake idle states table.
1688 */
1689static void __init adl_idle_state_table_update(void)
1690{
1691 /* Check if user prefers C1 over C1E. */
1692 if (preferred_states_mask & BIT(1) && !(preferred_states_mask & BIT(2))) {
1693 cpuidle_state_table[0].flags &= ~CPUIDLE_FLAG_UNUSABLE;
1694 cpuidle_state_table[1].flags |= CPUIDLE_FLAG_UNUSABLE;
1695
1696 /* Disable C1E by clearing the "C1E promotion" bit. */
1697 c1e_promotion = C1E_PROMOTION_DISABLE;
1698 return;
1699 }
1700
1701 /* Make sure C1E is enabled by default */
1702 c1e_promotion = C1E_PROMOTION_ENABLE;
1703}
1704
1576/**1705/**
1577 * spr_idle_state_table_update - Adjust Sapphire Rapids idle states table.1706 * spr_idle_state_table_update - Adjust Sapphire Rapids idle states table.
1578 */1707 */
@@ -1642,6 +1771,10 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) · 63 unmodified lines
1642 case INTEL_FAM6_SAPPHIRERAPIDS_X:1771 case INTEL_FAM6_SAPPHIRERAPIDS_X:
1643 spr_idle_state_table_update();1772 spr_idle_state_table_update();
1644 break;1773 break;
1774 case INTEL_FAM6_ALDERLAKE:
1775 case INTEL_FAM6_ALDERLAKE_L:
1776 adl_idle_state_table_update();
1777 break;
1645 }1778 }
1646 1779
1647 for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {1780 for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {
drivers/iio/chemical/scd30.h+1−4
@@ -68,10 +68,7 @@ struct scd30_state { · 67 unmodified lines
68 scd30_command_t command;68 scd30_command_t command;
69};69};
70 70
71int scd30_suspend(struct device *dev);71extern const struct dev_pm_ops scd30_pm_ops;
72int scd30_resume(struct device *dev);
73
74static __maybe_unused SIMPLE_DEV_PM_OPS(scd30_pm_ops, scd30_suspend, scd30_resume);
75 72
76int scd30_probe(struct device *dev, int irq, const char *name, void *priv, scd30_command_t command);73int scd30_probe(struct device *dev, int irq, const char *name, void *priv, scd30_command_t command);
77 74
drivers/iio/chemical/scd30_core.c+5−5
@@ -517,7 +517,7 @@ static const struct iio_chan_spec scd30_channels[] = { · 516 unmodified lines
517 IIO_CHAN_SOFT_TIMESTAMP(3),517 IIO_CHAN_SOFT_TIMESTAMP(3),
518};518};
519 519
520int __maybe_unused scd30_suspend(struct device *dev)520static int scd30_suspend(struct device *dev)
521{521{
522 struct iio_dev *indio_dev = dev_get_drvdata(dev);522 struct iio_dev *indio_dev = dev_get_drvdata(dev);
523 struct scd30_state *state = iio_priv(indio_dev);523 struct scd30_state *state = iio_priv(indio_dev);
@@ -529,9 +529,8 @@ int __maybe_unused scd30_suspend(struct device *dev) · 5 unmodified lines
529 529
530 return regulator_disable(state->vdd);530 return regulator_disable(state->vdd);
531}531}
532EXPORT_SYMBOL(scd30_suspend);
533 532
534int __maybe_unused scd30_resume(struct device *dev)533static int scd30_resume(struct device *dev)
535{534{
536 struct iio_dev *indio_dev = dev_get_drvdata(dev);535 struct iio_dev *indio_dev = dev_get_drvdata(dev);
537 struct scd30_state *state = iio_priv(indio_dev);536 struct scd30_state *state = iio_priv(indio_dev);
@@ -543,7 +542,8 @@ int __maybe_unused scd30_resume(struct device *dev) · 5 unmodified lines
543 542
544 return scd30_command_write(state, CMD_START_MEAS, state->pressure_comp);543 return scd30_command_write(state, CMD_START_MEAS, state->pressure_comp);
545}544}
546EXPORT_SYMBOL(scd30_resume);545
546EXPORT_NS_SIMPLE_DEV_PM_OPS(scd30_pm_ops, scd30_suspend, scd30_resume, IIO_SCD30);
547 547
548static void scd30_stop_meas(void *data)548static void scd30_stop_meas(void *data)
549{549{
@@ -759,7 +759,7 @@ int scd30_probe(struct device *dev, int irq, const char *name, void *priv, · 209 unmodified lines
759 759
760 return devm_iio_device_register(dev, indio_dev);760 return devm_iio_device_register(dev, indio_dev);
761}761}
762EXPORT_SYMBOL(scd30_probe);762EXPORT_SYMBOL_NS(scd30_probe, IIO_SCD30);
763 763
764MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");764MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
765MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor core driver");765MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor core driver");
drivers/iio/chemical/scd30_i2c.c+2−1
@@ -128,7 +128,7 @@ static struct i2c_driver scd30_i2c_driver = { · 127 unmodified lines
128 .driver = {128 .driver = {
129 .name = KBUILD_MODNAME,129 .name = KBUILD_MODNAME,
130 .of_match_table = scd30_i2c_of_match,130 .of_match_table = scd30_i2c_of_match,
131 .pm = &scd30_pm_ops,131 .pm = pm_sleep_ptr(&scd30_pm_ops),
132 },132 },
133 .probe_new = scd30_i2c_probe,133 .probe_new = scd30_i2c_probe,
134};134};
@@ -137,3 +137,4 @@ module_i2c_driver(scd30_i2c_driver); · 2 unmodified lines
137MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");137MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
138MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor i2c driver");138MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor i2c driver");
139MODULE_LICENSE("GPL v2");139MODULE_LICENSE("GPL v2");
140MODULE_IMPORT_NS(IIO_SCD30);
drivers/iio/chemical/scd30_serial.c+2−1
@@ -252,7 +252,7 @@ static struct serdev_device_driver scd30_serdev_driver = { · 251 unmodified lines
252 .driver = {252 .driver = {
253 .name = KBUILD_MODNAME,253 .name = KBUILD_MODNAME,
254 .of_match_table = scd30_serdev_of_match,254 .of_match_table = scd30_serdev_of_match,
255 .pm = &scd30_pm_ops,255 .pm = pm_sleep_ptr(&scd30_pm_ops),
256 },256 },
257 .probe = scd30_serdev_probe,257 .probe = scd30_serdev_probe,
258};258};
@@ -261,3 +261,4 @@ module_serdev_device_driver(scd30_serdev_driver); · 2 unmodified lines
261MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");261MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
262MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor serial driver");262MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor serial driver");
263MODULE_LICENSE("GPL v2");263MODULE_LICENSE("GPL v2");
264MODULE_IMPORT_NS(IIO_SCD30);
drivers/opp/of.c+3−3
@@ -1448,7 +1448,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node); · 1447 unmodified lines
1448 * Returns 0 on success or a proper -EINVAL value in case of error.1448 * Returns 0 on success or a proper -EINVAL value in case of error.
1449 */1449 */
1450static int __maybe_unused1450static int __maybe_unused
1451_get_dt_power(unsigned long *mW, unsigned long *kHz, struct device *dev)1451_get_dt_power(struct device *dev, unsigned long *mW, unsigned long *kHz)
1452{1452{
1453 struct dev_pm_opp *opp;1453 struct dev_pm_opp *opp;
1454 unsigned long opp_freq, opp_power;1454 unsigned long opp_freq, opp_power;
@@ -1482,8 +1482,8 @@ _get_dt_power(unsigned long *mW, unsigned long *kHz, struct device *dev) · 27 unmodified lines
1482 * Returns -EINVAL if the power calculation failed because of missing1482 * Returns -EINVAL if the power calculation failed because of missing
1483 * parameters, 0 otherwise.1483 * parameters, 0 otherwise.
1484 */1484 */
1485static int __maybe_unused _get_power(unsigned long *mW, unsigned long *kHz,1485static int __maybe_unused _get_power(struct device *dev, unsigned long *mW,
1486 struct device *dev)1486 unsigned long *kHz)
1487{1487{
1488 struct dev_pm_opp *opp;1488 struct dev_pm_opp *opp;
1489 struct device_node *np;1489 struct device_node *np;
drivers/powercap/dtpm_cpu.c+1−1
@@ -211,7 +211,7 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent) · 210 unmodified lines
211 return 0;211 return 0;
212 212
213 pd = em_cpu_get(cpu);213 pd = em_cpu_get(cpu);
214 if (!pd)214 if (!pd || em_is_artificial(pd))
215 return -EINVAL;215 return -EINVAL;
216 216
217 dtpm_cpu = kzalloc(sizeof(*dtpm_cpu), GFP_KERNEL);217 dtpm_cpu = kzalloc(sizeof(*dtpm_cpu), GFP_KERNEL);
drivers/powercap/intel_rapl_common.c+3−1
@@ -1010,7 +1010,7 @@ static u64 rapl_compute_time_window_atom(struct rapl_package *rp, u64 value, · 1009 unmodified lines
1010 * where time_unit is default to 1 sec. Never 0.1010 * where time_unit is default to 1 sec. Never 0.
1011 */1011 */
1012 if (!to_raw)1012 if (!to_raw)
1013 return (value) ? value *= rp->time_unit : rp->time_unit;1013 return (value) ? value * rp->time_unit : rp->time_unit;
1014 1014
1015 value = div64_u64(value, rp->time_unit);1015 value = div64_u64(value, rp->time_unit);
1016 1016
@@ -1107,6 +1107,8 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { · 90 unmodified lines
1107 X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rapl_defaults_core),1107 X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rapl_defaults_core),
1108 X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &rapl_defaults_core),1108 X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &rapl_defaults_core),
1109 X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &rapl_defaults_core),1109 X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &rapl_defaults_core),
1110 X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &rapl_defaults_core),
1111 X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &rapl_defaults_core),
1110 X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &rapl_defaults_spr_server),1112 X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &rapl_defaults_spr_server),
1111 X86_MATCH_INTEL_FAM6_MODEL(LAKEFIELD, &rapl_defaults_core),1113 X86_MATCH_INTEL_FAM6_MODEL(LAKEFIELD, &rapl_defaults_core),
1112 1114
drivers/powercap/intel_rapl_msr.c+1−0
@@ -140,6 +140,7 @@ static const struct x86_cpu_id pl4_support_ids[] = { · 139 unmodified lines
140 { X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY },140 { X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY },
141 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY },141 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY },
142 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY },142 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY },
143 { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE, X86_FEATURE_ANY },
143 {}144 {}
144};145};
145 146
drivers/soc/rockchip/pm_domains.c+118−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#include <linux/io.h>8#include <linux/io.h>
9#include <linux/iopoll.h>9#include <linux/iopoll.h>
10#include <linux/err.h>10#include <linux/err.h>
11#include <linux/mutex.h>
11#include <linux/pm_clock.h>12#include <linux/pm_clock.h>
12#include <linux/pm_domain.h>13#include <linux/pm_domain.h>
13#include <linux/of_address.h>14#include <linux/of_address.h>
@@ -16,6 +17,7 @@ · 2 unmodified lines
16#include <linux/clk.h>17#include <linux/clk.h>
17#include <linux/regmap.h>18#include <linux/regmap.h>
18#include <linux/mfd/syscon.h>19#include <linux/mfd/syscon.h>
20#include <soc/rockchip/pm_domains.h>
19#include <dt-bindings/power/px30-power.h>21#include <dt-bindings/power/px30-power.h>
20#include <dt-bindings/power/rk3036-power.h>22#include <dt-bindings/power/rk3036-power.h>
21#include <dt-bindings/power/rk3066-power.h>23#include <dt-bindings/power/rk3066-power.h>
@@ -139,6 +141,109 @@ struct rockchip_pmu { · 117 unmodified lines
139#define DOMAIN_RK3568(name, pwr, req, wakeup) \141#define DOMAIN_RK3568(name, pwr, req, wakeup) \
140 DOMAIN_M(name, pwr, pwr, req, req, req, wakeup)142 DOMAIN_M(name, pwr, pwr, req, req, req, wakeup)
141 143
144/*
145 * Dynamic Memory Controller may need to coordinate with us -- see
146 * rockchip_pmu_block().
147 *
148 * dmc_pmu_mutex protects registration-time races, so DMC driver doesn't try to
149 * block() while we're initializing the PMU.
150 */
151static DEFINE_MUTEX(dmc_pmu_mutex);
152static struct rockchip_pmu *dmc_pmu;
153
154/*
155 * Block PMU transitions and make sure they don't interfere with ARM Trusted
156 * Firmware operations. There are two conflicts, noted in the comments below.
157 *
158 * Caller must unblock PMU transitions via rockchip_pmu_unblock().
159 */
160int rockchip_pmu_block(void)
161{
162 struct rockchip_pmu *pmu;
163 struct generic_pm_domain *genpd;
164 struct rockchip_pm_domain *pd;
165 int i, ret;
166
167 mutex_lock(&dmc_pmu_mutex);
168
169 /* No PMU (yet)? Then we just block rockchip_pmu_probe(). */
170 if (!dmc_pmu)
171 return 0;
172 pmu = dmc_pmu;
173
174 /*
175 * mutex blocks all idle transitions: we can't touch the
176 * PMU_BUS_IDLE_REQ (our ".idle_offset") register while ARM Trusted
177 * Firmware might be using it.
178 */
179 mutex_lock(&pmu->mutex);
180
181 /*
182 * Power domain clocks: Per Rockchip, we *must* keep certain clocks
183 * enabled for the duration of power-domain transitions. Most
184 * transitions are handled by this driver, but some cases (in
185 * particular, DRAM DVFS / memory-controller idle) must be handled by
186 * firmware. Firmware can handle most clock management via a special
187 * "ungate" register (PMU_CRU_GATEDIS_CON0), but unfortunately, this
188 * doesn't handle PLLs. We can assist this transition by doing the
189 * clock management on behalf of firmware.
190 */
191 for (i = 0; i < pmu->genpd_data.num_domains; i++) {
192 genpd = pmu->genpd_data.domains[i];
193 if (genpd) {
194 pd = to_rockchip_pd(genpd);
195 ret = clk_bulk_enable(pd->num_clks, pd->clks);
196 if (ret < 0) {
197 dev_err(pmu->dev,
198 "failed to enable clks for domain '%s': %d\n",
199 genpd->name, ret);
200 goto err;
201 }
202 }
203 }
204
205 return 0;
206
207err:
208 for (i = i - 1; i >= 0; i--) {
209 genpd = pmu->genpd_data.domains[i];
210 if (genpd) {
211 pd = to_rockchip_pd(genpd);
212 clk_bulk_disable(pd->num_clks, pd->clks);
213 }
214 }
215 mutex_unlock(&pmu->mutex);
216 mutex_unlock(&dmc_pmu_mutex);
217
218 return ret;
219}
220EXPORT_SYMBOL_GPL(rockchip_pmu_block);
221
222/* Unblock PMU transitions. */
223void rockchip_pmu_unblock(void)
224{
225 struct rockchip_pmu *pmu;
226 struct generic_pm_domain *genpd;
227 struct rockchip_pm_domain *pd;
228 int i;
229
230 if (dmc_pmu) {
231 pmu = dmc_pmu;
232 for (i = 0; i < pmu->genpd_data.num_domains; i++) {
233 genpd = pmu->genpd_data.domains[i];
234 if (genpd) {
235 pd = to_rockchip_pd(genpd);
236 clk_bulk_disable(pd->num_clks, pd->clks);
237 }
238 }
239
240 mutex_unlock(&pmu->mutex);
241 }
242
243 mutex_unlock(&dmc_pmu_mutex);
244}
245EXPORT_SYMBOL_GPL(rockchip_pmu_unblock);
246
142static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)247static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
143{248{
144 struct rockchip_pmu *pmu = pd->pmu;249 struct rockchip_pmu *pmu = pd->pmu;
@@ -690,6 +795,12 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) · 545 unmodified lines
690 795
691 error = -ENODEV;796 error = -ENODEV;
692 797
798 /*
799 * Prevent any rockchip_pmu_block() from racing with the remainder of
800 * setup (clocks, register initialization).
801 */
802 mutex_lock(&dmc_pmu_mutex);
803
693 for_each_available_child_of_node(np, node) {804 for_each_available_child_of_node(np, node) {
694 error = rockchip_pm_add_one_domain(pmu, node);805 error = rockchip_pm_add_one_domain(pmu, node);
695 if (error) {806 if (error) {
@@ -719,10 +830,17 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) · 23 unmodified lines
719 goto err_out;830 goto err_out;
720 }831 }
721 832
833 /* We only expect one PMU. */
834 if (!WARN_ON_ONCE(dmc_pmu))
835 dmc_pmu = pmu;
836
837 mutex_unlock(&dmc_pmu_mutex);
838
722 return 0;839 return 0;
723 840
724err_out:841err_out:
725 rockchip_pm_domain_cleanup(pmu);842 rockchip_pm_domain_cleanup(pmu);
843 mutex_unlock(&dmc_pmu_mutex);
726 return error;844 return error;
727}845}
728 846
drivers/thermal/cpufreq_cooling.c+1−1
@@ -328,7 +328,7 @@ static inline bool em_is_sane(struct cpufreq_cooling_device *cpufreq_cdev, · 327 unmodified lines
328 struct cpufreq_policy *policy;328 struct cpufreq_policy *policy;
329 unsigned int nr_levels;329 unsigned int nr_levels;
330 330
331 if (!em)331 if (!em || em_is_artificial(em))
332 return false;332 return false;
333 333
334 policy = cpufreq_cdev->policy;334 policy = cpufreq_cdev->policy;
drivers/thermal/devfreq_cooling.c+5−3
@@ -358,6 +358,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, · 357 unmodified lines
358 struct thermal_cooling_device *cdev;358 struct thermal_cooling_device *cdev;
359 struct device *dev = df->dev.parent;359 struct device *dev = df->dev.parent;
360 struct devfreq_cooling_device *dfc;360 struct devfreq_cooling_device *dfc;
361 struct em_perf_domain *em;
361 char *name;362 char *name;
362 int err, num_opps;363 int err, num_opps;
363 364
@@ -367,8 +368,9 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, · 3 unmodified lines
367 368
368 dfc->devfreq = df;369 dfc->devfreq = df;
369 370
370 dfc->em_pd = em_pd_get(dev);371 em = em_pd_get(dev);
371 if (dfc->em_pd) {372 if (em && !em_is_artificial(em)) {
373 dfc->em_pd = em;
372 devfreq_cooling_ops.get_requested_power =374 devfreq_cooling_ops.get_requested_power =
373 devfreq_cooling_get_requested_power;375 devfreq_cooling_get_requested_power;
374 devfreq_cooling_ops.state2power = devfreq_cooling_state2power;376 devfreq_cooling_ops.state2power = devfreq_cooling_state2power;
@@ -379,7 +381,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, · 4 unmodified lines
379 num_opps = em_pd_nr_perf_states(dfc->em_pd);381 num_opps = em_pd_nr_perf_states(dfc->em_pd);
380 } else {382 } else {
381 /* Backward compatibility for drivers which do not use IPA */383 /* Backward compatibility for drivers which do not use IPA */
382 dev_dbg(dev, "missing EM for cooling device\n");384 dev_dbg(dev, "missing proper EM for cooling device\n");
383 385
384 num_opps = dev_pm_opp_get_opp_count(dev);386 num_opps = dev_pm_opp_get_opp_count(dev);
385 387
include/acpi/cppc_acpi.h+5−0
@@ -141,6 +141,7 @@ extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); · 140 unmodified lines
141extern int cppc_set_enable(int cpu, bool enable);141extern int cppc_set_enable(int cpu, bool enable);
142extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);142extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
143extern bool acpi_cpc_valid(void);143extern bool acpi_cpc_valid(void);
144extern bool cppc_allow_fast_switch(void);
144extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);145extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
145extern unsigned int cppc_get_transition_latency(int cpu);146extern unsigned int cppc_get_transition_latency(int cpu);
146extern bool cpc_ffh_supported(void);147extern bool cpc_ffh_supported(void);
@@ -175,6 +176,10 @@ static inline bool acpi_cpc_valid(void) · 28 unmodified lines
175{176{
176 return false;177 return false;
177}178}
179static inline bool cppc_allow_fast_switch(void)
180{
181 return false;
182}
178static inline unsigned int cppc_get_transition_latency(int cpu)183static inline unsigned int cppc_get_transition_latency(int cpu)
179{184{
180 return CPUFREQ_ETERNAL;185 return CPUFREQ_ETERNAL;
include/linux/acpi.h+2−0
@@ -574,6 +574,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); · 573 unmodified lines
574#define OSC_SB_OSLPI_SUPPORT 0x00000100574#define OSC_SB_OSLPI_SUPPORT 0x00000100
575#define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT 0x00001000575#define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT 0x00001000
576#define OSC_SB_GENERIC_INITIATOR_SUPPORT 0x00002000576#define OSC_SB_GENERIC_INITIATOR_SUPPORT 0x00002000
577#define OSC_SB_CPC_FLEXIBLE_ADR_SPACE 0x00004000
577#define OSC_SB_NATIVE_USB4_SUPPORT 0x00040000578#define OSC_SB_NATIVE_USB4_SUPPORT 0x00040000
578#define OSC_SB_PRM_SUPPORT 0x00200000579#define OSC_SB_PRM_SUPPORT 0x00200000
579 580
@@ -581,6 +582,7 @@ extern bool osc_sb_apei_support_acked; · 1 unmodified line
581extern bool osc_pc_lpi_support_confirmed;582extern bool osc_pc_lpi_support_confirmed;
582extern bool osc_sb_native_usb4_support_confirmed;583extern bool osc_sb_native_usb4_support_confirmed;
583extern bool osc_sb_cppc_not_supported;584extern bool osc_sb_cppc_not_supported;
585extern bool osc_cpc_flexible_adr_space_confirmed;
584 586
585/* USB4 Capabilities */587/* USB4 Capabilities */
586#define OSC_USB_USB3_TUNNELING 0x00000001588#define OSC_USB_USB3_TUNNELING 0x00000001
include/linux/devfreq.h+15−2
@@ -38,6 +38,7 @@ enum devfreq_timer { · 37 unmodified lines
38 38
39struct devfreq;39struct devfreq;
40struct devfreq_governor;40struct devfreq_governor;
41struct devfreq_cpu_data;
41struct thermal_cooling_device;42struct thermal_cooling_device;
42 43
43/**44/**
@@ -288,6 +289,11 @@ struct devfreq_simple_ondemand_data { · 244 unmodified lines
288#endif289#endif
289 290
290#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)291#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)
292enum devfreq_parent_dev_type {
293 DEVFREQ_PARENT_DEV,
294 CPUFREQ_PARENT_DEV,
295};
296
291/**297/**
292 * struct devfreq_passive_data - ``void *data`` fed to struct devfreq298 * struct devfreq_passive_data - ``void *data`` fed to struct devfreq
293 * and devfreq_add_device299 * and devfreq_add_device
@@ -299,8 +305,11 @@ struct devfreq_simple_ondemand_data { · 5 unmodified lines
299 * using governors except for passive governor.305 * using governors except for passive governor.
300 * If the devfreq device has the specific method to decide306 * If the devfreq device has the specific method to decide
301 * the next frequency, should use this callback.307 * the next frequency, should use this callback.
302 * @this: the devfreq instance of own device.308 * @parent_type: the parent type of the device.
303 * @nb: the notifier block for DEVFREQ_TRANSITION_NOTIFIER list309 * @this: the devfreq instance of own device.
310 * @nb: the notifier block for DEVFREQ_TRANSITION_NOTIFIER or
311 * CPUFREQ_TRANSITION_NOTIFIER list.
312 * @cpu_data_list: the list of cpu frequency data for all cpufreq_policy.
304 *313 *
305 * The devfreq_passive_data have to set the devfreq instance of parent314 * The devfreq_passive_data have to set the devfreq instance of parent
306 * device with governors except for the passive governor. But, don't need to315 * device with governors except for the passive governor. But, don't need to
@@ -314,9 +323,13 @@ struct devfreq_passive_data { · 7 unmodified lines
314 /* Optional callback to decide the next frequency of passvice device */323 /* Optional callback to decide the next frequency of passvice device */
315 int (*get_target_freq)(struct devfreq *this, unsigned long *freq);324 int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
316 325
326 /* Should set the type of parent device */
327 enum devfreq_parent_dev_type parent_type;
328
317 /* For passive governor's internal use. Don't need to set them */329 /* For passive governor's internal use. Don't need to set them */
318 struct devfreq *this;330 struct devfreq *this;
319 struct notifier_block nb;331 struct notifier_block nb;
332 struct list_head cpu_data_list;
320};333};
321#endif334#endif
322 335
include/linux/energy_model.h+31−4
@@ -67,11 +67,16 @@ struct em_perf_domain { · 66 unmodified lines
67 *67 *
68 * EM_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip inefficient states when estimating68 * EM_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip inefficient states when estimating
69 * energy consumption.69 * energy consumption.
70 *
71 * EM_PERF_DOMAIN_ARTIFICIAL: The power values are artificial and might be
72 * created by platform missing real power information
70 */73 */
71#define EM_PERF_DOMAIN_MILLIWATTS BIT(0)74#define EM_PERF_DOMAIN_MILLIWATTS BIT(0)
72#define EM_PERF_DOMAIN_SKIP_INEFFICIENCIES BIT(1)75#define EM_PERF_DOMAIN_SKIP_INEFFICIENCIES BIT(1)
76#define EM_PERF_DOMAIN_ARTIFICIAL BIT(2)
73 77
74#define em_span_cpus(em) (to_cpumask((em)->cpus))78#define em_span_cpus(em) (to_cpumask((em)->cpus))
79#define em_is_artificial(em) ((em)->flags & EM_PERF_DOMAIN_ARTIFICIAL)
75 80
76#ifdef CONFIG_ENERGY_MODEL81#ifdef CONFIG_ENERGY_MODEL
77#define EM_MAX_POWER 0xFFFF82#define EM_MAX_POWER 0xFFFF
@@ -96,11 +101,11 @@ struct em_data_callback { · 18 unmodified lines
96 /**101 /**
97 * active_power() - Provide power at the next performance state of102 * active_power() - Provide power at the next performance state of
98 * a device103 * a device
104 * @dev : Device for which we do this operation (can be a CPU)
99 * @power : Active power at the performance state105 * @power : Active power at the performance state
100 * (modified)106 * (modified)
101 * @freq : Frequency at the performance state in kHz107 * @freq : Frequency at the performance state in kHz
102 * (modified)108 * (modified)
103 * @dev : Device for which we do this operation (can be a CPU)
104 *109 *
105 * active_power() must find the lowest performance state of 'dev' above110 * active_power() must find the lowest performance state of 'dev' above
106 * 'freq' and update 'power' and 'freq' to the matching active power111 * 'freq' and update 'power' and 'freq' to the matching active power
@@ -112,11 +117,32 @@ struct em_data_callback { · 5 unmodified lines
112 *117 *
113 * Return 0 on success.118 * Return 0 on success.
114 */119 */
115 int (*active_power)(unsigned long *power, unsigned long *freq,120 int (*active_power)(struct device *dev, unsigned long *power,
116 struct device *dev);121 unsigned long *freq);
122
123 /**
124 * get_cost() - Provide the cost at the given performance state of
125 * a device
126 * @dev : Device for which we do this operation (can be a CPU)
127 * @freq : Frequency at the performance state in kHz
128 * @cost : The cost value for the performance state
129 * (modified)
130 *
131 * In case of CPUs, the cost is the one of a single CPU in the domain.
132 * It is expected to fit in the [0, EM_MAX_POWER] range due to internal
133 * usage in EAS calculation.
134 *
135 * Return 0 on success, or appropriate error value in case of failure.
136 */
137 int (*get_cost)(struct device *dev, unsigned long freq,
138 unsigned long *cost);
117};139};
118#define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb }
119#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) ((em_cb).active_power = cb)140#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) ((em_cb).active_power = cb)
141#define EM_ADV_DATA_CB(_active_power_cb, _cost_cb) \
142 { .active_power = _active_power_cb, \
143 .get_cost = _cost_cb }
144#define EM_DATA_CB(_active_power_cb) \
145 EM_ADV_DATA_CB(_active_power_cb, NULL)
120 146
121struct em_perf_domain *em_cpu_get(int cpu);147struct em_perf_domain *em_cpu_get(int cpu);
122struct em_perf_domain *em_pd_get(struct device *dev);148struct em_perf_domain *em_pd_get(struct device *dev);
@@ -264,6 +290,7 @@ static inline int em_pd_nr_perf_states(struct em_perf_domain *pd) · 141 unmodified lines
264 290
265#else291#else
266struct em_data_callback {};292struct em_data_callback {};
293#define EM_ADV_DATA_CB(_active_power_cb, _cost_cb) { }
267#define EM_DATA_CB(_active_power_cb) { }294#define EM_DATA_CB(_active_power_cb) { }
268#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) do { } while (0)295#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) do { } while (0)
269 296
include/linux/pm.h+9−5
@@ -368,13 +368,13 @@ const struct dev_pm_ops name = { \ · 367 unmodified lines
368 368
369#ifdef CONFIG_PM369#ifdef CONFIG_PM
370#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \370#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
371 runtime_resume_fn, idle_fn, sec) \371 runtime_resume_fn, idle_fn, sec, ns) \
372 _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \372 _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
373 runtime_resume_fn, idle_fn); \373 runtime_resume_fn, idle_fn); \
374 _EXPORT_SYMBOL(name, sec)374 __EXPORT_SYMBOL(name, sec, ns)
375#else375#else
376#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \376#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
377 runtime_resume_fn, idle_fn, sec) \377 runtime_resume_fn, idle_fn, sec, ns) \
378static __maybe_unused _DEFINE_DEV_PM_OPS(__static_##name, suspend_fn, \378static __maybe_unused _DEFINE_DEV_PM_OPS(__static_##name, suspend_fn, \
379 resume_fn, runtime_suspend_fn, \379 resume_fn, runtime_suspend_fn, \
380 runtime_resume_fn, idle_fn)380 runtime_resume_fn, idle_fn)
@@ -391,9 +391,13 @@ static __maybe_unused _DEFINE_DEV_PM_OPS(__static_##name, suspend_fn, \ · 10 unmodified lines
391 _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL)391 _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL)
392 392
393#define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \393#define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
394 _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "")394 _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "", "")
395#define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \395#define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
396 _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl")396 _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl", "")
397#define EXPORT_NS_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \
398 _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "", #ns)
399#define EXPORT_NS_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \
400 _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl", #ns)
397 401
398/* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */402/* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */
399#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \403#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
include/linux/pm_domain.h+14−10
@@ -91,6 +91,14 @@ struct gpd_dev_ops { · 90 unmodified lines
91 int (*stop)(struct device *dev);91 int (*stop)(struct device *dev);
92};92};
93 93
94struct genpd_governor_data {
95 s64 max_off_time_ns;
96 bool max_off_time_changed;
97 ktime_t next_wakeup;
98 bool cached_power_down_ok;
99 bool cached_power_down_state_idx;
100};
101
94struct genpd_power_state {102struct genpd_power_state {
95 s64 power_off_latency_ns;103 s64 power_off_latency_ns;
96 s64 power_on_latency_ns;104 s64 power_on_latency_ns;
@@ -98,7 +106,7 @@ struct genpd_power_state { · 1 unmodified line
98 u64 usage;106 u64 usage;
99 u64 rejected;107 u64 rejected;
100 struct fwnode_handle *fwnode;108 struct fwnode_handle *fwnode;
101 ktime_t idle_time;109 u64 idle_time;
102 void *data;110 void *data;
103};111};
104 112
@@ -114,6 +122,7 @@ struct generic_pm_domain { · 9 unmodified lines
114 struct list_head child_links; /* Links with PM domain as a child */122 struct list_head child_links; /* Links with PM domain as a child */
115 struct list_head dev_list; /* List of devices */123 struct list_head dev_list; /* List of devices */
116 struct dev_power_governor *gov;124 struct dev_power_governor *gov;
125 struct genpd_governor_data *gd; /* Data used by a genpd governor. */
117 struct work_struct power_off_work;126 struct work_struct power_off_work;
118 struct fwnode_handle *provider; /* Identity of the domain provider */127 struct fwnode_handle *provider; /* Identity of the domain provider */
119 bool has_provider;128 bool has_provider;
@@ -134,11 +143,6 @@ struct generic_pm_domain { · 14 unmodified lines
134 int (*set_performance_state)(struct generic_pm_domain *genpd,143 int (*set_performance_state)(struct generic_pm_domain *genpd,
135 unsigned int state);144 unsigned int state);
136 struct gpd_dev_ops dev_ops;145 struct gpd_dev_ops dev_ops;
137 s64 max_off_time_ns; /* Maximum allowed "suspended" time. */
138 ktime_t next_wakeup; /* Maintained by the domain governor */
139 bool max_off_time_changed;
140 bool cached_power_down_ok;
141 bool cached_power_down_state_idx;
142 int (*attach_dev)(struct generic_pm_domain *domain,146 int (*attach_dev)(struct generic_pm_domain *domain,
143 struct device *dev);147 struct device *dev);
144 void (*detach_dev)(struct generic_pm_domain *domain,148 void (*detach_dev)(struct generic_pm_domain *domain,
@@ -149,8 +153,8 @@ struct generic_pm_domain { · 4 unmodified lines
149 unsigned int state_count);153 unsigned int state_count);
150 unsigned int state_count; /* number of states */154 unsigned int state_count; /* number of states */
151 unsigned int state_idx; /* state that genpd will go to when off */155 unsigned int state_idx; /* state that genpd will go to when off */
152 ktime_t on_time;156 u64 on_time;
153 ktime_t accounting_time;157 u64 accounting_time;
154 const struct genpd_lock_ops *lock_ops;158 const struct genpd_lock_ops *lock_ops;
155 union {159 union {
156 struct mutex mlock;160 struct mutex mlock;
@@ -182,6 +186,7 @@ struct gpd_timing_data { · 25 unmodified lines
182 s64 suspend_latency_ns;186 s64 suspend_latency_ns;
183 s64 resume_latency_ns;187 s64 resume_latency_ns;
184 s64 effective_constraint_ns;188 s64 effective_constraint_ns;
189 ktime_t next_wakeup;
185 bool constraint_changed;190 bool constraint_changed;
186 bool cached_suspend_ok;191 bool cached_suspend_ok;
187};192};
@@ -193,14 +198,13 @@ struct pm_domain_data { · 5 unmodified lines
193 198
194struct generic_pm_domain_data {199struct generic_pm_domain_data {
195 struct pm_domain_data base;200 struct pm_domain_data base;
196 struct gpd_timing_data td;201 struct gpd_timing_data *td;
197 struct notifier_block nb;202 struct notifier_block nb;
198 struct notifier_block *power_nb;203 struct notifier_block *power_nb;
199 int cpu;204 int cpu;
200 unsigned int performance_state;205 unsigned int performance_state;
201 unsigned int default_pstate;206 unsigned int default_pstate;
202 unsigned int rpm_pstate;207 unsigned int rpm_pstate;
203 ktime_t next_wakeup;
204 void *data;208 void *data;
205};209};
206 210
include/linux/pm_runtime.h+8−2
@@ -41,10 +41,16 @@ · 40 unmodified lines
41 41
42#define EXPORT_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \42#define EXPORT_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
43 _EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \43 _EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \
44 suspend_fn, resume_fn, idle_fn, "")44 suspend_fn, resume_fn, idle_fn, "", "")
45#define EXPORT_GPL_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \45#define EXPORT_GPL_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
46 _EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \46 _EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \
47 suspend_fn, resume_fn, idle_fn, "_gpl")47 suspend_fn, resume_fn, idle_fn, "_gpl", "")
48#define EXPORT_NS_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn, ns) \
49 _EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \
50 suspend_fn, resume_fn, idle_fn, "", #ns)
51#define EXPORT_NS_GPL_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn, ns) \
52 _EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \
53 suspend_fn, resume_fn, idle_fn, "_gpl", #ns)
48 54
49#ifdef CONFIG_PM55#ifdef CONFIG_PM
50extern struct workqueue_struct *pm_wq;56extern struct workqueue_struct *pm_wq;
include/linux/suspend.h+39−5
@@ -542,22 +542,56 @@ static inline void unlock_system_sleep(void) {} · 541 unmodified lines
542#ifdef CONFIG_PM_SLEEP_DEBUG542#ifdef CONFIG_PM_SLEEP_DEBUG
543extern bool pm_print_times_enabled;543extern bool pm_print_times_enabled;
544extern bool pm_debug_messages_on;544extern bool pm_debug_messages_on;
545extern __printf(2, 3) void __pm_pr_dbg(bool defer, const char *fmt, ...);545static inline int pm_dyn_debug_messages_on(void)
546{
547#ifdef CONFIG_DYNAMIC_DEBUG
548 return 1;
549#else
550 return 0;
551#endif
552}
553#ifndef pr_fmt
554#define pr_fmt(fmt) "PM: " fmt
555#endif
556#define __pm_pr_dbg(fmt, ...) \
557 do { \
558 if (pm_debug_messages_on) \
559 printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \
560 else if (pm_dyn_debug_messages_on()) \
561 pr_debug(fmt, ##__VA_ARGS__); \
562 } while (0)
563#define __pm_deferred_pr_dbg(fmt, ...) \
564 do { \
565 if (pm_debug_messages_on) \
566 printk_deferred(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \
567 } while (0)
546#else568#else
547#define pm_print_times_enabled (false)569#define pm_print_times_enabled (false)
548#define pm_debug_messages_on (false)570#define pm_debug_messages_on (false)
549 571
550#include <linux/printk.h>572#include <linux/printk.h>
551 573
552#define __pm_pr_dbg(defer, fmt, ...) \574#define __pm_pr_dbg(fmt, ...) \
553 no_printk(KERN_DEBUG fmt, ##__VA_ARGS__)575 no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
576#define __pm_deferred_pr_dbg(fmt, ...) \
577 no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
554#endif578#endif
555 579
580/**
581 * pm_pr_dbg - print pm sleep debug messages
582 *
583 * If pm_debug_messages_on is enabled, print message.
584 * If pm_debug_messages_on is disabled and CONFIG_DYNAMIC_DEBUG is enabled,
585 * print message only from instances explicitly enabled on dynamic debug's
586 * control.
587 * If pm_debug_messages_on is disabled and CONFIG_DYNAMIC_DEBUG is disabled,
588 * don't print message.
589 */
556#define pm_pr_dbg(fmt, ...) \590#define pm_pr_dbg(fmt, ...) \
557 __pm_pr_dbg(false, fmt, ##__VA_ARGS__)591 __pm_pr_dbg(fmt, ##__VA_ARGS__)
558 592
559#define pm_deferred_pr_dbg(fmt, ...) \593#define pm_deferred_pr_dbg(fmt, ...) \
560 __pm_pr_dbg(true, fmt, ##__VA_ARGS__)594 __pm_deferred_pr_dbg(fmt, ##__VA_ARGS__)
561 595
562#ifdef CONFIG_PM_AUTOSLEEP596#ifdef CONFIG_PM_AUTOSLEEP
563 597
include/soc/rockchip/pm_domains.h+25−0
@@ -0,0 +1,25 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright 2022, The Chromium OS Authors. All rights reserved.
4 */
5
6#ifndef __SOC_ROCKCHIP_PM_DOMAINS_H__
7#define __SOC_ROCKCHIP_PM_DOMAINS_H__
8
9#ifdef CONFIG_ROCKCHIP_PM_DOMAINS
10
11int rockchip_pmu_block(void);
12void rockchip_pmu_unblock(void);
13
14#else /* CONFIG_ROCKCHIP_PM_DOMAINS */
15
16static inline int rockchip_pmu_block(void)
17{
18 return 0;
19}
20
21static inline void rockchip_pmu_unblock(void) { }
22
23#endif /* CONFIG_ROCKCHIP_PM_DOMAINS */
24
25#endif /* __SOC_ROCKCHIP_PM_DOMAINS_H__ */
kernel/power/Makefile+5−1
@@ -1,6 +1,10 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2 2
3ccflags-$(CONFIG_PM_DEBUG) := -DDEBUG3ifeq ($(CONFIG_DYNAMIC_DEBUG), y)
4CFLAGS_swap.o := -DDEBUG
5CFLAGS_snapshot.o := -DDEBUG
6CFLAGS_energy_model.o := -DDEBUG
7endif
4 8
5KASAN_SANITIZE_snapshot.o := n9KASAN_SANITIZE_snapshot.o := n
6 10
kernel/power/energy_model.c+36−29
@@ -54,28 +54,15 @@ static int em_debug_cpus_show(struct seq_file *s, void *unused) · 53 unmodified lines
54}54}
55DEFINE_SHOW_ATTRIBUTE(em_debug_cpus);55DEFINE_SHOW_ATTRIBUTE(em_debug_cpus);
56 56
57static int em_debug_units_show(struct seq_file *s, void *unused)57static int em_debug_flags_show(struct seq_file *s, void *unused)
58{58{
59 struct em_perf_domain *pd = s->private;59 struct em_perf_domain *pd = s->private;
60 char *units = (pd->flags & EM_PERF_DOMAIN_MILLIWATTS) ?
61 "milliWatts" : "bogoWatts";
62 60
63 seq_printf(s, "%s\n", units);61 seq_printf(s, "%#lx\n", pd->flags);
64 62
65 return 0;63 return 0;
66}64}
67DEFINE_SHOW_ATTRIBUTE(em_debug_units);65DEFINE_SHOW_ATTRIBUTE(em_debug_flags);
68
69static int em_debug_skip_inefficiencies_show(struct seq_file *s, void *unused)
70{
71 struct em_perf_domain *pd = s->private;
72 int enabled = (pd->flags & EM_PERF_DOMAIN_SKIP_INEFFICIENCIES) ? 1 : 0;
73
74 seq_printf(s, "%d\n", enabled);
75
76 return 0;
77}
78DEFINE_SHOW_ATTRIBUTE(em_debug_skip_inefficiencies);
79 66
80static void em_debug_create_pd(struct device *dev)67static void em_debug_create_pd(struct device *dev)
81{68{
@@ -89,9 +76,8 @@ static void em_debug_create_pd(struct device *dev) · 7 unmodified lines
89 debugfs_create_file("cpus", 0444, d, dev->em_pd->cpus,76 debugfs_create_file("cpus", 0444, d, dev->em_pd->cpus,
90 &em_debug_cpus_fops);77 &em_debug_cpus_fops);
91 78
92 debugfs_create_file("units", 0444, d, dev->em_pd, &em_debug_units_fops);79 debugfs_create_file("flags", 0444, d, dev->em_pd,
93 debugfs_create_file("skip-inefficiencies", 0444, d, dev->em_pd,80 &em_debug_flags_fops);
94 &em_debug_skip_inefficiencies_fops);
95 81
96 /* Create a sub-directory for each performance state */82 /* Create a sub-directory for each performance state */
97 for (i = 0; i < dev->em_pd->nr_perf_states; i++)83 for (i = 0; i < dev->em_pd->nr_perf_states; i++)
@@ -121,7 +107,8 @@ static void em_debug_remove_pd(struct device *dev) {} · 23 unmodified lines
121#endif107#endif
122 108
123static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,109static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
124 int nr_states, struct em_data_callback *cb)110 int nr_states, struct em_data_callback *cb,
111 unsigned long flags)
125{112{
126 unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX;113 unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX;
127 struct em_perf_state *table;114 struct em_perf_state *table;
@@ -139,7 +126,7 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd, · 11 unmodified lines
139 * lowest performance state of 'dev' above 'freq' and updates126 * lowest performance state of 'dev' above 'freq' and updates
140 * 'power' and 'freq' accordingly.127 * 'power' and 'freq' accordingly.
141 */128 */
142 ret = cb->active_power(&power, &freq, dev);129 ret = cb->active_power(dev, &power, &freq);
143 if (ret) {130 if (ret) {
144 dev_err(dev, "EM: invalid perf. state: %d\n",131 dev_err(dev, "EM: invalid perf. state: %d\n",
145 ret);132 ret);
@@ -173,10 +160,22 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd, · 27 unmodified lines
173 /* Compute the cost of each performance state. */160 /* Compute the cost of each performance state. */
174 fmax = (u64) table[nr_states - 1].frequency;161 fmax = (u64) table[nr_states - 1].frequency;
175 for (i = nr_states - 1; i >= 0; i--) {162 for (i = nr_states - 1; i >= 0; i--) {
176 unsigned long power_res = em_scale_power(table[i].power);163 unsigned long power_res, cost;
164
165 if (flags & EM_PERF_DOMAIN_ARTIFICIAL) {
166 ret = cb->get_cost(dev, table[i].frequency, &cost);
167 if (ret || !cost || cost > EM_MAX_POWER) {
168 dev_err(dev, "EM: invalid cost %lu %d\n",
169 cost, ret);
170 goto free_ps_table;
171 }
172 } else {
173 power_res = em_scale_power(table[i].power);
174 cost = div64_u64(fmax * power_res, table[i].frequency);
175 }
176
177 table[i].cost = cost;
177 178
178 table[i].cost = div64_u64(fmax * power_res,
179 table[i].frequency);
180 if (table[i].cost >= prev_cost) {179 if (table[i].cost >= prev_cost) {
181 table[i].flags = EM_PERF_STATE_INEFFICIENT;180 table[i].flags = EM_PERF_STATE_INEFFICIENT;
182 dev_dbg(dev, "EM: OPP:%lu is inefficient\n",181 dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
@@ -197,7 +196,8 @@ free_ps_table: · 14 unmodified lines
197}196}
198 197
199static int em_create_pd(struct device *dev, int nr_states,198static int em_create_pd(struct device *dev, int nr_states,
200 struct em_data_callback *cb, cpumask_t *cpus)199 struct em_data_callback *cb, cpumask_t *cpus,
200 unsigned long flags)
201{201{
202 struct em_perf_domain *pd;202 struct em_perf_domain *pd;
203 struct device *cpu_dev;203 struct device *cpu_dev;
@@ -215,7 +215,7 @@ static int em_create_pd(struct device *dev, int nr_states, · 11 unmodified lines
215 return -ENOMEM;215 return -ENOMEM;
216 }216 }
217 217
218 ret = em_create_perf_table(dev, pd, nr_states, cb);218 ret = em_create_perf_table(dev, pd, nr_states, cb, flags);
219 if (ret) {219 if (ret) {
220 kfree(pd);220 kfree(pd);
221 return ret;221 return ret;
@@ -259,6 +259,8 @@ static void em_cpufreq_update_efficiencies(struct device *dev) · 37 unmodified lines
259 found++;259 found++;
260 }260 }
261 261
262 cpufreq_cpu_put(policy);
263
262 if (!found)264 if (!found)
263 return;265 return;
264 266
@@ -332,6 +334,7 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, · 67 unmodified lines
332 bool milliwatts)334 bool milliwatts)
333{335{
334 unsigned long cap, prev_cap = 0;336 unsigned long cap, prev_cap = 0;
337 unsigned long flags = 0;
335 int cpu, ret;338 int cpu, ret;
336 339
337 if (!dev || !nr_states || !cb)340 if (!dev || !nr_states || !cb)
@@ -378,12 +381,16 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, · 40 unmodified lines
378 }381 }
379 }382 }
380 383
381 ret = em_create_pd(dev, nr_states, cb, cpus);384 if (milliwatts)
385 flags |= EM_PERF_DOMAIN_MILLIWATTS;
386 else if (cb->get_cost)
387 flags |= EM_PERF_DOMAIN_ARTIFICIAL;
388
389 ret = em_create_pd(dev, nr_states, cb, cpus, flags);
382 if (ret)390 if (ret)
383 goto unlock;391 goto unlock;
384 392
385 if (milliwatts)393 dev->em_pd->flags |= flags;
386 dev->em_pd->flags |= EM_PERF_DOMAIN_MILLIWATTS;
387 394
388 em_cpufreq_update_efficiencies(dev);395 em_cpufreq_update_efficiencies(dev);
389 396
kernel/power/main.c+0−29
@@ -545,35 +545,6 @@ static int __init pm_debug_messages_setup(char *str) · 544 unmodified lines
545}545}
546__setup("pm_debug_messages", pm_debug_messages_setup);546__setup("pm_debug_messages", pm_debug_messages_setup);
547 547
548/**
549 * __pm_pr_dbg - Print a suspend debug message to the kernel log.
550 * @defer: Whether or not to use printk_deferred() to print the message.
551 * @fmt: Message format.
552 *
553 * The message will be emitted if enabled through the pm_debug_messages
554 * sysfs attribute.
555 */
556void __pm_pr_dbg(bool defer, const char *fmt, ...)
557{
558 struct va_format vaf;
559 va_list args;
560
561 if (!pm_debug_messages_on)
562 return;
563
564 va_start(args, fmt);
565
566 vaf.fmt = fmt;
567 vaf.va = &args;
568
569 if (defer)
570 printk_deferred(KERN_DEBUG "PM: %pV", &vaf);
571 else
572 printk(KERN_DEBUG "PM: %pV", &vaf);
573
574 va_end(args);
575}
576
577#else /* !CONFIG_PM_SLEEP_DEBUG */548#else /* !CONFIG_PM_SLEEP_DEBUG */
578static inline void pm_print_times_init(void) {}549static inline void pm_print_times_init(void) {}
579#endif /* CONFIG_PM_SLEEP_DEBUG */550#endif /* CONFIG_PM_SLEEP_DEBUG */
kernel/power/process.c+0−3
@@ -6,9 +6,6 @@ · 5 unmodified lines
6 * Originally from swsusp.6 * Originally from swsusp.
7 */7 */
8 8
9
10#undef DEBUG
11
12#include <linux/interrupt.h>9#include <linux/interrupt.h>
13#include <linux/oom.h>10#include <linux/oom.h>
14#include <linux/suspend.h>11#include <linux/suspend.h>
kernel/power/snapshot.c+8−4
@@ -326,7 +326,7 @@ static void *chain_alloc(struct chain_allocator *ca, unsigned int size) · 325 unmodified lines
326 return ret;326 return ret;
327}327}
328 328
329/**329/*
330 * Data types related to memory bitmaps.330 * Data types related to memory bitmaps.
331 *331 *
332 * Memory bitmap is a structure consisting of many linked lists of332 * Memory bitmap is a structure consisting of many linked lists of
@@ -427,6 +427,10 @@ struct memory_bitmap { · 94 unmodified lines
427 427
428/**428/**
429 * alloc_rtree_node - Allocate a new node and add it to the radix tree.429 * alloc_rtree_node - Allocate a new node and add it to the radix tree.
430 * @gfp_mask: GFP mask for the allocation.
431 * @safe_needed: Get pages not used before hibernation (restore only)
432 * @ca: Pointer to a linked list of pages ("a chain") to allocate from
433 * @list: Radix Tree node to add.
430 *434 *
431 * This function is used to allocate inner nodes as well as the435 * This function is used to allocate inner nodes as well as the
432 * leave nodes of the radix tree. It also adds the node to the436 * leave nodes of the radix tree. It also adds the node to the
@@ -902,7 +906,7 @@ static bool rtree_next_node(struct memory_bitmap *bm) · 469 unmodified lines
902}906}
903 907
904/**908/**
905 * memory_bm_rtree_next_pfn - Find the next set bit in a memory bitmap.909 * memory_bm_next_pfn - Find the next set bit in a memory bitmap.
906 * @bm: Memory bitmap.910 * @bm: Memory bitmap.
907 *911 *
908 * Starting from the last returned position this function searches for the next912 * Starting from the last returned position this function searches for the next
@@ -1937,7 +1941,7 @@ static inline int get_highmem_buffer(int safe_needed) · 1028 unmodified lines
1937}1941}
1938 1942
1939/**1943/**
1940 * alloc_highmem_image_pages - Allocate some highmem pages for the image.1944 * alloc_highmem_pages - Allocate some highmem pages for the image.
1941 *1945 *
1942 * Try to allocate as many pages as needed, but if the number of free highmem1946 * Try to allocate as many pages as needed, but if the number of free highmem
1943 * pages is less than that, allocate them all.1947 * pages is less than that, allocate them all.
@@ -2224,7 +2228,7 @@ static int check_header(struct swsusp_info *info) · 280 unmodified lines
2224}2228}
2225 2229
2226/**2230/**
2227 * load header - Check the image header and copy the data from it.2231 * load_header - Check the image header and copy the data from it.
2228 */2232 */
2229static int load_header(struct swsusp_info *info)2233static int load_header(struct swsusp_info *info)
2230{2234{
tools/power/x86/turbostat/Makefile+1−1
@@ -9,7 +9,7 @@ ifeq ("$(origin O)", "command line") · 8 unmodified lines
9endif9endif
10 10
11turbostat : turbostat.c11turbostat : turbostat.c
12override CFLAGS += -O2 -Wall -I../../../include12override CFLAGS += -O2 -Wall -Wextra -I../../../include
13override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"'13override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"'
14override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"'14override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"'
15override CFLAGS += -D_FILE_OFFSET_BITS=6415override CFLAGS += -D_FILE_OFFSET_BITS=64
tools/power/x86/turbostat/turbostat.8+1−1
@@ -292,7 +292,7 @@ starts a new interval. · 291 unmodified lines
292must be run as root.292must be run as root.
293Alternatively, non-root users can be enabled to run turbostat this way:293Alternatively, non-root users can be enabled to run turbostat this way:
294 294
295# setcap cap_sys_rawio=ep ./turbostat295# setcap cap_sys_admin,cap_sys_rawio,cap_sys_nice=+ep ./turbostat
296 296
297# chmod +r /dev/cpu/*/msr297# chmod +r /dev/cpu/*/msr
298 298
tools/power/x86/turbostat/turbostat.c+386−208
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 * turbostat -- show CPU frequency and C-state residency3 * turbostat -- show CPU frequency and C-state residency
4 * on modern Intel and AMD processors.4 * on modern Intel and AMD processors.
5 *5 *
6 * Copyright (c) 2021 Intel Corporation.6 * Copyright (c) 2022 Intel Corporation.
7 * Len Brown <len.brown@intel.com>7 * Len Brown <len.brown@intel.com>
8 */8 */
9 9
@@ -37,6 +37,171 @@ · 27 unmodified lines
37#include <asm/unistd.h>37#include <asm/unistd.h>
38#include <stdbool.h>38#include <stdbool.h>
39 39
40#define UNUSED(x) (void)(x)
41
42/*
43 * This list matches the column headers, except
44 * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time
45 * 2. Core and CPU are moved to the end, we can't have strings that contain them
46 * matching on them for --show and --hide.
47 */
48
49/*
50 * buffer size used by sscanf() for added column names
51 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
52 */
53#define NAME_BYTES 20
54#define PATH_BYTES 128
55
56enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE };
57enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC };
58enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT };
59
60struct msr_counter {
61 unsigned int msr_num;
62 char name[NAME_BYTES];
63 char path[PATH_BYTES];
64 unsigned int width;
65 enum counter_type type;
66 enum counter_format format;
67 struct msr_counter *next;
68 unsigned int flags;
69#define FLAGS_HIDE (1 << 0)
70#define FLAGS_SHOW (1 << 1)
71#define SYSFS_PERCPU (1 << 1)
72};
73
74struct msr_counter bic[] = {
75 { 0x0, "usec", "", 0, 0, 0, NULL, 0 },
76 { 0x0, "Time_Of_Day_Seconds", "", 0, 0, 0, NULL, 0 },
77 { 0x0, "Package", "", 0, 0, 0, NULL, 0 },
78 { 0x0, "Node", "", 0, 0, 0, NULL, 0 },
79 { 0x0, "Avg_MHz", "", 0, 0, 0, NULL, 0 },
80 { 0x0, "Busy%", "", 0, 0, 0, NULL, 0 },
81 { 0x0, "Bzy_MHz", "", 0, 0, 0, NULL, 0 },
82 { 0x0, "TSC_MHz", "", 0, 0, 0, NULL, 0 },
83 { 0x0, "IRQ", "", 0, 0, 0, NULL, 0 },
84 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL, 0 },
85 { 0x0, "sysfs", "", 0, 0, 0, NULL, 0 },
86 { 0x0, "CPU%c1", "", 0, 0, 0, NULL, 0 },
87 { 0x0, "CPU%c3", "", 0, 0, 0, NULL, 0 },
88 { 0x0, "CPU%c6", "", 0, 0, 0, NULL, 0 },
89 { 0x0, "CPU%c7", "", 0, 0, 0, NULL, 0 },
90 { 0x0, "ThreadC", "", 0, 0, 0, NULL, 0 },
91 { 0x0, "CoreTmp", "", 0, 0, 0, NULL, 0 },
92 { 0x0, "CoreCnt", "", 0, 0, 0, NULL, 0 },
93 { 0x0, "PkgTmp", "", 0, 0, 0, NULL, 0 },
94 { 0x0, "GFX%rc6", "", 0, 0, 0, NULL, 0 },
95 { 0x0, "GFXMHz", "", 0, 0, 0, NULL, 0 },
96 { 0x0, "Pkg%pc2", "", 0, 0, 0, NULL, 0 },
97 { 0x0, "Pkg%pc3", "", 0, 0, 0, NULL, 0 },
98 { 0x0, "Pkg%pc6", "", 0, 0, 0, NULL, 0 },
99 { 0x0, "Pkg%pc7", "", 0, 0, 0, NULL, 0 },
100 { 0x0, "Pkg%pc8", "", 0, 0, 0, NULL, 0 },
101 { 0x0, "Pkg%pc9", "", 0, 0, 0, NULL, 0 },
102 { 0x0, "Pk%pc10", "", 0, 0, 0, NULL, 0 },
103 { 0x0, "CPU%LPI", "", 0, 0, 0, NULL, 0 },
104 { 0x0, "SYS%LPI", "", 0, 0, 0, NULL, 0 },
105 { 0x0, "PkgWatt", "", 0, 0, 0, NULL, 0 },
106 { 0x0, "CorWatt", "", 0, 0, 0, NULL, 0 },
107 { 0x0, "GFXWatt", "", 0, 0, 0, NULL, 0 },
108 { 0x0, "PkgCnt", "", 0, 0, 0, NULL, 0 },
109 { 0x0, "RAMWatt", "", 0, 0, 0, NULL, 0 },
110 { 0x0, "PKG_%", "", 0, 0, 0, NULL, 0 },
111 { 0x0, "RAM_%", "", 0, 0, 0, NULL, 0 },
112 { 0x0, "Pkg_J", "", 0, 0, 0, NULL, 0 },
113 { 0x0, "Cor_J", "", 0, 0, 0, NULL, 0 },
114 { 0x0, "GFX_J", "", 0, 0, 0, NULL, 0 },
115 { 0x0, "RAM_J", "", 0, 0, 0, NULL, 0 },
116 { 0x0, "Mod%c6", "", 0, 0, 0, NULL, 0 },
117 { 0x0, "Totl%C0", "", 0, 0, 0, NULL, 0 },
118 { 0x0, "Any%C0", "", 0, 0, 0, NULL, 0 },
119 { 0x0, "GFX%C0", "", 0, 0, 0, NULL, 0 },
120 { 0x0, "CPUGFX%", "", 0, 0, 0, NULL, 0 },
121 { 0x0, "Core", "", 0, 0, 0, NULL, 0 },
122 { 0x0, "CPU", "", 0, 0, 0, NULL, 0 },
123 { 0x0, "APIC", "", 0, 0, 0, NULL, 0 },
124 { 0x0, "X2APIC", "", 0, 0, 0, NULL, 0 },
125 { 0x0, "Die", "", 0, 0, 0, NULL, 0 },
126 { 0x0, "GFXAMHz", "", 0, 0, 0, NULL, 0 },
127 { 0x0, "IPC", "", 0, 0, 0, NULL, 0 },
128 { 0x0, "CoreThr", "", 0, 0, 0, NULL, 0 },
129};
130
131#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
132#define BIC_USEC (1ULL << 0)
133#define BIC_TOD (1ULL << 1)
134#define BIC_Package (1ULL << 2)
135#define BIC_Node (1ULL << 3)
136#define BIC_Avg_MHz (1ULL << 4)
137#define BIC_Busy (1ULL << 5)
138#define BIC_Bzy_MHz (1ULL << 6)
139#define BIC_TSC_MHz (1ULL << 7)
140#define BIC_IRQ (1ULL << 8)
141#define BIC_SMI (1ULL << 9)
142#define BIC_sysfs (1ULL << 10)
143#define BIC_CPU_c1 (1ULL << 11)
144#define BIC_CPU_c3 (1ULL << 12)
145#define BIC_CPU_c6 (1ULL << 13)
146#define BIC_CPU_c7 (1ULL << 14)
147#define BIC_ThreadC (1ULL << 15)
148#define BIC_CoreTmp (1ULL << 16)
149#define BIC_CoreCnt (1ULL << 17)
150#define BIC_PkgTmp (1ULL << 18)
151#define BIC_GFX_rc6 (1ULL << 19)
152#define BIC_GFXMHz (1ULL << 20)
153#define BIC_Pkgpc2 (1ULL << 21)
154#define BIC_Pkgpc3 (1ULL << 22)
155#define BIC_Pkgpc6 (1ULL << 23)
156#define BIC_Pkgpc7 (1ULL << 24)
157#define BIC_Pkgpc8 (1ULL << 25)
158#define BIC_Pkgpc9 (1ULL << 26)
159#define BIC_Pkgpc10 (1ULL << 27)
160#define BIC_CPU_LPI (1ULL << 28)
161#define BIC_SYS_LPI (1ULL << 29)
162#define BIC_PkgWatt (1ULL << 30)
163#define BIC_CorWatt (1ULL << 31)
164#define BIC_GFXWatt (1ULL << 32)
165#define BIC_PkgCnt (1ULL << 33)
166#define BIC_RAMWatt (1ULL << 34)
167#define BIC_PKG__ (1ULL << 35)
168#define BIC_RAM__ (1ULL << 36)
169#define BIC_Pkg_J (1ULL << 37)
170#define BIC_Cor_J (1ULL << 38)
171#define BIC_GFX_J (1ULL << 39)
172#define BIC_RAM_J (1ULL << 40)
173#define BIC_Mod_c6 (1ULL << 41)
174#define BIC_Totl_c0 (1ULL << 42)
175#define BIC_Any_c0 (1ULL << 43)
176#define BIC_GFX_c0 (1ULL << 44)
177#define BIC_CPUGFX (1ULL << 45)
178#define BIC_Core (1ULL << 46)
179#define BIC_CPU (1ULL << 47)
180#define BIC_APIC (1ULL << 48)
181#define BIC_X2APIC (1ULL << 49)
182#define BIC_Die (1ULL << 50)
183#define BIC_GFXACTMHz (1ULL << 51)
184#define BIC_IPC (1ULL << 52)
185#define BIC_CORE_THROT_CNT (1ULL << 53)
186
187#define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die )
188#define BIC_THERMAL_PWR ( BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__)
189#define BIC_FREQUENCY ( BIC_Avg_MHz | BIC_Busy | BIC_Bzy_MHz | BIC_TSC_MHz | BIC_GFXMHz | BIC_GFXACTMHz )
190#define BIC_IDLE ( BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX)
191#define BIC_OTHER ( BIC_IRQ | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC)
192
193#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
194
195unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
196unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
197
198#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
199#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
200#define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
201#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
202#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
203#define BIC_IS_ENABLED(COUNTER_BIT) (bic_enabled & COUNTER_BIT)
204
40char *proc_stat = "/proc/stat";205char *proc_stat = "/proc/stat";
41FILE *outf;206FILE *outf;
42int *fd_percpu;207int *fd_percpu;
@@ -48,6 +213,7 @@ struct timespec interval_ts = { 5, 0 }; · 5 unmodified lines
48unsigned int model_orig;213unsigned int model_orig;
49 214
50unsigned int num_iterations;215unsigned int num_iterations;
216unsigned int header_iterations;
51unsigned int debug;217unsigned int debug;
52unsigned int quiet;218unsigned int quiet;
53unsigned int shown;219unsigned int shown;
@@ -159,13 +325,6 @@ int ignore_stdin; · 105 unmodified lines
159 325
160#define MAX(a, b) ((a) > (b) ? (a) : (b))326#define MAX(a, b) ((a) > (b) ? (a) : (b))
161 327
162/*
163 * buffer size used by sscanf() for added column names
164 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
165 */
166#define NAME_BYTES 20
167#define PATH_BYTES 128
168
169int backwards_count;328int backwards_count;
170char *progname;329char *progname;
171 330
@@ -205,6 +364,7 @@ struct core_data { · 33 unmodified lines
205 unsigned int core_temp_c;364 unsigned int core_temp_c;
206 unsigned int core_energy; /* MSR_CORE_ENERGY_STAT */365 unsigned int core_energy; /* MSR_CORE_ENERGY_STAT */
207 unsigned int core_id;366 unsigned int core_id;
367 unsigned long long core_throt_cnt;
208 unsigned long long counter[MAX_ADDED_COUNTERS];368 unsigned long long counter[MAX_ADDED_COUNTERS];
209} *core_even, *core_odd;369} *core_even, *core_odd;
210 370
@@ -255,24 +415,6 @@ struct pkg_data { · 44 unmodified lines
255 415
256#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)416#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
257 417
258enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE };
259enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC };
260enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT };
261
262struct msr_counter {
263 unsigned int msr_num;
264 char name[NAME_BYTES];
265 char path[PATH_BYTES];
266 unsigned int width;
267 enum counter_type type;
268 enum counter_format format;
269 struct msr_counter *next;
270 unsigned int flags;
271#define FLAGS_HIDE (1 << 0)
272#define FLAGS_SHOW (1 << 1)
273#define SYSFS_PERCPU (1 << 1)
274};
275
276/*418/*
277 * The accumulated sum of MSR is defined as a monotonic419 * The accumulated sum of MSR is defined as a monotonic
278 * increasing MSR, it will be accumulated periodically,420 * increasing MSR, it will be accumulated periodically,
@@ -522,8 +664,10 @@ static int perf_instr_count_open(int cpu_num) · 243 unmodified lines
522 664
523 /* counter for cpu_num, including user + kernel and all processes */665 /* counter for cpu_num, including user + kernel and all processes */
524 fd = perf_event_open(&pea, -1, cpu_num, -1, 0);666 fd = perf_event_open(&pea, -1, cpu_num, -1, 0);
525 if (fd == -1)667 if (fd == -1) {
526 err(-1, "cpu%d: perf instruction counter\n", cpu_num);668 warn("cpu%d: perf instruction counter", cpu_num);
669 BIC_NOT_PRESENT(BIC_IPC);
670 }
527 671
528 return fd;672 return fd;
529}673}
@@ -550,143 +694,10 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) · 20 unmodified lines
550 return 0;694 return 0;
551}695}
552 696
553/*
554 * This list matches the column headers, except
555 * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time
556 * 2. Core and CPU are moved to the end, we can't have strings that contain them
557 * matching on them for --show and --hide.
558 */
559struct msr_counter bic[] = {
560 { 0x0, "usec" },
561 { 0x0, "Time_Of_Day_Seconds" },
562 { 0x0, "Package" },
563 { 0x0, "Node" },
564 { 0x0, "Avg_MHz" },
565 { 0x0, "Busy%" },
566 { 0x0, "Bzy_MHz" },
567 { 0x0, "TSC_MHz" },
568 { 0x0, "IRQ" },
569 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL },
570 { 0x0, "sysfs" },
571 { 0x0, "CPU%c1" },
572 { 0x0, "CPU%c3" },
573 { 0x0, "CPU%c6" },
574 { 0x0, "CPU%c7" },
575 { 0x0, "ThreadC" },
576 { 0x0, "CoreTmp" },
577 { 0x0, "CoreCnt" },
578 { 0x0, "PkgTmp" },
579 { 0x0, "GFX%rc6" },
580 { 0x0, "GFXMHz" },
581 { 0x0, "Pkg%pc2" },
582 { 0x0, "Pkg%pc3" },
583 { 0x0, "Pkg%pc6" },
584 { 0x0, "Pkg%pc7" },
585 { 0x0, "Pkg%pc8" },
586 { 0x0, "Pkg%pc9" },
587 { 0x0, "Pk%pc10" },
588 { 0x0, "CPU%LPI" },
589 { 0x0, "SYS%LPI" },
590 { 0x0, "PkgWatt" },
591 { 0x0, "CorWatt" },
592 { 0x0, "GFXWatt" },
593 { 0x0, "PkgCnt" },
594 { 0x0, "RAMWatt" },
595 { 0x0, "PKG_%" },
596 { 0x0, "RAM_%" },
597 { 0x0, "Pkg_J" },
598 { 0x0, "Cor_J" },
599 { 0x0, "GFX_J" },
600 { 0x0, "RAM_J" },
601 { 0x0, "Mod%c6" },
602 { 0x0, "Totl%C0" },
603 { 0x0, "Any%C0" },
604 { 0x0, "GFX%C0" },
605 { 0x0, "CPUGFX%" },
606 { 0x0, "Core" },
607 { 0x0, "CPU" },
608 { 0x0, "APIC" },
609 { 0x0, "X2APIC" },
610 { 0x0, "Die" },
611 { 0x0, "GFXAMHz" },
612 { 0x0, "IPC" },
613};
614
615#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
616#define BIC_USEC (1ULL << 0)
617#define BIC_TOD (1ULL << 1)
618#define BIC_Package (1ULL << 2)
619#define BIC_Node (1ULL << 3)
620#define BIC_Avg_MHz (1ULL << 4)
621#define BIC_Busy (1ULL << 5)
622#define BIC_Bzy_MHz (1ULL << 6)
623#define BIC_TSC_MHz (1ULL << 7)
624#define BIC_IRQ (1ULL << 8)
625#define BIC_SMI (1ULL << 9)
626#define BIC_sysfs (1ULL << 10)
627#define BIC_CPU_c1 (1ULL << 11)
628#define BIC_CPU_c3 (1ULL << 12)
629#define BIC_CPU_c6 (1ULL << 13)
630#define BIC_CPU_c7 (1ULL << 14)
631#define BIC_ThreadC (1ULL << 15)
632#define BIC_CoreTmp (1ULL << 16)
633#define BIC_CoreCnt (1ULL << 17)
634#define BIC_PkgTmp (1ULL << 18)
635#define BIC_GFX_rc6 (1ULL << 19)
636#define BIC_GFXMHz (1ULL << 20)
637#define BIC_Pkgpc2 (1ULL << 21)
638#define BIC_Pkgpc3 (1ULL << 22)
639#define BIC_Pkgpc6 (1ULL << 23)
640#define BIC_Pkgpc7 (1ULL << 24)
641#define BIC_Pkgpc8 (1ULL << 25)
642#define BIC_Pkgpc9 (1ULL << 26)
643#define BIC_Pkgpc10 (1ULL << 27)
644#define BIC_CPU_LPI (1ULL << 28)
645#define BIC_SYS_LPI (1ULL << 29)
646#define BIC_PkgWatt (1ULL << 30)
647#define BIC_CorWatt (1ULL << 31)
648#define BIC_GFXWatt (1ULL << 32)
649#define BIC_PkgCnt (1ULL << 33)
650#define BIC_RAMWatt (1ULL << 34)
651#define BIC_PKG__ (1ULL << 35)
652#define BIC_RAM__ (1ULL << 36)
653#define BIC_Pkg_J (1ULL << 37)
654#define BIC_Cor_J (1ULL << 38)
655#define BIC_GFX_J (1ULL << 39)
656#define BIC_RAM_J (1ULL << 40)
657#define BIC_Mod_c6 (1ULL << 41)
658#define BIC_Totl_c0 (1ULL << 42)
659#define BIC_Any_c0 (1ULL << 43)
660#define BIC_GFX_c0 (1ULL << 44)
661#define BIC_CPUGFX (1ULL << 45)
662#define BIC_Core (1ULL << 46)
663#define BIC_CPU (1ULL << 47)
664#define BIC_APIC (1ULL << 48)
665#define BIC_X2APIC (1ULL << 49)
666#define BIC_Die (1ULL << 50)
667#define BIC_GFXACTMHz (1ULL << 51)
668#define BIC_IPC (1ULL << 52)
669
670#define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die )
671#define BIC_THERMAL_PWR ( BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__)
672#define BIC_FREQUENCY ( BIC_Avg_MHz | BIC_Busy | BIC_Bzy_MHz | BIC_TSC_MHz | BIC_GFXMHz | BIC_GFXACTMHz )
673#define BIC_IDLE ( BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX)
674#define BIC_OTHER ( BIC_IRQ | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC)
675
676#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
677
678unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
679unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
680
681#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
682#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
683#define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
684#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
685#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
686#define BIC_IS_ENABLED(COUNTER_BIT) (bic_enabled & COUNTER_BIT)
687
688#define MAX_DEFERRED 16697#define MAX_DEFERRED 16
698char *deferred_add_names[MAX_DEFERRED];
689char *deferred_skip_names[MAX_DEFERRED];699char *deferred_skip_names[MAX_DEFERRED];
700int deferred_add_index;
690int deferred_skip_index;701int deferred_skip_index;
691 702
692/*703/*
@@ -720,6 +731,8 @@ void help(void) · 27 unmodified lines
720 " -l, --list list column headers only\n"731 " -l, --list list column headers only\n"
721 " -n, --num_iterations num\n"732 " -n, --num_iterations num\n"
722 " number of the measurement iterations\n"733 " number of the measurement iterations\n"
734 " -N, --header_iterations num\n"
735 " print header every num iterations\n"
723 " -o, --out file\n"736 " -o, --out file\n"
724 " create or truncate \"file\" for all output\n"737 " create or truncate \"file\" for all output\n"
725 " -q, --quiet skip decoding system configuration header\n"738 " -q, --quiet skip decoding system configuration header\n"
@@ -741,7 +754,7 @@ void help(void) · 15 unmodified lines
741 */754 */
742unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)755unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
743{756{
744 int i;757 unsigned int i;
745 unsigned long long retval = 0;758 unsigned long long retval = 0;
746 759
747 while (name_list) {760 while (name_list) {
@@ -752,40 +765,51 @@ unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode) · 4 unmodified lines
752 if (comma)765 if (comma)
753 *comma = '\0';766 *comma = '\0';
754 767
755 if (!strcmp(name_list, "all"))
756 return ~0;
757 if (!strcmp(name_list, "topology"))
758 return BIC_TOPOLOGY;
759 if (!strcmp(name_list, "power"))
760 return BIC_THERMAL_PWR;
761 if (!strcmp(name_list, "idle"))
762 return BIC_IDLE;
763 if (!strcmp(name_list, "frequency"))
764 return BIC_FREQUENCY;
765 if (!strcmp(name_list, "other"))
766 return BIC_OTHER;
767 if (!strcmp(name_list, "all"))
768 return 0;
769
770 for (i = 0; i < MAX_BIC; ++i) {768 for (i = 0; i < MAX_BIC; ++i) {
771 if (!strcmp(name_list, bic[i].name)) {769 if (!strcmp(name_list, bic[i].name)) {
772 retval |= (1ULL << i);770 retval |= (1ULL << i);
773 break;771 break;
774 }772 }
773 if (!strcmp(name_list, "all")) {
774 retval |= ~0;
775 break;
776 } else if (!strcmp(name_list, "topology")) {
777 retval |= BIC_TOPOLOGY;
778 break;
779 } else if (!strcmp(name_list, "power")) {
780 retval |= BIC_THERMAL_PWR;
781 break;
782 } else if (!strcmp(name_list, "idle")) {
783 retval |= BIC_IDLE;
784 break;
785 } else if (!strcmp(name_list, "frequency")) {
786 retval |= BIC_FREQUENCY;
787 break;
788 } else if (!strcmp(name_list, "other")) {
789 retval |= BIC_OTHER;
790 break;
791 }
792
775 }793 }
776 if (i == MAX_BIC) {794 if (i == MAX_BIC) {
777 if (mode == SHOW_LIST) {795 if (mode == SHOW_LIST) {
778 fprintf(stderr, "Invalid counter name: %s\n", name_list);796 deferred_add_names[deferred_add_index++] = name_list;
779 exit(-1);797 if (deferred_add_index >= MAX_DEFERRED) {
780 }798 fprintf(stderr, "More than max %d un-recognized --add options '%s'\n",
781 deferred_skip_names[deferred_skip_index++] = name_list;799 MAX_DEFERRED, name_list);
782 if (debug)800 help();
783 fprintf(stderr, "deferred \"%s\"\n", name_list);801 exit(1);
784 if (deferred_skip_index >= MAX_DEFERRED) {802 }
785 fprintf(stderr, "More than max %d un-recognized --skip options '%s'\n",803 } else {
786 MAX_DEFERRED, name_list);804 deferred_skip_names[deferred_skip_index++] = name_list;
787 help();805 if (debug)
788 exit(1);806 fprintf(stderr, "deferred \"%s\"\n", name_list);
807 if (deferred_skip_index >= MAX_DEFERRED) {
808 fprintf(stderr, "More than max %d un-recognized --skip options '%s'\n",
809 MAX_DEFERRED, name_list);
810 help();
811 exit(1);
812 }
789 }813 }
790 }814 }
791 815
@@ -872,6 +896,9 @@ void print_header(char *delim) · 80 unmodified lines
872 if (DO_BIC(BIC_CoreTmp))896 if (DO_BIC(BIC_CoreTmp))
873 outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : ""));897 outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : ""));
874 898
899 if (DO_BIC(BIC_CORE_THROT_CNT))
900 outp += sprintf(outp, "%sCoreThr", (printed++ ? delim : ""));
901
875 if (do_rapl && !rapl_joules) {902 if (do_rapl && !rapl_joules) {
876 if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY))903 if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY))
877 outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));904 outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
@@ -1011,6 +1038,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p · 133 unmodified lines
1011 outp += sprintf(outp, "c6: %016llX\n", c->c6);1038 outp += sprintf(outp, "c6: %016llX\n", c->c6);
1012 outp += sprintf(outp, "c7: %016llX\n", c->c7);1039 outp += sprintf(outp, "c7: %016llX\n", c->c7);
1013 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);1040 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
1041 outp += sprintf(outp, "cpu_throt_count: %016llX\n", c->core_throt_cnt);
1014 outp += sprintf(outp, "Joules: %0X\n", c->core_energy);1042 outp += sprintf(outp, "Joules: %0X\n", c->core_energy);
1015 1043
1016 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {1044 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
@@ -1225,6 +1253,10 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data · 208 unmodified lines
1225 if (DO_BIC(BIC_CoreTmp))1253 if (DO_BIC(BIC_CoreTmp))
1226 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);1254 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
1227 1255
1256 /* Core throttle count */
1257 if (DO_BIC(BIC_CORE_THROT_CNT))
1258 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->core_throt_cnt);
1259
1228 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {1260 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1229 if (mp->format == FORMAT_RAW) {1261 if (mp->format == FORMAT_RAW) {
1230 if (mp->width == 32)1262 if (mp->width == 32)
@@ -1311,6 +1343,7 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data · 80 unmodified lines
1311 if (DO_BIC(BIC_PkgWatt))1343 if (DO_BIC(BIC_PkgWatt))
1312 outp +=1344 outp +=
1313 sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float);1345 sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float);
1346
1314 if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY))1347 if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY))
1315 outp +=1348 outp +=
1316 sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);1349 sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);
@@ -1386,14 +1419,14 @@ void flush_output_stderr(void) · 69 unmodified lines
1386 1419
1387void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)1420void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1388{1421{
1389 static int printed;1422 static int count;
1390 1423
1391 if (!printed || !summary_only)1424 if ((!count || (header_iterations && !(count % header_iterations))) || !summary_only)
1392 print_header("\t");1425 print_header("\t");
1393 1426
1394 format_counters(&average.threads, &average.cores, &average.packages);1427 format_counters(&average.threads, &average.cores, &average.packages);
1395 1428
1396 printed = 1;1429 count++;
1397 1430
1398 if (summary_only)1431 if (summary_only)
1399 return;1432 return;
@@ -1467,6 +1500,7 @@ void delta_core(struct core_data *new, struct core_data *old) · 67 unmodified lines
1467 old->c6 = new->c6 - old->c6;1500 old->c6 = new->c6 - old->c6;
1468 old->c7 = new->c7 - old->c7;1501 old->c7 = new->c7 - old->c7;
1469 old->core_temp_c = new->core_temp_c;1502 old->core_temp_c = new->core_temp_c;
1503 old->core_throt_cnt = new->core_throt_cnt;
1470 old->mc6_us = new->mc6_us - old->mc6_us;1504 old->mc6_us = new->mc6_us - old->mc6_us;
1471 1505
1472 DELTA_WRAP32(new->core_energy, old->core_energy);1506 DELTA_WRAP32(new->core_energy, old->core_energy);
@@ -1626,6 +1660,7 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data · 153 unmodified lines
1626 c->mc6_us = 0;1660 c->mc6_us = 0;
1627 c->core_temp_c = 0;1661 c->core_temp_c = 0;
1628 c->core_energy = 0;1662 c->core_energy = 0;
1663 c->core_throt_cnt = 0;
1629 1664
1630 p->pkg_wtd_core_c0 = 0;1665 p->pkg_wtd_core_c0 = 0;
1631 p->pkg_any_core_c0 = 0;1666 p->pkg_any_core_c0 = 0;
@@ -1710,6 +1745,7 @@ int sum_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) · 78 unmodified lines
1710 average.cores.mc6_us += c->mc6_us;1745 average.cores.mc6_us += c->mc6_us;
1711 1746
1712 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);1747 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
1748 average.cores.core_throt_cnt = MAX(average.cores.core_throt_cnt, c->core_throt_cnt);
1713 1749
1714 average.cores.core_energy += c->core_energy;1750 average.cores.core_energy += c->core_energy;
1715 1751
@@ -1987,6 +2023,26 @@ void get_apic_id(struct thread_data *t) · 271 unmodified lines
1987 fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id);2023 fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id);
1988}2024}
1989 2025
2026int get_core_throt_cnt(int cpu, unsigned long long *cnt)
2027{
2028 char path[128 + PATH_BYTES];
2029 unsigned long long tmp;
2030 FILE *fp;
2031 int ret;
2032
2033 sprintf(path, "/sys/devices/system/cpu/cpu%d/thermal_throttle/core_throttle_count", cpu);
2034 fp = fopen(path, "r");
2035 if (!fp)
2036 return -1;
2037 ret = fscanf(fp, "%lld", &tmp);
2038 if (ret != 1)
2039 return -1;
2040 fclose(fp);
2041 *cnt = tmp;
2042
2043 return 0;
2044}
2045
1990/*2046/*
1991 * get_counters(...)2047 * get_counters(...)
1992 * migrate to cpu2048 * migrate to cpu
@@ -2129,6 +2185,9 @@ retry: · 136 unmodified lines
2129 c->core_temp_c = tj_max - ((msr >> 16) & 0x7F);2185 c->core_temp_c = tj_max - ((msr >> 16) & 0x7F);
2130 }2186 }
2131 2187
2188 if (DO_BIC(BIC_CORE_THROT_CNT))
2189 get_core_throt_cnt(cpu, &c->core_throt_cnt);
2190
2132 if (do_rapl & RAPL_AMD_F17H) {2191 if (do_rapl & RAPL_AMD_F17H) {
2133 if (get_msr(cpu, MSR_CORE_ENERGY_STAT, &msr))2192 if (get_msr(cpu, MSR_CORE_ENERGY_STAT, &msr))
2134 return -14;2193 return -14;
@@ -2428,6 +2487,9 @@ int has_turbo_ratio_group_limits(int family, int model) · 293 unmodified lines
2428 if (!genuine_intel)2487 if (!genuine_intel)
2429 return 0;2488 return 0;
2430 2489
2490 if (family != 6)
2491 return 0;
2492
2431 switch (model) {2493 switch (model) {
2432 case INTEL_FAM6_ATOM_GOLDMONT:2494 case INTEL_FAM6_ATOM_GOLDMONT:
2433 case INTEL_FAM6_SKYLAKE_X:2495 case INTEL_FAM6_SKYLAKE_X:
@@ -2435,8 +2497,9 @@ int has_turbo_ratio_group_limits(int family, int model) · 1 unmodified line
2435 case INTEL_FAM6_ATOM_GOLDMONT_D:2497 case INTEL_FAM6_ATOM_GOLDMONT_D:
2436 case INTEL_FAM6_ATOM_TREMONT_D:2498 case INTEL_FAM6_ATOM_TREMONT_D:
2437 return 1;2499 return 1;
2500 default:
2501 return 0;
2438 }2502 }
2439 return 0;
2440}2503}
2441 2504
2442static void dump_turbo_ratio_limits(int family, int model)2505static void dump_turbo_ratio_limits(int family, int model)
@@ -3027,6 +3090,8 @@ void set_max_cpu_num(void) · 584 unmodified lines
3027 */3090 */
3028int count_cpus(int cpu)3091int count_cpus(int cpu)
3029{3092{
3093 UNUSED(cpu);
3094
3030 topo.num_cpus++;3095 topo.num_cpus++;
3031 return 0;3096 return 0;
3032}3097}
@@ -3361,6 +3426,9 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg · 328 unmodified lines
3361 int i, ret;3426 int i, ret;
3362 int cpu = t->cpu_id;3427 int cpu = t->cpu_id;
3363 3428
3429 UNUSED(c);
3430 UNUSED(p);
3431
3364 for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) {3432 for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) {
3365 unsigned long long msr_cur, msr_last;3433 unsigned long long msr_cur, msr_last;
3366 off_t offset;3434 off_t offset;
@@ -3387,6 +3455,8 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg · 20 unmodified lines
3387 3455
3388static void msr_record_handler(union sigval v)3456static void msr_record_handler(union sigval v)
3389{3457{
3458 UNUSED(v);
3459
3390 for_all_cpus(update_msr_sum, EVEN_COUNTERS);3460 for_all_cpus(update_msr_sum, EVEN_COUNTERS);
3391}3461}
3392 3462
@@ -3439,6 +3509,9 @@ release_msr: · 46 unmodified lines
3439/*3509/*
3440 * set_my_sched_priority(pri)3510 * set_my_sched_priority(pri)
3441 * return previous3511 * return previous
3512 *
3513 * if non-root, do this:
3514 * # /sbin/setcap cap_sys_rawio,cap_sys_nice=+ep /usr/bin/turbostat
3442 */3515 */
3443int set_my_sched_priority(int priority)3516int set_my_sched_priority(int priority)
3444{3517{
@@ -3457,7 +3530,7 @@ int set_my_sched_priority(int priority) · 12 unmodified lines
3457 errno = 0;3530 errno = 0;
3458 retval = getpriority(PRIO_PROCESS, 0);3531 retval = getpriority(PRIO_PROCESS, 0);
3459 if (retval != priority)3532 if (retval != priority)
3460 err(-1, "getpriority(%d) != setpriority(%d)", retval, priority);3533 err(retval, "getpriority(%d) != setpriority(%d)", retval, priority);
3461 3534
3462 return original_priority;3535 return original_priority;
3463}3536}
@@ -3466,7 +3539,7 @@ void turbostat_loop() · 2 unmodified lines
3466{3539{
3467 int retval;3540 int retval;
3468 int restarted = 0;3541 int restarted = 0;
3469 int done_iters = 0;3542 unsigned int done_iters = 0;
3470 3543
3471 setup_signal_handler();3544 setup_signal_handler();
3472 3545
@@ -3678,6 +3751,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) · 205 unmodified lines
3678 break;3751 break;
3679 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */3752 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */
3680 no_MSR_MISC_PWR_MGMT = 1;3753 no_MSR_MISC_PWR_MGMT = 1;
3754 /* FALLTHRU */
3681 case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */3755 case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */
3682 pkg_cstate_limits = slv_pkg_cstate_limits;3756 pkg_cstate_limits = slv_pkg_cstate_limits;
3683 break;3757 break;
@@ -3721,6 +3795,9 @@ int has_slv_msrs(unsigned int family, unsigned int model) · 37 unmodified lines
3721 if (!genuine_intel)3795 if (!genuine_intel)
3722 return 0;3796 return 0;
3723 3797
3798 if (family != 6)
3799 return 0;
3800
3724 switch (model) {3801 switch (model) {
3725 case INTEL_FAM6_ATOM_SILVERMONT:3802 case INTEL_FAM6_ATOM_SILVERMONT:
3726 case INTEL_FAM6_ATOM_SILVERMONT_MID:3803 case INTEL_FAM6_ATOM_SILVERMONT_MID:
@@ -3736,6 +3813,9 @@ int is_dnv(unsigned int family, unsigned int model) · 9 unmodified lines
3736 if (!genuine_intel)3813 if (!genuine_intel)
3737 return 0;3814 return 0;
3738 3815
3816 if (family != 6)
3817 return 0;
3818
3739 switch (model) {3819 switch (model) {
3740 case INTEL_FAM6_ATOM_GOLDMONT_D:3820 case INTEL_FAM6_ATOM_GOLDMONT_D:
3741 return 1;3821 return 1;
@@ -3749,6 +3829,9 @@ int is_bdx(unsigned int family, unsigned int model) · 7 unmodified lines
3749 if (!genuine_intel)3829 if (!genuine_intel)
3750 return 0;3830 return 0;
3751 3831
3832 if (family != 6)
3833 return 0;
3834
3752 switch (model) {3835 switch (model) {
3753 case INTEL_FAM6_BROADWELL_X:3836 case INTEL_FAM6_BROADWELL_X:
3754 return 1;3837 return 1;
@@ -3762,6 +3845,9 @@ int is_skx(unsigned int family, unsigned int model) · 7 unmodified lines
3762 if (!genuine_intel)3845 if (!genuine_intel)
3763 return 0;3846 return 0;
3764 3847
3848 if (family != 6)
3849 return 0;
3850
3765 switch (model) {3851 switch (model) {
3766 case INTEL_FAM6_SKYLAKE_X:3852 case INTEL_FAM6_SKYLAKE_X:
3767 return 1;3853 return 1;
@@ -3775,6 +3861,9 @@ int is_icx(unsigned int family, unsigned int model) · 7 unmodified lines
3775 if (!genuine_intel)3861 if (!genuine_intel)
3776 return 0;3862 return 0;
3777 3863
3864 if (family != 6)
3865 return 0;
3866
3778 switch (model) {3867 switch (model) {
3779 case INTEL_FAM6_ICELAKE_X:3868 case INTEL_FAM6_ICELAKE_X:
3780 return 1;3869 return 1;
@@ -3787,6 +3876,9 @@ int is_ehl(unsigned int family, unsigned int model) · 6 unmodified lines
3787 if (!genuine_intel)3876 if (!genuine_intel)
3788 return 0;3877 return 0;
3789 3878
3879 if (family != 6)
3880 return 0;
3881
3790 switch (model) {3882 switch (model) {
3791 case INTEL_FAM6_ATOM_TREMONT:3883 case INTEL_FAM6_ATOM_TREMONT:
3792 return 1;3884 return 1;
@@ -3799,6 +3891,9 @@ int is_jvl(unsigned int family, unsigned int model) · 6 unmodified lines
3799 if (!genuine_intel)3891 if (!genuine_intel)
3800 return 0;3892 return 0;
3801 3893
3894 if (family != 6)
3895 return 0;
3896
3802 switch (model) {3897 switch (model) {
3803 case INTEL_FAM6_ATOM_TREMONT_D:3898 case INTEL_FAM6_ATOM_TREMONT_D:
3804 return 1;3899 return 1;
@@ -3811,6 +3906,9 @@ int has_turbo_ratio_limit(unsigned int family, unsigned int model) · 6 unmodified lines
3811 if (has_slv_msrs(family, model))3906 if (has_slv_msrs(family, model))
3812 return 0;3907 return 0;
3813 3908
3909 if (family != 6)
3910 return 0;
3911
3814 switch (model) {3912 switch (model) {
3815 /* Nehalem compatible, but do not include turbo-ratio limit support */3913 /* Nehalem compatible, but do not include turbo-ratio limit support */
3816 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */3914 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
@@ -4125,6 +4223,9 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) · 308 unmodified lines
4125 char *epb_string;4223 char *epb_string;
4126 int cpu, epb;4224 int cpu, epb;
4127 4225
4226 UNUSED(c);
4227 UNUSED(p);
4228
4128 if (!has_epb)4229 if (!has_epb)
4129 return 0;4230 return 0;
4130 4231
@@ -4171,6 +4272,9 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p) · 40 unmodified lines
4171 unsigned long long msr;4272 unsigned long long msr;
4172 int cpu;4273 int cpu;
4173 4274
4275 UNUSED(c);
4276 UNUSED(p);
4277
4174 if (!has_hwp)4278 if (!has_hwp)
4175 return 0;4279 return 0;
4176 4280
@@ -4254,6 +4358,9 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data · 77 unmodified lines
4254 unsigned long long msr;4358 unsigned long long msr;
4255 int cpu;4359 int cpu;
4256 4360
4361 UNUSED(c);
4362 UNUSED(p);
4363
4257 cpu = t->cpu_id;4364 cpu = t->cpu_id;
4258 4365
4259 /* per-package */4366 /* per-package */
@@ -4359,6 +4466,8 @@ double get_tdp_intel(unsigned int model) · 99 unmodified lines
4359 4466
4360double get_tdp_amd(unsigned int family)4467double get_tdp_amd(unsigned int family)
4361{4468{
4469 UNUSED(family);
4470
4362 /* This is the max stock TDP of HEDT/Server Fam17h+ chips */4471 /* This is the max stock TDP of HEDT/Server Fam17h+ chips */
4363 return 280.0;4472 return 280.0;
4364}4473}
@@ -4376,6 +4485,7 @@ static double rapl_dram_energy_units_probe(int model, double rapl_energy_units) · 11 unmodified lines
4376 case INTEL_FAM6_BROADWELL_X: /* BDX */4485 case INTEL_FAM6_BROADWELL_X: /* BDX */
4377 case INTEL_FAM6_SKYLAKE_X: /* SKX */4486 case INTEL_FAM6_SKYLAKE_X: /* SKX */
4378 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */4487 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
4488 case INTEL_FAM6_ICELAKE_X: /* ICX */
4379 return (rapl_dram_energy_units = 15.3 / 1000000);4489 return (rapl_dram_energy_units = 15.3 / 1000000);
4380 default:4490 default:
4381 return (rapl_energy_units);4491 return (rapl_energy_units);
@@ -4559,6 +4669,8 @@ void rapl_probe_amd(unsigned int family, unsigned int model) · 177 unmodified lines
4559 unsigned int has_rapl = 0;4669 unsigned int has_rapl = 0;
4560 double tdp;4670 double tdp;
4561 4671
4672 UNUSED(model);
4673
4562 if (max_extended_level >= 0x80000007) {4674 if (max_extended_level >= 0x80000007) {
4563 __cpuid(0x80000007, eax, ebx, ecx, edx);4675 __cpuid(0x80000007, eax, ebx, ecx, edx);
4564 /* RAPL (Fam 17h+) */4676 /* RAPL (Fam 17h+) */
@@ -4617,6 +4729,7 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model) · 52 unmodified lines
4617 case INTEL_FAM6_HASWELL_L: /* HSW */4729 case INTEL_FAM6_HASWELL_L: /* HSW */
4618 case INTEL_FAM6_HASWELL_G: /* HSW */4730 case INTEL_FAM6_HASWELL_G: /* HSW */
4619 do_gfx_perf_limit_reasons = 1;4731 do_gfx_perf_limit_reasons = 1;
4732 /* FALLTHRU */
4620 case INTEL_FAM6_HASWELL_X: /* HSX */4733 case INTEL_FAM6_HASWELL_X: /* HSX */
4621 do_core_perf_limit_reasons = 1;4734 do_core_perf_limit_reasons = 1;
4622 do_ring_perf_limit_reasons = 1;4735 do_ring_perf_limit_reasons = 1;
@@ -4643,6 +4756,9 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p · 20 unmodified lines
4643 unsigned int dts, dts2;4756 unsigned int dts, dts2;
4644 int cpu;4757 int cpu;
4645 4758
4759 UNUSED(c);
4760 UNUSED(p);
4761
4646 if (!(do_dts || do_ptm))4762 if (!(do_dts || do_ptm))
4647 return 0;4763 return 0;
4648 4764
@@ -4698,7 +4814,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p · 49 unmodified lines
4698 4814
4699void print_power_limit_msr(int cpu, unsigned long long msr, char *label)4815void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
4700{4816{
4701 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",4817 fprintf(outf, "cpu%d: %s: %sabled (%0.3f Watts, %f sec, clamp %sabled)\n",
4702 cpu, label,4818 cpu, label,
4703 ((msr >> 15) & 1) ? "EN" : "DIS",4819 ((msr >> 15) & 1) ? "EN" : "DIS",
4704 ((msr >> 0) & 0x7FFF) * rapl_power_units,4820 ((msr >> 0) & 0x7FFF) * rapl_power_units,
@@ -4714,6 +4830,9 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) · 9 unmodified lines
4714 const char *msr_name;4830 const char *msr_name;
4715 int cpu;4831 int cpu;
4716 4832
4833 UNUSED(c);
4834 UNUSED(p);
4835
4717 if (!do_rapl)4836 if (!do_rapl)
4718 return 0;4837 return 0;
4719 4838
@@ -4762,12 +4881,19 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) · 42 unmodified lines
4762 cpu, msr, (msr >> 63) & 1 ? "" : "UN");4881 cpu, msr, (msr >> 63) & 1 ? "" : "UN");
4763 4882
4764 print_power_limit_msr(cpu, msr, "PKG Limit #1");4883 print_power_limit_msr(cpu, msr, "PKG Limit #1");
4765 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",4884 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%0.3f Watts, %f* sec, clamp %sabled)\n",
4766 cpu,4885 cpu,
4767 ((msr >> 47) & 1) ? "EN" : "DIS",4886 ((msr >> 47) & 1) ? "EN" : "DIS",
4768 ((msr >> 32) & 0x7FFF) * rapl_power_units,4887 ((msr >> 32) & 0x7FFF) * rapl_power_units,
4769 (1.0 + (((msr >> 54) & 0x3) / 4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,4888 (1.0 + (((msr >> 54) & 0x3) / 4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
4770 ((msr >> 48) & 1) ? "EN" : "DIS");4889 ((msr >> 48) & 1) ? "EN" : "DIS");
4890
4891 if (get_msr(cpu, MSR_VR_CURRENT_CONFIG, &msr))
4892 return -9;
4893
4894 fprintf(outf, "cpu%d: MSR_VR_CURRENT_CONFIG: 0x%08llx\n", cpu, msr);
4895 fprintf(outf, "cpu%d: PKG Limit #4: %f Watts (%slocked)\n",
4896 cpu, ((msr >> 0) & 0x1FFF) * rapl_power_units, (msr >> 31) & 1 ? "" : "UN");
4771 }4897 }
4772 4898
4773 if (do_rapl & RAPL_DRAM_POWER_INFO) {4899 if (do_rapl & RAPL_DRAM_POWER_INFO) {
@@ -4830,6 +4956,9 @@ int has_snb_msrs(unsigned int family, unsigned int model) · 56 unmodified lines
4830 if (!genuine_intel)4956 if (!genuine_intel)
4831 return 0;4957 return 0;
4832 4958
4959 if (family != 6)
4960 return 0;
4961
4833 switch (model) {4962 switch (model) {
4834 case INTEL_FAM6_SANDYBRIDGE:4963 case INTEL_FAM6_SANDYBRIDGE:
4835 case INTEL_FAM6_SANDYBRIDGE_X:4964 case INTEL_FAM6_SANDYBRIDGE_X:
@@ -4873,6 +5002,9 @@ int has_c8910_msrs(unsigned int family, unsigned int model) · 37 unmodified lines
4873 if (!genuine_intel)5002 if (!genuine_intel)
4874 return 0;5003 return 0;
4875 5004
5005 if (family != 6)
5006 return 0;
5007
4876 switch (model) {5008 switch (model) {
4877 case INTEL_FAM6_HASWELL_L: /* HSW */5009 case INTEL_FAM6_HASWELL_L: /* HSW */
4878 case INTEL_FAM6_BROADWELL: /* BDW */5010 case INTEL_FAM6_BROADWELL: /* BDW */
@@ -4899,6 +5031,9 @@ int has_skl_msrs(unsigned int family, unsigned int model) · 20 unmodified lines
4899 if (!genuine_intel)5031 if (!genuine_intel)
4900 return 0;5032 return 0;
4901 5033
5034 if (family != 6)
5035 return 0;
5036
4902 switch (model) {5037 switch (model) {
4903 case INTEL_FAM6_SKYLAKE_L: /* SKL */5038 case INTEL_FAM6_SKYLAKE_L: /* SKL */
4904 case INTEL_FAM6_CANNONLAKE_L: /* CNL */5039 case INTEL_FAM6_CANNONLAKE_L: /* CNL */
@@ -4911,6 +5046,10 @@ int is_slm(unsigned int family, unsigned int model) · 6 unmodified lines
4911{5046{
4912 if (!genuine_intel)5047 if (!genuine_intel)
4913 return 0;5048 return 0;
5049
5050 if (family != 6)
5051 return 0;
5052
4914 switch (model) {5053 switch (model) {
4915 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */5054 case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */
4916 case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */5055 case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */
@@ -4923,6 +5062,10 @@ int is_knl(unsigned int family, unsigned int model) · 6 unmodified lines
4923{5062{
4924 if (!genuine_intel)5063 if (!genuine_intel)
4925 return 0;5064 return 0;
5065
5066 if (family != 6)
5067 return 0;
5068
4926 switch (model) {5069 switch (model) {
4927 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */5070 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
4928 return 1;5071 return 1;
@@ -4935,6 +5078,9 @@ int is_cnl(unsigned int family, unsigned int model) · 6 unmodified lines
4935 if (!genuine_intel)5078 if (!genuine_intel)
4936 return 0;5079 return 0;
4937 5080
5081 if (family != 6)
5082 return 0;
5083
4938 switch (model) {5084 switch (model) {
4939 case INTEL_FAM6_CANNONLAKE_L: /* CNL */5085 case INTEL_FAM6_CANNONLAKE_L: /* CNL */
4940 return 1;5086 return 1;
@@ -4989,6 +5135,9 @@ int get_cpu_type(struct thread_data *t, struct core_data *c, struct pkg_data *p) · 48 unmodified lines
4989{5135{
4990 unsigned int eax, ebx, ecx, edx;5136 unsigned int eax, ebx, ecx, edx;
4991 5137
5138 UNUSED(c);
5139 UNUSED(p);
5140
4992 if (!genuine_intel)5141 if (!genuine_intel)
4993 return 0;5142 return 0;
4994 5143
@@ -5025,6 +5174,9 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk · 30 unmodified lines
5025 unsigned int tcc_default, tcc_offset;5174 unsigned int tcc_default, tcc_offset;
5026 int cpu;5175 int cpu;
5027 5176
5177 UNUSED(c);
5178 UNUSED(p);
5179
5028 /* tj_max is used only for dts or ptm */5180 /* tj_max is used only for dts or ptm */
5029 if (!(do_dts || do_ptm))5181 if (!(do_dts || do_ptm))
5030 return 0;5182 return 0;
@@ -5572,6 +5724,11 @@ void process_cpuid() · 541 unmodified lines
5572 else5724 else
5573 BIC_NOT_PRESENT(BIC_CPU_LPI);5725 BIC_NOT_PRESENT(BIC_CPU_LPI);
5574 5726
5727 if (!access("/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count", R_OK))
5728 BIC_PRESENT(BIC_CORE_THROT_CNT);
5729 else
5730 BIC_NOT_PRESENT(BIC_CORE_THROT_CNT);
5731
5575 if (!access(sys_lpi_file_sysfs, R_OK)) {5732 if (!access(sys_lpi_file_sysfs, R_OK)) {
5576 sys_lpi_file = sys_lpi_file_sysfs;5733 sys_lpi_file = sys_lpi_file_sysfs;
5577 BIC_PRESENT(BIC_SYS_LPI);5734 BIC_PRESENT(BIC_SYS_LPI);
@@ -5601,11 +5758,6 @@ int dir_filter(const struct dirent *dirp) · 23 unmodified lines
5601 return 0;5758 return 0;
5602}5759}
5603 5760
5604int open_dev_cpu_msr(int dummy1)
5605{
5606 return 0;
5607}
5608
5609void topology_probe()5761void topology_probe()
5610{5762{
5611 int i;5763 int i;
@@ -5896,6 +6048,9 @@ void turbostat_init() · 284 unmodified lines
5896 6048
5897 if (!quiet && do_irtl_snb)6049 if (!quiet && do_irtl_snb)
5898 print_irtl();6050 print_irtl();
6051
6052 if (DO_BIC(BIC_IPC))
6053 (void)get_instr_count_fd(base_cpu);
5899}6054}
5900 6055
5901int fork_it(char **argv)6056int fork_it(char **argv)
@@ -5973,7 +6128,7 @@ int get_and_dump_counters(void) · 71 unmodified lines
5973 6128
5974void print_version()6129void print_version()
5975{6130{
5976 fprintf(outf, "turbostat version 21.05.04" " - Len Brown <lenb@kernel.org>\n");6131 fprintf(outf, "turbostat version 2022.04.16 - Len Brown <lenb@kernel.org>\n");
5977}6132}
5978 6133
5979int add_counter(unsigned int msr_num, char *path, char *name,6134int add_counter(unsigned int msr_num, char *path, char *name,
@@ -6138,6 +6293,16 @@ next: · 158 unmodified lines
6138 }6293 }
6139}6294}
6140 6295
6296int is_deferred_add(char *name)
6297{
6298 int i;
6299
6300 for (i = 0; i < deferred_add_index; ++i)
6301 if (!strcmp(name, deferred_add_names[i]))
6302 return 1;
6303 return 0;
6304}
6305
6141int is_deferred_skip(char *name)6306int is_deferred_skip(char *name)
6142{6307{
6143 int i;6308 int i;
@@ -6156,9 +6321,6 @@ void probe_sysfs(void) · 12 unmodified lines
6156 int state;6321 int state;
6157 char *sp;6322 char *sp;
6158 6323
6159 if (!DO_BIC(BIC_sysfs))
6160 return;
6161
6162 for (state = 10; state >= 0; --state) {6324 for (state = 10; state >= 0; --state) {
6163 6325
6164 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);6326 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
@@ -6181,6 +6343,9 @@ void probe_sysfs(void) · 16 unmodified lines
6181 6343
6182 sprintf(path, "cpuidle/state%d/time", state);6344 sprintf(path, "cpuidle/state%d/time", state);
6183 6345
6346 if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf))
6347 continue;
6348
6184 if (is_deferred_skip(name_buf))6349 if (is_deferred_skip(name_buf))
6185 continue;6350 continue;
6186 6351
@@ -6206,6 +6371,9 @@ void probe_sysfs(void) · 19 unmodified lines
6206 6371
6207 sprintf(path, "cpuidle/state%d/usage", state);6372 sprintf(path, "cpuidle/state%d/usage", state);
6208 6373
6374 if (!DO_BIC(BIC_sysfs) && !is_deferred_add(name_buf))
6375 continue;
6376
6209 if (is_deferred_skip(name_buf))6377 if (is_deferred_skip(name_buf))
6210 continue;6378 continue;
6211 6379
@@ -6313,6 +6481,7 @@ void cmdline(int argc, char **argv) · 101 unmodified lines
6313 { "interval", required_argument, 0, 'i' },6481 { "interval", required_argument, 0, 'i' },
6314 { "IPC", no_argument, 0, 'I' },6482 { "IPC", no_argument, 0, 'I' },
6315 { "num_iterations", required_argument, 0, 'n' },6483 { "num_iterations", required_argument, 0, 'n' },
6484 { "header_iterations", required_argument, 0, 'N' },
6316 { "help", no_argument, 0, 'h' },6485 { "help", no_argument, 0, 'h' },
6317 { "hide", required_argument, 0, 'H' }, // meh, -h taken by --help6486 { "hide", required_argument, 0, 'H' }, // meh, -h taken by --help
6318 { "Joules", no_argument, 0, 'J' },6487 { "Joules", no_argument, 0, 'J' },
@@ -6394,6 +6563,14 @@ void cmdline(int argc, char **argv) · 75 unmodified lines
6394 exit(2);6563 exit(2);
6395 }6564 }
6396 break;6565 break;
6566 case 'N':
6567 header_iterations = strtod(optarg, NULL);
6568
6569 if (header_iterations <= 0) {
6570 fprintf(outf, "iterations %d should be positive number\n", header_iterations);
6571 exit(2);
6572 }
6573 break;
6397 case 's':6574 case 's':
6398 /*6575 /*
6399 * --show: show only those specified6576 * --show: show only those specified
@@ -6432,6 +6609,8 @@ int main(int argc, char **argv) · 32 unmodified lines
6432 6609
6433 turbostat_init();6610 turbostat_init();
6434 6611
6612 msr_sum_record();
6613
6435 /* dump counters and exit */6614 /* dump counters and exit */
6436 if (dump_only)6615 if (dump_only)
6437 return get_and_dump_counters();6616 return get_and_dump_counters();
@@ -6443,7 +6622,6 @@ int main(int argc, char **argv) · 5 unmodified lines
6443 return 0;6622 return 0;
6444 }6623 }
6445 6624
6446 msr_sum_record();
6447 /*6625 /*
6448 * if any params left, it must be a command to fork6626 * if any params left, it must be a command to fork
6449 */6627 */