diff options
author | Imre Deak <imre.deak@intel.com> | 2018-08-06 05:58:37 -0400 |
---|---|---|
committer | Imre Deak <imre.deak@intel.com> | 2018-08-08 06:49:43 -0400 |
commit | f28ec6f4ea483554aacc59e8eb4a7667ecaf58ad (patch) | |
tree | f230657cb0e68205b8252237e90cefb21095bede /drivers/gpu/drm/i915/intel_runtime_pm.c | |
parent | 3ae27f7e103d95a820061fa692d0fe53303ccf98 (diff) |
drm/i915: Constify power well descriptors
It makes sense to keep unchanging data const. Extract such fields from
the i915_power_well struct into a new i915_power_well_desc struct that
we initialize during compile time. For the rest of the dynamic
fields allocate an array of i915_power_well objects in i915 dev_priv,
and link to each of these objects their corresponding
i915_power_well_desc object.
v2:
- Fix checkpatch warnings about missing param name in fn declaration and
lines over 80 chars. (Paulo)
- Move check for unique IDs to __set_power_wells().
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
[Fixed checkpatch warn in __set_power_wells()]
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180806095843.13294-5-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_runtime_pm.c | 206 |
1 files changed, 117 insertions, 89 deletions
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index b2d182cc3319..9f44a2b0113a 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -159,17 +159,17 @@ intel_display_power_domain_str(enum intel_display_power_domain domain) | |||
159 | static void intel_power_well_enable(struct drm_i915_private *dev_priv, | 159 | static void intel_power_well_enable(struct drm_i915_private *dev_priv, |
160 | struct i915_power_well *power_well) | 160 | struct i915_power_well *power_well) |
161 | { | 161 | { |
162 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); | 162 | DRM_DEBUG_KMS("enabling %s\n", power_well->desc->name); |
163 | power_well->ops->enable(dev_priv, power_well); | 163 | power_well->desc->ops->enable(dev_priv, power_well); |
164 | power_well->hw_enabled = true; | 164 | power_well->hw_enabled = true; |
165 | } | 165 | } |
166 | 166 | ||
167 | static void intel_power_well_disable(struct drm_i915_private *dev_priv, | 167 | static void intel_power_well_disable(struct drm_i915_private *dev_priv, |
168 | struct i915_power_well *power_well) | 168 | struct i915_power_well *power_well) |
169 | { | 169 | { |
170 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); | 170 | DRM_DEBUG_KMS("disabling %s\n", power_well->desc->name); |
171 | power_well->hw_enabled = false; | 171 | power_well->hw_enabled = false; |
172 | power_well->ops->disable(dev_priv, power_well); | 172 | power_well->desc->ops->disable(dev_priv, power_well); |
173 | } | 173 | } |
174 | 174 | ||
175 | static void intel_power_well_get(struct drm_i915_private *dev_priv, | 175 | static void intel_power_well_get(struct drm_i915_private *dev_priv, |
@@ -183,7 +183,7 @@ static void intel_power_well_put(struct drm_i915_private *dev_priv, | |||
183 | struct i915_power_well *power_well) | 183 | struct i915_power_well *power_well) |
184 | { | 184 | { |
185 | WARN(!power_well->count, "Use count on power well %s is already zero", | 185 | WARN(!power_well->count, "Use count on power well %s is already zero", |
186 | power_well->name); | 186 | power_well->desc->name); |
187 | 187 | ||
188 | if (!--power_well->count) | 188 | if (!--power_well->count) |
189 | intel_power_well_disable(dev_priv, power_well); | 189 | intel_power_well_disable(dev_priv, power_well); |
@@ -213,7 +213,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, | |||
213 | is_enabled = true; | 213 | is_enabled = true; |
214 | 214 | ||
215 | for_each_power_domain_well_rev(dev_priv, power_well, BIT_ULL(domain)) { | 215 | for_each_power_domain_well_rev(dev_priv, power_well, BIT_ULL(domain)) { |
216 | if (power_well->always_on) | 216 | if (power_well->desc->always_on) |
217 | continue; | 217 | continue; |
218 | 218 | ||
219 | if (!power_well->hw_enabled) { | 219 | if (!power_well->hw_enabled) { |
@@ -323,7 +323,7 @@ static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv, | |||
323 | static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv, | 323 | static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv, |
324 | struct i915_power_well *power_well) | 324 | struct i915_power_well *power_well) |
325 | { | 325 | { |
326 | enum i915_power_well_id id = power_well->id; | 326 | enum i915_power_well_id id = power_well->desc->id; |
327 | 327 | ||
328 | /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */ | 328 | /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */ |
329 | WARN_ON(intel_wait_for_register(dev_priv, | 329 | WARN_ON(intel_wait_for_register(dev_priv, |
@@ -350,7 +350,7 @@ static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv, | |||
350 | static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv, | 350 | static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv, |
351 | struct i915_power_well *power_well) | 351 | struct i915_power_well *power_well) |
352 | { | 352 | { |
353 | enum i915_power_well_id id = power_well->id; | 353 | enum i915_power_well_id id = power_well->desc->id; |
354 | bool disabled; | 354 | bool disabled; |
355 | u32 reqs; | 355 | u32 reqs; |
356 | 356 | ||
@@ -370,7 +370,7 @@ static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv, | |||
370 | return; | 370 | return; |
371 | 371 | ||
372 | DRM_DEBUG_KMS("%s forced on (bios:%d driver:%d kvmr:%d debug:%d)\n", | 372 | DRM_DEBUG_KMS("%s forced on (bios:%d driver:%d kvmr:%d debug:%d)\n", |
373 | power_well->name, | 373 | power_well->desc->name, |
374 | !!(reqs & 1), !!(reqs & 2), !!(reqs & 4), !!(reqs & 8)); | 374 | !!(reqs & 1), !!(reqs & 2), !!(reqs & 4), !!(reqs & 8)); |
375 | } | 375 | } |
376 | 376 | ||
@@ -386,8 +386,8 @@ static void gen9_wait_for_power_well_fuses(struct drm_i915_private *dev_priv, | |||
386 | static void hsw_power_well_enable(struct drm_i915_private *dev_priv, | 386 | static void hsw_power_well_enable(struct drm_i915_private *dev_priv, |
387 | struct i915_power_well *power_well) | 387 | struct i915_power_well *power_well) |
388 | { | 388 | { |
389 | enum i915_power_well_id id = power_well->id; | 389 | enum i915_power_well_id id = power_well->desc->id; |
390 | bool wait_fuses = power_well->hsw.has_fuses; | 390 | bool wait_fuses = power_well->desc->hsw.has_fuses; |
391 | enum skl_power_gate uninitialized_var(pg); | 391 | enum skl_power_gate uninitialized_var(pg); |
392 | u32 val; | 392 | u32 val; |
393 | 393 | ||
@@ -421,17 +421,19 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, | |||
421 | if (wait_fuses) | 421 | if (wait_fuses) |
422 | gen9_wait_for_power_well_fuses(dev_priv, pg); | 422 | gen9_wait_for_power_well_fuses(dev_priv, pg); |
423 | 423 | ||
424 | hsw_power_well_post_enable(dev_priv, power_well->hsw.irq_pipe_mask, | 424 | hsw_power_well_post_enable(dev_priv, |
425 | power_well->hsw.has_vga); | 425 | power_well->desc->hsw.irq_pipe_mask, |
426 | power_well->desc->hsw.has_vga); | ||
426 | } | 427 | } |
427 | 428 | ||
428 | static void hsw_power_well_disable(struct drm_i915_private *dev_priv, | 429 | static void hsw_power_well_disable(struct drm_i915_private *dev_priv, |
429 | struct i915_power_well *power_well) | 430 | struct i915_power_well *power_well) |
430 | { | 431 | { |
431 | enum i915_power_well_id id = power_well->id; | 432 | enum i915_power_well_id id = power_well->desc->id; |
432 | u32 val; | 433 | u32 val; |
433 | 434 | ||
434 | hsw_power_well_pre_disable(dev_priv, power_well->hsw.irq_pipe_mask); | 435 | hsw_power_well_pre_disable(dev_priv, |
436 | power_well->desc->hsw.irq_pipe_mask); | ||
435 | 437 | ||
436 | val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); | 438 | val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); |
437 | I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), | 439 | I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), |
@@ -445,7 +447,7 @@ static void | |||
445 | icl_combo_phy_aux_power_well_enable(struct drm_i915_private *dev_priv, | 447 | icl_combo_phy_aux_power_well_enable(struct drm_i915_private *dev_priv, |
446 | struct i915_power_well *power_well) | 448 | struct i915_power_well *power_well) |
447 | { | 449 | { |
448 | enum i915_power_well_id id = power_well->id; | 450 | enum i915_power_well_id id = power_well->desc->id; |
449 | enum port port = ICL_AUX_PW_TO_PORT(id); | 451 | enum port port = ICL_AUX_PW_TO_PORT(id); |
450 | u32 val; | 452 | u32 val; |
451 | 453 | ||
@@ -462,7 +464,7 @@ static void | |||
462 | icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv, | 464 | icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv, |
463 | struct i915_power_well *power_well) | 465 | struct i915_power_well *power_well) |
464 | { | 466 | { |
465 | enum i915_power_well_id id = power_well->id; | 467 | enum i915_power_well_id id = power_well->desc->id; |
466 | enum port port = ICL_AUX_PW_TO_PORT(id); | 468 | enum port port = ICL_AUX_PW_TO_PORT(id); |
467 | u32 val; | 469 | u32 val; |
468 | 470 | ||
@@ -484,7 +486,7 @@ icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv, | |||
484 | static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, | 486 | static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, |
485 | struct i915_power_well *power_well) | 487 | struct i915_power_well *power_well) |
486 | { | 488 | { |
487 | enum i915_power_well_id id = power_well->id; | 489 | enum i915_power_well_id id = power_well->desc->id; |
488 | u32 mask = HSW_PWR_WELL_CTL_REQ(id) | HSW_PWR_WELL_CTL_STATE(id); | 490 | u32 mask = HSW_PWR_WELL_CTL_REQ(id) | HSW_PWR_WELL_CTL_STATE(id); |
489 | 491 | ||
490 | return (I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & mask) == mask; | 492 | return (I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & mask) == mask; |
@@ -723,7 +725,7 @@ static void skl_enable_dc6(struct drm_i915_private *dev_priv) | |||
723 | static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, | 725 | static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, |
724 | struct i915_power_well *power_well) | 726 | struct i915_power_well *power_well) |
725 | { | 727 | { |
726 | enum i915_power_well_id id = power_well->id; | 728 | enum i915_power_well_id id = power_well->desc->id; |
727 | u32 mask = HSW_PWR_WELL_CTL_REQ(id); | 729 | u32 mask = HSW_PWR_WELL_CTL_REQ(id); |
728 | u32 bios_req = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)); | 730 | u32 bios_req = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)); |
729 | 731 | ||
@@ -740,19 +742,19 @@ static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, | |||
740 | static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | 742 | static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, |
741 | struct i915_power_well *power_well) | 743 | struct i915_power_well *power_well) |
742 | { | 744 | { |
743 | bxt_ddi_phy_init(dev_priv, power_well->bxt.phy); | 745 | bxt_ddi_phy_init(dev_priv, power_well->desc->bxt.phy); |
744 | } | 746 | } |
745 | 747 | ||
746 | static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | 748 | static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, |
747 | struct i915_power_well *power_well) | 749 | struct i915_power_well *power_well) |
748 | { | 750 | { |
749 | bxt_ddi_phy_uninit(dev_priv, power_well->bxt.phy); | 751 | bxt_ddi_phy_uninit(dev_priv, power_well->desc->bxt.phy); |
750 | } | 752 | } |
751 | 753 | ||
752 | static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv, | 754 | static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv, |
753 | struct i915_power_well *power_well) | 755 | struct i915_power_well *power_well) |
754 | { | 756 | { |
755 | return bxt_ddi_phy_is_enabled(dev_priv, power_well->bxt.phy); | 757 | return bxt_ddi_phy_is_enabled(dev_priv, power_well->desc->bxt.phy); |
756 | } | 758 | } |
757 | 759 | ||
758 | static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv) | 760 | static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv) |
@@ -761,16 +763,17 @@ static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv) | |||
761 | 763 | ||
762 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A); | 764 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A); |
763 | if (power_well->count > 0) | 765 | if (power_well->count > 0) |
764 | bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy); | 766 | bxt_ddi_phy_verify_state(dev_priv, power_well->desc->bxt.phy); |
765 | 767 | ||
766 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC); | 768 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC); |
767 | if (power_well->count > 0) | 769 | if (power_well->count > 0) |
768 | bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy); | 770 | bxt_ddi_phy_verify_state(dev_priv, power_well->desc->bxt.phy); |
769 | 771 | ||
770 | if (IS_GEMINILAKE(dev_priv)) { | 772 | if (IS_GEMINILAKE(dev_priv)) { |
771 | power_well = lookup_power_well(dev_priv, GLK_DPIO_CMN_C); | 773 | power_well = lookup_power_well(dev_priv, GLK_DPIO_CMN_C); |
772 | if (power_well->count > 0) | 774 | if (power_well->count > 0) |
773 | bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy); | 775 | bxt_ddi_phy_verify_state(dev_priv, |
776 | power_well->desc->bxt.phy); | ||
774 | } | 777 | } |
775 | } | 778 | } |
776 | 779 | ||
@@ -869,7 +872,7 @@ static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv, | |||
869 | static void vlv_set_power_well(struct drm_i915_private *dev_priv, | 872 | static void vlv_set_power_well(struct drm_i915_private *dev_priv, |
870 | struct i915_power_well *power_well, bool enable) | 873 | struct i915_power_well *power_well, bool enable) |
871 | { | 874 | { |
872 | enum i915_power_well_id power_well_id = power_well->id; | 875 | enum i915_power_well_id power_well_id = power_well->desc->id; |
873 | u32 mask; | 876 | u32 mask; |
874 | u32 state; | 877 | u32 state; |
875 | u32 ctrl; | 878 | u32 ctrl; |
@@ -917,7 +920,7 @@ static void vlv_power_well_disable(struct drm_i915_private *dev_priv, | |||
917 | static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, | 920 | static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, |
918 | struct i915_power_well *power_well) | 921 | struct i915_power_well *power_well) |
919 | { | 922 | { |
920 | enum i915_power_well_id power_well_id = power_well->id; | 923 | enum i915_power_well_id power_well_id = power_well->desc->id; |
921 | bool enabled = false; | 924 | bool enabled = false; |
922 | u32 mask; | 925 | u32 mask; |
923 | u32 state; | 926 | u32 state; |
@@ -1107,7 +1110,7 @@ lookup_power_well(struct drm_i915_private *dev_priv, | |||
1107 | struct i915_power_well *power_well; | 1110 | struct i915_power_well *power_well; |
1108 | 1111 | ||
1109 | power_well = &power_domains->power_wells[i]; | 1112 | power_well = &power_domains->power_wells[i]; |
1110 | if (power_well->id == power_well_id) | 1113 | if (power_well->desc->id == power_well_id) |
1111 | return power_well; | 1114 | return power_well; |
1112 | } | 1115 | } |
1113 | 1116 | ||
@@ -1146,7 +1149,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) | |||
1146 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) | | 1149 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) | |
1147 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1)); | 1150 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1)); |
1148 | 1151 | ||
1149 | if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) { | 1152 | if (cmn_bc->desc->ops->is_enabled(dev_priv, cmn_bc)) { |
1150 | phy_status |= PHY_POWERGOOD(DPIO_PHY0); | 1153 | phy_status |= PHY_POWERGOOD(DPIO_PHY0); |
1151 | 1154 | ||
1152 | /* this assumes override is only used to enable lanes */ | 1155 | /* this assumes override is only used to enable lanes */ |
@@ -1187,7 +1190,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) | |||
1187 | phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1); | 1190 | phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1); |
1188 | } | 1191 | } |
1189 | 1192 | ||
1190 | if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) { | 1193 | if (cmn_d->desc->ops->is_enabled(dev_priv, cmn_d)) { |
1191 | phy_status |= PHY_POWERGOOD(DPIO_PHY1); | 1194 | phy_status |= PHY_POWERGOOD(DPIO_PHY1); |
1192 | 1195 | ||
1193 | /* this assumes override is only used to enable lanes */ | 1196 | /* this assumes override is only used to enable lanes */ |
@@ -1231,10 +1234,10 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | |||
1231 | enum pipe pipe; | 1234 | enum pipe pipe; |
1232 | uint32_t tmp; | 1235 | uint32_t tmp; |
1233 | 1236 | ||
1234 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC && | 1237 | WARN_ON_ONCE(power_well->desc->id != PUNIT_POWER_WELL_DPIO_CMN_BC && |
1235 | power_well->id != PUNIT_POWER_WELL_DPIO_CMN_D); | 1238 | power_well->desc->id != PUNIT_POWER_WELL_DPIO_CMN_D); |
1236 | 1239 | ||
1237 | if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { | 1240 | if (power_well->desc->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { |
1238 | pipe = PIPE_A; | 1241 | pipe = PIPE_A; |
1239 | phy = DPIO_PHY0; | 1242 | phy = DPIO_PHY0; |
1240 | } else { | 1243 | } else { |
@@ -1262,7 +1265,7 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | |||
1262 | DPIO_SUS_CLK_CONFIG_GATE_CLKREQ; | 1265 | DPIO_SUS_CLK_CONFIG_GATE_CLKREQ; |
1263 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW28, tmp); | 1266 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW28, tmp); |
1264 | 1267 | ||
1265 | if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { | 1268 | if (power_well->desc->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { |
1266 | tmp = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW6_CH1); | 1269 | tmp = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW6_CH1); |
1267 | tmp |= DPIO_DYNPWRDOWNEN_CH1; | 1270 | tmp |= DPIO_DYNPWRDOWNEN_CH1; |
1268 | vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW6_CH1, tmp); | 1271 | vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW6_CH1, tmp); |
@@ -1293,10 +1296,10 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | |||
1293 | { | 1296 | { |
1294 | enum dpio_phy phy; | 1297 | enum dpio_phy phy; |
1295 | 1298 | ||
1296 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC && | 1299 | WARN_ON_ONCE(power_well->desc->id != PUNIT_POWER_WELL_DPIO_CMN_BC && |
1297 | power_well->id != PUNIT_POWER_WELL_DPIO_CMN_D); | 1300 | power_well->desc->id != PUNIT_POWER_WELL_DPIO_CMN_D); |
1298 | 1301 | ||
1299 | if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { | 1302 | if (power_well->desc->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { |
1300 | phy = DPIO_PHY0; | 1303 | phy = DPIO_PHY0; |
1301 | assert_pll_disabled(dev_priv, PIPE_A); | 1304 | assert_pll_disabled(dev_priv, PIPE_A); |
1302 | assert_pll_disabled(dev_priv, PIPE_B); | 1305 | assert_pll_disabled(dev_priv, PIPE_B); |
@@ -2051,7 +2054,7 @@ static const struct i915_power_well_ops chv_dpio_cmn_power_well_ops = { | |||
2051 | .is_enabled = vlv_power_well_enabled, | 2054 | .is_enabled = vlv_power_well_enabled, |
2052 | }; | 2055 | }; |
2053 | 2056 | ||
2054 | static struct i915_power_well i9xx_always_on_power_well[] = { | 2057 | static const struct i915_power_well_desc i9xx_always_on_power_well[] = { |
2055 | { | 2058 | { |
2056 | .name = "always-on", | 2059 | .name = "always-on", |
2057 | .always_on = 1, | 2060 | .always_on = 1, |
@@ -2068,7 +2071,7 @@ static const struct i915_power_well_ops i830_pipes_power_well_ops = { | |||
2068 | .is_enabled = i830_pipes_power_well_enabled, | 2071 | .is_enabled = i830_pipes_power_well_enabled, |
2069 | }; | 2072 | }; |
2070 | 2073 | ||
2071 | static struct i915_power_well i830_power_wells[] = { | 2074 | static const struct i915_power_well_desc i830_power_wells[] = { |
2072 | { | 2075 | { |
2073 | .name = "always-on", | 2076 | .name = "always-on", |
2074 | .always_on = 1, | 2077 | .always_on = 1, |
@@ -2105,7 +2108,7 @@ static const struct i915_power_well_ops bxt_dpio_cmn_power_well_ops = { | |||
2105 | .is_enabled = bxt_dpio_cmn_power_well_enabled, | 2108 | .is_enabled = bxt_dpio_cmn_power_well_enabled, |
2106 | }; | 2109 | }; |
2107 | 2110 | ||
2108 | static struct i915_power_well hsw_power_wells[] = { | 2111 | static const struct i915_power_well_desc hsw_power_wells[] = { |
2109 | { | 2112 | { |
2110 | .name = "always-on", | 2113 | .name = "always-on", |
2111 | .always_on = 1, | 2114 | .always_on = 1, |
@@ -2124,7 +2127,7 @@ static struct i915_power_well hsw_power_wells[] = { | |||
2124 | }, | 2127 | }, |
2125 | }; | 2128 | }; |
2126 | 2129 | ||
2127 | static struct i915_power_well bdw_power_wells[] = { | 2130 | static const struct i915_power_well_desc bdw_power_wells[] = { |
2128 | { | 2131 | { |
2129 | .name = "always-on", | 2132 | .name = "always-on", |
2130 | .always_on = 1, | 2133 | .always_on = 1, |
@@ -2165,7 +2168,7 @@ static const struct i915_power_well_ops vlv_dpio_power_well_ops = { | |||
2165 | .is_enabled = vlv_power_well_enabled, | 2168 | .is_enabled = vlv_power_well_enabled, |
2166 | }; | 2169 | }; |
2167 | 2170 | ||
2168 | static struct i915_power_well vlv_power_wells[] = { | 2171 | static const struct i915_power_well_desc vlv_power_wells[] = { |
2169 | { | 2172 | { |
2170 | .name = "always-on", | 2173 | .name = "always-on", |
2171 | .always_on = 1, | 2174 | .always_on = 1, |
@@ -2223,7 +2226,7 @@ static struct i915_power_well vlv_power_wells[] = { | |||
2223 | }, | 2226 | }, |
2224 | }; | 2227 | }; |
2225 | 2228 | ||
2226 | static struct i915_power_well chv_power_wells[] = { | 2229 | static const struct i915_power_well_desc chv_power_wells[] = { |
2227 | { | 2230 | { |
2228 | .name = "always-on", | 2231 | .name = "always-on", |
2229 | .always_on = 1, | 2232 | .always_on = 1, |
@@ -2263,12 +2266,12 @@ bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, | |||
2263 | bool ret; | 2266 | bool ret; |
2264 | 2267 | ||
2265 | power_well = lookup_power_well(dev_priv, power_well_id); | 2268 | power_well = lookup_power_well(dev_priv, power_well_id); |
2266 | ret = power_well->ops->is_enabled(dev_priv, power_well); | 2269 | ret = power_well->desc->ops->is_enabled(dev_priv, power_well); |
2267 | 2270 | ||
2268 | return ret; | 2271 | return ret; |
2269 | } | 2272 | } |
2270 | 2273 | ||
2271 | static struct i915_power_well skl_power_wells[] = { | 2274 | static const struct i915_power_well_desc skl_power_wells[] = { |
2272 | { | 2275 | { |
2273 | .name = "always-on", | 2276 | .name = "always-on", |
2274 | .always_on = 1, | 2277 | .always_on = 1, |
@@ -2336,7 +2339,7 @@ static struct i915_power_well skl_power_wells[] = { | |||
2336 | }, | 2339 | }, |
2337 | }; | 2340 | }; |
2338 | 2341 | ||
2339 | static struct i915_power_well bxt_power_wells[] = { | 2342 | static const struct i915_power_well_desc bxt_power_wells[] = { |
2340 | { | 2343 | { |
2341 | .name = "always-on", | 2344 | .name = "always-on", |
2342 | .always_on = 1, | 2345 | .always_on = 1, |
@@ -2390,7 +2393,7 @@ static struct i915_power_well bxt_power_wells[] = { | |||
2390 | }, | 2393 | }, |
2391 | }; | 2394 | }; |
2392 | 2395 | ||
2393 | static struct i915_power_well glk_power_wells[] = { | 2396 | static const struct i915_power_well_desc glk_power_wells[] = { |
2394 | { | 2397 | { |
2395 | .name = "always-on", | 2398 | .name = "always-on", |
2396 | .always_on = 1, | 2399 | .always_on = 1, |
@@ -2490,7 +2493,7 @@ static struct i915_power_well glk_power_wells[] = { | |||
2490 | }, | 2493 | }, |
2491 | }; | 2494 | }; |
2492 | 2495 | ||
2493 | static struct i915_power_well cnl_power_wells[] = { | 2496 | static const struct i915_power_well_desc cnl_power_wells[] = { |
2494 | { | 2497 | { |
2495 | .name = "always-on", | 2498 | .name = "always-on", |
2496 | .always_on = 1, | 2499 | .always_on = 1, |
@@ -2594,7 +2597,7 @@ static const struct i915_power_well_ops icl_combo_phy_aux_power_well_ops = { | |||
2594 | .is_enabled = hsw_power_well_enabled, | 2597 | .is_enabled = hsw_power_well_enabled, |
2595 | }; | 2598 | }; |
2596 | 2599 | ||
2597 | static struct i915_power_well icl_power_wells[] = { | 2600 | static const struct i915_power_well_desc icl_power_wells[] = { |
2598 | { | 2601 | { |
2599 | .name = "always-on", | 2602 | .name = "always-on", |
2600 | .always_on = 1, | 2603 | .always_on = 1, |
@@ -2805,26 +2808,38 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv, | |||
2805 | return mask; | 2808 | return mask; |
2806 | } | 2809 | } |
2807 | 2810 | ||
2808 | static void assert_power_well_ids_unique(struct drm_i915_private *dev_priv) | 2811 | static int |
2812 | __set_power_wells(struct i915_power_domains *power_domains, | ||
2813 | const struct i915_power_well_desc *power_well_descs, | ||
2814 | int power_well_count) | ||
2809 | { | 2815 | { |
2810 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 2816 | u64 power_well_ids = 0; |
2811 | u64 power_well_ids; | ||
2812 | int i; | 2817 | int i; |
2813 | 2818 | ||
2814 | power_well_ids = 0; | 2819 | power_domains->power_well_count = power_well_count; |
2815 | for (i = 0; i < power_domains->power_well_count; i++) { | 2820 | power_domains->power_wells = |
2816 | enum i915_power_well_id id = power_domains->power_wells[i].id; | 2821 | kcalloc(power_well_count, |
2822 | sizeof(*power_domains->power_wells), | ||
2823 | GFP_KERNEL); | ||
2824 | if (!power_domains->power_wells) | ||
2825 | return -ENOMEM; | ||
2826 | |||
2827 | for (i = 0; i < power_well_count; i++) { | ||
2828 | enum i915_power_well_id id = power_well_descs[i].id; | ||
2829 | |||
2830 | power_domains->power_wells[i].desc = &power_well_descs[i]; | ||
2817 | 2831 | ||
2818 | WARN_ON(id >= sizeof(power_well_ids) * 8); | 2832 | WARN_ON(id >= sizeof(power_well_ids) * 8); |
2819 | WARN_ON(power_well_ids & BIT_ULL(id)); | 2833 | WARN_ON(power_well_ids & BIT_ULL(id)); |
2820 | power_well_ids |= BIT_ULL(id); | 2834 | power_well_ids |= BIT_ULL(id); |
2821 | } | 2835 | } |
2836 | |||
2837 | return 0; | ||
2822 | } | 2838 | } |
2823 | 2839 | ||
2824 | #define set_power_wells(power_domains, __power_wells) ({ \ | 2840 | #define set_power_wells(power_domains, __power_well_descs) \ |
2825 | (power_domains)->power_wells = (__power_wells); \ | 2841 | __set_power_wells(power_domains, __power_well_descs, \ |
2826 | (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ | 2842 | ARRAY_SIZE(__power_well_descs)) |
2827 | }) | ||
2828 | 2843 | ||
2829 | /** | 2844 | /** |
2830 | * intel_power_domains_init - initializes the power domain structures | 2845 | * intel_power_domains_init - initializes the power domain structures |
@@ -2836,6 +2851,7 @@ static void assert_power_well_ids_unique(struct drm_i915_private *dev_priv) | |||
2836 | int intel_power_domains_init(struct drm_i915_private *dev_priv) | 2851 | int intel_power_domains_init(struct drm_i915_private *dev_priv) |
2837 | { | 2852 | { |
2838 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 2853 | struct i915_power_domains *power_domains = &dev_priv->power_domains; |
2854 | int err; | ||
2839 | 2855 | ||
2840 | i915_modparams.disable_power_well = | 2856 | i915_modparams.disable_power_well = |
2841 | sanitize_disable_power_well_option(dev_priv, | 2857 | sanitize_disable_power_well_option(dev_priv, |
@@ -2852,15 +2868,15 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) | |||
2852 | * the disabling order is reversed. | 2868 | * the disabling order is reversed. |
2853 | */ | 2869 | */ |
2854 | if (IS_ICELAKE(dev_priv)) { | 2870 | if (IS_ICELAKE(dev_priv)) { |
2855 | set_power_wells(power_domains, icl_power_wells); | 2871 | err = set_power_wells(power_domains, icl_power_wells); |
2856 | } else if (IS_HASWELL(dev_priv)) { | 2872 | } else if (IS_HASWELL(dev_priv)) { |
2857 | set_power_wells(power_domains, hsw_power_wells); | 2873 | err = set_power_wells(power_domains, hsw_power_wells); |
2858 | } else if (IS_BROADWELL(dev_priv)) { | 2874 | } else if (IS_BROADWELL(dev_priv)) { |
2859 | set_power_wells(power_domains, bdw_power_wells); | 2875 | err = set_power_wells(power_domains, bdw_power_wells); |
2860 | } else if (IS_GEN9_BC(dev_priv)) { | 2876 | } else if (IS_GEN9_BC(dev_priv)) { |
2861 | set_power_wells(power_domains, skl_power_wells); | 2877 | err = set_power_wells(power_domains, skl_power_wells); |
2862 | } else if (IS_CANNONLAKE(dev_priv)) { | 2878 | } else if (IS_CANNONLAKE(dev_priv)) { |
2863 | set_power_wells(power_domains, cnl_power_wells); | 2879 | err = set_power_wells(power_domains, cnl_power_wells); |
2864 | 2880 | ||
2865 | /* | 2881 | /* |
2866 | * DDI and Aux IO are getting enabled for all ports | 2882 | * DDI and Aux IO are getting enabled for all ports |
@@ -2872,22 +2888,31 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) | |||
2872 | power_domains->power_well_count -= 2; | 2888 | power_domains->power_well_count -= 2; |
2873 | 2889 | ||
2874 | } else if (IS_BROXTON(dev_priv)) { | 2890 | } else if (IS_BROXTON(dev_priv)) { |
2875 | set_power_wells(power_domains, bxt_power_wells); | 2891 | err = set_power_wells(power_domains, bxt_power_wells); |
2876 | } else if (IS_GEMINILAKE(dev_priv)) { | 2892 | } else if (IS_GEMINILAKE(dev_priv)) { |
2877 | set_power_wells(power_domains, glk_power_wells); | 2893 | err = set_power_wells(power_domains, glk_power_wells); |
2878 | } else if (IS_CHERRYVIEW(dev_priv)) { | 2894 | } else if (IS_CHERRYVIEW(dev_priv)) { |
2879 | set_power_wells(power_domains, chv_power_wells); | 2895 | err = set_power_wells(power_domains, chv_power_wells); |
2880 | } else if (IS_VALLEYVIEW(dev_priv)) { | 2896 | } else if (IS_VALLEYVIEW(dev_priv)) { |
2881 | set_power_wells(power_domains, vlv_power_wells); | 2897 | err = set_power_wells(power_domains, vlv_power_wells); |
2882 | } else if (IS_I830(dev_priv)) { | 2898 | } else if (IS_I830(dev_priv)) { |
2883 | set_power_wells(power_domains, i830_power_wells); | 2899 | err = set_power_wells(power_domains, i830_power_wells); |
2884 | } else { | 2900 | } else { |
2885 | set_power_wells(power_domains, i9xx_always_on_power_well); | 2901 | err = set_power_wells(power_domains, i9xx_always_on_power_well); |
2886 | } | 2902 | } |
2887 | 2903 | ||
2888 | assert_power_well_ids_unique(dev_priv); | 2904 | return err; |
2905 | } | ||
2889 | 2906 | ||
2890 | return 0; | 2907 | /** |
2908 | * intel_power_domains_cleanup - clean up power domains resources | ||
2909 | * @dev_priv: i915 device instance | ||
2910 | * | ||
2911 | * Release any resources acquired by intel_power_domains_init() | ||
2912 | */ | ||
2913 | void intel_power_domains_cleanup(struct drm_i915_private *dev_priv) | ||
2914 | { | ||
2915 | kfree(dev_priv->power_domains.power_wells); | ||
2891 | } | 2916 | } |
2892 | 2917 | ||
2893 | static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv) | 2918 | static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv) |
@@ -2897,9 +2922,9 @@ static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv) | |||
2897 | 2922 | ||
2898 | mutex_lock(&power_domains->lock); | 2923 | mutex_lock(&power_domains->lock); |
2899 | for_each_power_well(dev_priv, power_well) { | 2924 | for_each_power_well(dev_priv, power_well) { |
2900 | power_well->ops->sync_hw(dev_priv, power_well); | 2925 | power_well->desc->ops->sync_hw(dev_priv, power_well); |
2901 | power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, | 2926 | power_well->hw_enabled = |
2902 | power_well); | 2927 | power_well->desc->ops->is_enabled(dev_priv, power_well); |
2903 | } | 2928 | } |
2904 | mutex_unlock(&power_domains->lock); | 2929 | mutex_unlock(&power_domains->lock); |
2905 | } | 2930 | } |
@@ -3398,7 +3423,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) | |||
3398 | * override and set the lane powerdown bits accding to the | 3423 | * override and set the lane powerdown bits accding to the |
3399 | * current lane status. | 3424 | * current lane status. |
3400 | */ | 3425 | */ |
3401 | if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) { | 3426 | if (cmn_bc->desc->ops->is_enabled(dev_priv, cmn_bc)) { |
3402 | uint32_t status = I915_READ(DPLL(PIPE_A)); | 3427 | uint32_t status = I915_READ(DPLL(PIPE_A)); |
3403 | unsigned int mask; | 3428 | unsigned int mask; |
3404 | 3429 | ||
@@ -3429,7 +3454,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) | |||
3429 | dev_priv->chv_phy_assert[DPIO_PHY0] = true; | 3454 | dev_priv->chv_phy_assert[DPIO_PHY0] = true; |
3430 | } | 3455 | } |
3431 | 3456 | ||
3432 | if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) { | 3457 | if (cmn_d->desc->ops->is_enabled(dev_priv, cmn_d)) { |
3433 | uint32_t status = I915_READ(DPIO_PHY_STATUS); | 3458 | uint32_t status = I915_READ(DPIO_PHY_STATUS); |
3434 | unsigned int mask; | 3459 | unsigned int mask; |
3435 | 3460 | ||
@@ -3465,15 +3490,15 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) | |||
3465 | lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D); | 3490 | lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D); |
3466 | 3491 | ||
3467 | /* If the display might be already active skip this */ | 3492 | /* If the display might be already active skip this */ |
3468 | if (cmn->ops->is_enabled(dev_priv, cmn) && | 3493 | if (cmn->desc->ops->is_enabled(dev_priv, cmn) && |
3469 | disp2d->ops->is_enabled(dev_priv, disp2d) && | 3494 | disp2d->desc->ops->is_enabled(dev_priv, disp2d) && |
3470 | I915_READ(DPIO_CTL) & DPIO_CMNRST) | 3495 | I915_READ(DPIO_CTL) & DPIO_CMNRST) |
3471 | return; | 3496 | return; |
3472 | 3497 | ||
3473 | DRM_DEBUG_KMS("toggling display PHY side reset\n"); | 3498 | DRM_DEBUG_KMS("toggling display PHY side reset\n"); |
3474 | 3499 | ||
3475 | /* cmnlane needs DPLL registers */ | 3500 | /* cmnlane needs DPLL registers */ |
3476 | disp2d->ops->enable(dev_priv, disp2d); | 3501 | disp2d->desc->ops->enable(dev_priv, disp2d); |
3477 | 3502 | ||
3478 | /* | 3503 | /* |
3479 | * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx: | 3504 | * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx: |
@@ -3482,7 +3507,7 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) | |||
3482 | * Simply ungating isn't enough to reset the PHY enough to get | 3507 | * Simply ungating isn't enough to reset the PHY enough to get |
3483 | * ports and lanes running. | 3508 | * ports and lanes running. |
3484 | */ | 3509 | */ |
3485 | cmn->ops->disable(dev_priv, cmn); | 3510 | cmn->desc->ops->disable(dev_priv, cmn); |
3486 | } | 3511 | } |
3487 | 3512 | ||
3488 | /** | 3513 | /** |
@@ -3598,9 +3623,9 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv) | |||
3598 | enum intel_display_power_domain domain; | 3623 | enum intel_display_power_domain domain; |
3599 | 3624 | ||
3600 | DRM_DEBUG_DRIVER("%-25s %d\n", | 3625 | DRM_DEBUG_DRIVER("%-25s %d\n", |
3601 | power_well->name, power_well->count); | 3626 | power_well->desc->name, power_well->count); |
3602 | 3627 | ||
3603 | for_each_power_domain(domain, power_well->domains) | 3628 | for_each_power_domain(domain, power_well->desc->domains) |
3604 | DRM_DEBUG_DRIVER(" %-23s %d\n", | 3629 | DRM_DEBUG_DRIVER(" %-23s %d\n", |
3605 | intel_display_power_domain_str(domain), | 3630 | intel_display_power_domain_str(domain), |
3606 | power_domains->domain_use_count[domain]); | 3631 | power_domains->domain_use_count[domain]); |
@@ -3636,22 +3661,25 @@ void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | |||
3636 | * and PW1 power wells) are under FW control, so ignore them, | 3661 | * and PW1 power wells) are under FW control, so ignore them, |
3637 | * since their state can change asynchronously. | 3662 | * since their state can change asynchronously. |
3638 | */ | 3663 | */ |
3639 | if (!power_well->domains) | 3664 | if (!power_well->desc->domains) |
3640 | continue; | 3665 | continue; |
3641 | 3666 | ||
3642 | enabled = power_well->ops->is_enabled(dev_priv, power_well); | 3667 | enabled = power_well->desc->ops->is_enabled(dev_priv, |
3643 | if ((power_well->count || power_well->always_on) != enabled) | 3668 | power_well); |
3669 | if ((power_well->count || power_well->desc->always_on) != | ||
3670 | enabled) | ||
3644 | DRM_ERROR("power well %s state mismatch (refcount %d/enabled %d)", | 3671 | DRM_ERROR("power well %s state mismatch (refcount %d/enabled %d)", |
3645 | power_well->name, power_well->count, enabled); | 3672 | power_well->desc->name, |
3673 | power_well->count, enabled); | ||
3646 | 3674 | ||
3647 | domains_count = 0; | 3675 | domains_count = 0; |
3648 | for_each_power_domain(domain, power_well->domains) | 3676 | for_each_power_domain(domain, power_well->desc->domains) |
3649 | domains_count += power_domains->domain_use_count[domain]; | 3677 | domains_count += power_domains->domain_use_count[domain]; |
3650 | 3678 | ||
3651 | if (power_well->count != domains_count) { | 3679 | if (power_well->count != domains_count) { |
3652 | DRM_ERROR("power well %s refcount/domain refcount mismatch " | 3680 | DRM_ERROR("power well %s refcount/domain refcount mismatch " |
3653 | "(refcount %d/domains refcount %d)\n", | 3681 | "(refcount %d/domains refcount %d)\n", |
3654 | power_well->name, power_well->count, | 3682 | power_well->desc->name, power_well->count, |
3655 | domains_count); | 3683 | domains_count); |
3656 | dump_domain_info = true; | 3684 | dump_domain_info = true; |
3657 | } | 3685 | } |