blob: a877eb52f0a30ee5b65c5452ca0f9103b999dc67 [file] [log] [blame]
Lloyd Atkinson09fed912016-06-24 18:14:13 -04001/*
Dhaval Patel81e87882016-10-19 21:41:56 -07002 * Copyright (c) 2015-2017 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
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500197 * @INTR_IDX_AUTOREFRESH_DONE: Autorefresh done for cmd mode panel meaning
198 * autorefresh has triggered a double buffer flip
Dhaval Patel81e87882016-10-19 21:41:56 -0700199 */
200enum sde_intr_idx {
201 INTR_IDX_VSYNC,
202 INTR_IDX_PINGPONG,
203 INTR_IDX_UNDERRUN,
Dhaval Patel0e558f42017-04-30 00:51:40 -0700204 INTR_IDX_CTL_START,
Dhaval Patel81e87882016-10-19 21:41:56 -0700205 INTR_IDX_RDPTR,
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500206 INTR_IDX_AUTOREFRESH_DONE,
Dhaval Patel81e87882016-10-19 21:41:56 -0700207 INTR_IDX_MAX,
208};
209
210/**
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500211 * sde_encoder_irq - tracking structure for interrupts
212 * @name: string name of interrupt
213 * @intr_type: Encoder interrupt type
214 * @intr_idx: Encoder interrupt enumeration
215 * @hw_idx: HW Block ID
216 * @irq_idx: IRQ interface lookup index from SDE IRQ framework
217 * will be -EINVAL if IRQ is not registered
218 * @irq_cb: interrupt callback
219 */
220struct sde_encoder_irq {
221 const char *name;
222 enum sde_intr_type intr_type;
223 enum sde_intr_idx intr_idx;
224 int hw_idx;
225 int irq_idx;
226 struct sde_irq_callback cb;
227};
228
229/**
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400230 * struct sde_encoder_phys - physical encoder that drives a single INTF block
231 * tied to a specific panel / sub-panel. Abstract type, sub-classed by
232 * phys_vid or phys_cmd for video mode or command mode encs respectively.
233 * @parent: Pointer to the containing virtual encoder
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400234 * @connector: If a mode is set, cached pointer to the active connector
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400235 * @ops: Operations exposed to the virtual encoder
236 * @parent_ops: Callbacks exposed by the parent to the phys_enc
237 * @hw_mdptop: Hardware interface to the top registers
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400238 * @hw_ctl: Hardware interface to the ctl registers
Alan Kwongbb27c092016-07-20 16:41:25 -0400239 * @hw_cdm: Hardware interface to the cdm registers
240 * @cdm_cfg: Chroma-down hardware configuration
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700241 * @hw_pp: Hardware interface to the ping pong registers
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400242 * @sde_kms: Pointer to the sde_kms top level
243 * @cached_mode: DRM mode cached at mode_set time, acted on in enable
244 * @enabled: Whether the encoder has enabled and running a mode
245 * @split_role: Role to play in a split-panel configuration
Clarence Ip03521982016-08-26 10:49:47 -0400246 * @intf_mode: Interface mode
Dhaval Patel81e87882016-10-19 21:41:56 -0700247 * @intf_idx: Interface index on sde hardware
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800248 * @comp_type: Type of compression supported
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400249 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400250 * @enable_state: Enable state tracking
Alan Kwongbaa56352016-10-04 09:38:11 -0400251 * @vblank_refcount: Reference count of vblank request
Dhaval Patel81e87882016-10-19 21:41:56 -0700252 * @vsync_cnt: Vsync count for the physical encoder
253 * @underrun_cnt: Underrun count for the physical encoder
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400254 * @pending_kickoff_cnt: Atomic counter tracking the number of kickoffs
255 * vs. the number of done/vblank irqs. Should hover
256 * between 0-2 Incremented when a new kickoff is
257 * scheduled. Decremented in irq handler
Dhaval Patel0e558f42017-04-30 00:51:40 -0700258 * @pending_ctlstart_cnt: Atomic counter tracking the number of ctl start
259 * pending.
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700260 * @pending_retire_fence_cnt: Atomic counter tracking the pending retire
261 * fences that have to be signalled.
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400262 * @pending_kickoff_wq: Wait queue for blocking until kickoff completes
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500263 * @irq: IRQ tracking structures
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400264 */
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400265struct sde_encoder_phys {
266 struct drm_encoder *parent;
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400267 struct drm_connector *connector;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400268 struct sde_encoder_phys_ops ops;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400269 struct sde_encoder_virt_ops parent_ops;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400270 struct sde_hw_mdp *hw_mdptop;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400271 struct sde_hw_ctl *hw_ctl;
Alan Kwongbb27c092016-07-20 16:41:25 -0400272 struct sde_hw_cdm *hw_cdm;
273 struct sde_hw_cdm_cfg cdm_cfg;
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700274 struct sde_hw_pingpong *hw_pp;
Ben Chan78647cd2016-06-26 22:02:47 -0400275 struct sde_kms *sde_kms;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400276 struct drm_display_mode cached_mode;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400277 enum sde_enc_split_role split_role;
Clarence Ip03521982016-08-26 10:49:47 -0400278 enum sde_intf_mode intf_mode;
Dhaval Patel81e87882016-10-19 21:41:56 -0700279 enum sde_intf intf_idx;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800280 enum msm_display_compression_type comp_type;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400281 spinlock_t *enc_spinlock;
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400282 enum sde_enc_enable_state enable_state;
Alan Kwongbaa56352016-10-04 09:38:11 -0400283 atomic_t vblank_refcount;
Dhaval Patel81e87882016-10-19 21:41:56 -0700284 atomic_t vsync_cnt;
285 atomic_t underrun_cnt;
Dhaval Patel0e558f42017-04-30 00:51:40 -0700286 atomic_t pending_ctlstart_cnt;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400287 atomic_t pending_kickoff_cnt;
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700288 atomic_t pending_retire_fence_cnt;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400289 wait_queue_head_t pending_kickoff_wq;
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500290 struct sde_encoder_irq irq[INTR_IDX_MAX];
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400291};
292
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400293static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)
294{
Dhaval Patel0e558f42017-04-30 00:51:40 -0700295 atomic_inc_return(&phys->pending_ctlstart_cnt);
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400296 return atomic_inc_return(&phys->pending_kickoff_cnt);
297}
298
Ben Chan78647cd2016-06-26 22:02:47 -0400299/**
300 * struct sde_encoder_phys_vid - sub-class of sde_encoder_phys to handle video
301 * mode specific operations
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400302 * @base: Baseclass physical encoder structure
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400303 * @hw_intf: Hardware interface to the intf registers
Alan Kwong4aacd532017-02-04 18:51:33 -0800304 * @timing_params: Current timing parameter
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400305 * @rot_fetch: Prefill for inline rotation
Clarence Ip569d5af2017-10-14 21:09:01 -0400306 * @error_count: Number of consecutive kickoffs that experienced an error
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400307 * @rot_fetch_valid: true if rot_fetch is updated (reset in enc enable)
Ben Chan78647cd2016-06-26 22:02:47 -0400308 */
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400309struct sde_encoder_phys_vid {
310 struct sde_encoder_phys base;
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400311 struct sde_hw_intf *hw_intf;
Alan Kwong4aacd532017-02-04 18:51:33 -0800312 struct intf_timing_params timing_params;
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400313 struct intf_prog_fetch rot_fetch;
Clarence Ip569d5af2017-10-14 21:09:01 -0400314 int error_count;
Alan Kwongf5fd32b2017-08-18 11:24:31 -0400315 bool rot_fetch_valid;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400316};
317
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400318/**
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500319 * struct sde_encoder_phys_cmd_autorefresh - autorefresh state tracking
320 * @cfg: current active autorefresh configuration
321 * @kickoff_cnt: atomic count tracking autorefresh done irq kickoffs pending
322 * @kickoff_wq: wait queue for waiting on autorefresh done irq
323 */
324struct sde_encoder_phys_cmd_autorefresh {
325 struct sde_hw_autorefresh cfg;
326 atomic_t kickoff_cnt;
327 wait_queue_head_t kickoff_wq;
328};
329
330/**
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400331 * struct sde_encoder_phys_cmd - sub-class of sde_encoder_phys to handle command
332 * mode specific operations
333 * @base: Baseclass physical encoder structure
334 * @intf_idx: Intf Block index used by this phys encoder
335 * @stream_sel: Stream selection for multi-stream interfaces
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500336 * @serialize_wait4pp: serialize wait4pp feature waits for pp_done interrupt
337 * after ctl_start instead of before next frame kickoff
338 * @pp_timeout_report_cnt: number of pingpong done irq timeout errors
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400339 * @autorefresh: autorefresh feature state
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700340 * @pending_rd_ptr_cnt: atomic counter to indicate if retire fence can be
341 * signaled at the next rd_ptr_irq
Veera Sundaram Sankaran91f5c912017-07-27 10:26:19 -0700342 * @rd_ptr_timestamp: last rd_ptr_irq timestamp
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400343 * @pending_vblank_cnt: Atomic counter tracking pending wait for VBLANK
344 * @pending_vblank_wq: Wait queue for blocking until VBLANK received
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400345 */
346struct sde_encoder_phys_cmd {
347 struct sde_encoder_phys base;
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400348 int stream_sel;
Dhaval Patel056e7622017-01-25 13:23:02 -0800349 bool serialize_wait4pp;
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500350 int pp_timeout_report_cnt;
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500351 struct sde_encoder_phys_cmd_autorefresh autorefresh;
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700352 atomic_t pending_rd_ptr_cnt;
Veera Sundaram Sankaran91f5c912017-07-27 10:26:19 -0700353 ktime_t rd_ptr_timestamp;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400354 atomic_t pending_vblank_cnt;
355 wait_queue_head_t pending_vblank_wq;
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400356};
357
358/**
Alan Kwongbb27c092016-07-20 16:41:25 -0400359 * struct sde_encoder_phys_wb - sub-class of sde_encoder_phys to handle
360 * writeback specific operations
361 * @base: Baseclass physical encoder structure
362 * @hw_wb: Hardware interface to the wb registers
363 * @irq_idx: IRQ interface lookup index
364 * @wbdone_timeout: Timeout value for writeback done in msec
365 * @bypass_irqreg: Bypass irq register/unregister if non-zero
366 * @wbdone_complete: for wbdone irq synchronization
367 * @wb_cfg: Writeback hardware configuration
Alan Kwong143f50c2017-04-28 07:34:28 -0700368 * @cdp_cfg: Writeback CDP configuration
Alan Kwongbb27c092016-07-20 16:41:25 -0400369 * @intf_cfg: Interface hardware configuration
370 * @wb_roi: Writeback region-of-interest
371 * @wb_fmt: Writeback pixel format
Alan Kwong03b89842017-08-17 16:32:45 -0400372 * @wb_fb: Pointer to current writeback framebuffer
373 * @wb_aspace: Pointer to current writeback address space
Alan Kwongbb27c092016-07-20 16:41:25 -0400374 * @frame_count: Counter of completed writeback operations
375 * @kickoff_count: Counter of issued writeback operations
Jordan Croused8e96522017-02-13 10:14:16 -0700376 * @aspace: address space identifier for non-secure/secure domain
Alan Kwongbb27c092016-07-20 16:41:25 -0400377 * @wb_dev: Pointer to writeback device
378 * @start_time: Start time of writeback latest request
379 * @end_time: End time of writeback latest request
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700380 * @bo_disable: Buffer object(s) to use during the disabling state
381 * @fb_disable: Frame buffer to use during the disabling state
Harsh Sahufae4d812017-11-29 15:08:59 -0800382 * @crtc Pointer to drm_crtc
Alan Kwongbb27c092016-07-20 16:41:25 -0400383 */
384struct sde_encoder_phys_wb {
385 struct sde_encoder_phys base;
386 struct sde_hw_wb *hw_wb;
387 int irq_idx;
Alan Kwonga172ef52016-09-27 00:29:10 -0400388 struct sde_irq_callback irq_cb;
Alan Kwongbb27c092016-07-20 16:41:25 -0400389 u32 wbdone_timeout;
390 u32 bypass_irqreg;
391 struct completion wbdone_complete;
392 struct sde_hw_wb_cfg wb_cfg;
Alan Kwong143f50c2017-04-28 07:34:28 -0700393 struct sde_hw_wb_cdp_cfg cdp_cfg;
Alan Kwongbb27c092016-07-20 16:41:25 -0400394 struct sde_hw_intf_cfg intf_cfg;
395 struct sde_rect wb_roi;
396 const struct sde_format *wb_fmt;
Alan Kwong03b89842017-08-17 16:32:45 -0400397 struct drm_framebuffer *wb_fb;
398 struct msm_gem_address_space *wb_aspace;
Alan Kwongbb27c092016-07-20 16:41:25 -0400399 u32 frame_count;
400 u32 kickoff_count;
Jordan Croused8e96522017-02-13 10:14:16 -0700401 struct msm_gem_address_space *aspace[SDE_IOMMU_DOMAIN_MAX];
Alan Kwongbb27c092016-07-20 16:41:25 -0400402 struct sde_wb_device *wb_dev;
403 ktime_t start_time;
404 ktime_t end_time;
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700405 struct drm_gem_object *bo_disable[SDE_MAX_PLANES];
406 struct drm_framebuffer *fb_disable;
Harsh Sahufae4d812017-11-29 15:08:59 -0800407 struct drm_crtc *crtc;
Alan Kwongbb27c092016-07-20 16:41:25 -0400408};
409
410/**
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400411 * struct sde_enc_phys_init_params - initialization parameters for phys encs
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400412 * @sde_kms: Pointer to the sde_kms top level
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400413 * @parent: Pointer to the containing virtual encoder
414 * @parent_ops: Callbacks exposed by the parent to the phys_enc
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400415 * @split_role: Role to play in a split-panel configuration
416 * @intf_idx: Interface index this phys_enc will control
417 * @wb_idx: Writeback index this phys_enc will control
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800418 * @comp_type: Type of compression supported
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400419 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400420 */
421struct sde_enc_phys_init_params {
422 struct sde_kms *sde_kms;
423 struct drm_encoder *parent;
424 struct sde_encoder_virt_ops parent_ops;
425 enum sde_enc_split_role split_role;
426 enum sde_intf intf_idx;
427 enum sde_wb wb_idx;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800428 enum msm_display_compression_type comp_type;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400429 spinlock_t *enc_spinlock;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400430};
431
432/**
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500433 * sde_encoder_wait_info - container for passing arguments to irq wait functions
434 * @wq: wait queue structure
435 * @atomic_cnt: wait until atomic_cnt equals zero
436 * @timeout_ms: timeout value in milliseconds
437 */
438struct sde_encoder_wait_info {
439 wait_queue_head_t *wq;
440 atomic_t *atomic_cnt;
441 s64 timeout_ms;
442};
443
444/**
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400445 * sde_encoder_phys_vid_init - Construct a new video mode physical encoder
446 * @p: Pointer to init params structure
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400447 * Return: Error code or newly allocated encoder
448 */
449struct sde_encoder_phys *sde_encoder_phys_vid_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400450 struct sde_enc_phys_init_params *p);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400451
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400452/**
453 * sde_encoder_phys_cmd_init - Construct a new command mode physical encoder
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400454 * @p: Pointer to init params structure
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400455 * Return: Error code or newly allocated encoder
456 */
457struct sde_encoder_phys *sde_encoder_phys_cmd_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400458 struct sde_enc_phys_init_params *p);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400459
Alan Kwongbb27c092016-07-20 16:41:25 -0400460/**
461 * sde_encoder_phys_wb_init - Construct a new writeback physical encoder
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400462 * @p: Pointer to init params structure
Alan Kwongbb27c092016-07-20 16:41:25 -0400463 * Return: Error code or newly allocated encoder
464 */
465#ifdef CONFIG_DRM_SDE_WB
466struct sde_encoder_phys *sde_encoder_phys_wb_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400467 struct sde_enc_phys_init_params *p);
Alan Kwongbb27c092016-07-20 16:41:25 -0400468#else
469static inline
470struct sde_encoder_phys *sde_encoder_phys_wb_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400471 struct sde_enc_phys_init_params *p)
Alan Kwongbb27c092016-07-20 16:41:25 -0400472{
473 return NULL;
474}
475#endif
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400476
Alan Kwongbb27c092016-07-20 16:41:25 -0400477void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
478 struct drm_framebuffer *fb, const struct sde_format *format,
479 struct sde_rect *wb_roi);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400480
Clarence Ip110d15c2016-08-16 14:44:41 -0400481/**
Alan Kwong4212dd42017-09-19 17:22:33 -0400482 * sde_encoder_helper_trigger_flush - control flush helper function
483 * This helper function may be optionally specified by physical
484 * encoders if they require ctl_flush triggering.
485 * @phys_enc: Pointer to physical encoder structure
486 */
487void sde_encoder_helper_trigger_flush(struct sde_encoder_phys *phys_enc);
488
489/**
Clarence Ip110d15c2016-08-16 14:44:41 -0400490 * sde_encoder_helper_trigger_start - control start helper function
491 * This helper function may be optionally specified by physical
492 * encoders if they require ctl_start triggering.
493 * @phys_enc: Pointer to physical encoder structure
494 */
495void sde_encoder_helper_trigger_start(struct sde_encoder_phys *phys_enc);
496
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500497/**
498 * sde_encoder_helper_wait_event_timeout - wait for event with timeout
499 * taking into account that jiffies may jump between reads leading to
500 * incorrectly detected timeouts. Prevent failure in this scenario by
501 * making sure that elapsed time during wait is valid.
502 * @drm_id: drm object id for logging
503 * @hw_id: hw instance id for logging
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500504 * @info: wait info structure
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500505 */
506int sde_encoder_helper_wait_event_timeout(
507 int32_t drm_id,
508 int32_t hw_id,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500509 struct sde_encoder_wait_info *info);
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500510
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500511/**
512 * sde_encoder_helper_hw_reset - issue ctl hw reset
513 * This helper function may be optionally specified by physical
514 * encoders if they require ctl hw reset. If state is currently
515 * SDE_ENC_ERR_NEEDS_HW_RESET, it is set back to SDE_ENC_ENABLED.
516 * @phys_enc: Pointer to physical encoder structure
517 */
518void sde_encoder_helper_hw_reset(struct sde_encoder_phys *phys_enc);
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400519
520static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
521 struct sde_encoder_phys *phys_enc)
522{
523 enum sde_rm_topology_name topology;
524
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700525 if (!phys_enc || phys_enc->enable_state == SDE_ENC_DISABLING)
526 return BLEND_3D_NONE;
527
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400528 topology = sde_connector_get_topology_name(phys_enc->connector);
529 if (phys_enc->split_role == ENC_ROLE_SOLO &&
Ingrid Gallardo83532222017-06-02 16:48:51 -0700530 (topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE ||
531 topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC))
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400532 return BLEND_3D_H_ROW_INT;
533
534 return BLEND_3D_NONE;
535}
536
Clarence Ip8e69ad02016-12-09 09:43:57 -0500537/**
538 * sde_encoder_helper_split_config - split display configuration helper function
539 * This helper function may be used by physical encoders to configure
540 * the split display related registers.
541 * @phys_enc: Pointer to physical encoder structure
542 * @interface: enum sde_intf setting
543 */
544void sde_encoder_helper_split_config(
545 struct sde_encoder_phys *phys_enc,
546 enum sde_intf interface);
547
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700548/**
Clarence Ip662698e2017-09-12 18:34:16 -0400549 * sde_encoder_helper_reset_mixers - reset mixers associated with phys enc
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700550 * @phys_enc: Pointer to physical encoder structure
551 * @fb: Optional fb for specifying new mixer output resolution, may be NULL
552 * Return: Zero on success
553 */
Clarence Ip662698e2017-09-12 18:34:16 -0400554int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc,
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700555 struct drm_framebuffer *fb);
556
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500557/**
558 * sde_encoder_helper_report_irq_timeout - utility to report error that irq has
559 * timed out, including reporting frame error event to crtc and debug dump
560 * @phys_enc: Pointer to physical encoder structure
561 * @intr_idx: Failing interrupt index
562 */
563void sde_encoder_helper_report_irq_timeout(struct sde_encoder_phys *phys_enc,
564 enum sde_intr_idx intr_idx);
565
566/**
567 * sde_encoder_helper_wait_for_irq - utility to wait on an irq.
568 * note: will call sde_encoder_helper_wait_for_irq on timeout
569 * @phys_enc: Pointer to physical encoder structure
570 * @intr_idx: encoder interrupt index
571 * @wait_info: wait info struct
572 * @Return: 0 or -ERROR
573 */
574int sde_encoder_helper_wait_for_irq(struct sde_encoder_phys *phys_enc,
575 enum sde_intr_idx intr_idx,
576 struct sde_encoder_wait_info *wait_info);
577
578/**
579 * sde_encoder_helper_register_irq - register and enable an irq
580 * @phys_enc: Pointer to physical encoder structure
581 * @intr_idx: encoder interrupt index
582 * @Return: 0 or -ERROR
583 */
584int sde_encoder_helper_register_irq(struct sde_encoder_phys *phys_enc,
585 enum sde_intr_idx intr_idx);
586
587/**
588 * sde_encoder_helper_unregister_irq - unregister and disable an irq
589 * @phys_enc: Pointer to physical encoder structure
590 * @intr_idx: encoder interrupt index
591 * @Return: 0 or -ERROR
592 */
593int sde_encoder_helper_unregister_irq(struct sde_encoder_phys *phys_enc,
594 enum sde_intr_idx intr_idx);
595
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400596#endif /* __sde_encoder_phys_H__ */