/* * Copyright © 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include <drm/drm_atomic_helper.h> #include <drm/drm_damage_helper.h> #include <drm/drm_debugfs.h> #include "i915_drv.h" #include "i915_reg.h" #include "intel_alpm.h" #include "intel_atomic.h" #include "intel_crtc.h" #include "intel_cursor_regs.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" #include "intel_frontbuffer.h" #include "intel_hdmi.h" #include "intel_psr.h" #include "intel_psr_regs.h" #include "intel_snps_phy.h" #include "skl_universal_plane.h" /** * DOC: Panel Self Refresh (PSR/SRD) * * Since Haswell Display controller supports Panel Self-Refresh on display * panels witch have a remote frame buffer (RFB) implemented according to PSR * spec in eDP1.3. PSR feature allows the display to go to lower standby states * when system is idle but display is on as it eliminates display refresh * request to DDR memory completely as long as the frame buffer for that * display is unchanged. * * Panel Self Refresh must be supported by both Hardware (source) and * Panel (sink). * * PSR saves power by caching the framebuffer in the panel RFB, which allows us * to power down the link and memory controller. For DSI panels the same idea * is called "manual mode". * * The implementation uses the hardware-based PSR support which automatically * enters/exits self-refresh mode. The hardware takes care of sending the * required DP aux message and could even retrain the link (that part isn't * enabled yet though). The hardware also keeps track of any frontbuffer * changes to know when to exit self-refresh mode again. Unfortunately that * part doesn't work too well, hence why the i915 PSR support uses the * software frontbuffer tracking to make sure it doesn't miss a screen * update. For this integration intel_psr_invalidate() and intel_psr_flush() * get called by the frontbuffer tracking code. Note that because of locking * issues the self-refresh re-enable code is done from a work queue, which * must be correctly synchronized/cancelled when shutting down the pipe." * * DC3CO (DC3 clock off) * * On top of PSR2, GEN12 adds a intermediate power savings state that turns * clock off automatically during PSR2 idle state. * The smaller overhead of DC3co entry/exit vs. the overhead of PSR2 deep sleep * entry/exit allows the HW to enter a low-power state even when page flipping * periodically (for instance a 30fps video playback scenario). * * Every time a flips occurs PSR2 will get out of deep sleep state(if it was), * so DC3CO is enabled and tgl_dc3co_disable_work is schedule to run after 6 * frames, if no other flip occurs and the function above is executed, DC3CO is * disabled and PSR2 is configured to enter deep sleep, resetting again in case * of another flip. * Front buffer modifications do not trigger DC3CO activation on purpose as it * would bring a lot of complexity and most of the moderns systems will only * use page flips. */ /* * Description of PSR mask bits: * * EDP_PSR_DEBUG[16]/EDP_PSR_DEBUG_MASK_DISP_REG_WRITE (hsw-skl): * * When unmasked (nearly) all display register writes (eg. even * SWF) trigger a PSR exit. Some registers are excluded from this * and they have a more specific mask (described below). On icl+ * this bit no longer exists and is effectively always set. * * PIPE_MISC[21]/PIPE_MISC_PSR_MASK_PIPE_REG_WRITE (skl+): * * When unmasked (nearly) all pipe/plane register writes * trigger a PSR exit. Some plane registers are excluded from this * and they have a more specific mask (described below). * * CHICKEN_PIPESL_1[11]/SKL_PSR_MASK_PLANE_FLIP (skl+): * PIPE_MISC[23]/PIPE_MISC_PSR_MASK_PRIMARY_FLIP (bdw): * EDP_PSR_DEBUG[23]/EDP_PSR_DEBUG_MASK_PRIMARY_FLIP (hsw): * * When unmasked PRI_SURF/PLANE_SURF writes trigger a PSR exit. * SPR_SURF/CURBASE are not included in this and instead are * controlled by PIPE_MISC_PSR_MASK_PIPE_REG_WRITE (skl+) or * EDP_PSR_DEBUG_MASK_DISP_REG_WRITE (hsw/bdw). * * PIPE_MISC[22]/PIPE_MISC_PSR_MASK_SPRITE_ENABLE (bdw): * EDP_PSR_DEBUG[21]/EDP_PSR_DEBUG_MASK_SPRITE_ENABLE (hsw): * * When unmasked PSR is blocked as long as the sprite * plane is enabled. skl+ with their universal planes no * longer have a mask bit like this, and no plane being * enabledb blocks PSR. * * PIPE_MISC[21]/PIPE_MISC_PSR_MASK_CURSOR_MOVE (bdw): * EDP_PSR_DEBUG[20]/EDP_PSR_DEBUG_MASK_CURSOR_MOVE (hsw): * * When umasked CURPOS writes trigger a PSR exit. On skl+ * this doesn't exit but CURPOS is included in the * PIPE_MISC_PSR_MASK_PIPE_REG_WRITE mask. * * PIPE_MISC[20]/PIPE_MISC_PSR_MASK_VBLANK_VSYNC_INT (bdw+): * EDP_PSR_DEBUG[19]/EDP_PSR_DEBUG_MASK_VBLANK_VSYNC_INT (hsw): * * When unmasked PSR is blocked as long as vblank and/or vsync * interrupt is unmasked in IMR *and* enabled in IER. * * CHICKEN_TRANS[30]/SKL_UNMASK_VBL_TO_PIPE_IN_SRD (skl+): * CHICKEN_PAR1_1[15]/HSW_MASK_VBL_TO_PIPE_IN_SRD (hsw/bdw): * * Selectcs whether PSR exit generates an extra vblank before * the first frame is transmitted. Also note the opposite polarity * if the bit on hsw/bdw vs. skl+ (masked==generate the extra vblank, * unmasked==do not generate the extra vblank). * * With DC states enabled the extra vblank happens after link training, * with DC states disabled it happens immediately upuon PSR exit trigger. * No idea as of now why there is a difference. HSW/BDW (which don't * even have DMC) always generate it after link training. Go figure. * * Unfortunately CHICKEN_TRANS itself seems to be double buffered * and thus won't latch until the first vblank. So with DC states * enabled the register effctively uses the reset value during DC5 * exit+PSR exit sequence, and thus the bit does nothing until * latched by the vblank that it was trying to prevent from being * generated in the first place. So we should probably call this * one a chicken/egg bit instead on skl+. * * In standby mode (as opposed to link-off) this makes no difference * as the timing generator keeps running the whole time generating * normal periodic vblanks. * * WaPsrDPAMaskVBlankInSRD asks us to set the bit on hsw/bdw, * and doing so makes the behaviour match the skl+ reset value. * * CHICKEN_PIPESL_1[0]/BDW_UNMASK_VBL_TO_REGS_IN_SRD (bdw): * CHICKEN_PIPESL_1[15]/HSW_UNMASK_VBL_TO_REGS_IN_SRD (hsw): * * On BDW without this bit is no vblanks whatsoever are * generated after PSR exit. On HSW this has no apparant effect. * WaPsrDPRSUnmaskVBlankInSRD says to set this. * * The rest of the bits are more self-explanatory and/or * irrelevant for normal operation. * * Description of intel_crtc_state variables. has_psr, has_panel_replay and * has_sel_update: * * has_psr (alone): PSR1 * has_psr + has_sel_update: PSR2 * has_psr + has_panel_replay: Panel Replay * has_psr + has_panel_replay + has_sel_update: Panel Replay Selective Update * * Description of some intel_psr varibles. enabled, panel_replay_enabled, * sel_update_enabled * * enabled (alone): PSR1 * enabled + sel_update_enabled: PSR2 * enabled + panel_replay_enabled: Panel Replay * enabled + panel_replay_enabled + sel_update_enabled: Panel Replay SU */ #define CAN_PSR(intel_dp) … bool intel_encoder_can_psr(struct intel_encoder *encoder) { … } bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { … } static bool psr_global_enabled(struct intel_dp *intel_dp) { … } static bool psr2_global_enabled(struct intel_dp *intel_dp) { … } static bool psr2_su_region_et_global_enabled(struct intel_dp *intel_dp) { … } static bool panel_replay_global_enabled(struct intel_dp *intel_dp) { … } static u32 psr_irq_psr_error_bit_get(struct intel_dp *intel_dp) { … } static u32 psr_irq_post_exit_bit_get(struct intel_dp *intel_dp) { … } static u32 psr_irq_pre_entry_bit_get(struct intel_dp *intel_dp) { … } static u32 psr_irq_mask_get(struct intel_dp *intel_dp) { … } static i915_reg_t psr_ctl_reg(struct intel_display *display, enum transcoder cpu_transcoder) { … } static i915_reg_t psr_debug_reg(struct intel_display *display, enum transcoder cpu_transcoder) { … } static i915_reg_t psr_perf_cnt_reg(struct intel_display *display, enum transcoder cpu_transcoder) { … } static i915_reg_t psr_status_reg(struct intel_display *display, enum transcoder cpu_transcoder) { … } static i915_reg_t psr_imr_reg(struct intel_display *display, enum transcoder cpu_transcoder) { … } static i915_reg_t psr_iir_reg(struct intel_display *display, enum transcoder cpu_transcoder) { … } static i915_reg_t psr_aux_ctl_reg(struct intel_display *display, enum transcoder cpu_transcoder) { … } static i915_reg_t psr_aux_data_reg(struct intel_display *display, enum transcoder cpu_transcoder, int i) { … } static void psr_irq_control(struct intel_dp *intel_dp) { … } static void psr_event_print(struct intel_display *display, u32 val, bool sel_update_enabled) { … } void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir) { … } static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp) { … } static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp) { … } static unsigned int intel_dp_get_su_x_granularity_offset(struct intel_dp *intel_dp) { … } static unsigned int intel_dp_get_su_y_granularity_offset(struct intel_dp *intel_dp) { … } /* * Note: Bits related to granularity are same in panel replay and psr * registers. Rely on PSR definitions on these "common" bits. */ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp) { … } static void _panel_replay_init_dpcd(struct intel_dp *intel_dp) { … } static void _psr_init_dpcd(struct intel_dp *intel_dp) { … } void intel_psr_init_dpcd(struct intel_dp *intel_dp) { … } static void hsw_psr_setup_aux(struct intel_dp *intel_dp) { … } static bool psr2_su_region_et_valid(struct intel_dp *intel_dp, bool panel_replay) { … } static void _panel_replay_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { … } static void _psr_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { … } static void intel_psr_enable_sink_alpm(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { … } void intel_psr_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { … } static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) { … } static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) { … } static void hsw_activate_psr1(struct intel_dp *intel_dp) { … } static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) { … } static int psr2_block_count_lines(struct intel_dp *intel_dp) { … } static int psr2_block_count(struct intel_dp *intel_dp) { … } static u8 frames_before_su_entry(struct intel_dp *intel_dp) { … } static void dg2_activate_panel_replay(struct intel_dp *intel_dp) { … } static void hsw_activate_psr2(struct intel_dp *intel_dp) { … } static bool transcoder_has_psr2(struct intel_display *display, enum transcoder cpu_transcoder) { … } static u32 intel_get_frame_time_us(const struct intel_crtc_state *crtc_state) { … } static void psr2_program_idle_frames(struct intel_dp *intel_dp, u32 idle_frames) { … } static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp) { … } static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp) { … } static void tgl_dc3co_disable_work(struct work_struct *work) { … } static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp) { … } static bool dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static void tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static bool psr2_granularity_check(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp, const struct drm_display_mode *adjusted_mode) { … } static bool wake_lines_fit_into_vblank(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, bool aux_less) { … } static bool alpm_config_valid(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, bool aux_less) { … } static bool intel_psr2_config_valid(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static bool intel_sel_update_config_valid(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static bool _psr_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { … } static bool _panel_replay_compute_config(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { … } void intel_psr_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { … } void intel_psr_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { … } static void intel_psr_activate(struct intel_dp *intel_dp) { … } static u32 wa_16013835468_bit_get(struct intel_dp *intel_dp) { … } /* * Wa_16013835468 * Wa_14015648006 */ static void wm_optimization_wa(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { … } static void intel_psr_enable_source(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { … } static bool psr_interrupt_error_check(struct intel_dp *intel_dp) { … } static void intel_psr_enable_locked(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { … } static void intel_psr_exit(struct intel_dp *intel_dp) { … } static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp) { … } static void intel_psr_disable_locked(struct intel_dp *intel_dp) { … } /** * intel_psr_disable - Disable PSR * @intel_dp: Intel DP * @old_crtc_state: old CRTC state * * This function needs to be called before disabling pipe. */ void intel_psr_disable(struct intel_dp *intel_dp, const struct intel_crtc_state *old_crtc_state) { … } /** * intel_psr_pause - Pause PSR * @intel_dp: Intel DP * * This function need to be called after enabling psr. */ void intel_psr_pause(struct intel_dp *intel_dp) { … } /** * intel_psr_resume - Resume PSR * @intel_dp: Intel DP * * This function need to be called after pausing psr. */ void intel_psr_resume(struct intel_dp *intel_dp) { … } static u32 man_trk_ctl_enable_bit_get(struct intel_display *display) { … } static u32 man_trk_ctl_single_full_frame_bit_get(struct intel_display *display) { … } static u32 man_trk_ctl_partial_frame_bit_get(struct intel_display *display) { … } static u32 man_trk_ctl_continuos_full_frame(struct intel_display *display) { … } static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) { … } void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state) { … } static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, bool full_update) { … } static u32 psr2_pipe_srcsz_early_tpt_calc(struct intel_crtc_state *crtc_state, bool full_update) { … } static void clip_area_update(struct drm_rect *overlap_damage_area, struct drm_rect *damage_area, struct drm_rect *pipe_src) { … } static void intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_state) { … } /* * When early transport is in use we need to extend SU area to cover * cursor fully when cursor is in SU area. */ static void intel_psr2_sel_fetch_et_alignment(struct intel_atomic_state *state, struct intel_crtc *crtc, bool *cursor_in_su_area) { … } /* * TODO: Not clear how to handle planes with negative position, * also planes are not updated if they have a negative X * position so for now doing a full update in this cases * * Plane scaling and rotation is not supported by selective fetch and both * properties can change without a modeset, so need to be check at every * atomic commit. */ static bool psr2_sel_fetch_plane_state_supported(const struct intel_plane_state *plane_state) { … } /* * Check for pipe properties that is not supported by selective fetch. * * TODO: pipe scaling causes a modeset but skl_update_scaler_crtc() is executed * after intel_psr_compute_config(), so for now keeping PSR2 selective fetch * enabled and going to the full update path. */ static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *crtc_state) { … } int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { … } void intel_psr_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { … } void intel_psr_post_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { … } static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp) { … } static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp) { … } /** * intel_psr_wait_for_idle_locked - wait for PSR be ready for a pipe update * @new_crtc_state: new CRTC state * * This function is expected to be called from pipe_update_start() where it is * not expected to race with PSR enable or disable. */ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_state) { … } static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp) { … } static int intel_psr_fastset_force(struct intel_display *display) { … } int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val) { … } static void intel_psr_handle_irq(struct intel_dp *intel_dp) { … } static void intel_psr_work(struct work_struct *work) { … } static void _psr_invalidate_handle(struct intel_dp *intel_dp) { … } /** * intel_psr_invalidate - Invalidate PSR * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * @origin: which operation caused the invalidate * * Since the hardware frontbuffer tracking has gaps we need to integrate * with the software frontbuffer tracking. This function gets called every * time frontbuffer rendering starts and a buffer gets dirtied. PSR must be * disabled if the frontbuffer mask contains a buffer relevant to PSR. * * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits." */ void intel_psr_invalidate(struct intel_display *display, unsigned frontbuffer_bits, enum fb_op_origin origin) { … } /* * When we will be completely rely on PSR2 S/W tracking in future, * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP * event also therefore tgl_dc3co_flush_locked() require to be changed * accordingly in future. */ static void tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits, enum fb_op_origin origin) { … } static void _psr_flush_handle(struct intel_dp *intel_dp) { … } /** * intel_psr_flush - Flush PSR * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * @origin: which operation caused the flush * * Since the hardware frontbuffer tracking has gaps we need to integrate * with the software frontbuffer tracking. This function gets called every * time frontbuffer rendering has completed and flushed out to memory. PSR * can be enabled again if no other frontbuffer relevant to PSR is dirty. * * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits. */ void intel_psr_flush(struct intel_display *display, unsigned frontbuffer_bits, enum fb_op_origin origin) { … } /** * intel_psr_init - Init basic PSR work and mutex. * @intel_dp: Intel DP * * This function is called after the initializing connector. * (the initializing of connector treats the handling of connector capabilities) * And it initializes basic PSR stuff for each DP Encoder. */ void intel_psr_init(struct intel_dp *intel_dp) { … } static int psr_get_status_and_error_status(struct intel_dp *intel_dp, u8 *status, u8 *error_status) { … } static void psr_alpm_check(struct intel_dp *intel_dp) { … } static void psr_capability_changed_check(struct intel_dp *intel_dp) { … } /* * On common bits: * DP_PSR_RFB_STORAGE_ERROR == DP_PANEL_REPLAY_RFB_STORAGE_ERROR * DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR == DP_PANEL_REPLAY_VSC_SDP_UNCORRECTABLE_ERROR * DP_PSR_LINK_CRC_ERROR == DP_PANEL_REPLAY_LINK_CRC_ERROR * this function is relying on PSR definitions */ void intel_psr_short_pulse(struct intel_dp *intel_dp) { … } bool intel_psr_enabled(struct intel_dp *intel_dp) { … } /** * intel_psr_lock - grab PSR lock * @crtc_state: the crtc state * * This is initially meant to be used by around CRTC update, when * vblank sensitive registers are updated and we need grab the lock * before it to avoid vblank evasion. */ void intel_psr_lock(const struct intel_crtc_state *crtc_state) { … } /** * intel_psr_unlock - release PSR lock * @crtc_state: the crtc state * * Release the PSR lock that was held during pipe update. */ void intel_psr_unlock(const struct intel_crtc_state *crtc_state) { … } static void psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) { … } static void intel_psr_sink_capability(struct intel_dp *intel_dp, struct seq_file *m) { … } static void intel_psr_print_mode(struct intel_dp *intel_dp, struct seq_file *m) { … } static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) { … } static int i915_edp_psr_status_show(struct seq_file *m, void *data) { … } DEFINE_SHOW_ATTRIBUTE(…); static int i915_edp_psr_debug_set(void *data, u64 val) { … } static int i915_edp_psr_debug_get(void *data, u64 *val) { … } DEFINE_SIMPLE_ATTRIBUTE(…); void intel_psr_debugfs_register(struct intel_display *display) { … } static const char *psr_mode_str(struct intel_dp *intel_dp) { … } static int i915_psr_sink_status_show(struct seq_file *m, void *data) { … } DEFINE_SHOW_ATTRIBUTE(…); static int i915_psr_status_show(struct seq_file *m, void *data) { … } DEFINE_SHOW_ATTRIBUTE(…); void intel_psr_connector_debugfs_add(struct intel_connector *connector) { … }