blob: c1a40f5dac4feed6ab67861aa3d092d0bb754c77 [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.
102 * @mode_set: DRM Call. Set a DRM mode.
103 * This likely caches the mode, for use at enable.
104 * @enable: DRM Call. Enable a DRM mode.
105 * @disable: DRM Call. Disable mode.
Alan Kwongbb27c092016-07-20 16:41:25 -0400106 * @atomic_check: DRM Call. Atomic check new DRM state.
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400107 * @destroy: DRM Call. Destroy and release resources.
108 * @get_hw_resources: Populate the structure with the hardware
109 * resources that this phys_enc is using.
110 * Expect no overlap between phys_encs.
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400111 * @control_vblank_irq Register/Deregister for VBLANK IRQ
112 * @wait_for_commit_done: Wait for hardware to have flushed the
113 * current pending frames to hardware
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -0700114 * @wait_for_tx_complete: Wait for hardware to transfer the pixels
115 * to the panel
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400116 * @prepare_for_kickoff: Do any work necessary prior to a kickoff
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500117 * For CMD encoder, may wait for previous tx done
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400118 * @handle_post_kickoff: Do any work necessary post-kickoff work
Clarence Ip110d15c2016-08-16 14:44:41 -0400119 * @trigger_start: Process start event on physical encoder
Clarence Ip8e69ad02016-12-09 09:43:57 -0500120 * @needs_single_flush: Whether encoder slaves need to be flushed
Jayant Shekhar1d50ed22016-11-04 18:41:12 +0530121 * @setup_misr: Sets up MISR, enable and disables based on sysfs
122 * @collect_misr: Collects MISR data on frame update
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500123 * @hw_reset: Issue HW recovery such as CTL reset and clear
124 * SDE_ENC_ERR_NEEDS_HW_RESET state
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700125 * @irq_control: Handler to enable/disable all the encoder IRQs
Lloyd Atkinson73fb8092017-02-08 16:02:55 -0500126 * @update_split_role: Update the split role of the phys enc
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -0700127 * @restore: Restore all the encoder configs.
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400128 */
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400129
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400130struct sde_encoder_phys_ops {
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -0700131 int (*late_register)(struct sde_encoder_phys *encoder,
132 struct dentry *debugfs_root);
Lloyd Atkinsone123c172017-02-27 13:19:08 -0500133 void (*prepare_commit)(struct sde_encoder_phys *encoder);
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400134 bool (*is_master)(struct sde_encoder_phys *encoder);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400135 bool (*mode_fixup)(struct sde_encoder_phys *encoder,
136 const struct drm_display_mode *mode,
137 struct drm_display_mode *adjusted_mode);
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400138 void (*mode_set)(struct sde_encoder_phys *encoder,
139 struct drm_display_mode *mode,
140 struct drm_display_mode *adjusted_mode);
141 void (*enable)(struct sde_encoder_phys *encoder);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400142 void (*disable)(struct sde_encoder_phys *encoder);
Alan Kwongbb27c092016-07-20 16:41:25 -0400143 int (*atomic_check)(struct sde_encoder_phys *encoder,
144 struct drm_crtc_state *crtc_state,
145 struct drm_connector_state *conn_state);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400146 void (*destroy)(struct sde_encoder_phys *encoder);
147 void (*get_hw_resources)(struct sde_encoder_phys *encoder,
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400148 struct sde_encoder_hw_resources *hw_res,
149 struct drm_connector_state *conn_state);
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400150 int (*control_vblank_irq)(struct sde_encoder_phys *enc, bool enable);
151 int (*wait_for_commit_done)(struct sde_encoder_phys *phys_enc);
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -0700152 int (*wait_for_tx_complete)(struct sde_encoder_phys *phys_enc);
Alan Kwong4aacd532017-02-04 18:51:33 -0800153 void (*prepare_for_kickoff)(struct sde_encoder_phys *phys_enc,
154 struct sde_encoder_kickoff_params *params);
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400155 void (*handle_post_kickoff)(struct sde_encoder_phys *phys_enc);
Clarence Ip110d15c2016-08-16 14:44:41 -0400156 void (*trigger_start)(struct sde_encoder_phys *phys_enc);
Clarence Ip8e69ad02016-12-09 09:43:57 -0500157 bool (*needs_single_flush)(struct sde_encoder_phys *phys_enc);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +0530158
159 void (*setup_misr)(struct sde_encoder_phys *phys_encs,
Dhaval Patelf9245d62017-03-28 16:24:00 -0700160 bool enable, u32 frame_count);
161 u32 (*collect_misr)(struct sde_encoder_phys *phys_enc);
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500162 void (*hw_reset)(struct sde_encoder_phys *phys_enc);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700163 void (*irq_control)(struct sde_encoder_phys *phys, bool enable);
Lloyd Atkinson73fb8092017-02-08 16:02:55 -0500164 void (*update_split_role)(struct sde_encoder_phys *phys_enc,
165 enum sde_enc_split_role role);
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -0700166 void (*restore)(struct sde_encoder_phys *phys);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400167};
168
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400169/**
Dhaval Patel81e87882016-10-19 21:41:56 -0700170 * enum sde_intr_idx - sde encoder interrupt index
171 * @INTR_IDX_VSYNC: Vsync interrupt for video mode panel
172 * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
173 * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
174 * @INTR_IDX_RDPTR: Readpointer done unterrupt for cmd mode panel
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500175 * @INTR_IDX_AUTOREFRESH_DONE: Autorefresh done for cmd mode panel meaning
176 * autorefresh has triggered a double buffer flip
Dhaval Patel81e87882016-10-19 21:41:56 -0700177 */
178enum sde_intr_idx {
179 INTR_IDX_VSYNC,
180 INTR_IDX_PINGPONG,
181 INTR_IDX_UNDERRUN,
Dhaval Patel0e558f42017-04-30 00:51:40 -0700182 INTR_IDX_CTL_START,
Dhaval Patel81e87882016-10-19 21:41:56 -0700183 INTR_IDX_RDPTR,
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500184 INTR_IDX_AUTOREFRESH_DONE,
Dhaval Patel81e87882016-10-19 21:41:56 -0700185 INTR_IDX_MAX,
186};
187
188/**
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500189 * sde_encoder_irq - tracking structure for interrupts
190 * @name: string name of interrupt
191 * @intr_type: Encoder interrupt type
192 * @intr_idx: Encoder interrupt enumeration
193 * @hw_idx: HW Block ID
194 * @irq_idx: IRQ interface lookup index from SDE IRQ framework
195 * will be -EINVAL if IRQ is not registered
196 * @irq_cb: interrupt callback
197 */
198struct sde_encoder_irq {
199 const char *name;
200 enum sde_intr_type intr_type;
201 enum sde_intr_idx intr_idx;
202 int hw_idx;
203 int irq_idx;
204 struct sde_irq_callback cb;
205};
206
207/**
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400208 * struct sde_encoder_phys - physical encoder that drives a single INTF block
209 * tied to a specific panel / sub-panel. Abstract type, sub-classed by
210 * phys_vid or phys_cmd for video mode or command mode encs respectively.
211 * @parent: Pointer to the containing virtual encoder
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400212 * @connector: If a mode is set, cached pointer to the active connector
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400213 * @ops: Operations exposed to the virtual encoder
214 * @parent_ops: Callbacks exposed by the parent to the phys_enc
215 * @hw_mdptop: Hardware interface to the top registers
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400216 * @hw_ctl: Hardware interface to the ctl registers
Alan Kwongbb27c092016-07-20 16:41:25 -0400217 * @hw_cdm: Hardware interface to the cdm registers
218 * @cdm_cfg: Chroma-down hardware configuration
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700219 * @hw_pp: Hardware interface to the ping pong registers
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400220 * @sde_kms: Pointer to the sde_kms top level
221 * @cached_mode: DRM mode cached at mode_set time, acted on in enable
222 * @enabled: Whether the encoder has enabled and running a mode
223 * @split_role: Role to play in a split-panel configuration
Clarence Ip03521982016-08-26 10:49:47 -0400224 * @intf_mode: Interface mode
Dhaval Patel81e87882016-10-19 21:41:56 -0700225 * @intf_idx: Interface index on sde hardware
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800226 * @comp_type: Type of compression supported
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400227 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400228 * @enable_state: Enable state tracking
Alan Kwongbaa56352016-10-04 09:38:11 -0400229 * @vblank_refcount: Reference count of vblank request
Dhaval Patel81e87882016-10-19 21:41:56 -0700230 * @vsync_cnt: Vsync count for the physical encoder
231 * @underrun_cnt: Underrun count for the physical encoder
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400232 * @pending_kickoff_cnt: Atomic counter tracking the number of kickoffs
233 * vs. the number of done/vblank irqs. Should hover
234 * between 0-2 Incremented when a new kickoff is
235 * scheduled. Decremented in irq handler
Dhaval Patel0e558f42017-04-30 00:51:40 -0700236 * @pending_ctlstart_cnt: Atomic counter tracking the number of ctl start
237 * pending.
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700238 * @pending_retire_fence_cnt: Atomic counter tracking the pending retire
239 * fences that have to be signalled.
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400240 * @pending_kickoff_wq: Wait queue for blocking until kickoff completes
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500241 * @irq: IRQ tracking structures
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400242 */
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400243struct sde_encoder_phys {
244 struct drm_encoder *parent;
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400245 struct drm_connector *connector;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400246 struct sde_encoder_phys_ops ops;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400247 struct sde_encoder_virt_ops parent_ops;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400248 struct sde_hw_mdp *hw_mdptop;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400249 struct sde_hw_ctl *hw_ctl;
Alan Kwongbb27c092016-07-20 16:41:25 -0400250 struct sde_hw_cdm *hw_cdm;
251 struct sde_hw_cdm_cfg cdm_cfg;
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700252 struct sde_hw_pingpong *hw_pp;
Ben Chan78647cd2016-06-26 22:02:47 -0400253 struct sde_kms *sde_kms;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400254 struct drm_display_mode cached_mode;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400255 enum sde_enc_split_role split_role;
Clarence Ip03521982016-08-26 10:49:47 -0400256 enum sde_intf_mode intf_mode;
Dhaval Patel81e87882016-10-19 21:41:56 -0700257 enum sde_intf intf_idx;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800258 enum msm_display_compression_type comp_type;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400259 spinlock_t *enc_spinlock;
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400260 enum sde_enc_enable_state enable_state;
Alan Kwongbaa56352016-10-04 09:38:11 -0400261 atomic_t vblank_refcount;
Dhaval Patel81e87882016-10-19 21:41:56 -0700262 atomic_t vsync_cnt;
263 atomic_t underrun_cnt;
Dhaval Patel0e558f42017-04-30 00:51:40 -0700264 atomic_t pending_ctlstart_cnt;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400265 atomic_t pending_kickoff_cnt;
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700266 atomic_t pending_retire_fence_cnt;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400267 wait_queue_head_t pending_kickoff_wq;
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500268 struct sde_encoder_irq irq[INTR_IDX_MAX];
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400269};
270
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400271static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)
272{
Dhaval Patel0e558f42017-04-30 00:51:40 -0700273 atomic_inc_return(&phys->pending_ctlstart_cnt);
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400274 return atomic_inc_return(&phys->pending_kickoff_cnt);
275}
276
Ben Chan78647cd2016-06-26 22:02:47 -0400277/**
278 * struct sde_encoder_phys_vid - sub-class of sde_encoder_phys to handle video
279 * mode specific operations
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400280 * @base: Baseclass physical encoder structure
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400281 * @hw_intf: Hardware interface to the intf registers
Alan Kwong4aacd532017-02-04 18:51:33 -0800282 * @timing_params: Current timing parameter
283 * @rot_prefill_line: number of line to prefill for inline rotation; 0 disable
Ben Chan78647cd2016-06-26 22:02:47 -0400284 */
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400285struct sde_encoder_phys_vid {
286 struct sde_encoder_phys base;
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400287 struct sde_hw_intf *hw_intf;
Alan Kwong4aacd532017-02-04 18:51:33 -0800288 struct intf_timing_params timing_params;
289 u64 rot_prefill_line;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400290};
291
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400292/**
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500293 * struct sde_encoder_phys_cmd_autorefresh - autorefresh state tracking
294 * @cfg: current active autorefresh configuration
295 * @kickoff_cnt: atomic count tracking autorefresh done irq kickoffs pending
296 * @kickoff_wq: wait queue for waiting on autorefresh done irq
297 */
298struct sde_encoder_phys_cmd_autorefresh {
299 struct sde_hw_autorefresh cfg;
300 atomic_t kickoff_cnt;
301 wait_queue_head_t kickoff_wq;
302};
303
304/**
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400305 * struct sde_encoder_phys_cmd - sub-class of sde_encoder_phys to handle command
306 * mode specific operations
307 * @base: Baseclass physical encoder structure
308 * @intf_idx: Intf Block index used by this phys encoder
309 * @stream_sel: Stream selection for multi-stream interfaces
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500310 * @serialize_wait4pp: serialize wait4pp feature waits for pp_done interrupt
311 * after ctl_start instead of before next frame kickoff
312 * @pp_timeout_report_cnt: number of pingpong done irq timeout errors
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700313 * @pending_rd_ptr_cnt: atomic counter to indicate if retire fence can be
314 * signaled at the next rd_ptr_irq
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500315 * @autorefresh: autorefresh feature state
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400316 */
317struct sde_encoder_phys_cmd {
318 struct sde_encoder_phys base;
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400319 int stream_sel;
Dhaval Patel056e7622017-01-25 13:23:02 -0800320 bool serialize_wait4pp;
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500321 int pp_timeout_report_cnt;
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -0500322 struct sde_encoder_phys_cmd_autorefresh autorefresh;
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -0700323 atomic_t pending_rd_ptr_cnt;
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400324};
325
326/**
Alan Kwongbb27c092016-07-20 16:41:25 -0400327 * struct sde_encoder_phys_wb - sub-class of sde_encoder_phys to handle
328 * writeback specific operations
329 * @base: Baseclass physical encoder structure
330 * @hw_wb: Hardware interface to the wb registers
331 * @irq_idx: IRQ interface lookup index
332 * @wbdone_timeout: Timeout value for writeback done in msec
333 * @bypass_irqreg: Bypass irq register/unregister if non-zero
334 * @wbdone_complete: for wbdone irq synchronization
335 * @wb_cfg: Writeback hardware configuration
Alan Kwong143f50c2017-04-28 07:34:28 -0700336 * @cdp_cfg: Writeback CDP configuration
Alan Kwongbb27c092016-07-20 16:41:25 -0400337 * @intf_cfg: Interface hardware configuration
338 * @wb_roi: Writeback region-of-interest
339 * @wb_fmt: Writeback pixel format
340 * @frame_count: Counter of completed writeback operations
341 * @kickoff_count: Counter of issued writeback operations
Jordan Croused8e96522017-02-13 10:14:16 -0700342 * @aspace: address space identifier for non-secure/secure domain
Alan Kwongbb27c092016-07-20 16:41:25 -0400343 * @wb_dev: Pointer to writeback device
344 * @start_time: Start time of writeback latest request
345 * @end_time: End time of writeback latest request
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700346 * @bo_disable: Buffer object(s) to use during the disabling state
347 * @fb_disable: Frame buffer to use during the disabling state
Alan Kwongbb27c092016-07-20 16:41:25 -0400348 */
349struct sde_encoder_phys_wb {
350 struct sde_encoder_phys base;
351 struct sde_hw_wb *hw_wb;
352 int irq_idx;
Alan Kwonga172ef52016-09-27 00:29:10 -0400353 struct sde_irq_callback irq_cb;
Alan Kwongbb27c092016-07-20 16:41:25 -0400354 u32 wbdone_timeout;
355 u32 bypass_irqreg;
356 struct completion wbdone_complete;
357 struct sde_hw_wb_cfg wb_cfg;
Alan Kwong143f50c2017-04-28 07:34:28 -0700358 struct sde_hw_wb_cdp_cfg cdp_cfg;
Alan Kwongbb27c092016-07-20 16:41:25 -0400359 struct sde_hw_intf_cfg intf_cfg;
360 struct sde_rect wb_roi;
361 const struct sde_format *wb_fmt;
362 u32 frame_count;
363 u32 kickoff_count;
Jordan Croused8e96522017-02-13 10:14:16 -0700364 struct msm_gem_address_space *aspace[SDE_IOMMU_DOMAIN_MAX];
Alan Kwongbb27c092016-07-20 16:41:25 -0400365 struct sde_wb_device *wb_dev;
366 ktime_t start_time;
367 ktime_t end_time;
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700368 struct drm_gem_object *bo_disable[SDE_MAX_PLANES];
369 struct drm_framebuffer *fb_disable;
Alan Kwongbb27c092016-07-20 16:41:25 -0400370};
371
372/**
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400373 * struct sde_enc_phys_init_params - initialization parameters for phys encs
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400374 * @sde_kms: Pointer to the sde_kms top level
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400375 * @parent: Pointer to the containing virtual encoder
376 * @parent_ops: Callbacks exposed by the parent to the phys_enc
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400377 * @split_role: Role to play in a split-panel configuration
378 * @intf_idx: Interface index this phys_enc will control
379 * @wb_idx: Writeback index this phys_enc will control
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800380 * @comp_type: Type of compression supported
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400381 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400382 */
383struct sde_enc_phys_init_params {
384 struct sde_kms *sde_kms;
385 struct drm_encoder *parent;
386 struct sde_encoder_virt_ops parent_ops;
387 enum sde_enc_split_role split_role;
388 enum sde_intf intf_idx;
389 enum sde_wb wb_idx;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800390 enum msm_display_compression_type comp_type;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400391 spinlock_t *enc_spinlock;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400392};
393
394/**
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500395 * sde_encoder_wait_info - container for passing arguments to irq wait functions
396 * @wq: wait queue structure
397 * @atomic_cnt: wait until atomic_cnt equals zero
398 * @timeout_ms: timeout value in milliseconds
399 */
400struct sde_encoder_wait_info {
401 wait_queue_head_t *wq;
402 atomic_t *atomic_cnt;
403 s64 timeout_ms;
404};
405
406/**
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400407 * sde_encoder_phys_vid_init - Construct a new video mode physical encoder
408 * @p: Pointer to init params structure
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400409 * Return: Error code or newly allocated encoder
410 */
411struct sde_encoder_phys *sde_encoder_phys_vid_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400412 struct sde_enc_phys_init_params *p);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400413
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400414/**
415 * sde_encoder_phys_cmd_init - Construct a new command mode physical encoder
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400416 * @p: Pointer to init params structure
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400417 * Return: Error code or newly allocated encoder
418 */
419struct sde_encoder_phys *sde_encoder_phys_cmd_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400420 struct sde_enc_phys_init_params *p);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400421
Alan Kwongbb27c092016-07-20 16:41:25 -0400422/**
423 * sde_encoder_phys_wb_init - Construct a new writeback physical encoder
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400424 * @p: Pointer to init params structure
Alan Kwongbb27c092016-07-20 16:41:25 -0400425 * Return: Error code or newly allocated encoder
426 */
427#ifdef CONFIG_DRM_SDE_WB
428struct sde_encoder_phys *sde_encoder_phys_wb_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400429 struct sde_enc_phys_init_params *p);
Alan Kwongbb27c092016-07-20 16:41:25 -0400430#else
431static inline
432struct sde_encoder_phys *sde_encoder_phys_wb_init(
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -0400433 struct sde_enc_phys_init_params *p)
Alan Kwongbb27c092016-07-20 16:41:25 -0400434{
435 return NULL;
436}
437#endif
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400438
Alan Kwongbb27c092016-07-20 16:41:25 -0400439void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
440 struct drm_framebuffer *fb, const struct sde_format *format,
441 struct sde_rect *wb_roi);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -0400442
Clarence Ip110d15c2016-08-16 14:44:41 -0400443/**
444 * sde_encoder_helper_trigger_start - control start helper function
445 * This helper function may be optionally specified by physical
446 * encoders if they require ctl_start triggering.
447 * @phys_enc: Pointer to physical encoder structure
448 */
449void sde_encoder_helper_trigger_start(struct sde_encoder_phys *phys_enc);
450
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500451/**
452 * sde_encoder_helper_wait_event_timeout - wait for event with timeout
453 * taking into account that jiffies may jump between reads leading to
454 * incorrectly detected timeouts. Prevent failure in this scenario by
455 * making sure that elapsed time during wait is valid.
456 * @drm_id: drm object id for logging
457 * @hw_id: hw instance id for logging
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500458 * @info: wait info structure
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500459 */
460int sde_encoder_helper_wait_event_timeout(
461 int32_t drm_id,
462 int32_t hw_id,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500463 struct sde_encoder_wait_info *info);
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -0500464
Lloyd Atkinson8c49c582016-11-18 14:23:54 -0500465/**
466 * sde_encoder_helper_hw_reset - issue ctl hw reset
467 * This helper function may be optionally specified by physical
468 * encoders if they require ctl hw reset. If state is currently
469 * SDE_ENC_ERR_NEEDS_HW_RESET, it is set back to SDE_ENC_ENABLED.
470 * @phys_enc: Pointer to physical encoder structure
471 */
472void sde_encoder_helper_hw_reset(struct sde_encoder_phys *phys_enc);
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400473
474static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
475 struct sde_encoder_phys *phys_enc)
476{
477 enum sde_rm_topology_name topology;
478
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700479 if (!phys_enc || phys_enc->enable_state == SDE_ENC_DISABLING)
480 return BLEND_3D_NONE;
481
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400482 topology = sde_connector_get_topology_name(phys_enc->connector);
483 if (phys_enc->split_role == ENC_ROLE_SOLO &&
Ingrid Gallardo83532222017-06-02 16:48:51 -0700484 (topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE ||
485 topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC))
Lloyd Atkinson55987b02016-08-16 16:57:46 -0400486 return BLEND_3D_H_ROW_INT;
487
488 return BLEND_3D_NONE;
489}
490
Clarence Ip8e69ad02016-12-09 09:43:57 -0500491/**
492 * sde_encoder_helper_split_config - split display configuration helper function
493 * This helper function may be used by physical encoders to configure
494 * the split display related registers.
495 * @phys_enc: Pointer to physical encoder structure
496 * @interface: enum sde_intf setting
497 */
498void sde_encoder_helper_split_config(
499 struct sde_encoder_phys *phys_enc,
500 enum sde_intf interface);
501
Clarence Ip9c65f7b2017-03-20 06:48:15 -0700502/**
503 * sde_encoder_helper_hw_release - prepare for h/w reset during disable
504 * @phys_enc: Pointer to physical encoder structure
505 * @fb: Optional fb for specifying new mixer output resolution, may be NULL
506 * Return: Zero on success
507 */
508int sde_encoder_helper_hw_release(struct sde_encoder_phys *phys_enc,
509 struct drm_framebuffer *fb);
510
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500511/**
512 * sde_encoder_helper_report_irq_timeout - utility to report error that irq has
513 * timed out, including reporting frame error event to crtc and debug dump
514 * @phys_enc: Pointer to physical encoder structure
515 * @intr_idx: Failing interrupt index
516 */
517void sde_encoder_helper_report_irq_timeout(struct sde_encoder_phys *phys_enc,
518 enum sde_intr_idx intr_idx);
519
520/**
521 * sde_encoder_helper_wait_for_irq - utility to wait on an irq.
522 * note: will call sde_encoder_helper_wait_for_irq on timeout
523 * @phys_enc: Pointer to physical encoder structure
524 * @intr_idx: encoder interrupt index
525 * @wait_info: wait info struct
526 * @Return: 0 or -ERROR
527 */
528int sde_encoder_helper_wait_for_irq(struct sde_encoder_phys *phys_enc,
529 enum sde_intr_idx intr_idx,
530 struct sde_encoder_wait_info *wait_info);
531
532/**
533 * sde_encoder_helper_register_irq - register and enable an irq
534 * @phys_enc: Pointer to physical encoder structure
535 * @intr_idx: encoder interrupt index
536 * @Return: 0 or -ERROR
537 */
538int sde_encoder_helper_register_irq(struct sde_encoder_phys *phys_enc,
539 enum sde_intr_idx intr_idx);
540
541/**
542 * sde_encoder_helper_unregister_irq - unregister and disable an irq
543 * @phys_enc: Pointer to physical encoder structure
544 * @intr_idx: encoder interrupt index
545 * @Return: 0 or -ERROR
546 */
547int sde_encoder_helper_unregister_irq(struct sde_encoder_phys *phys_enc,
548 enum sde_intr_idx intr_idx);
549
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400550#endif /* __sde_encoder_phys_H__ */