Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
0004  * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
0005  */
0006 
0007 #ifndef __DPU_ENCODER_PHYS_H__
0008 #define __DPU_ENCODER_PHYS_H__
0009 
0010 #include <drm/drm_writeback.h>
0011 #include <linux/jiffies.h>
0012 
0013 #include "dpu_kms.h"
0014 #include "dpu_hw_intf.h"
0015 #include "dpu_hw_wb.h"
0016 #include "dpu_hw_pingpong.h"
0017 #include "dpu_hw_ctl.h"
0018 #include "dpu_hw_top.h"
0019 #include "dpu_encoder.h"
0020 #include "dpu_crtc.h"
0021 
0022 #define DPU_ENCODER_NAME_MAX    16
0023 
0024 /* wait for at most 2 vsync for lowest refresh rate (24hz) */
0025 #define KICKOFF_TIMEOUT_MS      84
0026 #define KICKOFF_TIMEOUT_JIFFIES     msecs_to_jiffies(KICKOFF_TIMEOUT_MS)
0027 
0028 /**
0029  * enum dpu_enc_split_role - Role this physical encoder will play in a
0030  *  split-panel configuration, where one panel is master, and others slaves.
0031  *  Masters have extra responsibilities, like managing the VBLANK IRQ.
0032  * @ENC_ROLE_SOLO:  This is the one and only panel. This encoder is master.
0033  * @ENC_ROLE_MASTER:    This encoder is the master of a split panel config.
0034  * @ENC_ROLE_SLAVE: This encoder is not the master of a split panel config.
0035  */
0036 enum dpu_enc_split_role {
0037     ENC_ROLE_SOLO,
0038     ENC_ROLE_MASTER,
0039     ENC_ROLE_SLAVE,
0040 };
0041 
0042 /**
0043  * enum dpu_enc_enable_state - current enabled state of the physical encoder
0044  * @DPU_ENC_DISABLING:  Encoder transitioning to disable state
0045  *          Events bounding transition are encoder type specific
0046  * @DPU_ENC_DISABLED:   Encoder is disabled
0047  * @DPU_ENC_ENABLING:   Encoder transitioning to enabled
0048  *          Events bounding transition are encoder type specific
0049  * @DPU_ENC_ENABLED:    Encoder is enabled
0050  * @DPU_ENC_ERR_NEEDS_HW_RESET: Encoder is enabled, but requires a hw_reset
0051  *              to recover from a previous error
0052  */
0053 enum dpu_enc_enable_state {
0054     DPU_ENC_DISABLING,
0055     DPU_ENC_DISABLED,
0056     DPU_ENC_ENABLING,
0057     DPU_ENC_ENABLED,
0058     DPU_ENC_ERR_NEEDS_HW_RESET
0059 };
0060 
0061 struct dpu_encoder_phys;
0062 
0063 /**
0064  * struct dpu_encoder_virt_ops - Interface the containing virtual encoder
0065  *  provides for the physical encoders to use to callback.
0066  * @handle_vblank_virt: Notify virtual encoder of vblank IRQ reception
0067  *          Note: This is called from IRQ handler context.
0068  * @handle_underrun_virt: Notify virtual encoder of underrun IRQ reception
0069  *          Note: This is called from IRQ handler context.
0070  * @handle_frame_done:  Notify virtual encoder that this phys encoder
0071  *          completes last request frame.
0072  */
0073 struct dpu_encoder_virt_ops {
0074     void (*handle_vblank_virt)(struct drm_encoder *,
0075             struct dpu_encoder_phys *phys);
0076     void (*handle_underrun_virt)(struct drm_encoder *,
0077             struct dpu_encoder_phys *phys);
0078     void (*handle_frame_done)(struct drm_encoder *,
0079             struct dpu_encoder_phys *phys, u32 event);
0080 };
0081 
0082 /**
0083  * struct dpu_encoder_phys_ops - Interface the physical encoders provide to
0084  *  the containing virtual encoder.
0085  * @late_register:      DRM Call. Add Userspace interfaces, debugfs.
0086  * @prepare_commit:     MSM Atomic Call, start of atomic commit sequence
0087  * @is_master:          Whether this phys_enc is the current master
0088  *              encoder. Can be switched at enable time. Based
0089  *              on split_role and current mode (CMD/VID).
0090  * @atomic_mode_set:        DRM Call. Set a DRM mode.
0091  *              This likely caches the mode, for use at enable.
0092  * @enable:         DRM Call. Enable a DRM mode.
0093  * @disable:            DRM Call. Disable mode.
0094  * @atomic_check:       DRM Call. Atomic check new DRM state.
0095  * @destroy:            DRM Call. Destroy and release resources.
0096  * @control_vblank_irq      Register/Deregister for VBLANK IRQ
0097  * @wait_for_commit_done:   Wait for hardware to have flushed the
0098  *              current pending frames to hardware
0099  * @wait_for_tx_complete:   Wait for hardware to transfer the pixels
0100  *              to the panel
0101  * @wait_for_vblank:        Wait for VBLANK, for sub-driver internal use
0102  * @prepare_for_kickoff:    Do any work necessary prior to a kickoff
0103  *              For CMD encoder, may wait for previous tx done
0104  * @handle_post_kickoff:    Do any work necessary post-kickoff work
0105  * @trigger_start:      Process start event on physical encoder
0106  * @needs_single_flush:     Whether encoder slaves need to be flushed
0107  * @irq_control:        Handler to enable/disable all the encoder IRQs
0108  * @prepare_idle_pc:        phys encoder can update the vsync_enable status
0109  *                              on idle power collapse prepare
0110  * @restore:            Restore all the encoder configs.
0111  * @get_line_count:     Obtain current vertical line count
0112  */
0113 
0114 struct dpu_encoder_phys_ops {
0115     int (*late_register)(struct dpu_encoder_phys *encoder,
0116             struct dentry *debugfs_root);
0117     void (*prepare_commit)(struct dpu_encoder_phys *encoder);
0118     bool (*is_master)(struct dpu_encoder_phys *encoder);
0119     void (*atomic_mode_set)(struct dpu_encoder_phys *encoder,
0120             struct drm_crtc_state *crtc_state,
0121             struct drm_connector_state *conn_state);
0122     void (*enable)(struct dpu_encoder_phys *encoder);
0123     void (*disable)(struct dpu_encoder_phys *encoder);
0124     int (*atomic_check)(struct dpu_encoder_phys *encoder,
0125                 struct drm_crtc_state *crtc_state,
0126                 struct drm_connector_state *conn_state);
0127     void (*destroy)(struct dpu_encoder_phys *encoder);
0128     int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
0129     int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
0130     int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
0131     int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc);
0132     void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc);
0133     void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc);
0134     void (*trigger_start)(struct dpu_encoder_phys *phys_enc);
0135     bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc);
0136     void (*irq_control)(struct dpu_encoder_phys *phys, bool enable);
0137     void (*prepare_idle_pc)(struct dpu_encoder_phys *phys_enc);
0138     void (*restore)(struct dpu_encoder_phys *phys);
0139     int (*get_line_count)(struct dpu_encoder_phys *phys);
0140     int (*get_frame_count)(struct dpu_encoder_phys *phys);
0141     void (*prepare_wb_job)(struct dpu_encoder_phys *phys_enc,
0142             struct drm_writeback_job *job);
0143     void (*cleanup_wb_job)(struct dpu_encoder_phys *phys_enc,
0144             struct drm_writeback_job *job);
0145     bool (*is_valid_for_commit)(struct dpu_encoder_phys *phys_enc);
0146 };
0147 
0148 /**
0149  * enum dpu_intr_idx - dpu encoder interrupt index
0150  * @INTR_IDX_VSYNC:    Vsync interrupt for video mode panel
0151  * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
0152  * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
0153  * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
0154  * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
0155  */
0156 enum dpu_intr_idx {
0157     INTR_IDX_VSYNC,
0158     INTR_IDX_PINGPONG,
0159     INTR_IDX_UNDERRUN,
0160     INTR_IDX_CTL_START,
0161     INTR_IDX_RDPTR,
0162     INTR_IDX_WB_DONE,
0163     INTR_IDX_MAX,
0164 };
0165 
0166 /**
0167  * struct dpu_encoder_phys - physical encoder that drives a single INTF block
0168  *  tied to a specific panel / sub-panel. Abstract type, sub-classed by
0169  *  phys_vid or phys_cmd for video mode or command mode encs respectively.
0170  * @parent:     Pointer to the containing virtual encoder
0171  * @ops:        Operations exposed to the virtual encoder
0172  * @parent_ops:     Callbacks exposed by the parent to the phys_enc
0173  * @hw_mdptop:      Hardware interface to the top registers
0174  * @hw_ctl:     Hardware interface to the ctl registers
0175  * @hw_pp:      Hardware interface to the ping pong registers
0176  * @hw_intf:        Hardware interface to the intf registers
0177  * @hw_wb:      Hardware interface to the wb registers
0178  * @dpu_kms:        Pointer to the dpu_kms top level
0179  * @cached_mode:    DRM mode cached at mode_set time, acted on in enable
0180  * @enabled:        Whether the encoder has enabled and running a mode
0181  * @split_role:     Role to play in a split-panel configuration
0182  * @intf_mode:      Interface mode
0183  * @intf_idx:       Interface index on dpu hardware
0184  * @wb_idx:         Writeback index on dpu hardware
0185  * @enc_spinlock:   Virtual-Encoder-Wide Spin Lock for IRQ purposes
0186  * @enable_state:   Enable state tracking
0187  * @vblank_refcount:    Reference count of vblank request
0188  * @vsync_cnt:      Vsync count for the physical encoder
0189  * @underrun_cnt:   Underrun count for the physical encoder
0190  * @pending_kickoff_cnt:    Atomic counter tracking the number of kickoffs
0191  *              vs. the number of done/vblank irqs. Should hover
0192  *              between 0-2 Incremented when a new kickoff is
0193  *              scheduled. Decremented in irq handler
0194  * @pending_ctlstart_cnt:   Atomic counter tracking the number of ctl start
0195  *                              pending.
0196  * @pending_kickoff_wq:     Wait queue for blocking until kickoff completes
0197  * @irq:            IRQ indices
0198  */
0199 struct dpu_encoder_phys {
0200     struct drm_encoder *parent;
0201     struct dpu_encoder_phys_ops ops;
0202     const struct dpu_encoder_virt_ops *parent_ops;
0203     struct dpu_hw_mdp *hw_mdptop;
0204     struct dpu_hw_ctl *hw_ctl;
0205     struct dpu_hw_pingpong *hw_pp;
0206     struct dpu_hw_intf *hw_intf;
0207     struct dpu_hw_wb *hw_wb;
0208     struct dpu_kms *dpu_kms;
0209     struct drm_display_mode cached_mode;
0210     enum dpu_enc_split_role split_role;
0211     enum dpu_intf_mode intf_mode;
0212     enum dpu_intf intf_idx;
0213     enum dpu_wb wb_idx;
0214     spinlock_t *enc_spinlock;
0215     enum dpu_enc_enable_state enable_state;
0216     atomic_t vblank_refcount;
0217     atomic_t vsync_cnt;
0218     atomic_t underrun_cnt;
0219     atomic_t pending_ctlstart_cnt;
0220     atomic_t pending_kickoff_cnt;
0221     wait_queue_head_t pending_kickoff_wq;
0222     int irq[INTR_IDX_MAX];
0223 };
0224 
0225 static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
0226 {
0227     atomic_inc_return(&phys->pending_ctlstart_cnt);
0228     return atomic_inc_return(&phys->pending_kickoff_cnt);
0229 }
0230 
0231 /**
0232  * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to handle command
0233  *  mode specific operations
0234  * @base:   Baseclass physical encoder structure
0235  * @wbirq_refcount:     Reference count of writeback interrupt
0236  * @wb_done_timeout_cnt: number of wb done irq timeout errors
0237  * @wb_cfg:  writeback block config to store fb related details
0238  * @wb_conn: backpointer to writeback connector
0239  * @wb_job: backpointer to current writeback job
0240  * @dest:   dpu buffer layout for current writeback output buffer
0241  */
0242 struct dpu_encoder_phys_wb {
0243     struct dpu_encoder_phys base;
0244     atomic_t wbirq_refcount;
0245     int wb_done_timeout_cnt;
0246     struct dpu_hw_wb_cfg wb_cfg;
0247     struct drm_writeback_connector *wb_conn;
0248     struct drm_writeback_job *wb_job;
0249     struct dpu_hw_fmt_layout dest;
0250 };
0251 
0252 /**
0253  * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command
0254  *  mode specific operations
0255  * @base:   Baseclass physical encoder structure
0256  * @intf_idx:   Intf Block index used by this phys encoder
0257  * @stream_sel: Stream selection for multi-stream interfaces
0258  * @serialize_wait4pp:  serialize wait4pp feature waits for pp_done interrupt
0259  *          after ctl_start instead of before next frame kickoff
0260  * @pp_timeout_report_cnt: number of pingpong done irq timeout errors
0261  * @pending_vblank_cnt: Atomic counter tracking pending wait for VBLANK
0262  * @pending_vblank_wq: Wait queue for blocking until VBLANK received
0263  */
0264 struct dpu_encoder_phys_cmd {
0265     struct dpu_encoder_phys base;
0266     int stream_sel;
0267     bool serialize_wait4pp;
0268     int pp_timeout_report_cnt;
0269     atomic_t pending_vblank_cnt;
0270     wait_queue_head_t pending_vblank_wq;
0271 };
0272 
0273 /**
0274  * struct dpu_enc_phys_init_params - initialization parameters for phys encs
0275  * @dpu_kms:        Pointer to the dpu_kms top level
0276  * @parent:     Pointer to the containing virtual encoder
0277  * @parent_ops:     Callbacks exposed by the parent to the phys_enc
0278  * @split_role:     Role to play in a split-panel configuration
0279  * @intf_idx:       Interface index this phys_enc will control
0280  * @wb_idx:         Writeback index this phys_enc will control
0281  * @enc_spinlock:   Virtual-Encoder-Wide Spin Lock for IRQ purposes
0282  */
0283 struct dpu_enc_phys_init_params {
0284     struct dpu_kms *dpu_kms;
0285     struct drm_encoder *parent;
0286     const struct dpu_encoder_virt_ops *parent_ops;
0287     enum dpu_enc_split_role split_role;
0288     enum dpu_intf intf_idx;
0289     enum dpu_wb wb_idx;
0290     spinlock_t *enc_spinlock;
0291 };
0292 
0293 /**
0294  * dpu_encoder_wait_info - container for passing arguments to irq wait functions
0295  * @wq: wait queue structure
0296  * @atomic_cnt: wait until atomic_cnt equals zero
0297  * @timeout_ms: timeout value in milliseconds
0298  */
0299 struct dpu_encoder_wait_info {
0300     wait_queue_head_t *wq;
0301     atomic_t *atomic_cnt;
0302     s64 timeout_ms;
0303 };
0304 
0305 /**
0306  * dpu_encoder_phys_vid_init - Construct a new video mode physical encoder
0307  * @p:  Pointer to init params structure
0308  * Return: Error code or newly allocated encoder
0309  */
0310 struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
0311         struct dpu_enc_phys_init_params *p);
0312 
0313 /**
0314  * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder
0315  * @p:  Pointer to init params structure
0316  * Return: Error code or newly allocated encoder
0317  */
0318 struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
0319         struct dpu_enc_phys_init_params *p);
0320 
0321 /**
0322  * dpu_encoder_phys_wb_init - initialize writeback encoder
0323  * @init:   Pointer to init info structure with initialization params
0324  */
0325 struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
0326         struct dpu_enc_phys_init_params *p);
0327 
0328 /**
0329  * dpu_encoder_helper_trigger_start - control start helper function
0330  *  This helper function may be optionally specified by physical
0331  *  encoders if they require ctl_start triggering.
0332  * @phys_enc: Pointer to physical encoder structure
0333  */
0334 void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc);
0335 
0336 static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
0337         struct dpu_encoder_phys *phys_enc)
0338 {
0339     struct dpu_crtc_state *dpu_cstate;
0340 
0341     if (!phys_enc || phys_enc->enable_state == DPU_ENC_DISABLING)
0342         return BLEND_3D_NONE;
0343 
0344     dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state);
0345 
0346     /* Use merge_3d unless DSC MERGE topology is used */
0347     if (phys_enc->split_role == ENC_ROLE_SOLO &&
0348         dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
0349         !dpu_encoder_use_dsc_merge(phys_enc->parent))
0350         return BLEND_3D_H_ROW_INT;
0351 
0352     return BLEND_3D_NONE;
0353 }
0354 
0355 /**
0356  * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
0357  *   This helper function is used by physical encoder to get DSC blocks mask
0358  *   used for this encoder.
0359  * @phys_enc: Pointer to physical encoder structure
0360  */
0361 unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
0362 
0363 /**
0364  * dpu_encoder_helper_split_config - split display configuration helper function
0365  *  This helper function may be used by physical encoders to configure
0366  *  the split display related registers.
0367  * @phys_enc: Pointer to physical encoder structure
0368  * @interface: enum dpu_intf setting
0369  */
0370 void dpu_encoder_helper_split_config(
0371         struct dpu_encoder_phys *phys_enc,
0372         enum dpu_intf interface);
0373 
0374 /**
0375  * dpu_encoder_helper_report_irq_timeout - utility to report error that irq has
0376  *  timed out, including reporting frame error event to crtc and debug dump
0377  * @phys_enc: Pointer to physical encoder structure
0378  * @intr_idx: Failing interrupt index
0379  */
0380 void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
0381         enum dpu_intr_idx intr_idx);
0382 
0383 /**
0384  * dpu_encoder_helper_wait_for_irq - utility to wait on an irq.
0385  *  note: will call dpu_encoder_helper_wait_for_irq on timeout
0386  * @phys_enc: Pointer to physical encoder structure
0387  * @irq: IRQ index
0388  * @func: IRQ callback to be called in case of timeout
0389  * @wait_info: wait info struct
0390  * @Return: 0 or -ERROR
0391  */
0392 int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
0393         int irq,
0394         void (*func)(void *arg, int irq_idx),
0395         struct dpu_encoder_wait_info *wait_info);
0396 
0397 /**
0398  * dpu_encoder_helper_phys_cleanup - helper to cleanup dpu pipeline
0399  * @phys_enc: Pointer to physical encoder structure
0400  */
0401 void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
0402 
0403 #endif /* __dpu_encoder_phys_H__ */