diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_hdcp.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_runtime_pm.c | 206 |
7 files changed, 141 insertions, 102 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f9ce35da4123..23f38bc257a2 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -2845,10 +2845,10 @@ static int i915_power_domain_info(struct seq_file *m, void *unused) | |||
| 2845 | enum intel_display_power_domain power_domain; | 2845 | enum intel_display_power_domain power_domain; |
| 2846 | 2846 | ||
| 2847 | power_well = &power_domains->power_wells[i]; | 2847 | power_well = &power_domains->power_wells[i]; |
| 2848 | seq_printf(m, "%-25s %d\n", power_well->name, | 2848 | seq_printf(m, "%-25s %d\n", power_well->desc->name, |
| 2849 | power_well->count); | 2849 | power_well->count); |
| 2850 | 2850 | ||
| 2851 | for_each_power_domain(power_domain, power_well->domains) | 2851 | for_each_power_domain(power_domain, power_well->desc->domains) |
| 2852 | seq_printf(m, " %-23s %d\n", | 2852 | seq_printf(m, " %-23s %d\n", |
| 2853 | intel_display_power_domain_str(power_domain), | 2853 | intel_display_power_domain_str(power_domain), |
| 2854 | power_domains->domain_use_count[power_domain]); | 2854 | power_domains->domain_use_count[power_domain]); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6396318cf73c..9dce55182c3a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -924,7 +924,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, | |||
| 924 | intel_uc_init_early(dev_priv); | 924 | intel_uc_init_early(dev_priv); |
| 925 | intel_pm_setup(dev_priv); | 925 | intel_pm_setup(dev_priv); |
| 926 | intel_init_dpio(dev_priv); | 926 | intel_init_dpio(dev_priv); |
| 927 | intel_power_domains_init(dev_priv); | 927 | ret = intel_power_domains_init(dev_priv); |
| 928 | if (ret < 0) | ||
| 929 | goto err_uc; | ||
| 928 | intel_irq_init(dev_priv); | 930 | intel_irq_init(dev_priv); |
| 929 | intel_hangcheck_init(dev_priv); | 931 | intel_hangcheck_init(dev_priv); |
| 930 | intel_init_display_hooks(dev_priv); | 932 | intel_init_display_hooks(dev_priv); |
| @@ -936,6 +938,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, | |||
| 936 | 938 | ||
| 937 | return 0; | 939 | return 0; |
| 938 | 940 | ||
| 941 | err_uc: | ||
| 942 | intel_uc_cleanup_early(dev_priv); | ||
| 943 | i915_gem_cleanup_early(dev_priv); | ||
| 939 | err_workqueues: | 944 | err_workqueues: |
| 940 | i915_workqueues_cleanup(dev_priv); | 945 | i915_workqueues_cleanup(dev_priv); |
| 941 | err_engines: | 946 | err_engines: |
| @@ -950,6 +955,7 @@ err_engines: | |||
| 950 | static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) | 955 | static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) |
| 951 | { | 956 | { |
| 952 | intel_irq_fini(dev_priv); | 957 | intel_irq_fini(dev_priv); |
| 958 | intel_power_domains_cleanup(dev_priv); | ||
| 953 | intel_uc_cleanup_early(dev_priv); | 959 | intel_uc_cleanup_early(dev_priv); |
| 954 | i915_gem_cleanup_early(dev_priv); | 960 | i915_gem_cleanup_early(dev_priv); |
| 955 | i915_workqueues_cleanup(dev_priv); | 961 | i915_workqueues_cleanup(dev_priv); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 657f46e0cae9..5cedd65326c5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -868,13 +868,9 @@ struct i915_power_well_ops { | |||
| 868 | }; | 868 | }; |
| 869 | 869 | ||
| 870 | /* Power well structure for haswell */ | 870 | /* Power well structure for haswell */ |
| 871 | struct i915_power_well { | 871 | struct i915_power_well_desc { |
| 872 | const char *name; | 872 | const char *name; |
| 873 | bool always_on; | 873 | bool always_on; |
| 874 | /* power well enable/disable usage count */ | ||
| 875 | int count; | ||
| 876 | /* cached hw enabled state */ | ||
| 877 | bool hw_enabled; | ||
| 878 | u64 domains; | 874 | u64 domains; |
| 879 | /* unique identifier for this power well */ | 875 | /* unique identifier for this power well */ |
| 880 | enum i915_power_well_id id; | 876 | enum i915_power_well_id id; |
| @@ -897,6 +893,14 @@ struct i915_power_well { | |||
| 897 | const struct i915_power_well_ops *ops; | 893 | const struct i915_power_well_ops *ops; |
| 898 | }; | 894 | }; |
| 899 | 895 | ||
| 896 | struct i915_power_well { | ||
| 897 | const struct i915_power_well_desc *desc; | ||
| 898 | /* power well enable/disable usage count */ | ||
| 899 | int count; | ||
| 900 | /* cached hw enabled state */ | ||
| 901 | bool hw_enabled; | ||
| 902 | }; | ||
| 903 | |||
| 900 | struct i915_power_domains { | 904 | struct i915_power_domains { |
| 901 | /* | 905 | /* |
| 902 | * Power wells needed for initialization at driver init and suspend | 906 | * Power wells needed for initialization at driver init and suspend |
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h index 0a79a46d5805..6a28bac71128 100644 --- a/drivers/gpu/drm/i915/intel_display.h +++ b/drivers/gpu/drm/i915/intel_display.h | |||
| @@ -329,11 +329,11 @@ struct intel_link_m_n { | |||
| 329 | 329 | ||
| 330 | #define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask) \ | 330 | #define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask) \ |
| 331 | for_each_power_well(__dev_priv, __power_well) \ | 331 | for_each_power_well(__dev_priv, __power_well) \ |
| 332 | for_each_if((__power_well)->domains & (__domain_mask)) | 332 | for_each_if((__power_well)->desc->domains & (__domain_mask)) |
| 333 | 333 | ||
| 334 | #define for_each_power_domain_well_rev(__dev_priv, __power_well, __domain_mask) \ | 334 | #define for_each_power_domain_well_rev(__dev_priv, __power_well, __domain_mask) \ |
| 335 | for_each_power_well_rev(__dev_priv, __power_well) \ | 335 | for_each_power_well_rev(__dev_priv, __power_well) \ |
| 336 | for_each_if((__power_well)->domains & (__domain_mask)) | 336 | for_each_if((__power_well)->desc->domains & (__domain_mask)) |
| 337 | 337 | ||
| 338 | #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \ | 338 | #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \ |
| 339 | for ((__i) = 0; \ | 339 | for ((__i) = 0; \ |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3576ab5735b1..0601abb8c71f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -1948,6 +1948,7 @@ int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state); | |||
| 1948 | 1948 | ||
| 1949 | /* intel_runtime_pm.c */ | 1949 | /* intel_runtime_pm.c */ |
| 1950 | int intel_power_domains_init(struct drm_i915_private *); | 1950 | int intel_power_domains_init(struct drm_i915_private *); |
| 1951 | void intel_power_domains_cleanup(struct drm_i915_private *dev_priv); | ||
| 1951 | void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume); | 1952 | void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume); |
| 1952 | void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv); | 1953 | void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv); |
| 1953 | void intel_power_domains_suspend(struct drm_i915_private *dev_priv); | 1954 | void intel_power_domains_suspend(struct drm_i915_private *dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 0cc6a861bcf8..26e48fc95543 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c | |||
| @@ -57,9 +57,9 @@ static bool hdcp_key_loadable(struct drm_i915_private *dev_priv) | |||
| 57 | 57 | ||
| 58 | /* PG1 (power well #1) needs to be enabled */ | 58 | /* PG1 (power well #1) needs to be enabled */ |
| 59 | for_each_power_well(dev_priv, power_well) { | 59 | for_each_power_well(dev_priv, power_well) { |
| 60 | if (power_well->id == id) { | 60 | if (power_well->desc->id == id) { |
| 61 | enabled = power_well->ops->is_enabled(dev_priv, | 61 | enabled = power_well->desc->ops->is_enabled(dev_priv, |
| 62 | power_well); | 62 | power_well); |
| 63 | break; | 63 | break; |
| 64 | } | 64 | } |
| 65 | } | 65 | } |
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 | } |
