blob: b1547aba04a25045448282875982c1f354d6d762 [file] [log] [blame]
Lloyd Atkinson09fed912016-06-24 18:14:13 -04001/*
Narender Ankam1afbd172020-03-16 17:27:44 +05302 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#ifndef __SDE_ENCODER_PHYS_H__
16#define __SDE_ENCODER_PHYS_H__
17
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -050018#include <linux/jiffies.h>
Dhaval Patel49ef6d72017-03-26 09:35:53 -070019#include <linux/sde_rsc.h>
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -050020
Lloyd Atkinson09fed912016-06-24 18:14:13 -040021#include "sde_kms.h"
22#include "sde_hw_intf.h"
Lloyd Atkinsona59eead2016-05-30 14:37:06 -040023#include "sde_hw_pingpong.h"
Clarence Ipc475b082016-06-26 09:27:23 -040024#include "sde_hw_ctl.h"
Lloyd Atkinson5d722782016-05-30 14:09:41 -040025#include "sde_hw_top.h"
Alan Kwongbb27c092016-07-20 16:41:25 -040026#include "sde_hw_wb.h"
27#include "sde_hw_cdm.h"
Alan Kwong83285fb2016-10-21 20:51:17 -040028#include "sde_encoder.h"
29#include "sde_connector.h"
Alan Kwongbb27c092016-07-20 16:41:25 -040030
31#define SDE_ENCODER_NAME_MAX 16
Lloyd Atkinson09fed912016-06-24 18:14:13 -040032
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -050033/* wait for at most 2 vsync for lowest refresh rate (24hz) */
34#define KICKOFF_TIMEOUT_MS 84
35#define KICKOFF_TIMEOUT_JIFFIES msecs_to_jiffies(KICKOFF_TIMEOUT_MS)
36
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040037/**
38 * enum sde_enc_split_role - Role this physical encoder will play in a
39 * split-panel configuration, where one panel is master, and others slaves.
40 * Masters have extra responsibilities, like managing the VBLANK IRQ.
41 * @ENC_ROLE_SOLO: This is the one and only panel. This encoder is master.
42 * @ENC_ROLE_MASTER: This encoder is the master of a split panel config.
43 * @ENC_ROLE_SLAVE: This encoder is not the master of a split panel config.
Lloyd Atkinson73fb8092017-02-08 16:02:55 -050044 * @ENC_ROLE_SKIP: This encoder is not participating in kickoffs
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040045 */
46enum sde_enc_split_role {
47 ENC_ROLE_SOLO,
48 ENC_ROLE_MASTER,
Lloyd Atkinson73fb8092017-02-08 16:02:55 -050049 ENC_ROLE_SLAVE,
50 ENC_ROLE_SKIP
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040051};
Lloyd Atkinson09fed912016-06-24 18:14:13 -040052
Lloyd Atkinson8c49c582016-11-18 14:23:54 -050053/**
54 * enum sde_enc_enable_state - current enabled state of the physical encoder
Clarence Ip9c65f7b2017-03-20 06:48:15 -070055 * @SDE_ENC_DISABLING: Encoder transitioning to disable state
56 * Events bounding transition are encoder type specific
Lloyd Atkinson8c49c582016-11-18 14:23:54 -050057 * @SDE_ENC_DISABLED: Encoder is disabled
58 * @SDE_ENC_ENABLING: Encoder transitioning to enabled
59 * Events bounding transition are encoder type specific
60 * @SDE_ENC_ENABLED: Encoder is enabled
61 * @SDE_ENC_ERR_NEEDS_HW_RESET: Encoder is enabled, but requires a hw_reset
62 * to recover from a previous error
63 */
64enum sde_enc_enable_state {
Clarence Ip9c65f7b2017-03-20 06:48:15 -070065 SDE_ENC_DISABLING,
Lloyd Atkinson8c49c582016-11-18 14:23:54 -050066 SDE_ENC_DISABLED,
67 SDE_ENC_ENABLING,
68 SDE_ENC_ENABLED,
69 SDE_ENC_ERR_NEEDS_HW_RESET
70};
71
Lloyd Atkinson09fed912016-06-24 18:14:13 -040072struct sde_encoder_phys;
73
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040074/**
75 * struct sde_encoder_virt_ops - Interface the containing virtual encoder
76 * provides for the physical encoders to use to callback.
77 * @handle_vblank_virt: Notify virtual encoder of vblank IRQ reception
78 * Note: This is called from IRQ handler context.
Dhaval Patel81e87882016-10-19 21:41:56 -070079 * @handle_underrun_virt: Notify virtual encoder of underrun IRQ reception
80 * Note: This is called from IRQ handler context.
Alan Kwong628d19e2016-10-31 13:50:13 -040081 * @handle_frame_done: Notify virtual encoder that this phys encoder
82 * completes last request frame.
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040083 */
Lloyd Atkinson09fed912016-06-24 18:14:13 -040084struct sde_encoder_virt_ops {
Dhaval Patel81e87882016-10-19 21:41:56 -070085 void (*handle_vblank_virt)(struct drm_encoder *,
86 struct sde_encoder_phys *phys);
87 void (*handle_underrun_virt)(struct drm_encoder *,
88 struct sde_encoder_phys *phys);
Alan Kwong628d19e2016-10-31 13:50:13 -040089 void (*handle_frame_done)(struct drm_encoder *,
90 struct sde_encoder_phys *phys, u32 event);
Lloyd Atkinson09fed912016-06-24 18:14:13 -040091};
92
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040093/**
94 * struct sde_encoder_phys_ops - Interface the physical encoders provide to
95 * the containing virtual encoder.
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -070096 * @late_register: DRM Call. Add Userspace interfaces, debugfs.
Lloyd Atkinsone123c172017-02-27 13:19:08 -050097 * @prepare_commit: MSM Atomic Call, start of atomic commit sequence
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040098 * @is_master: Whether this phys_enc is the current master
99 * encoder. Can be switched at enable time. Based
100 * on split_role and current mode (CMD/VID).
101 * @mode_fixup: DRM Call. Fixup a DRM mode.
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -0700102 * @cont_splash_mode_set: mode set with specific HW resources during
103 * cont splash enabled state.
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400104 * @mode_set: DRM Call. Set a DRM mode.
105 * This likely caches the mode, for use at enable.
106 * @enable: DRM Call. Enable a DRM mode.
107 * @disable: DRM Call. Disable mode.
Alan Kwongbb27c092016-07-20 16:41:25 -0400108 * @atomic_check: DRM Call. Atomic check new DRM state.
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400109 * @destroy: DRM Call. Destroy and release resources.
110 * @get_hw_resources: Populate the structure with the hardware
111 * resources that this phys_enc is using.
112 * Expect no overlap between phys_encs.
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400113 * @control_vblank_irq Register/Deregister for VBLANK IRQ
114 * @wait_for_commit_done: Wait for hardware to have flushed the
115 * current pending frames to hardware
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -0700116 * @wait_for_tx_complete: Wait for hardware to transfer the pixels
117 * to the panel
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400118 * @wait_for_vblank: Wait for VBLANK, for sub-driver internal use
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400119 * @prepare_for_kickoff: Do any work necessary prior to a kickoff
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500120 * For CMD encoder, may wait for previous tx done
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400121 * @handle_post_kickoff: Do any work necessary post-kickoff work
Alan Kwong4212dd42017-09-19 17:22:33 -0400122 * @trigger_flush: Process flush event on physical encoder
Clarence Ip110d15c2016-08-16 14:44:41 -0400123 * @trigger_start: Process start event on physical encoder
Clarence Ip8e69ad02016-12-09 09:43:57 -0500124 * @needs_single_flush: Whether encoder slaves need to be flushed
Jayant Shekhar1d50ed22016-11-04 18:41:12 +0530125 * @setup_misr: Sets up MISR, enable and disables based on sysfs
126 * @collect_misr: Collects MISR data on frame update
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500127 * @hw_reset: Issue HW recovery such as CTL reset and clear
128 * SDE_ENC_ERR_NEEDS_HW_RESET state
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700129 * @irq_control: Handler to enable/disable all the encoder IRQs
Lloyd Atkinson73fb8092017-02-08 16:02:55 -0500130 * @update_split_role: Update the split role of the phys enc
Veera Sundaram Sankaran33db4282017-11-01 12:45:25 -0700131 * @control_te: Interface to control the vsync_enable status
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -0700132 * @restore: Restore all the encoder configs.
Dhaval Patel99412a52017-07-24 19:16:45 -0700133 * @is_autorefresh_enabled: provides the autorefresh current
134 * enable/disable state.
Clarence Ip5e3df1d2017-11-07 21:28:25 -0500135 * @get_line_count: Obtain current internal vertical line count
136 * @get_wr_line_count: Obtain current output vertical line count
Ingrid Gallardo61210ea2017-10-17 17:29:31 -0700137 * @wait_dma_trigger: Returns true if lut dma has to trigger and wait
138 * unitl transaction is complete.
Sandeep Panda11b20d82017-06-19 12:57:27 +0530139 * @wait_for_active: Wait for display scan line to be in active area
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400140 */
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400141
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400142struct sde_encoder_phys_ops {
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -0700143 int (*late_register)(struct sde_encoder_phys *encoder,
144 struct dentry *debugfs_root);
Lloyd Atkinsone123c172017-02-27 13:19:08 -0500145 void (*prepare_commit)(struct sde_encoder_phys *encoder);
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400146 bool (*is_master)(struct sde_encoder_phys *encoder);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400147 bool (*mode_fixup)(struct sde_encoder_phys *encoder,
148 const struct drm_display_mode *mode,
149 struct drm_display_mode *adjusted_mode);
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400150 void (*mode_set)(struct sde_encoder_phys *encoder,
151 struct drm_display_mode *mode,
152 struct drm_display_mode *adjusted_mode);
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -0700153 void (*cont_splash_mode_set)(struct sde_encoder_phys *encoder,
154 struct drm_display_mode *adjusted_mode);
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400155 void (*enable)(struct sde_encoder_phys *encoder);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400156 void (*disable)(struct sde_encoder_phys *encoder);
Alan Kwongbb27c092016-07-20 16:41:25 -0400157 int (*atomic_check)(struct sde_encoder_phys *encoder,
158 struct drm_crtc_state *crtc_state,
159 struct drm_connector_state *conn_state);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400160 void (*destroy)(struct sde_encoder_phys *encoder);
161 void (*get_hw_resources)(struct sde_encoder_phys *encoder,
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400162 struct sde_encoder_hw_resources *hw_res,
163 struct drm_connector_state *conn_state);
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400164 int (*control_vblank_irq)(struct sde_encoder_phys *enc, bool enable);
165 int (*wait_for_commit_done)(struct sde_encoder_phys *phys_enc);
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -0700166 int (*wait_for_tx_complete)(struct sde_encoder_phys *phys_enc);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400167 int (*wait_for_vblank)(struct sde_encoder_phys *phys_enc);
Clarence Ip85f4f4532017-10-04 12:10:13 -0400168 int (*prepare_for_kickoff)(struct sde_encoder_phys *phys_enc,
Alan Kwong4aacd532017-02-04 18:51:33 -0800169 struct sde_encoder_kickoff_params *params);
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400170 void (*handle_post_kickoff)(struct sde_encoder_phys *phys_enc);
Alan Kwong4212dd42017-09-19 17:22:33 -0400171 void (*trigger_flush)(struct sde_encoder_phys *phys_enc);
Clarence Ip110d15c2016-08-16 14:44:41 -0400172 void (*trigger_start)(struct sde_encoder_phys *phys_enc);
Clarence Ip8e69ad02016-12-09 09:43:57 -0500173 bool (*needs_single_flush)(struct sde_encoder_phys *phys_enc);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +0530174
175 void (*setup_misr)(struct sde_encoder_phys *phys_encs,
Dhaval Patelf9245d62017-03-28 16:24:00 -0700176 bool enable, u32 frame_count);
177 u32 (*collect_misr)(struct sde_encoder_phys *phys_enc);
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500178 void (*hw_reset)(struct sde_encoder_phys *phys_enc);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700179 void (*irq_control)(struct sde_encoder_phys *phys, bool enable);
Lloyd Atkinson73fb8092017-02-08 16:02:55 -0500180 void (*update_split_role)(struct sde_encoder_phys *phys_enc,
181 enum sde_enc_split_role role);
Veera Sundaram Sankaran33db4282017-11-01 12:45:25 -0700182 void (*control_te)(struct sde_encoder_phys *phys_enc, bool enable);
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -0700183 void (*restore)(struct sde_encoder_phys *phys);
Dhaval Patel99412a52017-07-24 19:16:45 -0700184 bool (*is_autorefresh_enabled)(struct sde_encoder_phys *phys);
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400185 int (*get_line_count)(struct sde_encoder_phys *phys);
Clarence Ip5e3df1d2017-11-07 21:28:25 -0500186 int (*get_wr_line_count)(struct sde_encoder_phys *phys);
Ingrid Gallardo61210ea2017-10-17 17:29:31 -0700187 bool (*wait_dma_trigger)(struct sde_encoder_phys *phys);
Sandeep Panda11b20d82017-06-19 12:57:27 +0530188 int (*wait_for_active)(struct sde_encoder_phys *phys);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400189};
190
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400191/**
Dhaval Patel81e87882016-10-19 21:41:56 -0700192 * enum sde_intr_idx - sde encoder interrupt index
193 * @INTR_IDX_VSYNC: Vsync interrupt for video mode panel
194 * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
195 * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
196 * @INTR_IDX_RDPTR: Readpointer done unterrupt for cmd mode panel
Prabhanjan Kandula77cc0ee2018-04-15 21:44:50 -0700197 * @INTR_IDX_WB_DONE: Writeback done interrupt for WB
198 * @INTR_IDX_PP2_OVFL: Pingpong overflow interrupt on PP2 for Concurrent WB
199 * @INTR_IDX_PP2_OVFL: Pingpong overflow interrupt on PP3 for Concurrent WB
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500200 * @INTR_IDX_AUTOREFRESH_DONE: Autorefresh done for cmd mode panel meaning
201 * autorefresh has triggered a double buffer flip
Dhaval Patel81e87882016-10-19 21:41:56 -0700202 */
203enum sde_intr_idx {
204 INTR_IDX_VSYNC,
205 INTR_IDX_PINGPONG,
206 INTR_IDX_UNDERRUN,
Dhaval Patel0e558f42017-04-30 00:51:40 -0700207 INTR_IDX_CTL_START,
Dhaval Patel81e87882016-10-19 21:41:56 -0700208 INTR_IDX_RDPTR,
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500209 INTR_IDX_AUTOREFRESH_DONE,
Prabhanjan Kandula77cc0ee2018-04-15 21:44:50 -0700210 INTR_IDX_WB_DONE,
211 INTR_IDX_PP2_OVFL,
212 INTR_IDX_PP3_OVFL,
Dhaval Patel81e87882016-10-19 21:41:56 -0700213 INTR_IDX_MAX,
214};
215
216/**
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500217 * sde_encoder_irq - tracking structure for interrupts
218 * @name: string name of interrupt
219 * @intr_type: Encoder interrupt type
220 * @intr_idx: Encoder interrupt enumeration
221 * @hw_idx: HW Block ID
222 * @irq_idx: IRQ interface lookup index from SDE IRQ framework
223 * will be -EINVAL if IRQ is not registered
224 * @irq_cb: interrupt callback
225 */
226struct sde_encoder_irq {
227 const char *name;
228 enum sde_intr_type intr_type;
229 enum sde_intr_idx intr_idx;
230 int hw_idx;
231 int irq_idx;
232 struct sde_irq_callback cb;
233};
234
235/**
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400236 * struct sde_encoder_phys - physical encoder that drives a single INTF block
237 * tied to a specific panel / sub-panel. Abstract type, sub-classed by
238 * phys_vid or phys_cmd for video mode or command mode encs respectively.
239 * @parent: Pointer to the containing virtual encoder
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400240 * @connector: If a mode is set, cached pointer to the active connector
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400241 * @ops: Operations exposed to the virtual encoder
242 * @parent_ops: Callbacks exposed by the parent to the phys_enc
243 * @hw_mdptop: Hardware interface to the top registers
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400244 * @hw_ctl: Hardware interface to the ctl registers
Alan Kwongbb27c092016-07-20 16:41:25 -0400245 * @hw_cdm: Hardware interface to the cdm registers
246 * @cdm_cfg: Chroma-down hardware configuration
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700247 * @hw_pp: Hardware interface to the ping pong registers
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400248 * @sde_kms: Pointer to the sde_kms top level
249 * @cached_mode: DRM mode cached at mode_set time, acted on in enable
250 * @enabled: Whether the encoder has enabled and running a mode
251 * @split_role: Role to play in a split-panel configuration
Clarence Ip03521982016-08-26 10:49:47 -0400252 * @intf_mode: Interface mode
Dhaval Patel81e87882016-10-19 21:41:56 -0700253 * @intf_idx: Interface index on sde hardware
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800254 * @comp_type: Type of compression supported
Narender Ankam1afbd172020-03-16 17:27:44 +0530255 * @enc_cdm_csc: Cached CSC type of CDM block
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400256 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400257 * @enable_state: Enable state tracking
Alan Kwongbaa56352016-10-04 09:38:11 -0400258 * @vblank_refcount: Reference count of vblank request
Shubhashree Dhar5c9e2022018-09-03 15:49:42 +0530259 * @wbirq_refcount: Reference count of wb irq request
Dhaval Patel81e87882016-10-19 21:41:56 -0700260 * @vsync_cnt: Vsync count for the physical encoder
261 * @underrun_cnt: Underrun count for the physical encoder
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400262 * @pending_kickoff_cnt: Atomic counter tracking the number of kickoffs
263 * vs. the number of done/vblank irqs. Should hover
264 * between 0-2 Incremented when a new kickoff is
265 * scheduled. Decremented in irq handler
Dhaval Patel0e558f42017-04-30 00:51:40 -0700266 * @pending_ctlstart_cnt: Atomic counter tracking the number of ctl start
267 * pending.
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700268 * @pending_retire_fence_cnt: Atomic counter tracking the pending retire
269 * fences that have to be signalled.
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400270 * @pending_kickoff_wq: Wait queue for blocking until kickoff completes
Krishna Manikandanfb29f692019-04-09 17:00:41 +0530271 * @ctlstart_timeout: Indicates if ctl start timeout occurred
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500272 * @irq: IRQ tracking structures
Ingrid Gallardo72cd1632018-02-28 15:26:37 -0800273 * @cont_splash_single_flush Variable to check if single flush is enabled.
274 * @cont_splash_settings Variable to store continuous splash settings.
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -0700275 * @in_clone_mode Indicates if encoder is in clone mode ref@CWB
Kalyan Thota6a9f3b72018-01-18 18:00:02 +0530276 * @vfp_cached: cached vertical front porch to be used for
277 * programming ROT and MDP fetch start
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400278 */
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400279struct sde_encoder_phys {
280 struct drm_encoder *parent;
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400281 struct drm_connector *connector;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400282 struct sde_encoder_phys_ops ops;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400283 struct sde_encoder_virt_ops parent_ops;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400284 struct sde_hw_mdp *hw_mdptop;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400285 struct sde_hw_ctl *hw_ctl;
Alan Kwongbb27c092016-07-20 16:41:25 -0400286 struct sde_hw_cdm *hw_cdm;
287 struct sde_hw_cdm_cfg cdm_cfg;
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700288 struct sde_hw_pingpong *hw_pp;
Ben Chan78647cd2016-06-26 22:02:47 -0400289 struct sde_kms *sde_kms;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400290 struct drm_display_mode cached_mode;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400291 enum sde_enc_split_role split_role;
Clarence Ip03521982016-08-26 10:49:47 -0400292 enum sde_intf_mode intf_mode;
Dhaval Patel81e87882016-10-19 21:41:56 -0700293 enum sde_intf intf_idx;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800294 enum msm_display_compression_type comp_type;
Narender Ankam1afbd172020-03-16 17:27:44 +0530295 enum sde_csc_type enc_cdm_csc;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400296 spinlock_t *enc_spinlock;
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400297 enum sde_enc_enable_state enable_state;
Raviteja Tamatam3ea60b82018-04-27 15:41:18 +0530298 struct mutex *vblank_ctl_lock;
Alan Kwongbaa56352016-10-04 09:38:11 -0400299 atomic_t vblank_refcount;
Shubhashree Dhar5c9e2022018-09-03 15:49:42 +0530300 atomic_t wbirq_refcount;
Dhaval Patel81e87882016-10-19 21:41:56 -0700301 atomic_t vsync_cnt;
302 atomic_t underrun_cnt;
Dhaval Patel0e558f42017-04-30 00:51:40 -0700303 atomic_t pending_ctlstart_cnt;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400304 atomic_t pending_kickoff_cnt;
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700305 atomic_t pending_retire_fence_cnt;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400306 wait_queue_head_t pending_kickoff_wq;
Krishna Manikandanfb29f692019-04-09 17:00:41 +0530307 atomic_t ctlstart_timeout;
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500308 struct sde_encoder_irq irq[INTR_IDX_MAX];
Ingrid Gallardo72cd1632018-02-28 15:26:37 -0800309 u32 cont_splash_single_flush;
310 bool cont_splash_settings;
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -0700311 bool in_clone_mode;
Kalyan Thota6a9f3b72018-01-18 18:00:02 +0530312 int vfp_cached;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400313};
314
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400315static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)
316{
Dhaval Patel0e558f42017-04-30 00:51:40 -0700317 atomic_inc_return(&phys->pending_ctlstart_cnt);
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400318 return atomic_inc_return(&phys->pending_kickoff_cnt);
319}
320
Ben Chan78647cd2016-06-26 22:02:47 -0400321/**
322 * struct sde_encoder_phys_vid - sub-class of sde_encoder_phys to handle video
323 * mode specific operations
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400324 * @base: Baseclass physical encoder structure
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400325 * @hw_intf: Hardware interface to the intf registers
Alan Kwong4aacd532017-02-04 18:51:33 -0800326 * @timing_params: Current timing parameter
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400327 * @rot_fetch: Prefill for inline rotation
Clarence Ip569d5af2017-10-14 21:09:01 -0400328 * @error_count: Number of consecutive kickoffs that experienced an error
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400329 * @rot_fetch_valid: true if rot_fetch is updated (reset in enc enable)
Ben Chan78647cd2016-06-26 22:02:47 -0400330 */
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400331struct sde_encoder_phys_vid {
332 struct sde_encoder_phys base;
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400333 struct sde_hw_intf *hw_intf;
Alan Kwong4aacd532017-02-04 18:51:33 -0800334 struct intf_timing_params timing_params;
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400335 struct intf_prog_fetch rot_fetch;
Clarence Ip569d5af2017-10-14 21:09:01 -0400336 int error_count;
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400337 bool rot_fetch_valid;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400338};
339
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400340/**
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500341 * struct sde_encoder_phys_cmd_autorefresh - autorefresh state tracking
342 * @cfg: current active autorefresh configuration
343 * @kickoff_cnt: atomic count tracking autorefresh done irq kickoffs pending
344 * @kickoff_wq: wait queue for waiting on autorefresh done irq
345 */
346struct sde_encoder_phys_cmd_autorefresh {
347 struct sde_hw_autorefresh cfg;
348 atomic_t kickoff_cnt;
349 wait_queue_head_t kickoff_wq;
350};
351
352/**
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400353 * struct sde_encoder_phys_cmd - sub-class of sde_encoder_phys to handle command
354 * mode specific operations
355 * @base: Baseclass physical encoder structure
356 * @intf_idx: Intf Block index used by this phys encoder
357 * @stream_sel: Stream selection for multi-stream interfaces
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500358 * @serialize_wait4pp: serialize wait4pp feature waits for pp_done interrupt
359 * after ctl_start instead of before next frame kickoff
360 * @pp_timeout_report_cnt: number of pingpong done irq timeout errors
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400361 * @autorefresh: autorefresh feature state
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700362 * @pending_rd_ptr_cnt: atomic counter to indicate if retire fence can be
363 * signaled at the next rd_ptr_irq
Veera Sundaram Sankaran91f5c912017-07-27 10:26:19 -0700364 * @rd_ptr_timestamp: last rd_ptr_irq timestamp
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400365 * @pending_vblank_cnt: Atomic counter tracking pending wait for VBLANK
366 * @pending_vblank_wq: Wait queue for blocking until VBLANK received
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400367 */
368struct sde_encoder_phys_cmd {
369 struct sde_encoder_phys base;
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400370 int stream_sel;
Dhaval Patel056e7622017-01-25 13:23:02 -0800371 bool serialize_wait4pp;
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500372 int pp_timeout_report_cnt;
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500373 struct sde_encoder_phys_cmd_autorefresh autorefresh;
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700374 atomic_t pending_rd_ptr_cnt;
Veera Sundaram Sankaran91f5c912017-07-27 10:26:19 -0700375 ktime_t rd_ptr_timestamp;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400376 atomic_t pending_vblank_cnt;
377 wait_queue_head_t pending_vblank_wq;
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400378};
379
380/**
Alan Kwongbb27c092016-07-20 16:41:25 -0400381 * struct sde_encoder_phys_wb - sub-class of sde_encoder_phys to handle
382 * writeback specific operations
383 * @base: Baseclass physical encoder structure
384 * @hw_wb: Hardware interface to the wb registers
Alan Kwongbb27c092016-07-20 16:41:25 -0400385 * @wbdone_timeout: Timeout value for writeback done in msec
386 * @bypass_irqreg: Bypass irq register/unregister if non-zero
387 * @wbdone_complete: for wbdone irq synchronization
388 * @wb_cfg: Writeback hardware configuration
Alan Kwong143f50c2017-04-28 07:34:28 -0700389 * @cdp_cfg: Writeback CDP configuration
Alan Kwongbb27c092016-07-20 16:41:25 -0400390 * @intf_cfg: Interface hardware configuration
391 * @wb_roi: Writeback region-of-interest
392 * @wb_fmt: Writeback pixel format
Alan Kwong03b89842017-08-17 16:32:45 -0400393 * @wb_fb: Pointer to current writeback framebuffer
394 * @wb_aspace: Pointer to current writeback address space
Alan Kwongbb27c092016-07-20 16:41:25 -0400395 * @frame_count: Counter of completed writeback operations
396 * @kickoff_count: Counter of issued writeback operations
Jordan Croused8e96522017-02-13 10:14:16 -0700397 * @aspace: address space identifier for non-secure/secure domain
Alan Kwongbb27c092016-07-20 16:41:25 -0400398 * @wb_dev: Pointer to writeback device
399 * @start_time: Start time of writeback latest request
400 * @end_time: End time of writeback latest request
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700401 * @bo_disable: Buffer object(s) to use during the disabling state
402 * @fb_disable: Frame buffer to use during the disabling state
Harsh Sahufae4d812017-11-29 15:08:59 -0800403 * @crtc Pointer to drm_crtc
Alan Kwongbb27c092016-07-20 16:41:25 -0400404 */
405struct sde_encoder_phys_wb {
406 struct sde_encoder_phys base;
407 struct sde_hw_wb *hw_wb;
Alan Kwongbb27c092016-07-20 16:41:25 -0400408 u32 wbdone_timeout;
409 u32 bypass_irqreg;
410 struct completion wbdone_complete;
411 struct sde_hw_wb_cfg wb_cfg;
Alan Kwong143f50c2017-04-28 07:34:28 -0700412 struct sde_hw_wb_cdp_cfg cdp_cfg;
Alan Kwongbb27c092016-07-20 16:41:25 -0400413 struct sde_hw_intf_cfg intf_cfg;
414 struct sde_rect wb_roi;
415 const struct sde_format *wb_fmt;
Alan Kwong03b89842017-08-17 16:32:45 -0400416 struct drm_framebuffer *wb_fb;
417 struct msm_gem_address_space *wb_aspace;
Alan Kwongbb27c092016-07-20 16:41:25 -0400418 u32 frame_count;
419 u32 kickoff_count;
Jordan Croused8e96522017-02-13 10:14:16 -0700420 struct msm_gem_address_space *aspace[SDE_IOMMU_DOMAIN_MAX];
Alan Kwongbb27c092016-07-20 16:41:25 -0400421 struct sde_wb_device *wb_dev;
422 ktime_t start_time;
423 ktime_t end_time;
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700424 struct drm_gem_object *bo_disable[SDE_MAX_PLANES];
425 struct drm_framebuffer *fb_disable;
Harsh Sahufae4d812017-11-29 15:08:59 -0800426 struct drm_crtc *crtc;
Alan Kwongbb27c092016-07-20 16:41:25 -0400427};
428
429/**
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400430 * struct sde_enc_phys_init_params - initialization parameters for phys encs
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400431 * @sde_kms: Pointer to the sde_kms top level
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400432 * @parent: Pointer to the containing virtual encoder
433 * @parent_ops: Callbacks exposed by the parent to the phys_enc
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400434 * @split_role: Role to play in a split-panel configuration
435 * @intf_idx: Interface index this phys_enc will control
436 * @wb_idx: Writeback index this phys_enc will control
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800437 * @comp_type: Type of compression supported
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400438 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400439 */
440struct sde_enc_phys_init_params {
441 struct sde_kms *sde_kms;
442 struct drm_encoder *parent;
443 struct sde_encoder_virt_ops parent_ops;
444 enum sde_enc_split_role split_role;
445 enum sde_intf intf_idx;
446 enum sde_wb wb_idx;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800447 enum msm_display_compression_type comp_type;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400448 spinlock_t *enc_spinlock;
Raviteja Tamatam3ea60b82018-04-27 15:41:18 +0530449 struct mutex *vblank_ctl_lock;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400450};
451
452/**
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500453 * sde_encoder_wait_info - container for passing arguments to irq wait functions
454 * @wq: wait queue structure
455 * @atomic_cnt: wait until atomic_cnt equals zero
456 * @timeout_ms: timeout value in milliseconds
457 */
458struct sde_encoder_wait_info {
459 wait_queue_head_t *wq;
460 atomic_t *atomic_cnt;
461 s64 timeout_ms;
462};
463
464/**
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400465 * sde_encoder_phys_vid_init - Construct a new video mode physical encoder
466 * @p: Pointer to init params structure
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400467 * Return: Error code or newly allocated encoder
468 */
469struct sde_encoder_phys *sde_encoder_phys_vid_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400470 struct sde_enc_phys_init_params *p);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400471
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400472/**
473 * sde_encoder_phys_cmd_init - Construct a new command mode physical encoder
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400474 * @p: Pointer to init params structure
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400475 * Return: Error code or newly allocated encoder
476 */
477struct sde_encoder_phys *sde_encoder_phys_cmd_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400478 struct sde_enc_phys_init_params *p);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400479
Alan Kwongbb27c092016-07-20 16:41:25 -0400480/**
481 * sde_encoder_phys_wb_init - Construct a new writeback physical encoder
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400482 * @p: Pointer to init params structure
Alan Kwongbb27c092016-07-20 16:41:25 -0400483 * Return: Error code or newly allocated encoder
484 */
485#ifdef CONFIG_DRM_SDE_WB
486struct sde_encoder_phys *sde_encoder_phys_wb_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400487 struct sde_enc_phys_init_params *p);
Alan Kwongbb27c092016-07-20 16:41:25 -0400488#else
489static inline
490struct sde_encoder_phys *sde_encoder_phys_wb_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400491 struct sde_enc_phys_init_params *p)
Alan Kwongbb27c092016-07-20 16:41:25 -0400492{
493 return NULL;
494}
495#endif
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400496
Alan Kwongbb27c092016-07-20 16:41:25 -0400497void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
Chirag Khuranaed859f52019-11-20 18:18:12 +0530498 const struct sde_format *format, u32 output_type,
499 struct sde_rect *roi);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400500
Clarence Ip110d15c2016-08-16 14:44:41 -0400501/**
Alan Kwong4212dd42017-09-19 17:22:33 -0400502 * sde_encoder_helper_trigger_flush - control flush helper function
503 * This helper function may be optionally specified by physical
504 * encoders if they require ctl_flush triggering.
505 * @phys_enc: Pointer to physical encoder structure
506 */
507void sde_encoder_helper_trigger_flush(struct sde_encoder_phys *phys_enc);
508
509/**
Clarence Ip110d15c2016-08-16 14:44:41 -0400510 * sde_encoder_helper_trigger_start - control start helper function
511 * This helper function may be optionally specified by physical
512 * encoders if they require ctl_start triggering.
513 * @phys_enc: Pointer to physical encoder structure
514 */
515void sde_encoder_helper_trigger_start(struct sde_encoder_phys *phys_enc);
516
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500517/**
518 * sde_encoder_helper_wait_event_timeout - wait for event with timeout
519 * taking into account that jiffies may jump between reads leading to
520 * incorrectly detected timeouts. Prevent failure in this scenario by
521 * making sure that elapsed time during wait is valid.
522 * @drm_id: drm object id for logging
523 * @hw_id: hw instance id for logging
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500524 * @info: wait info structure
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500525 */
526int sde_encoder_helper_wait_event_timeout(
527 int32_t drm_id,
528 int32_t hw_id,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500529 struct sde_encoder_wait_info *info);
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500530
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500531/**
532 * sde_encoder_helper_hw_reset - issue ctl hw reset
533 * This helper function may be optionally specified by physical
534 * encoders if they require ctl hw reset. If state is currently
535 * SDE_ENC_ERR_NEEDS_HW_RESET, it is set back to SDE_ENC_ENABLED.
536 * @phys_enc: Pointer to physical encoder structure
537 */
538void sde_encoder_helper_hw_reset(struct sde_encoder_phys *phys_enc);
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400539
540static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
541 struct sde_encoder_phys *phys_enc)
542{
543 enum sde_rm_topology_name topology;
544
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700545 if (!phys_enc || phys_enc->enable_state == SDE_ENC_DISABLING)
546 return BLEND_3D_NONE;
547
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400548 topology = sde_connector_get_topology_name(phys_enc->connector);
549 if (phys_enc->split_role == ENC_ROLE_SOLO &&
Ingrid Gallardo83532222017-06-02 16:48:51 -0700550 (topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE ||
551 topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC))
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400552 return BLEND_3D_H_ROW_INT;
553
Kalyan Thota27ec06c2019-03-18 13:19:59 +0530554 if ((phys_enc->split_role == ENC_ROLE_MASTER ||
555 phys_enc->split_role == ENC_ROLE_SLAVE) &&
556 ((topology == SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE) ||
557 (topology == SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC)))
558 return BLEND_3D_H_ROW_INT;
559
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400560 return BLEND_3D_NONE;
561}
562
Clarence Ip8e69ad02016-12-09 09:43:57 -0500563/**
564 * sde_encoder_helper_split_config - split display configuration helper function
565 * This helper function may be used by physical encoders to configure
566 * the split display related registers.
567 * @phys_enc: Pointer to physical encoder structure
568 * @interface: enum sde_intf setting
569 */
570void sde_encoder_helper_split_config(
571 struct sde_encoder_phys *phys_enc,
572 enum sde_intf interface);
573
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700574/**
Clarence Ip662698e2017-09-12 18:34:16 -0400575 * sde_encoder_helper_reset_mixers - reset mixers associated with phys enc
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700576 * @phys_enc: Pointer to physical encoder structure
577 * @fb: Optional fb for specifying new mixer output resolution, may be NULL
578 * Return: Zero on success
579 */
Clarence Ip662698e2017-09-12 18:34:16 -0400580int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc,
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700581 struct drm_framebuffer *fb);
582
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500583/**
584 * sde_encoder_helper_report_irq_timeout - utility to report error that irq has
585 * timed out, including reporting frame error event to crtc and debug dump
586 * @phys_enc: Pointer to physical encoder structure
587 * @intr_idx: Failing interrupt index
588 */
589void sde_encoder_helper_report_irq_timeout(struct sde_encoder_phys *phys_enc,
590 enum sde_intr_idx intr_idx);
591
592/**
593 * sde_encoder_helper_wait_for_irq - utility to wait on an irq.
594 * note: will call sde_encoder_helper_wait_for_irq on timeout
595 * @phys_enc: Pointer to physical encoder structure
596 * @intr_idx: encoder interrupt index
597 * @wait_info: wait info struct
598 * @Return: 0 or -ERROR
599 */
600int sde_encoder_helper_wait_for_irq(struct sde_encoder_phys *phys_enc,
601 enum sde_intr_idx intr_idx,
602 struct sde_encoder_wait_info *wait_info);
603
604/**
605 * sde_encoder_helper_register_irq - register and enable an irq
606 * @phys_enc: Pointer to physical encoder structure
607 * @intr_idx: encoder interrupt index
608 * @Return: 0 or -ERROR
609 */
610int sde_encoder_helper_register_irq(struct sde_encoder_phys *phys_enc,
611 enum sde_intr_idx intr_idx);
612
613/**
614 * sde_encoder_helper_unregister_irq - unregister and disable an irq
615 * @phys_enc: Pointer to physical encoder structure
616 * @intr_idx: encoder interrupt index
617 * @Return: 0 or -ERROR
618 */
619int sde_encoder_helper_unregister_irq(struct sde_encoder_phys *phys_enc,
620 enum sde_intr_idx intr_idx);
621
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400622#endif /* __sde_encoder_phys_H__ */