Michal Wajdeczko | 09a28bd | 2017-12-21 21:57:30 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright © 2006-2017 Intel Corporation |
| 3 | * |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 | * copy of this software and associated documentation files (the "Software"), |
| 6 | * to deal in the Software without restriction, including without limitation |
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 8 | * and/or sell copies of the Software, and to permit persons to whom the |
| 9 | * Software is furnished to do so, subject to the following conditions: |
| 10 | * |
| 11 | * The above copyright notice and this permission notice (including the next |
| 12 | * paragraph) shall be included in all copies or substantial portions of the |
| 13 | * Software. |
| 14 | * |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 21 | * IN THE SOFTWARE. |
| 22 | * |
| 23 | */ |
| 24 | |
| 25 | #ifndef _INTEL_DISPLAY_H_ |
| 26 | #define _INTEL_DISPLAY_H_ |
| 27 | |
| 28 | enum pipe { |
| 29 | INVALID_PIPE = -1, |
| 30 | |
| 31 | PIPE_A = 0, |
| 32 | PIPE_B, |
| 33 | PIPE_C, |
| 34 | _PIPE_EDP, |
| 35 | |
| 36 | I915_MAX_PIPES = _PIPE_EDP |
| 37 | }; |
| 38 | |
| 39 | #define pipe_name(p) ((p) + 'A') |
| 40 | |
| 41 | enum transcoder { |
| 42 | TRANSCODER_A = 0, |
| 43 | TRANSCODER_B, |
| 44 | TRANSCODER_C, |
| 45 | TRANSCODER_EDP, |
| 46 | TRANSCODER_DSI_A, |
| 47 | TRANSCODER_DSI_C, |
| 48 | |
| 49 | I915_MAX_TRANSCODERS |
| 50 | }; |
| 51 | |
| 52 | static inline const char *transcoder_name(enum transcoder transcoder) |
| 53 | { |
| 54 | switch (transcoder) { |
| 55 | case TRANSCODER_A: |
| 56 | return "A"; |
| 57 | case TRANSCODER_B: |
| 58 | return "B"; |
| 59 | case TRANSCODER_C: |
| 60 | return "C"; |
| 61 | case TRANSCODER_EDP: |
| 62 | return "EDP"; |
| 63 | case TRANSCODER_DSI_A: |
| 64 | return "DSI A"; |
| 65 | case TRANSCODER_DSI_C: |
| 66 | return "DSI C"; |
| 67 | default: |
| 68 | return "<invalid>"; |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | static inline bool transcoder_is_dsi(enum transcoder transcoder) |
| 73 | { |
| 74 | return transcoder == TRANSCODER_DSI_A || transcoder == TRANSCODER_DSI_C; |
| 75 | } |
| 76 | |
| 77 | /* |
| 78 | * Global legacy plane identifier. Valid only for primary/sprite |
| 79 | * planes on pre-g4x, and only for primary planes on g4x-bdw. |
| 80 | */ |
| 81 | enum i9xx_plane_id { |
| 82 | PLANE_A, |
| 83 | PLANE_B, |
| 84 | PLANE_C, |
| 85 | }; |
| 86 | |
| 87 | #define plane_name(p) ((p) + 'A') |
| 88 | #define sprite_name(p, s) ((p) * INTEL_INFO(dev_priv)->num_sprites[(p)] + (s) + 'A') |
| 89 | |
| 90 | /* |
| 91 | * Per-pipe plane identifier. |
| 92 | * I915_MAX_PLANES in the enum below is the maximum (across all platforms) |
| 93 | * number of planes per CRTC. Not all platforms really have this many planes, |
| 94 | * which means some arrays of size I915_MAX_PLANES may have unused entries |
| 95 | * between the topmost sprite plane and the cursor plane. |
| 96 | * |
| 97 | * This is expected to be passed to various register macros |
| 98 | * (eg. PLANE_CTL(), PS_PLANE_SEL(), etc.) so adjust with care. |
| 99 | */ |
| 100 | enum plane_id { |
| 101 | PLANE_PRIMARY, |
| 102 | PLANE_SPRITE0, |
| 103 | PLANE_SPRITE1, |
| 104 | PLANE_SPRITE2, |
| 105 | PLANE_CURSOR, |
| 106 | |
| 107 | I915_MAX_PLANES, |
| 108 | }; |
| 109 | |
| 110 | #define for_each_plane_id_on_crtc(__crtc, __p) \ |
| 111 | for ((__p) = PLANE_PRIMARY; (__p) < I915_MAX_PLANES; (__p)++) \ |
| 112 | for_each_if((__crtc)->plane_ids_mask & BIT(__p)) |
| 113 | |
| 114 | enum port { |
| 115 | PORT_NONE = -1, |
| 116 | |
| 117 | PORT_A = 0, |
| 118 | PORT_B, |
| 119 | PORT_C, |
| 120 | PORT_D, |
| 121 | PORT_E, |
Rodrigo Vivi | 841b5ed7 | 2018-01-11 16:00:03 -0200 | [diff] [blame] | 122 | PORT_F, |
Michal Wajdeczko | 09a28bd | 2017-12-21 21:57:30 +0000 | [diff] [blame] | 123 | |
| 124 | I915_MAX_PORTS |
| 125 | }; |
| 126 | |
| 127 | #define port_name(p) ((p) + 'A') |
| 128 | |
| 129 | enum dpio_channel { |
| 130 | DPIO_CH0, |
| 131 | DPIO_CH1 |
| 132 | }; |
| 133 | |
| 134 | enum dpio_phy { |
| 135 | DPIO_PHY0, |
| 136 | DPIO_PHY1, |
| 137 | DPIO_PHY2, |
| 138 | }; |
| 139 | |
| 140 | #define I915_NUM_PHYS_VLV 2 |
| 141 | |
Ville Syrjälä | bdabdb6 | 2018-02-22 20:10:30 +0200 | [diff] [blame] | 142 | enum aux_ch { |
| 143 | AUX_CH_A, |
| 144 | AUX_CH_B, |
| 145 | AUX_CH_C, |
| 146 | AUX_CH_D, |
| 147 | _AUX_CH_E, /* does not exist */ |
| 148 | AUX_CH_F, |
| 149 | }; |
| 150 | |
| 151 | #define aux_ch_name(a) ((a) + 'A') |
| 152 | |
Michal Wajdeczko | 09a28bd | 2017-12-21 21:57:30 +0000 | [diff] [blame] | 153 | enum intel_display_power_domain { |
| 154 | POWER_DOMAIN_PIPE_A, |
| 155 | POWER_DOMAIN_PIPE_B, |
| 156 | POWER_DOMAIN_PIPE_C, |
| 157 | POWER_DOMAIN_PIPE_A_PANEL_FITTER, |
| 158 | POWER_DOMAIN_PIPE_B_PANEL_FITTER, |
| 159 | POWER_DOMAIN_PIPE_C_PANEL_FITTER, |
| 160 | POWER_DOMAIN_TRANSCODER_A, |
| 161 | POWER_DOMAIN_TRANSCODER_B, |
| 162 | POWER_DOMAIN_TRANSCODER_C, |
| 163 | POWER_DOMAIN_TRANSCODER_EDP, |
| 164 | POWER_DOMAIN_TRANSCODER_DSI_A, |
| 165 | POWER_DOMAIN_TRANSCODER_DSI_C, |
| 166 | POWER_DOMAIN_PORT_DDI_A_LANES, |
| 167 | POWER_DOMAIN_PORT_DDI_B_LANES, |
| 168 | POWER_DOMAIN_PORT_DDI_C_LANES, |
| 169 | POWER_DOMAIN_PORT_DDI_D_LANES, |
| 170 | POWER_DOMAIN_PORT_DDI_E_LANES, |
Rodrigo Vivi | 9787e83 | 2018-01-29 15:22:22 -0800 | [diff] [blame] | 171 | POWER_DOMAIN_PORT_DDI_F_LANES, |
Michal Wajdeczko | 09a28bd | 2017-12-21 21:57:30 +0000 | [diff] [blame] | 172 | POWER_DOMAIN_PORT_DDI_A_IO, |
| 173 | POWER_DOMAIN_PORT_DDI_B_IO, |
| 174 | POWER_DOMAIN_PORT_DDI_C_IO, |
| 175 | POWER_DOMAIN_PORT_DDI_D_IO, |
| 176 | POWER_DOMAIN_PORT_DDI_E_IO, |
Rodrigo Vivi | 9787e83 | 2018-01-29 15:22:22 -0800 | [diff] [blame] | 177 | POWER_DOMAIN_PORT_DDI_F_IO, |
Michal Wajdeczko | 09a28bd | 2017-12-21 21:57:30 +0000 | [diff] [blame] | 178 | POWER_DOMAIN_PORT_DSI, |
| 179 | POWER_DOMAIN_PORT_CRT, |
| 180 | POWER_DOMAIN_PORT_OTHER, |
| 181 | POWER_DOMAIN_VGA, |
| 182 | POWER_DOMAIN_AUDIO, |
| 183 | POWER_DOMAIN_PLLS, |
| 184 | POWER_DOMAIN_AUX_A, |
| 185 | POWER_DOMAIN_AUX_B, |
| 186 | POWER_DOMAIN_AUX_C, |
| 187 | POWER_DOMAIN_AUX_D, |
Rodrigo Vivi | a324fca | 2018-01-29 15:22:15 -0800 | [diff] [blame] | 188 | POWER_DOMAIN_AUX_F, |
Dhinakaran Pandiyan | b891d5e | 2018-02-23 14:15:15 -0800 | [diff] [blame] | 189 | POWER_DOMAIN_AUX_IO_A, |
Michal Wajdeczko | 09a28bd | 2017-12-21 21:57:30 +0000 | [diff] [blame] | 190 | POWER_DOMAIN_GMBUS, |
| 191 | POWER_DOMAIN_MODESET, |
| 192 | POWER_DOMAIN_GT_IRQ, |
| 193 | POWER_DOMAIN_INIT, |
| 194 | |
| 195 | POWER_DOMAIN_NUM, |
| 196 | }; |
| 197 | |
| 198 | #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A) |
| 199 | #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \ |
| 200 | ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER) |
| 201 | #define POWER_DOMAIN_TRANSCODER(tran) \ |
| 202 | ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \ |
| 203 | (tran) + POWER_DOMAIN_TRANSCODER_A) |
| 204 | |
| 205 | /* Used by dp and fdi links */ |
| 206 | struct intel_link_m_n { |
| 207 | u32 tu; |
| 208 | u32 gmch_m; |
| 209 | u32 gmch_n; |
| 210 | u32 link_m; |
| 211 | u32 link_n; |
| 212 | }; |
| 213 | |
| 214 | #define for_each_pipe(__dev_priv, __p) \ |
| 215 | for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++) |
| 216 | |
| 217 | #define for_each_pipe_masked(__dev_priv, __p, __mask) \ |
| 218 | for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++) \ |
| 219 | for_each_if((__mask) & BIT(__p)) |
| 220 | |
| 221 | #define for_each_universal_plane(__dev_priv, __pipe, __p) \ |
| 222 | for ((__p) = 0; \ |
| 223 | (__p) < INTEL_INFO(__dev_priv)->num_sprites[(__pipe)] + 1; \ |
| 224 | (__p)++) |
| 225 | |
| 226 | #define for_each_sprite(__dev_priv, __p, __s) \ |
| 227 | for ((__s) = 0; \ |
| 228 | (__s) < INTEL_INFO(__dev_priv)->num_sprites[(__p)]; \ |
| 229 | (__s)++) |
| 230 | |
| 231 | #define for_each_port_masked(__port, __ports_mask) \ |
| 232 | for ((__port) = PORT_A; (__port) < I915_MAX_PORTS; (__port)++) \ |
| 233 | for_each_if((__ports_mask) & BIT(__port)) |
| 234 | |
| 235 | #define for_each_crtc(dev, crtc) \ |
| 236 | list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head) |
| 237 | |
| 238 | #define for_each_intel_plane(dev, intel_plane) \ |
| 239 | list_for_each_entry(intel_plane, \ |
| 240 | &(dev)->mode_config.plane_list, \ |
| 241 | base.head) |
| 242 | |
| 243 | #define for_each_intel_plane_mask(dev, intel_plane, plane_mask) \ |
| 244 | list_for_each_entry(intel_plane, \ |
| 245 | &(dev)->mode_config.plane_list, \ |
| 246 | base.head) \ |
| 247 | for_each_if((plane_mask) & \ |
| 248 | BIT(drm_plane_index(&intel_plane->base))) |
| 249 | |
| 250 | #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) \ |
| 251 | list_for_each_entry(intel_plane, \ |
| 252 | &(dev)->mode_config.plane_list, \ |
| 253 | base.head) \ |
| 254 | for_each_if((intel_plane)->pipe == (intel_crtc)->pipe) |
| 255 | |
| 256 | #define for_each_intel_crtc(dev, intel_crtc) \ |
| 257 | list_for_each_entry(intel_crtc, \ |
| 258 | &(dev)->mode_config.crtc_list, \ |
| 259 | base.head) |
| 260 | |
| 261 | #define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \ |
| 262 | list_for_each_entry(intel_crtc, \ |
| 263 | &(dev)->mode_config.crtc_list, \ |
| 264 | base.head) \ |
| 265 | for_each_if((crtc_mask) & BIT(drm_crtc_index(&intel_crtc->base))) |
| 266 | |
| 267 | #define for_each_intel_encoder(dev, intel_encoder) \ |
| 268 | list_for_each_entry(intel_encoder, \ |
| 269 | &(dev)->mode_config.encoder_list, \ |
| 270 | base.head) |
| 271 | |
| 272 | #define for_each_intel_connector_iter(intel_connector, iter) \ |
| 273 | while ((intel_connector = to_intel_connector(drm_connector_list_iter_next(iter)))) |
| 274 | |
| 275 | #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ |
| 276 | list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ |
| 277 | for_each_if((intel_encoder)->base.crtc == (__crtc)) |
| 278 | |
| 279 | #define for_each_connector_on_encoder(dev, __encoder, intel_connector) \ |
| 280 | list_for_each_entry((intel_connector), &(dev)->mode_config.connector_list, base.head) \ |
| 281 | for_each_if((intel_connector)->base.encoder == (__encoder)) |
| 282 | |
| 283 | #define for_each_power_domain(domain, mask) \ |
| 284 | for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \ |
| 285 | for_each_if(BIT_ULL(domain) & (mask)) |
| 286 | |
| 287 | #define for_each_power_well(__dev_priv, __power_well) \ |
| 288 | for ((__power_well) = (__dev_priv)->power_domains.power_wells; \ |
| 289 | (__power_well) - (__dev_priv)->power_domains.power_wells < \ |
| 290 | (__dev_priv)->power_domains.power_well_count; \ |
| 291 | (__power_well)++) |
| 292 | |
| 293 | #define for_each_power_well_rev(__dev_priv, __power_well) \ |
| 294 | for ((__power_well) = (__dev_priv)->power_domains.power_wells + \ |
| 295 | (__dev_priv)->power_domains.power_well_count - 1; \ |
| 296 | (__power_well) - (__dev_priv)->power_domains.power_wells >= 0; \ |
| 297 | (__power_well)--) |
| 298 | |
| 299 | #define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask) \ |
| 300 | for_each_power_well(__dev_priv, __power_well) \ |
| 301 | for_each_if((__power_well)->domains & (__domain_mask)) |
| 302 | |
| 303 | #define for_each_power_domain_well_rev(__dev_priv, __power_well, __domain_mask) \ |
| 304 | for_each_power_well_rev(__dev_priv, __power_well) \ |
| 305 | for_each_if((__power_well)->domains & (__domain_mask)) |
| 306 | |
| 307 | #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \ |
| 308 | for ((__i) = 0; \ |
| 309 | (__i) < (__state)->base.dev->mode_config.num_total_plane && \ |
| 310 | ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \ |
| 311 | (new_plane_state) = to_intel_plane_state((__state)->base.planes[__i].new_state), 1); \ |
| 312 | (__i)++) \ |
| 313 | for_each_if(plane) |
| 314 | |
| 315 | #define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state, __i) \ |
| 316 | for ((__i) = 0; \ |
| 317 | (__i) < (__state)->base.dev->mode_config.num_crtc && \ |
| 318 | ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \ |
| 319 | (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \ |
| 320 | (__i)++) \ |
| 321 | for_each_if(crtc) |
| 322 | |
| 323 | #define for_each_oldnew_intel_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \ |
| 324 | for ((__i) = 0; \ |
| 325 | (__i) < (__state)->base.dev->mode_config.num_total_plane && \ |
| 326 | ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \ |
| 327 | (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), \ |
| 328 | (new_plane_state) = to_intel_plane_state((__state)->base.planes[__i].new_state), 1); \ |
| 329 | (__i)++) \ |
| 330 | for_each_if(plane) |
| 331 | |
| 332 | void intel_link_compute_m_n(int bpp, int nlanes, |
| 333 | int pixel_clock, int link_clock, |
| 334 | struct intel_link_m_n *m_n, |
| 335 | bool reduce_m_n); |
| 336 | |
| 337 | #endif |