1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright © 2019 Intel Corporation 4 */ 5 6 #ifndef __INTEL_DISPLAY_POWER_H__ 7 #define __INTEL_DISPLAY_POWER_H__ 8 9 #include "intel_runtime_pm.h" 10 #include "i915_reg.h" 11 12 enum dpio_channel; 13 enum dpio_phy; 14 struct drm_i915_private; 15 struct i915_power_well; 16 struct intel_encoder; 17 18 enum intel_display_power_domain { 19 POWER_DOMAIN_DISPLAY_CORE, 20 POWER_DOMAIN_PIPE_A, 21 POWER_DOMAIN_PIPE_B, 22 POWER_DOMAIN_PIPE_C, 23 POWER_DOMAIN_PIPE_D, 24 POWER_DOMAIN_PIPE_A_PANEL_FITTER, 25 POWER_DOMAIN_PIPE_B_PANEL_FITTER, 26 POWER_DOMAIN_PIPE_C_PANEL_FITTER, 27 POWER_DOMAIN_PIPE_D_PANEL_FITTER, 28 POWER_DOMAIN_TRANSCODER_A, 29 POWER_DOMAIN_TRANSCODER_B, 30 POWER_DOMAIN_TRANSCODER_C, 31 POWER_DOMAIN_TRANSCODER_D, 32 POWER_DOMAIN_TRANSCODER_EDP, 33 /* VDSC/joining for eDP/DSI transcoder (ICL) or pipe A (TGL) */ 34 POWER_DOMAIN_TRANSCODER_VDSC_PW2, 35 POWER_DOMAIN_TRANSCODER_DSI_A, 36 POWER_DOMAIN_TRANSCODER_DSI_C, 37 POWER_DOMAIN_PORT_DDI_A_LANES, 38 POWER_DOMAIN_PORT_DDI_B_LANES, 39 POWER_DOMAIN_PORT_DDI_C_LANES, 40 POWER_DOMAIN_PORT_DDI_D_LANES, 41 POWER_DOMAIN_PORT_DDI_E_LANES, 42 POWER_DOMAIN_PORT_DDI_F_LANES, 43 POWER_DOMAIN_PORT_DDI_G_LANES, 44 POWER_DOMAIN_PORT_DDI_H_LANES, 45 POWER_DOMAIN_PORT_DDI_I_LANES, 46 47 POWER_DOMAIN_PORT_DDI_LANES_TC1 = POWER_DOMAIN_PORT_DDI_D_LANES, /* tgl+ */ 48 POWER_DOMAIN_PORT_DDI_LANES_TC2, 49 POWER_DOMAIN_PORT_DDI_LANES_TC3, 50 POWER_DOMAIN_PORT_DDI_LANES_TC4, 51 POWER_DOMAIN_PORT_DDI_LANES_TC5, 52 POWER_DOMAIN_PORT_DDI_LANES_TC6, 53 54 POWER_DOMAIN_PORT_DDI_LANES_D_XELPD = POWER_DOMAIN_PORT_DDI_LANES_TC5, /* XELPD */ 55 POWER_DOMAIN_PORT_DDI_LANES_E_XELPD, 56 57 POWER_DOMAIN_PORT_DDI_A_IO, 58 POWER_DOMAIN_PORT_DDI_B_IO, 59 POWER_DOMAIN_PORT_DDI_C_IO, 60 POWER_DOMAIN_PORT_DDI_D_IO, 61 POWER_DOMAIN_PORT_DDI_E_IO, 62 POWER_DOMAIN_PORT_DDI_F_IO, 63 POWER_DOMAIN_PORT_DDI_G_IO, 64 POWER_DOMAIN_PORT_DDI_H_IO, 65 POWER_DOMAIN_PORT_DDI_I_IO, 66 67 POWER_DOMAIN_PORT_DDI_IO_TC1 = POWER_DOMAIN_PORT_DDI_D_IO, /* tgl+ */ 68 POWER_DOMAIN_PORT_DDI_IO_TC2, 69 POWER_DOMAIN_PORT_DDI_IO_TC3, 70 POWER_DOMAIN_PORT_DDI_IO_TC4, 71 POWER_DOMAIN_PORT_DDI_IO_TC5, 72 POWER_DOMAIN_PORT_DDI_IO_TC6, 73 74 POWER_DOMAIN_PORT_DDI_IO_D_XELPD = POWER_DOMAIN_PORT_DDI_IO_TC5, /* XELPD */ 75 POWER_DOMAIN_PORT_DDI_IO_E_XELPD, 76 77 POWER_DOMAIN_PORT_DSI, 78 POWER_DOMAIN_PORT_CRT, 79 POWER_DOMAIN_PORT_OTHER, 80 POWER_DOMAIN_VGA, 81 POWER_DOMAIN_AUDIO_MMIO, 82 POWER_DOMAIN_AUDIO_PLAYBACK, 83 POWER_DOMAIN_AUX_A, 84 POWER_DOMAIN_AUX_B, 85 POWER_DOMAIN_AUX_C, 86 POWER_DOMAIN_AUX_D, 87 POWER_DOMAIN_AUX_E, 88 POWER_DOMAIN_AUX_F, 89 POWER_DOMAIN_AUX_G, 90 POWER_DOMAIN_AUX_H, 91 POWER_DOMAIN_AUX_I, 92 93 POWER_DOMAIN_AUX_USBC1 = POWER_DOMAIN_AUX_D, /* tgl+ */ 94 POWER_DOMAIN_AUX_USBC2, 95 POWER_DOMAIN_AUX_USBC3, 96 POWER_DOMAIN_AUX_USBC4, 97 POWER_DOMAIN_AUX_USBC5, 98 POWER_DOMAIN_AUX_USBC6, 99 100 POWER_DOMAIN_AUX_D_XELPD = POWER_DOMAIN_AUX_USBC5, /* XELPD */ 101 POWER_DOMAIN_AUX_E_XELPD, 102 103 POWER_DOMAIN_AUX_IO_A, 104 POWER_DOMAIN_AUX_C_TBT, 105 POWER_DOMAIN_AUX_D_TBT, 106 POWER_DOMAIN_AUX_E_TBT, 107 POWER_DOMAIN_AUX_F_TBT, 108 POWER_DOMAIN_AUX_G_TBT, 109 POWER_DOMAIN_AUX_H_TBT, 110 POWER_DOMAIN_AUX_I_TBT, 111 112 POWER_DOMAIN_AUX_TBT1 = POWER_DOMAIN_AUX_D_TBT, /* tgl+ */ 113 POWER_DOMAIN_AUX_TBT2, 114 POWER_DOMAIN_AUX_TBT3, 115 POWER_DOMAIN_AUX_TBT4, 116 POWER_DOMAIN_AUX_TBT5, 117 POWER_DOMAIN_AUX_TBT6, 118 119 POWER_DOMAIN_GMBUS, 120 POWER_DOMAIN_MODESET, 121 POWER_DOMAIN_GT_IRQ, 122 POWER_DOMAIN_DC_OFF, 123 POWER_DOMAIN_TC_COLD_OFF, 124 POWER_DOMAIN_INIT, 125 126 POWER_DOMAIN_NUM, 127 }; 128 129 /* 130 * i915_power_well_id: 131 * 132 * IDs used to look up power wells. Power wells accessed directly bypassing 133 * the power domains framework must be assigned a unique ID. The rest of power 134 * wells must be assigned DISP_PW_ID_NONE. 135 */ 136 enum i915_power_well_id { 137 DISP_PW_ID_NONE, 138 139 VLV_DISP_PW_DISP2D, 140 BXT_DISP_PW_DPIO_CMN_A, 141 VLV_DISP_PW_DPIO_CMN_BC, 142 GLK_DISP_PW_DPIO_CMN_C, 143 CHV_DISP_PW_DPIO_CMN_D, 144 HSW_DISP_PW_GLOBAL, 145 SKL_DISP_PW_MISC_IO, 146 SKL_DISP_PW_1, 147 SKL_DISP_PW_2, 148 ICL_DISP_PW_3, 149 SKL_DISP_DC_OFF, 150 TGL_DISP_PW_TC_COLD_OFF, 151 }; 152 153 #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A) 154 #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \ 155 ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER) 156 #define POWER_DOMAIN_TRANSCODER(tran) \ 157 ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \ 158 (tran) + POWER_DOMAIN_TRANSCODER_A) 159 160 struct i915_power_domains { 161 /* 162 * Power wells needed for initialization at driver init and suspend 163 * time are on. They are kept on until after the first modeset. 164 */ 165 bool initializing; 166 bool display_core_suspended; 167 int power_well_count; 168 169 intel_wakeref_t init_wakeref; 170 intel_wakeref_t disable_wakeref; 171 172 struct mutex lock; 173 int domain_use_count[POWER_DOMAIN_NUM]; 174 175 struct delayed_work async_put_work; 176 intel_wakeref_t async_put_wakeref; 177 u64 async_put_domains[2]; 178 179 struct i915_power_well *power_wells; 180 }; 181 182 struct intel_display_power_domain_set { 183 u64 mask; 184 #ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM 185 intel_wakeref_t wakerefs[POWER_DOMAIN_NUM]; 186 #endif 187 }; 188 189 #define for_each_power_domain(domain, mask) \ 190 for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \ 191 for_each_if(BIT_ULL(domain) & (mask)) 192 193 #define for_each_power_well(__dev_priv, __power_well) \ 194 for ((__power_well) = (__dev_priv)->power_domains.power_wells; \ 195 (__power_well) - (__dev_priv)->power_domains.power_wells < \ 196 (__dev_priv)->power_domains.power_well_count; \ 197 (__power_well)++) 198 199 #define for_each_power_well_reverse(__dev_priv, __power_well) \ 200 for ((__power_well) = (__dev_priv)->power_domains.power_wells + \ 201 (__dev_priv)->power_domains.power_well_count - 1; \ 202 (__power_well) - (__dev_priv)->power_domains.power_wells >= 0; \ 203 (__power_well)--) 204 205 #define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask) \ 206 for_each_power_well(__dev_priv, __power_well) \ 207 for_each_if((__power_well)->desc->domains & (__domain_mask)) 208 209 #define for_each_power_domain_well_reverse(__dev_priv, __power_well, __domain_mask) \ 210 for_each_power_well_reverse(__dev_priv, __power_well) \ 211 for_each_if((__power_well)->desc->domains & (__domain_mask)) 212 213 int intel_power_domains_init(struct drm_i915_private *dev_priv); 214 void intel_power_domains_cleanup(struct drm_i915_private *dev_priv); 215 void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume); 216 void intel_power_domains_driver_remove(struct drm_i915_private *dev_priv); 217 void intel_power_domains_enable(struct drm_i915_private *dev_priv); 218 void intel_power_domains_disable(struct drm_i915_private *dev_priv); 219 void intel_power_domains_suspend(struct drm_i915_private *dev_priv, 220 enum i915_drm_suspend_mode); 221 void intel_power_domains_resume(struct drm_i915_private *dev_priv); 222 223 void intel_display_power_suspend_late(struct drm_i915_private *i915); 224 void intel_display_power_resume_early(struct drm_i915_private *i915); 225 void intel_display_power_suspend(struct drm_i915_private *i915); 226 void intel_display_power_resume(struct drm_i915_private *i915); 227 void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv, 228 u32 state); 229 230 const char * 231 intel_display_power_domain_str(enum intel_display_power_domain domain); 232 233 bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, 234 enum intel_display_power_domain domain); 235 bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, 236 enum i915_power_well_id power_well_id); 237 bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, 238 enum intel_display_power_domain domain); 239 intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, 240 enum intel_display_power_domain domain); 241 intel_wakeref_t 242 intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, 243 enum intel_display_power_domain domain); 244 void __intel_display_power_put_async(struct drm_i915_private *i915, 245 enum intel_display_power_domain domain, 246 intel_wakeref_t wakeref); 247 void intel_display_power_flush_work(struct drm_i915_private *i915); 248 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) 249 void intel_display_power_put(struct drm_i915_private *dev_priv, 250 enum intel_display_power_domain domain, 251 intel_wakeref_t wakeref); 252 static inline void 253 intel_display_power_put_async(struct drm_i915_private *i915, 254 enum intel_display_power_domain domain, 255 intel_wakeref_t wakeref) 256 { 257 __intel_display_power_put_async(i915, domain, wakeref); 258 } 259 #else 260 void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, 261 enum intel_display_power_domain domain); 262 263 static inline void 264 intel_display_power_put(struct drm_i915_private *i915, 265 enum intel_display_power_domain domain, 266 intel_wakeref_t wakeref) 267 { 268 intel_display_power_put_unchecked(i915, domain); 269 } 270 271 static inline void 272 intel_display_power_put_async(struct drm_i915_private *i915, 273 enum intel_display_power_domain domain, 274 intel_wakeref_t wakeref) 275 { 276 __intel_display_power_put_async(i915, domain, -1); 277 } 278 #endif 279 280 void 281 intel_display_power_get_in_set(struct drm_i915_private *i915, 282 struct intel_display_power_domain_set *power_domain_set, 283 enum intel_display_power_domain domain); 284 285 bool 286 intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, 287 struct intel_display_power_domain_set *power_domain_set, 288 enum intel_display_power_domain domain); 289 290 void 291 intel_display_power_put_mask_in_set(struct drm_i915_private *i915, 292 struct intel_display_power_domain_set *power_domain_set, 293 u64 mask); 294 295 static inline void 296 intel_display_power_put_all_in_set(struct drm_i915_private *i915, 297 struct intel_display_power_domain_set *power_domain_set) 298 { 299 intel_display_power_put_mask_in_set(i915, power_domain_set, power_domain_set->mask); 300 } 301 302 void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m); 303 304 /* 305 * FIXME: We should probably switch this to a 0-based scheme to be consistent 306 * with how we now name/number DBUF_CTL instances. 307 */ 308 enum dbuf_slice { 309 DBUF_S1, 310 DBUF_S2, 311 DBUF_S3, 312 DBUF_S4, 313 I915_MAX_DBUF_SLICES 314 }; 315 316 void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, 317 u8 req_slices); 318 319 #define with_intel_display_power(i915, domain, wf) \ 320 for ((wf) = intel_display_power_get((i915), (domain)); (wf); \ 321 intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0) 322 323 #define with_intel_display_power_if_enabled(i915, domain, wf) \ 324 for ((wf) = intel_display_power_get_if_enabled((i915), (domain)); (wf); \ 325 intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0) 326 327 void chv_phy_powergate_lanes(struct intel_encoder *encoder, 328 bool override, unsigned int mask); 329 bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, 330 enum dpio_channel ch, bool override); 331 332 #endif /* __INTEL_DISPLAY_POWER_H__ */ 333