linux/drivers/gpu/drm/i915/display/intel_display_power.h
<<
>>
Prefs
   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_display.h"
  10#include "intel_runtime_pm.h"
  11#include "i915_reg.h"
  12
  13struct drm_i915_private;
  14struct intel_encoder;
  15
  16enum intel_display_power_domain {
  17        POWER_DOMAIN_DISPLAY_CORE,
  18        POWER_DOMAIN_PIPE_A,
  19        POWER_DOMAIN_PIPE_B,
  20        POWER_DOMAIN_PIPE_C,
  21        POWER_DOMAIN_PIPE_A_PANEL_FITTER,
  22        POWER_DOMAIN_PIPE_B_PANEL_FITTER,
  23        POWER_DOMAIN_PIPE_C_PANEL_FITTER,
  24        POWER_DOMAIN_TRANSCODER_A,
  25        POWER_DOMAIN_TRANSCODER_B,
  26        POWER_DOMAIN_TRANSCODER_C,
  27        POWER_DOMAIN_TRANSCODER_EDP,
  28        POWER_DOMAIN_TRANSCODER_EDP_VDSC,
  29        POWER_DOMAIN_TRANSCODER_DSI_A,
  30        POWER_DOMAIN_TRANSCODER_DSI_C,
  31        POWER_DOMAIN_PORT_DDI_A_LANES,
  32        POWER_DOMAIN_PORT_DDI_B_LANES,
  33        POWER_DOMAIN_PORT_DDI_C_LANES,
  34        POWER_DOMAIN_PORT_DDI_D_LANES,
  35        POWER_DOMAIN_PORT_DDI_E_LANES,
  36        POWER_DOMAIN_PORT_DDI_F_LANES,
  37        POWER_DOMAIN_PORT_DDI_A_IO,
  38        POWER_DOMAIN_PORT_DDI_B_IO,
  39        POWER_DOMAIN_PORT_DDI_C_IO,
  40        POWER_DOMAIN_PORT_DDI_D_IO,
  41        POWER_DOMAIN_PORT_DDI_E_IO,
  42        POWER_DOMAIN_PORT_DDI_F_IO,
  43        POWER_DOMAIN_PORT_DSI,
  44        POWER_DOMAIN_PORT_CRT,
  45        POWER_DOMAIN_PORT_OTHER,
  46        POWER_DOMAIN_VGA,
  47        POWER_DOMAIN_AUDIO,
  48        POWER_DOMAIN_AUX_A,
  49        POWER_DOMAIN_AUX_B,
  50        POWER_DOMAIN_AUX_C,
  51        POWER_DOMAIN_AUX_D,
  52        POWER_DOMAIN_AUX_E,
  53        POWER_DOMAIN_AUX_F,
  54        POWER_DOMAIN_AUX_IO_A,
  55        POWER_DOMAIN_AUX_TBT1,
  56        POWER_DOMAIN_AUX_TBT2,
  57        POWER_DOMAIN_AUX_TBT3,
  58        POWER_DOMAIN_AUX_TBT4,
  59        POWER_DOMAIN_GMBUS,
  60        POWER_DOMAIN_MODESET,
  61        POWER_DOMAIN_GT_IRQ,
  62        POWER_DOMAIN_INIT,
  63
  64        POWER_DOMAIN_NUM,
  65};
  66
  67#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
  68#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
  69                ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
  70#define POWER_DOMAIN_TRANSCODER(tran) \
  71        ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
  72         (tran) + POWER_DOMAIN_TRANSCODER_A)
  73
  74struct i915_power_well;
  75
  76struct i915_power_well_ops {
  77        /*
  78         * Synchronize the well's hw state to match the current sw state, for
  79         * example enable/disable it based on the current refcount. Called
  80         * during driver init and resume time, possibly after first calling
  81         * the enable/disable handlers.
  82         */
  83        void (*sync_hw)(struct drm_i915_private *dev_priv,
  84                        struct i915_power_well *power_well);
  85        /*
  86         * Enable the well and resources that depend on it (for example
  87         * interrupts located on the well). Called after the 0->1 refcount
  88         * transition.
  89         */
  90        void (*enable)(struct drm_i915_private *dev_priv,
  91                       struct i915_power_well *power_well);
  92        /*
  93         * Disable the well and resources that depend on it. Called after
  94         * the 1->0 refcount transition.
  95         */
  96        void (*disable)(struct drm_i915_private *dev_priv,
  97                        struct i915_power_well *power_well);
  98        /* Returns the hw enabled state. */
  99        bool (*is_enabled)(struct drm_i915_private *dev_priv,
 100                           struct i915_power_well *power_well);
 101};
 102
 103struct i915_power_well_regs {
 104        i915_reg_t bios;
 105        i915_reg_t driver;
 106        i915_reg_t kvmr;
 107        i915_reg_t debug;
 108};
 109
 110/* Power well structure for haswell */
 111struct i915_power_well_desc {
 112        const char *name;
 113        bool always_on;
 114        u64 domains;
 115        /* unique identifier for this power well */
 116        enum i915_power_well_id id;
 117        /*
 118         * Arbitraty data associated with this power well. Platform and power
 119         * well specific.
 120         */
 121        union {
 122                struct {
 123                        /*
 124                         * request/status flag index in the PUNIT power well
 125                         * control/status registers.
 126                         */
 127                        u8 idx;
 128                } vlv;
 129                struct {
 130                        enum dpio_phy phy;
 131                } bxt;
 132                struct {
 133                        const struct i915_power_well_regs *regs;
 134                        /*
 135                         * request/status flag index in the power well
 136                         * constrol/status registers.
 137                         */
 138                        u8 idx;
 139                        /* Mask of pipes whose IRQ logic is backed by the pw */
 140                        u8 irq_pipe_mask;
 141                        /* The pw is backing the VGA functionality */
 142                        bool has_vga:1;
 143                        bool has_fuses:1;
 144                        /*
 145                         * The pw is for an ICL+ TypeC PHY port in
 146                         * Thunderbolt mode.
 147                         */
 148                        bool is_tc_tbt:1;
 149                } hsw;
 150        };
 151        const struct i915_power_well_ops *ops;
 152};
 153
 154struct i915_power_well {
 155        const struct i915_power_well_desc *desc;
 156        /* power well enable/disable usage count */
 157        int count;
 158        /* cached hw enabled state */
 159        bool hw_enabled;
 160};
 161
 162struct i915_power_domains {
 163        /*
 164         * Power wells needed for initialization at driver init and suspend
 165         * time are on. They are kept on until after the first modeset.
 166         */
 167        bool initializing;
 168        bool display_core_suspended;
 169        int power_well_count;
 170
 171        intel_wakeref_t wakeref;
 172
 173        struct mutex lock;
 174        int domain_use_count[POWER_DOMAIN_NUM];
 175
 176        struct delayed_work async_put_work;
 177        intel_wakeref_t async_put_wakeref;
 178        u64 async_put_domains[2];
 179
 180        struct i915_power_well *power_wells;
 181};
 182
 183#define for_each_power_domain(domain, mask)                             \
 184        for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++)     \
 185                for_each_if(BIT_ULL(domain) & (mask))
 186
 187#define for_each_power_well(__dev_priv, __power_well)                           \
 188        for ((__power_well) = (__dev_priv)->power_domains.power_wells;  \
 189             (__power_well) - (__dev_priv)->power_domains.power_wells < \
 190                (__dev_priv)->power_domains.power_well_count;           \
 191             (__power_well)++)
 192
 193#define for_each_power_well_reverse(__dev_priv, __power_well)                   \
 194        for ((__power_well) = (__dev_priv)->power_domains.power_wells +         \
 195                              (__dev_priv)->power_domains.power_well_count - 1; \
 196             (__power_well) - (__dev_priv)->power_domains.power_wells >= 0;     \
 197             (__power_well)--)
 198
 199#define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask)     \
 200        for_each_power_well(__dev_priv, __power_well)                           \
 201                for_each_if((__power_well)->desc->domains & (__domain_mask))
 202
 203#define for_each_power_domain_well_reverse(__dev_priv, __power_well, __domain_mask) \
 204        for_each_power_well_reverse(__dev_priv, __power_well)                   \
 205                for_each_if((__power_well)->desc->domains & (__domain_mask))
 206
 207void skl_enable_dc6(struct drm_i915_private *dev_priv);
 208void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv);
 209void bxt_enable_dc9(struct drm_i915_private *dev_priv);
 210void bxt_disable_dc9(struct drm_i915_private *dev_priv);
 211void gen9_enable_dc5(struct drm_i915_private *dev_priv);
 212
 213int intel_power_domains_init(struct drm_i915_private *dev_priv);
 214void intel_power_domains_cleanup(struct drm_i915_private *dev_priv);
 215void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume);
 216void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv);
 217void icl_display_core_init(struct drm_i915_private *dev_priv, bool resume);
 218void icl_display_core_uninit(struct drm_i915_private *dev_priv);
 219void intel_power_domains_enable(struct drm_i915_private *dev_priv);
 220void intel_power_domains_disable(struct drm_i915_private *dev_priv);
 221void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
 222                                 enum i915_drm_suspend_mode);
 223void intel_power_domains_resume(struct drm_i915_private *dev_priv);
 224void hsw_enable_pc8(struct drm_i915_private *dev_priv);
 225void hsw_disable_pc8(struct drm_i915_private *dev_priv);
 226void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume);
 227void bxt_display_core_uninit(struct drm_i915_private *dev_priv);
 228
 229const char *
 230intel_display_power_domain_str(enum intel_display_power_domain domain);
 231
 232bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
 233                                    enum intel_display_power_domain domain);
 234bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
 235                                      enum intel_display_power_domain domain);
 236intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
 237                                        enum intel_display_power_domain domain);
 238intel_wakeref_t
 239intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
 240                                   enum intel_display_power_domain domain);
 241void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
 242                                       enum intel_display_power_domain domain);
 243void __intel_display_power_put_async(struct drm_i915_private *i915,
 244                                     enum intel_display_power_domain domain,
 245                                     intel_wakeref_t wakeref);
 246void intel_display_power_flush_work(struct drm_i915_private *i915);
 247#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
 248void intel_display_power_put(struct drm_i915_private *dev_priv,
 249                             enum intel_display_power_domain domain,
 250                             intel_wakeref_t wakeref);
 251static inline void
 252intel_display_power_put_async(struct drm_i915_private *i915,
 253                              enum intel_display_power_domain domain,
 254                              intel_wakeref_t wakeref)
 255{
 256        __intel_display_power_put_async(i915, domain, wakeref);
 257}
 258#else
 259static inline void
 260intel_display_power_put(struct drm_i915_private *i915,
 261                        enum intel_display_power_domain domain,
 262                        intel_wakeref_t wakeref)
 263{
 264        intel_display_power_put_unchecked(i915, domain);
 265}
 266
 267static inline void
 268intel_display_power_put_async(struct drm_i915_private *i915,
 269                              enum intel_display_power_domain domain,
 270                              intel_wakeref_t wakeref)
 271{
 272        __intel_display_power_put_async(i915, domain, -1);
 273}
 274#endif
 275
 276#define with_intel_display_power(i915, domain, wf) \
 277        for ((wf) = intel_display_power_get((i915), (domain)); (wf); \
 278             intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0)
 279
 280void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
 281                            u8 req_slices);
 282
 283void chv_phy_powergate_lanes(struct intel_encoder *encoder,
 284                             bool override, unsigned int mask);
 285bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
 286                          enum dpio_channel ch, bool override);
 287
 288#endif /* __INTEL_DISPLAY_POWER_H__ */
 289