blob: 16a9791786cbd5c3685db2f660020d34c1ed95f0 [file] [log] [blame]
Dhaval Patel14d46ce2017-01-17 16:28:12 -08001/*
Narender Ankamdc32cdf2020-03-16 17:21:08 +05302 * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
Dhaval Patel14d46ce2017-01-17 16:28:12 -08003 * Copyright (C) 2013 Red Hat
4 * Author: Rob Clark <robdclark@gmail.com>
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07005 *
Dhaval Patel14d46ce2017-01-17 16:28:12 -08006 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07009 *
Dhaval Patel14d46ce2017-01-17 16:28:12 -080010 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070017 */
18
Clarence Ip19af1362016-09-23 14:57:51 -040019#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
Lloyd Atkinsona8781382017-07-17 10:20:43 -040020#include <linux/kthread.h>
Dhaval Patel22ef6df2016-10-20 14:42:52 -070021#include <linux/debugfs.h>
22#include <linux/seq_file.h>
Dhaval Patel49ef6d72017-03-26 09:35:53 -070023#include <linux/sde_rsc.h>
Dhaval Patel22ef6df2016-10-20 14:42:52 -070024
Lloyd Atkinson09fed912016-06-24 18:14:13 -040025#include "msm_drv.h"
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070026#include "sde_kms.h"
27#include "drm_crtc.h"
28#include "drm_crtc_helper.h"
29
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -040030#include "sde_hwio.h"
31#include "sde_hw_catalog.h"
32#include "sde_hw_intf.h"
Clarence Ipc475b082016-06-26 09:27:23 -040033#include "sde_hw_ctl.h"
34#include "sde_formats.h"
Lloyd Atkinson09fed912016-06-24 18:14:13 -040035#include "sde_encoder_phys.h"
Dhaval Patel020f7e122016-11-15 14:39:18 -080036#include "sde_power_handle.h"
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -080037#include "sde_hw_dsc.h"
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -070038#include "sde_crtc.h"
Narendra Muppalla77b32932017-05-10 13:53:11 -070039#include "sde_trace.h"
Lloyd Atkinson05ef8232017-03-08 16:35:36 -050040#include "sde_core_irq.h"
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -040041
Clarence Ip19af1362016-09-23 14:57:51 -040042#define SDE_DEBUG_ENC(e, fmt, ...) SDE_DEBUG("enc%d " fmt,\
43 (e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
44
45#define SDE_ERROR_ENC(e, fmt, ...) SDE_ERROR("enc%d " fmt,\
46 (e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
47
Lloyd Atkinson05ef8232017-03-08 16:35:36 -050048#define SDE_DEBUG_PHYS(p, fmt, ...) SDE_DEBUG("enc%d intf%d pp%d " fmt,\
49 (p) ? (p)->parent->base.id : -1, \
50 (p) ? (p)->intf_idx - INTF_0 : -1, \
51 (p) ? ((p)->hw_pp ? (p)->hw_pp->idx - PINGPONG_0 : -1) : -1, \
52 ##__VA_ARGS__)
53
54#define SDE_ERROR_PHYS(p, fmt, ...) SDE_ERROR("enc%d intf%d pp%d " fmt,\
55 (p) ? (p)->parent->base.id : -1, \
56 (p) ? (p)->intf_idx - INTF_0 : -1, \
57 (p) ? ((p)->hw_pp ? (p)->hw_pp->idx - PINGPONG_0 : -1) : -1, \
58 ##__VA_ARGS__)
59
Lloyd Atkinson5d722782016-05-30 14:09:41 -040060/*
61 * Two to anticipate panels that can do cmd/vid dynamic switching
62 * plan is to create all possible physical encoder types, and switch between
63 * them at runtime
64 */
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040065#define NUM_PHYS_ENCODER_TYPES 2
Lloyd Atkinson5d722782016-05-30 14:09:41 -040066
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -040067#define MAX_PHYS_ENCODERS_PER_VIRTUAL \
68 (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
69
Vishnuvardhan Prodduturi6b1803a2019-01-19 16:35:34 +053070#define MAX_CHANNELS_PER_ENC 4
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -070071
Dhaval Patelf9245d62017-03-28 16:24:00 -070072#define MISR_BUFF_SIZE 256
73
Clarence Ip89628132017-07-27 13:33:51 -040074#define IDLE_SHORT_TIMEOUT 1
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -070075
Raviteja Tamatam3eebe962017-10-26 09:55:24 +053076#define FAULT_TOLERENCE_DELTA_IN_MS 2
77
78#define FAULT_TOLERENCE_WAIT_IN_MS 5
79
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -040080/* Maximum number of VSYNC wait attempts for RSC state transition */
81#define MAX_RSC_WAIT 5
82
Ping Li16162692018-05-08 14:13:46 -070083#define TOPOLOGY_DUALPIPE_MERGE_MODE(x) \
84 (((x) == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE) || \
85 ((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE) || \
86 ((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC))
87
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -070088/**
89 * enum sde_enc_rc_events - events for resource control state machine
90 * @SDE_ENC_RC_EVENT_KICKOFF:
91 * This event happens at NORMAL priority.
92 * Event that signals the start of the transfer. When this event is
93 * received, enable MDP/DSI core clocks and request RSC with CMD state.
94 * Regardless of the previous state, the resource should be in ON state
95 * at the end of this event.
96 * @SDE_ENC_RC_EVENT_FRAME_DONE:
97 * This event happens at INTERRUPT level.
98 * Event signals the end of the data transfer after the PP FRAME_DONE
99 * event. At the end of this event, a delayed work is scheduled to go to
Dhaval Patelc9e213b2017-11-02 12:13:12 -0700100 * IDLE_PC state after IDLE_POWERCOLLAPSE_DURATION time.
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400101 * @SDE_ENC_RC_EVENT_PRE_STOP:
102 * This event happens at NORMAL priority.
103 * This event, when received during the ON state, set RSC to IDLE, and
104 * and leave the RC STATE in the PRE_OFF state.
105 * It should be followed by the STOP event as part of encoder disable.
106 * If received during IDLE or OFF states, it will do nothing.
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700107 * @SDE_ENC_RC_EVENT_STOP:
108 * This event happens at NORMAL priority.
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400109 * When this event is received, disable all the MDP/DSI core clocks, and
110 * disable IRQs. It should be called from the PRE_OFF or IDLE states.
111 * IDLE is expected when IDLE_PC has run, and PRE_OFF did nothing.
112 * PRE_OFF is expected when PRE_STOP was executed during the ON state.
113 * Resource state should be in OFF at the end of the event.
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700114 * @SDE_ENC_RC_EVENT_PRE_MODESET:
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700115 * This event happens at NORMAL priority from a work item.
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700116 * Event signals that there is a seamless mode switch is in prgoress. A
117 * client needs to turn of only irq - leave clocks ON to reduce the mode
118 * switch latency.
119 * @SDE_ENC_RC_EVENT_POST_MODESET:
120 * This event happens at NORMAL priority from a work item.
121 * Event signals that seamless mode switch is complete and resources are
122 * acquired. Clients wants to turn on the irq again and update the rsc
123 * with new vtotal.
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700124 * @SDE_ENC_RC_EVENT_ENTER_IDLE:
125 * This event happens at NORMAL priority from a work item.
Dhaval Patelc9e213b2017-11-02 12:13:12 -0700126 * Event signals that there were no frame updates for
127 * IDLE_POWERCOLLAPSE_DURATION time. This would disable MDP/DSI core clocks
128 * and request RSC with IDLE state and change the resource state to IDLE.
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800129 * @SDE_ENC_RC_EVENT_EARLY_WAKEUP:
130 * This event is triggered from the input event thread when touch event is
131 * received from the input device. On receiving this event,
132 * - If the device is in SDE_ENC_RC_STATE_IDLE state, it turns ON the
133 clocks and enable RSC.
134 * - If the device is in SDE_ENC_RC_STATE_ON state, it resets the delayed
135 * off work since a new commit is imminent.
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700136 */
137enum sde_enc_rc_events {
138 SDE_ENC_RC_EVENT_KICKOFF = 1,
139 SDE_ENC_RC_EVENT_FRAME_DONE,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400140 SDE_ENC_RC_EVENT_PRE_STOP,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700141 SDE_ENC_RC_EVENT_STOP,
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700142 SDE_ENC_RC_EVENT_PRE_MODESET,
143 SDE_ENC_RC_EVENT_POST_MODESET,
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800144 SDE_ENC_RC_EVENT_ENTER_IDLE,
145 SDE_ENC_RC_EVENT_EARLY_WAKEUP,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700146};
147
148/*
149 * enum sde_enc_rc_states - states that the resource control maintains
150 * @SDE_ENC_RC_STATE_OFF: Resource is in OFF state
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400151 * @SDE_ENC_RC_STATE_PRE_OFF: Resource is transitioning to OFF state
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700152 * @SDE_ENC_RC_STATE_ON: Resource is in ON state
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700153 * @SDE_ENC_RC_STATE_MODESET: Resource is in modeset state
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700154 * @SDE_ENC_RC_STATE_IDLE: Resource is in IDLE state
155 */
156enum sde_enc_rc_states {
157 SDE_ENC_RC_STATE_OFF,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400158 SDE_ENC_RC_STATE_PRE_OFF,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700159 SDE_ENC_RC_STATE_ON,
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700160 SDE_ENC_RC_STATE_MODESET,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700161 SDE_ENC_RC_STATE_IDLE
162};
163
Chirag Khuranaed859f52019-11-20 18:18:12 +0530164/* rgb to yuv color space conversion matrix */
165static struct sde_csc_cfg sde_csc_10bit_convert[SDE_MAX_CSC] = {
166 [SDE_CSC_RGB2YUV_601L] = {
167 {
168 TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032),
169 TO_S15D16(0xffb4), TO_S15D16(0xff6b), TO_S15D16(0x00e1),
170 TO_S15D16(0x00e1), TO_S15D16(0xff44), TO_S15D16(0xffdb),
171 },
172 { 0x0, 0x0, 0x0,},
173 { 0x0040, 0x0200, 0x0200,},
174 { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
175 { 0x0040, 0x03ac, 0x0040, 0x03c0, 0x0040, 0x03c0,},
176 },
177
178 [SDE_CSC_RGB2YUV_601FR] = {
179 {
180 TO_S15D16(0x0099), TO_S15D16(0x012d), TO_S15D16(0x003a),
181 TO_S15D16(0xffaa), TO_S15D16(0xff56), TO_S15D16(0x0100),
182 TO_S15D16(0x0100), TO_S15D16(0xff2a), TO_S15D16(0xffd6),
183 },
184 { 0x0, 0x0, 0x0,},
185 { 0x0000, 0x0200, 0x0200,},
186 { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
187 { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
188 },
Narender Ankamdc32cdf2020-03-16 17:21:08 +0530189
190 [SDE_CSC_RGB2YUV_709L] = {
191 {
192 TO_S15D16(0x005d), TO_S15D16(0x013a), TO_S15D16(0x0020),
193 TO_S15D16(0xffcc), TO_S15D16(0xff53), TO_S15D16(0x00e1),
194 TO_S15D16(0x00e1), TO_S15D16(0xff34), TO_S15D16(0xffeb),
195 },
196 { 0x0, 0x0, 0x0,},
197 { 0x0040, 0x0200, 0x0200,},
198 { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
199 { 0x0040, 0x03ac, 0x0040, 0x03c0, 0x0040, 0x03c0,},
200 },
201
202 [SDE_CSC_RGB2YUV_2020L] = {
203 {
204 TO_S15D16(0x0073), TO_S15D16(0x0129), TO_S15D16(0x001a),
205 TO_S15D16(0xffc1), TO_S15D16(0xff5e), TO_S15D16(0x00e0),
206 TO_S15D16(0x00e0), TO_S15D16(0xff32), TO_S15D16(0xffee),
207 },
208 { 0x0, 0x0, 0x0,},
209 { 0x0040, 0x0200, 0x0200,},
210 { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
211 { 0x0040, 0x03ac, 0x0040, 0x03c0, 0x0040, 0x03c0,},
212 },
213
214 [SDE_CSC_RGB2YUV_2020FR] = {
215 {
216 TO_S15D16(0x0086), TO_S15D16(0x015b), TO_S15D16(0x001e),
217 TO_S15D16(0xffb9), TO_S15D16(0xff47), TO_S15D16(0x0100),
218 TO_S15D16(0x0100), TO_S15D16(0xff15), TO_S15D16(0xffeb),
219 },
220 { 0x0, 0x0, 0x0,},
221 { 0x0, 0x0200, 0x0200,},
222 { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
223 { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
224 },
Chirag Khuranaed859f52019-11-20 18:18:12 +0530225};
226
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400227/**
228 * struct sde_encoder_virt - virtual encoder. Container of one or more physical
229 * encoders. Virtual encoder manages one "logical" display. Physical
230 * encoders manage one intf block, tied to a specific panel/sub-panel.
231 * Virtual encoder defers as much as possible to the physical encoders.
232 * Virtual encoder registers itself with the DRM Framework as the encoder.
233 * @base: drm_encoder base class for registration with DRM
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400234 * @enc_spin_lock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400235 * @bus_scaling_client: Client handle to the bus scaling interface
236 * @num_phys_encs: Actual number of physical encoders contained.
237 * @phys_encs: Container of physical encoders managed.
238 * @cur_master: Pointer to the current master in this mode. Optimization
239 * Only valid after enable. Cleared as disable.
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700240 * @hw_pp Handle to the pingpong blocks used for the display. No.
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500241 * pingpong blocks can be different than num_phys_encs.
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800242 * @hw_dsc: Array of DSC block handles used for the display.
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500243 * @intfs_swapped Whether or not the phys_enc interfaces have been swapped
244 * for partial update right-only cases, such as pingpong
245 * split where virtual pingpong does not generate IRQs
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400246 * @crtc_vblank_cb: Callback into the upper layer / CRTC for
247 * notification of the VBLANK
248 * @crtc_vblank_cb_data: Data from upper layer for VBLANK notification
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400249 * @crtc_kickoff_cb: Callback into CRTC that will flush & start
250 * all CTL paths
251 * @crtc_kickoff_cb_data: Opaque user data given to crtc_kickoff_cb
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700252 * @debugfs_root: Debug file system root file node
253 * @enc_lock: Lock around physical encoder create/destroy and
254 access.
Alan Kwong628d19e2016-10-31 13:50:13 -0400255 * @frame_busy_mask: Bitmask tracking which phys_enc we are still
256 * busy processing current command.
257 * Bit0 = phys_encs[0] etc.
258 * @crtc_frame_event_cb: callback handler for frame event
259 * @crtc_frame_event_cb_data: callback handler private data
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400260 * @vsync_event_timer: vsync timer
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700261 * @rsc_client: rsc client pointer
262 * @rsc_state_init: boolean to indicate rsc config init
263 * @disp_info: local copy of msm_display_info struct
Dhaval Patelf9245d62017-03-28 16:24:00 -0700264 * @misr_enable: misr enable/disable status
Dhaval Patel010f5172017-08-01 22:40:09 -0700265 * @misr_frame_count: misr frame count before start capturing the data
Veera Sundaram Sankaran42ac38d2018-07-06 12:42:04 -0700266 * @idle_pc_enabled: indicate if idle power collapse is enabled
267 * currently. This can be controlled by user-mode
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700268 * @rc_lock: resource control mutex lock to protect
269 * virt encoder over various state changes
270 * @rc_state: resource controller state
271 * @delayed_off_work: delayed worker to schedule disabling of
272 * clks and resources after IDLE_TIMEOUT time.
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400273 * @vsync_event_work: worker to handle vsync event for autorefresh
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800274 * @input_event_work: worker to handle input device touch events
Dhaval Patel222023e2018-02-27 12:24:07 -0800275 * @esd_trigger_work: worker to handle esd trigger events
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800276 * @input_handler: handler for input device events
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700277 * @topology: topology of the display
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -0700278 * @vblank_enabled: boolean to track userspace vblank vote
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700279 * @rsc_config: rsc configuration for display vtotal, fps, etc.
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400280 * @cur_conn_roi: current connector roi
281 * @prv_conn_roi: previous connector roi to optimize if unchanged
Harsh Sahu1e52ed02017-11-28 14:34:22 -0800282 * @crtc pointer to drm_crtc
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400283 */
284struct sde_encoder_virt {
285 struct drm_encoder base;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400286 spinlock_t enc_spinlock;
Raviteja Tamatam3ea60b82018-04-27 15:41:18 +0530287 struct mutex vblank_ctl_lock;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400288 uint32_t bus_scaling_client;
289
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400290 uint32_t display_num_of_h_tiles;
291
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400292 unsigned int num_phys_encs;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400293 struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
294 struct sde_encoder_phys *cur_master;
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700295 struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800296 struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400297
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500298 bool intfs_swapped;
299
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400300 void (*crtc_vblank_cb)(void *);
301 void *crtc_vblank_cb_data;
302
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700303 struct dentry *debugfs_root;
304 struct mutex enc_lock;
Alan Kwong628d19e2016-10-31 13:50:13 -0400305 DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
306 void (*crtc_frame_event_cb)(void *, u32 event);
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -0700307 struct sde_crtc_frame_event_cb_data crtc_frame_event_cb_data;
Alan Kwong628d19e2016-10-31 13:50:13 -0400308
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400309 struct timer_list vsync_event_timer;
Dhaval Patel020f7e122016-11-15 14:39:18 -0800310
311 struct sde_rsc_client *rsc_client;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700312 bool rsc_state_init;
Dhaval Patel020f7e122016-11-15 14:39:18 -0800313 struct msm_display_info disp_info;
Dhaval Patelf9245d62017-03-28 16:24:00 -0700314 bool misr_enable;
Dhaval Patel010f5172017-08-01 22:40:09 -0700315 u32 misr_frame_count;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700316
Veera Sundaram Sankaran42ac38d2018-07-06 12:42:04 -0700317 bool idle_pc_enabled;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700318 struct mutex rc_lock;
319 enum sde_enc_rc_states rc_state;
Lloyd Atkinsona8781382017-07-17 10:20:43 -0400320 struct kthread_delayed_work delayed_off_work;
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400321 struct kthread_work vsync_event_work;
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800322 struct kthread_work input_event_work;
Dhaval Patel222023e2018-02-27 12:24:07 -0800323 struct kthread_work esd_trigger_work;
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800324 struct input_handler *input_handler;
Shubhashree Dhar0c6ce3c2018-08-03 19:49:31 +0530325 bool input_handler_registered;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700326 struct msm_display_topology topology;
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -0700327 bool vblank_enabled;
Alan Kwong56f1a942017-04-04 11:53:42 -0700328
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700329 struct sde_rsc_cmd_config rsc_config;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400330 struct sde_rect cur_conn_roi;
331 struct sde_rect prv_conn_roi;
Harsh Sahu1e52ed02017-11-28 14:34:22 -0800332 struct drm_crtc *crtc;
Dhaval Patel30874eb2018-05-31 13:33:31 -0700333
334 bool elevated_ahb_vote;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400335};
336
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400337#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700338
Lloyd Atkinson7fdd4c22017-11-16 20:10:17 -0500339static void _sde_encoder_pm_qos_add_request(struct drm_encoder *drm_enc)
340{
341 struct msm_drm_private *priv;
342 struct sde_kms *sde_kms;
343 struct pm_qos_request *req;
344 u32 cpu_mask;
345 u32 cpu_dma_latency;
346 int cpu;
347
348 if (!drm_enc->dev || !drm_enc->dev->dev_private) {
349 SDE_ERROR("drm device invalid\n");
350 return;
351 }
352
353 priv = drm_enc->dev->dev_private;
354 if (!priv->kms) {
355 SDE_ERROR("invalid kms\n");
356 return;
357 }
358
359 sde_kms = to_sde_kms(priv->kms);
360 if (!sde_kms || !sde_kms->catalog)
361 return;
362
363 cpu_mask = sde_kms->catalog->perf.cpu_mask;
364 cpu_dma_latency = sde_kms->catalog->perf.cpu_dma_latency;
365 if (!cpu_mask)
366 return;
367
368 req = &sde_kms->pm_qos_cpu_req;
369 req->type = PM_QOS_REQ_AFFINE_CORES;
370 cpumask_empty(&req->cpus_affine);
371 for_each_possible_cpu(cpu) {
372 if ((1 << cpu) & cpu_mask)
373 cpumask_set_cpu(cpu, &req->cpus_affine);
374 }
375 pm_qos_add_request(req, PM_QOS_CPU_DMA_LATENCY, cpu_dma_latency);
376
377 SDE_EVT32_VERBOSE(DRMID(drm_enc), cpu_mask, cpu_dma_latency);
378}
379
380static void _sde_encoder_pm_qos_remove_request(struct drm_encoder *drm_enc)
381{
382 struct msm_drm_private *priv;
383 struct sde_kms *sde_kms;
384
385 if (!drm_enc->dev || !drm_enc->dev->dev_private) {
386 SDE_ERROR("drm device invalid\n");
387 return;
388 }
389
390 priv = drm_enc->dev->dev_private;
391 if (!priv->kms) {
392 SDE_ERROR("invalid kms\n");
393 return;
394 }
395
396 sde_kms = to_sde_kms(priv->kms);
397 if (!sde_kms || !sde_kms->catalog || !sde_kms->catalog->perf.cpu_mask)
398 return;
399
400 pm_qos_remove_request(&sde_kms->pm_qos_cpu_req);
401}
402
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700403static struct drm_connector_state *_sde_encoder_get_conn_state(
404 struct drm_encoder *drm_enc)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800405{
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700406 struct msm_drm_private *priv;
407 struct sde_kms *sde_kms;
408 struct list_head *connector_list;
409 struct drm_connector *conn_iter;
410
411 if (!drm_enc) {
412 SDE_ERROR("invalid argument\n");
413 return NULL;
414 }
415
416 priv = drm_enc->dev->dev_private;
417 sde_kms = to_sde_kms(priv->kms);
418 connector_list = &sde_kms->dev->mode_config.connector_list;
419
420 list_for_each_entry(conn_iter, connector_list, head)
421 if (conn_iter->encoder == drm_enc)
422 return conn_iter->state;
423
424 return NULL;
425}
426
427static int _sde_encoder_get_mode_info(struct drm_encoder *drm_enc,
428 struct msm_mode_info *mode_info)
429{
430 struct drm_connector_state *conn_state;
431
432 if (!drm_enc || !mode_info) {
433 SDE_ERROR("invalid arguments\n");
434 return -EINVAL;
435 }
436
437 conn_state = _sde_encoder_get_conn_state(drm_enc);
438 if (!conn_state) {
439 SDE_ERROR("invalid connector state for the encoder: %d\n",
440 drm_enc->base.id);
441 return -EINVAL;
442 }
443
444 return sde_connector_get_mode_info(conn_state, mode_info);
445}
446
447static bool _sde_encoder_is_dsc_enabled(struct drm_encoder *drm_enc)
448{
Lloyd Atkinson094780d2017-04-24 17:25:08 -0400449 struct msm_compression_info *comp_info;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700450 struct msm_mode_info mode_info;
451 int rc = 0;
Lloyd Atkinson094780d2017-04-24 17:25:08 -0400452
453 if (!drm_enc)
454 return false;
455
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700456 rc = _sde_encoder_get_mode_info(drm_enc, &mode_info);
457 if (rc) {
458 SDE_ERROR("failed to get mode info, enc: %d\n",
459 drm_enc->base.id);
460 return false;
461 }
462
463 comp_info = &mode_info.comp_info;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800464
465 return (comp_info->comp_type == MSM_DISPLAY_COMPRESSION_DSC);
466}
467
Lloyd Atkinson094780d2017-04-24 17:25:08 -0400468bool sde_encoder_is_dsc_merge(struct drm_encoder *drm_enc)
469{
470 enum sde_rm_topology_name topology;
471 struct sde_encoder_virt *sde_enc;
472 struct drm_connector *drm_conn;
473
474 if (!drm_enc)
475 return false;
476
477 sde_enc = to_sde_encoder_virt(drm_enc);
478 if (!sde_enc->cur_master)
479 return false;
480
481 drm_conn = sde_enc->cur_master->connector;
482 if (!drm_conn)
483 return false;
484
485 topology = sde_connector_get_topology_name(drm_conn);
Vishnuvardhan Prodduturi6b1803a2019-01-19 16:35:34 +0530486 if (topology == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE ||
487 topology == SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE)
Lloyd Atkinson094780d2017-04-24 17:25:08 -0400488 return true;
489
490 return false;
491}
492
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -0700493int sde_encoder_in_clone_mode(struct drm_encoder *drm_enc)
494{
495 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
496
497 return sde_enc && sde_enc->cur_master &&
498 sde_enc->cur_master->in_clone_mode;
499}
500
Dhaval Patelf9245d62017-03-28 16:24:00 -0700501static inline int _sde_encoder_power_enable(struct sde_encoder_virt *sde_enc,
502 bool enable)
503{
504 struct drm_encoder *drm_enc;
505 struct msm_drm_private *priv;
506 struct sde_kms *sde_kms;
507
508 if (!sde_enc) {
509 SDE_ERROR("invalid sde enc\n");
510 return -EINVAL;
511 }
512
513 drm_enc = &sde_enc->base;
514 if (!drm_enc->dev || !drm_enc->dev->dev_private) {
515 SDE_ERROR("drm device invalid\n");
516 return -EINVAL;
517 }
518
519 priv = drm_enc->dev->dev_private;
520 if (!priv->kms) {
521 SDE_ERROR("invalid kms\n");
522 return -EINVAL;
523 }
524
525 sde_kms = to_sde_kms(priv->kms);
526
527 return sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
528 enable);
529}
530
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500531void sde_encoder_helper_report_irq_timeout(struct sde_encoder_phys *phys_enc,
532 enum sde_intr_idx intr_idx)
533{
534 SDE_EVT32(DRMID(phys_enc->parent),
535 phys_enc->intf_idx - INTF_0,
536 phys_enc->hw_pp->idx - PINGPONG_0,
537 intr_idx);
538 SDE_ERROR_PHYS(phys_enc, "irq %d timeout\n", intr_idx);
539
540 if (phys_enc->parent_ops.handle_frame_done)
541 phys_enc->parent_ops.handle_frame_done(
542 phys_enc->parent, phys_enc,
543 SDE_ENCODER_FRAME_EVENT_ERROR);
544}
545
546int sde_encoder_helper_wait_for_irq(struct sde_encoder_phys *phys_enc,
547 enum sde_intr_idx intr_idx,
548 struct sde_encoder_wait_info *wait_info)
549{
550 struct sde_encoder_irq *irq;
551 u32 irq_status;
552 int ret;
553
554 if (!phys_enc || !wait_info || intr_idx >= INTR_IDX_MAX) {
555 SDE_ERROR("invalid params\n");
556 return -EINVAL;
557 }
558 irq = &phys_enc->irq[intr_idx];
559
560 /* note: do master / slave checking outside */
561
562 /* return EWOULDBLOCK since we know the wait isn't necessary */
563 if (phys_enc->enable_state == SDE_ENC_DISABLED) {
564 SDE_ERROR_PHYS(phys_enc, "encoder is disabled\n");
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400565 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
566 irq->irq_idx, intr_idx, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500567 return -EWOULDBLOCK;
568 }
569
570 if (irq->irq_idx < 0) {
571 SDE_DEBUG_PHYS(phys_enc, "irq %s hw %d disabled, skip wait\n",
572 irq->name, irq->hw_idx);
573 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
574 irq->irq_idx);
575 return 0;
576 }
577
578 SDE_DEBUG_PHYS(phys_enc, "pending_cnt %d\n",
579 atomic_read(wait_info->atomic_cnt));
Dhaval Patela5f75952017-07-25 11:17:41 -0700580 SDE_EVT32_VERBOSE(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
581 irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
582 atomic_read(wait_info->atomic_cnt), SDE_EVTLOG_FUNC_ENTRY);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500583
584 ret = sde_encoder_helper_wait_event_timeout(
585 DRMID(phys_enc->parent),
586 irq->hw_idx,
587 wait_info);
588
589 if (ret <= 0) {
590 irq_status = sde_core_irq_read(phys_enc->sde_kms,
591 irq->irq_idx, true);
592 if (irq_status) {
593 unsigned long flags;
594
Dhaval Patela5f75952017-07-25 11:17:41 -0700595 SDE_EVT32(DRMID(phys_enc->parent), intr_idx,
596 irq->hw_idx, irq->irq_idx,
597 phys_enc->hw_pp->idx - PINGPONG_0,
598 atomic_read(wait_info->atomic_cnt));
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500599 SDE_DEBUG_PHYS(phys_enc,
600 "done but irq %d not triggered\n",
601 irq->irq_idx);
602 local_irq_save(flags);
603 irq->cb.func(phys_enc, irq->irq_idx);
604 local_irq_restore(flags);
605 ret = 0;
606 } else {
607 ret = -ETIMEDOUT;
Dhaval Patela5f75952017-07-25 11:17:41 -0700608 SDE_EVT32(DRMID(phys_enc->parent), intr_idx,
609 irq->hw_idx, irq->irq_idx,
610 phys_enc->hw_pp->idx - PINGPONG_0,
611 atomic_read(wait_info->atomic_cnt), irq_status,
612 SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500613 }
614 } else {
615 ret = 0;
Dhaval Patela5f75952017-07-25 11:17:41 -0700616 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
617 irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
618 atomic_read(wait_info->atomic_cnt));
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500619 }
620
Dhaval Patela5f75952017-07-25 11:17:41 -0700621 SDE_EVT32_VERBOSE(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
622 irq->irq_idx, ret, phys_enc->hw_pp->idx - PINGPONG_0,
623 atomic_read(wait_info->atomic_cnt), SDE_EVTLOG_FUNC_EXIT);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500624
625 return ret;
626}
627
628int sde_encoder_helper_register_irq(struct sde_encoder_phys *phys_enc,
629 enum sde_intr_idx intr_idx)
630{
631 struct sde_encoder_irq *irq;
632 int ret = 0;
633
634 if (!phys_enc || intr_idx >= INTR_IDX_MAX) {
635 SDE_ERROR("invalid params\n");
636 return -EINVAL;
637 }
638 irq = &phys_enc->irq[intr_idx];
639
640 if (irq->irq_idx >= 0) {
Raviteja Tamatam68892de2017-06-20 04:47:19 +0530641 SDE_DEBUG_PHYS(phys_enc,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500642 "skipping already registered irq %s type %d\n",
643 irq->name, irq->intr_type);
644 return 0;
645 }
646
647 irq->irq_idx = sde_core_irq_idx_lookup(phys_enc->sde_kms,
648 irq->intr_type, irq->hw_idx);
649 if (irq->irq_idx < 0) {
650 SDE_ERROR_PHYS(phys_enc,
651 "failed to lookup IRQ index for %s type:%d\n",
652 irq->name, irq->intr_type);
653 return -EINVAL;
654 }
655
656 ret = sde_core_irq_register_callback(phys_enc->sde_kms, irq->irq_idx,
657 &irq->cb);
658 if (ret) {
659 SDE_ERROR_PHYS(phys_enc,
660 "failed to register IRQ callback for %s\n",
661 irq->name);
662 irq->irq_idx = -EINVAL;
663 return ret;
664 }
665
666 ret = sde_core_irq_enable(phys_enc->sde_kms, &irq->irq_idx, 1);
667 if (ret) {
668 SDE_ERROR_PHYS(phys_enc,
669 "enable IRQ for intr:%s failed, irq_idx %d\n",
670 irq->name, irq->irq_idx);
671
672 sde_core_irq_unregister_callback(phys_enc->sde_kms,
673 irq->irq_idx, &irq->cb);
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400674
675 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
676 irq->irq_idx, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500677 irq->irq_idx = -EINVAL;
678 return ret;
679 }
680
681 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx, irq->irq_idx);
682 SDE_DEBUG_PHYS(phys_enc, "registered irq %s idx: %d\n",
683 irq->name, irq->irq_idx);
684
685 return ret;
686}
687
688int sde_encoder_helper_unregister_irq(struct sde_encoder_phys *phys_enc,
689 enum sde_intr_idx intr_idx)
690{
691 struct sde_encoder_irq *irq;
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400692 int ret;
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500693
694 if (!phys_enc) {
695 SDE_ERROR("invalid encoder\n");
696 return -EINVAL;
697 }
698 irq = &phys_enc->irq[intr_idx];
699
700 /* silently skip irqs that weren't registered */
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400701 if (irq->irq_idx < 0) {
702 SDE_ERROR(
703 "extra unregister irq, enc%d intr_idx:0x%x hw_idx:0x%x irq_idx:0x%x\n",
704 DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
705 irq->irq_idx);
706 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
707 irq->irq_idx, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500708 return 0;
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400709 }
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500710
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400711 ret = sde_core_irq_disable(phys_enc->sde_kms, &irq->irq_idx, 1);
712 if (ret)
713 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
714 irq->irq_idx, ret, SDE_EVTLOG_ERROR);
715
716 ret = sde_core_irq_unregister_callback(phys_enc->sde_kms, irq->irq_idx,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500717 &irq->cb);
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400718 if (ret)
719 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
720 irq->irq_idx, ret, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500721
722 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx, irq->irq_idx);
723 SDE_DEBUG_PHYS(phys_enc, "unregistered %d\n", irq->irq_idx);
724
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400725 irq->irq_idx = -EINVAL;
726
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500727 return 0;
728}
729
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400730void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc,
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400731 struct sde_encoder_hw_resources *hw_res,
732 struct drm_connector_state *conn_state)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400733{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400734 struct sde_encoder_virt *sde_enc = NULL;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700735 struct msm_mode_info mode_info;
736 int rc, i = 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400737
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400738 if (!hw_res || !drm_enc || !conn_state) {
Clarence Ip19af1362016-09-23 14:57:51 -0400739 SDE_ERROR("invalid argument(s), drm_enc %d, res %d, state %d\n",
740 drm_enc != 0, hw_res != 0, conn_state != 0);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400741 return;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400742 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400743
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400744 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -0400745 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400746
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400747 /* Query resources used by phys encs, expected to be without overlap */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400748 memset(hw_res, 0, sizeof(*hw_res));
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400749 hw_res->display_num_of_h_tiles = sde_enc->display_num_of_h_tiles;
750
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400751 for (i = 0; i < sde_enc->num_phys_encs; i++) {
752 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
753
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400754 if (phys && phys->ops.get_hw_resources)
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400755 phys->ops.get_hw_resources(phys, hw_res, conn_state);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400756 }
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700757
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700758 /**
759 * NOTE: Do not use sde_encoder_get_mode_info here as this function is
760 * called from atomic_check phase. Use the below API to get mode
761 * information of the temporary conn_state passed.
762 */
763 rc = sde_connector_get_mode_info(conn_state, &mode_info);
764 if (rc) {
765 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
766 return;
767 }
768
769 hw_res->topology = mode_info.topology;
Jeykumar Sankaran6f215d42017-09-12 16:15:23 -0700770 hw_res->is_primary = sde_enc->disp_info.is_primary;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400771}
772
Clarence Ip3649f8b2016-10-31 09:59:44 -0400773void sde_encoder_destroy(struct drm_encoder *drm_enc)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400774{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400775 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400776 int i = 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400777
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400778 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -0400779 SDE_ERROR("invalid encoder\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400780 return;
781 }
782
783 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -0400784 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400785
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700786 mutex_lock(&sde_enc->enc_lock);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800787 sde_rsc_client_destroy(sde_enc->rsc_client);
788
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700789 for (i = 0; i < sde_enc->num_phys_encs; i++) {
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400790 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
791
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400792 if (phys && phys->ops.destroy) {
793 phys->ops.destroy(phys);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400794 --sde_enc->num_phys_encs;
795 sde_enc->phys_encs[i] = NULL;
796 }
797 }
798
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700799 if (sde_enc->num_phys_encs)
Clarence Ip19af1362016-09-23 14:57:51 -0400800 SDE_ERROR_ENC(sde_enc, "expected 0 num_phys_encs not %d\n",
Abhijit Kulkarni40e38162016-06-26 22:12:09 -0400801 sde_enc->num_phys_encs);
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700802 sde_enc->num_phys_encs = 0;
803 mutex_unlock(&sde_enc->enc_lock);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400804
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400805 drm_encoder_cleanup(drm_enc);
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700806 mutex_destroy(&sde_enc->enc_lock);
807
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800808 if (sde_enc->input_handler) {
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800809 kfree(sde_enc->input_handler);
Shubhashree Dhar25b05422018-05-30 15:42:04 +0530810 sde_enc->input_handler = NULL;
Shubhashree Dhar0c6ce3c2018-08-03 19:49:31 +0530811 sde_enc->input_handler_registered = false;
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -0800812 }
813
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400814 kfree(sde_enc);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700815}
816
Clarence Ip8e69ad02016-12-09 09:43:57 -0500817void sde_encoder_helper_split_config(
818 struct sde_encoder_phys *phys_enc,
819 enum sde_intf interface)
820{
821 struct sde_encoder_virt *sde_enc;
822 struct split_pipe_cfg cfg = { 0 };
823 struct sde_hw_mdp *hw_mdptop;
824 enum sde_rm_topology_name topology;
Dhaval Patel5cd59a02017-06-13 16:29:40 -0700825 struct msm_display_info *disp_info;
Clarence Ip8e69ad02016-12-09 09:43:57 -0500826
827 if (!phys_enc || !phys_enc->hw_mdptop || !phys_enc->parent) {
828 SDE_ERROR("invalid arg(s), encoder %d\n", phys_enc != 0);
829 return;
830 }
831
832 sde_enc = to_sde_encoder_virt(phys_enc->parent);
833 hw_mdptop = phys_enc->hw_mdptop;
Dhaval Patel5cd59a02017-06-13 16:29:40 -0700834 disp_info = &sde_enc->disp_info;
835
836 if (disp_info->intf_type != DRM_MODE_CONNECTOR_DSI)
837 return;
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500838
839 /**
840 * disable split modes since encoder will be operating in as the only
841 * encoder, either for the entire use case in the case of, for example,
842 * single DSI, or for this frame in the case of left/right only partial
843 * update.
844 */
845 if (phys_enc->split_role == ENC_ROLE_SOLO) {
846 if (hw_mdptop->ops.setup_split_pipe)
847 hw_mdptop->ops.setup_split_pipe(hw_mdptop, &cfg);
848 if (hw_mdptop->ops.setup_pp_split)
849 hw_mdptop->ops.setup_pp_split(hw_mdptop, &cfg);
850 return;
851 }
852
853 cfg.en = true;
Clarence Ip8e69ad02016-12-09 09:43:57 -0500854 cfg.mode = phys_enc->intf_mode;
855 cfg.intf = interface;
856
857 if (cfg.en && phys_enc->ops.needs_single_flush &&
858 phys_enc->ops.needs_single_flush(phys_enc))
859 cfg.split_flush_en = true;
860
861 topology = sde_connector_get_topology_name(phys_enc->connector);
862 if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
863 cfg.pp_split_slave = cfg.intf;
864 else
865 cfg.pp_split_slave = INTF_MAX;
866
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500867 if (phys_enc->split_role == ENC_ROLE_MASTER) {
Clarence Ip8e69ad02016-12-09 09:43:57 -0500868 SDE_DEBUG_ENC(sde_enc, "enable %d\n", cfg.en);
869
870 if (hw_mdptop->ops.setup_split_pipe)
871 hw_mdptop->ops.setup_split_pipe(hw_mdptop, &cfg);
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -0400872 } else if (sde_enc->hw_pp[0]) {
Clarence Ip8e69ad02016-12-09 09:43:57 -0500873 /*
874 * slave encoder
875 * - determine split index from master index,
876 * assume master is first pp
877 */
878 cfg.pp_split_index = sde_enc->hw_pp[0]->idx - PINGPONG_0;
879 SDE_DEBUG_ENC(sde_enc, "master using pp%d\n",
880 cfg.pp_split_index);
881
882 if (hw_mdptop->ops.setup_pp_split)
883 hw_mdptop->ops.setup_pp_split(hw_mdptop, &cfg);
884 }
885}
886
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400887static int sde_encoder_virt_atomic_check(
888 struct drm_encoder *drm_enc,
889 struct drm_crtc_state *crtc_state,
890 struct drm_connector_state *conn_state)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400891{
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400892 struct sde_encoder_virt *sde_enc;
893 struct msm_drm_private *priv;
894 struct sde_kms *sde_kms;
Alan Kwongbb27c092016-07-20 16:41:25 -0400895 const struct drm_display_mode *mode;
896 struct drm_display_mode *adj_mode;
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700897 struct sde_connector *sde_conn = NULL;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700898 struct sde_connector_state *sde_conn_state = NULL;
Lloyd Atkinson5ca13aa2017-10-26 18:12:20 -0400899 struct sde_crtc_state *sde_crtc_state = NULL;
Alan Kwongbb27c092016-07-20 16:41:25 -0400900 int i = 0;
901 int ret = 0;
902
Alan Kwongbb27c092016-07-20 16:41:25 -0400903 if (!drm_enc || !crtc_state || !conn_state) {
Clarence Ip19af1362016-09-23 14:57:51 -0400904 SDE_ERROR("invalid arg(s), drm_enc %d, crtc/conn state %d/%d\n",
905 drm_enc != 0, crtc_state != 0, conn_state != 0);
Alan Kwongbb27c092016-07-20 16:41:25 -0400906 return -EINVAL;
907 }
908
909 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -0400910 SDE_DEBUG_ENC(sde_enc, "\n");
911
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400912 priv = drm_enc->dev->dev_private;
913 sde_kms = to_sde_kms(priv->kms);
Alan Kwongbb27c092016-07-20 16:41:25 -0400914 mode = &crtc_state->mode;
915 adj_mode = &crtc_state->adjusted_mode;
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700916 sde_conn = to_sde_connector(conn_state->connector);
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700917 sde_conn_state = to_sde_connector_state(conn_state);
Lloyd Atkinson5ca13aa2017-10-26 18:12:20 -0400918 sde_crtc_state = to_sde_crtc_state(crtc_state);
919
920 SDE_EVT32(DRMID(drm_enc), drm_atomic_crtc_needs_modeset(crtc_state));
Alan Kwongbb27c092016-07-20 16:41:25 -0400921
922 /* perform atomic check on the first physical encoder (master) */
923 for (i = 0; i < sde_enc->num_phys_encs; i++) {
924 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
925
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400926 if (phys && phys->ops.atomic_check)
Alan Kwongbb27c092016-07-20 16:41:25 -0400927 ret = phys->ops.atomic_check(phys, crtc_state,
928 conn_state);
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400929 else if (phys && phys->ops.mode_fixup)
930 if (!phys->ops.mode_fixup(phys, mode, adj_mode))
Alan Kwongbb27c092016-07-20 16:41:25 -0400931 ret = -EINVAL;
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400932
933 if (ret) {
Clarence Ip19af1362016-09-23 14:57:51 -0400934 SDE_ERROR_ENC(sde_enc,
935 "mode unsupported, phys idx %d\n", i);
Alan Kwongbb27c092016-07-20 16:41:25 -0400936 break;
937 }
938 }
939
Lloyd Atkinson5ca13aa2017-10-26 18:12:20 -0400940 if (!ret && drm_atomic_crtc_needs_modeset(crtc_state)) {
941 struct sde_rect mode_roi, roi;
942
943 mode_roi.x = 0;
944 mode_roi.y = 0;
945 mode_roi.w = crtc_state->adjusted_mode.hdisplay;
946 mode_roi.h = crtc_state->adjusted_mode.vdisplay;
947
948 if (sde_conn_state->rois.num_rects) {
949 sde_kms_rect_merge_rectangles(
950 &sde_conn_state->rois, &roi);
951 if (!sde_kms_rect_is_equal(&mode_roi, &roi)) {
952 SDE_ERROR_ENC(sde_enc,
953 "roi (%d,%d,%d,%d) on connector invalid during modeset\n",
954 roi.x, roi.y, roi.w, roi.h);
955 ret = -EINVAL;
956 }
957 }
958
959 if (sde_crtc_state->user_roi_list.num_rects) {
960 sde_kms_rect_merge_rectangles(
961 &sde_crtc_state->user_roi_list, &roi);
962 if (!sde_kms_rect_is_equal(&mode_roi, &roi)) {
963 SDE_ERROR_ENC(sde_enc,
964 "roi (%d,%d,%d,%d) on crtc invalid during modeset\n",
965 roi.x, roi.y, roi.w, roi.h);
966 ret = -EINVAL;
967 }
968 }
969
970 if (ret)
971 return ret;
972 }
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700973
Lloyd Atkinson4ced69e2017-11-03 12:16:09 -0400974 if (!ret) {
975 /**
976 * record topology in previous atomic state to be able to handle
977 * topology transitions correctly.
978 */
979 enum sde_rm_topology_name old_top;
980
981 old_top = sde_connector_get_property(conn_state,
982 CONNECTOR_PROP_TOPOLOGY_NAME);
983 ret = sde_connector_set_old_topology_name(conn_state, old_top);
984 if (ret)
985 return ret;
986 }
987
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700988 if (!ret && sde_conn && drm_atomic_crtc_needs_modeset(crtc_state)) {
989 struct msm_display_topology *topology = NULL;
990
991 ret = sde_conn->ops.get_mode_info(adj_mode,
Jeykumar Sankaran905ba332017-10-19 10:45:02 -0700992 &sde_conn_state->mode_info,
Alan Kwongb1bca602017-09-18 17:28:45 -0400993 sde_kms->catalog->max_mixer_width,
994 sde_conn->display);
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700995 if (ret) {
996 SDE_ERROR_ENC(sde_enc,
997 "failed to get mode info, rc = %d\n", ret);
998 return ret;
999 }
1000
1001 /* Reserve dynamic resources, indicating atomic_check phase */
1002 ret = sde_rm_reserve(&sde_kms->rm, drm_enc, crtc_state,
1003 conn_state, true);
1004 if (ret) {
1005 SDE_ERROR_ENC(sde_enc,
1006 "RM failed to reserve resources, rc = %d\n",
1007 ret);
1008 return ret;
1009 }
1010
1011 /**
1012 * Update connector state with the topology selected for the
1013 * resource set validated. Reset the topology if we are
1014 * de-activating crtc.
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001015 */
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001016 if (crtc_state->active)
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001017 topology = &sde_conn_state->mode_info.topology;
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001018
1019 ret = sde_rm_update_topology(conn_state, topology);
1020 if (ret) {
1021 SDE_ERROR_ENC(sde_enc,
1022 "RM failed to update topology, rc: %d\n", ret);
1023 return ret;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001024 }
Jeykumar Sankaran736d79d2017-10-05 17:44:24 -07001025
Jeykumar Sankaran83ddcb02017-10-27 11:34:50 -07001026 ret = sde_connector_set_blob_data(conn_state->connector,
1027 conn_state,
1028 CONNECTOR_PROP_SDE_INFO);
Jeykumar Sankaran736d79d2017-10-05 17:44:24 -07001029 if (ret) {
1030 SDE_ERROR_ENC(sde_enc,
1031 "connector failed to update info, rc: %d\n",
1032 ret);
1033 return ret;
1034 }
1035
1036 }
1037
1038 ret = sde_connector_roi_v1_check_roi(conn_state);
1039 if (ret) {
1040 SDE_ERROR_ENC(sde_enc, "connector roi check failed, rc: %d",
1041 ret);
1042 return ret;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001043 }
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001044
Gopikrishnaiah Anandan703eb902016-10-06 18:43:57 -07001045 if (!ret)
Gopikrishnaiah Anandane0e5e0c2016-05-25 11:05:33 -07001046 drm_mode_set_crtcinfo(adj_mode, 0);
Alan Kwongbb27c092016-07-20 16:41:25 -04001047
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04001048 SDE_EVT32(DRMID(drm_enc), adj_mode->flags, adj_mode->private_flags);
Alan Kwongbb27c092016-07-20 16:41:25 -04001049
1050 return ret;
1051}
1052
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001053static int _sde_encoder_dsc_update_pic_dim(struct msm_display_dsc_info *dsc,
1054 int pic_width, int pic_height)
1055{
1056 if (!dsc || !pic_width || !pic_height) {
1057 SDE_ERROR("invalid input: pic_width=%d pic_height=%d\n",
1058 pic_width, pic_height);
1059 return -EINVAL;
1060 }
1061
1062 if ((pic_width % dsc->slice_width) ||
1063 (pic_height % dsc->slice_height)) {
1064 SDE_ERROR("pic_dim=%dx%d has to be multiple of slice=%dx%d\n",
1065 pic_width, pic_height,
1066 dsc->slice_width, dsc->slice_height);
1067 return -EINVAL;
1068 }
1069
1070 dsc->pic_width = pic_width;
1071 dsc->pic_height = pic_height;
1072
1073 return 0;
1074}
1075
1076static void _sde_encoder_dsc_pclk_param_calc(struct msm_display_dsc_info *dsc,
1077 int intf_width)
1078{
1079 int slice_per_pkt, slice_per_intf;
1080 int bytes_in_slice, total_bytes_per_intf;
1081
1082 if (!dsc || !dsc->slice_width || !dsc->slice_per_pkt ||
1083 (intf_width < dsc->slice_width)) {
1084 SDE_ERROR("invalid input: intf_width=%d slice_width=%d\n",
1085 intf_width, dsc ? dsc->slice_width : -1);
1086 return;
1087 }
1088
1089 slice_per_pkt = dsc->slice_per_pkt;
1090 slice_per_intf = DIV_ROUND_UP(intf_width, dsc->slice_width);
1091
1092 /*
1093 * If slice_per_pkt is greater than slice_per_intf then default to 1.
1094 * This can happen during partial update.
1095 */
1096 if (slice_per_pkt > slice_per_intf)
1097 slice_per_pkt = 1;
1098
1099 bytes_in_slice = DIV_ROUND_UP(dsc->slice_width * dsc->bpp, 8);
1100 total_bytes_per_intf = bytes_in_slice * slice_per_intf;
1101
1102 dsc->eol_byte_num = total_bytes_per_intf % 3;
1103 dsc->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3);
1104 dsc->bytes_in_slice = bytes_in_slice;
1105 dsc->bytes_per_pkt = bytes_in_slice * slice_per_pkt;
1106 dsc->pkt_per_line = slice_per_intf / slice_per_pkt;
1107}
1108
1109static int _sde_encoder_dsc_initial_line_calc(struct msm_display_dsc_info *dsc,
1110 int enc_ip_width)
1111{
1112 int ssm_delay, total_pixels, soft_slice_per_enc;
1113
1114 soft_slice_per_enc = enc_ip_width / dsc->slice_width;
1115
1116 /*
1117 * minimum number of initial line pixels is a sum of:
1118 * 1. sub-stream multiplexer delay (83 groups for 8bpc,
1119 * 91 for 10 bpc) * 3
1120 * 2. for two soft slice cases, add extra sub-stream multiplexer * 3
1121 * 3. the initial xmit delay
1122 * 4. total pipeline delay through the "lock step" of encoder (47)
1123 * 5. 6 additional pixels as the output of the rate buffer is
1124 * 48 bits wide
1125 */
1126 ssm_delay = ((dsc->bpc < 10) ? 84 : 92);
1127 total_pixels = ssm_delay * 3 + dsc->initial_xmit_delay + 47;
1128 if (soft_slice_per_enc > 1)
1129 total_pixels += (ssm_delay * 3);
1130 dsc->initial_lines = DIV_ROUND_UP(total_pixels, dsc->slice_width);
1131 return 0;
1132}
1133
1134static bool _sde_encoder_dsc_ich_reset_override_needed(bool pu_en,
1135 struct msm_display_dsc_info *dsc)
1136{
1137 /*
1138 * As per the DSC spec, ICH_RESET can be either end of the slice line
1139 * or at the end of the slice. HW internally generates ich_reset at
1140 * end of the slice line if DSC_MERGE is used or encoder has two
1141 * soft slices. However, if encoder has only 1 soft slice and DSC_MERGE
1142 * is not used then it will generate ich_reset at the end of slice.
1143 *
1144 * Now as per the spec, during one PPS session, position where
1145 * ich_reset is generated should not change. Now if full-screen frame
1146 * has more than 1 soft slice then HW will automatically generate
1147 * ich_reset at the end of slice_line. But for the same panel, if
1148 * partial frame is enabled and only 1 encoder is used with 1 slice,
1149 * then HW will generate ich_reset at end of the slice. This is a
1150 * mismatch. Prevent this by overriding HW's decision.
1151 */
1152 return pu_en && dsc && (dsc->full_frame_slices > 1) &&
1153 (dsc->slice_width == dsc->pic_width);
1154}
1155
1156static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc,
1157 struct sde_hw_pingpong *hw_pp, struct msm_display_dsc_info *dsc,
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001158 u32 common_mode, bool ich_reset, bool enable)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001159{
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001160 if (!enable) {
1161 if (hw_pp->ops.disable_dsc)
1162 hw_pp->ops.disable_dsc(hw_pp);
1163 return;
1164 }
1165
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001166 if (hw_dsc->ops.dsc_config)
1167 hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, ich_reset);
1168
1169 if (hw_dsc->ops.dsc_config_thresh)
1170 hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc);
1171
1172 if (hw_pp->ops.setup_dsc)
1173 hw_pp->ops.setup_dsc(hw_pp);
1174
1175 if (hw_pp->ops.enable_dsc)
1176 hw_pp->ops.enable_dsc(hw_pp);
1177}
1178
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001179static void _sde_encoder_get_connector_roi(
1180 struct sde_encoder_virt *sde_enc,
1181 struct sde_rect *merged_conn_roi)
1182{
1183 struct drm_connector *drm_conn;
1184 struct sde_connector_state *c_state;
1185
1186 if (!sde_enc || !merged_conn_roi)
1187 return;
1188
1189 drm_conn = sde_enc->phys_encs[0]->connector;
1190
1191 if (!drm_conn || !drm_conn->state)
1192 return;
1193
1194 c_state = to_sde_connector_state(drm_conn->state);
1195 sde_kms_rect_merge_rectangles(&c_state->rois, merged_conn_roi);
1196}
1197
Ingrid Gallardo83532222017-06-02 16:48:51 -07001198static int _sde_encoder_dsc_n_lm_1_enc_1_intf(struct sde_encoder_virt *sde_enc)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001199{
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001200 int this_frame_slices;
1201 int intf_ip_w, enc_ip_w;
1202 int ich_res, dsc_common_mode = 0;
1203
1204 struct sde_hw_pingpong *hw_pp = sde_enc->hw_pp[0];
1205 struct sde_hw_dsc *hw_dsc = sde_enc->hw_dsc[0];
1206 struct sde_encoder_phys *enc_master = sde_enc->cur_master;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001207 const struct sde_rect *roi = &sde_enc->cur_conn_roi;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001208 struct msm_mode_info mode_info;
1209 struct msm_display_dsc_info *dsc = NULL;
1210 int rc;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001211
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001212 if (hw_dsc == NULL || hw_pp == NULL || !enc_master) {
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001213 SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
1214 return -EINVAL;
1215 }
1216
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001217 rc = _sde_encoder_get_mode_info(&sde_enc->base, &mode_info);
1218 if (rc) {
1219 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
1220 return -EINVAL;
1221 }
1222
1223 dsc = &mode_info.comp_info.dsc_info;
1224
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001225 _sde_encoder_dsc_update_pic_dim(dsc, roi->w, roi->h);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001226
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001227 this_frame_slices = roi->w / dsc->slice_width;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001228 intf_ip_w = this_frame_slices * dsc->slice_width;
1229 _sde_encoder_dsc_pclk_param_calc(dsc, intf_ip_w);
1230
1231 enc_ip_w = intf_ip_w;
1232 _sde_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
1233
1234 ich_res = _sde_encoder_dsc_ich_reset_override_needed(false, dsc);
1235
1236 if (enc_master->intf_mode == INTF_MODE_VIDEO)
1237 dsc_common_mode = DSC_MODE_VIDEO;
1238
1239 SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n",
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001240 roi->w, roi->h, dsc_common_mode);
1241 SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001242
1243 _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode,
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001244 ich_res, true);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001245
1246 return 0;
1247}
Ingrid Gallardo83532222017-06-02 16:48:51 -07001248
Vishnuvardhan Prodduturi6b1803a2019-01-19 16:35:34 +05301249
1250static int _sde_encoder_dsc_4_lm_4_enc_2_intf(struct sde_encoder_virt *sde_enc,
1251 struct sde_encoder_kickoff_params *params)
1252{
1253 int this_frame_slices;
1254 int intf_ip_w, enc_ip_w;
1255 int ich_res, dsc_common_mode;
1256
1257 struct sde_encoder_phys *enc_master = sde_enc->cur_master;
1258 const struct sde_rect *roi = &sde_enc->cur_conn_roi;
1259 struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
1260 struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
1261 struct msm_display_dsc_info dsc[MAX_CHANNELS_PER_ENC];
1262 struct msm_mode_info mode_info;
1263 bool half_panel_partial_update;
1264 int i, rc;
1265
1266 memset(hw_dsc, 0, sizeof(struct sde_hw_dsc *)*MAX_CHANNELS_PER_ENC);
1267 memset(hw_pp, 0, sizeof(struct sde_hw_pingpong *)*MAX_CHANNELS_PER_ENC);
1268
1269 for (i = 0; i < params->num_channels; i++) {
1270 hw_pp[i] = sde_enc->hw_pp[i];
1271 hw_dsc[i] = sde_enc->hw_dsc[i];
1272
1273 if (!hw_pp[i] || !hw_dsc[i]) {
1274 SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
1275 return -EINVAL;
1276 }
1277 }
1278
1279 rc = _sde_encoder_get_mode_info(&sde_enc->base, &mode_info);
1280 if (rc) {
1281 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
1282 return -EINVAL;
1283 }
1284
1285 half_panel_partial_update =
1286 hweight_long(params->affected_displays) == 1;
1287
1288 dsc_common_mode = 0;
1289 if (!half_panel_partial_update)
1290 dsc_common_mode |= DSC_MODE_SPLIT_PANEL | DSC_MODE_MULTIPLEX;
1291 if (enc_master->intf_mode == INTF_MODE_VIDEO)
1292 dsc_common_mode |= DSC_MODE_VIDEO;
1293
1294 memcpy(&dsc[0], &mode_info.comp_info.dsc_info, sizeof(dsc[0]));
1295 memcpy(&dsc[1], &mode_info.comp_info.dsc_info, sizeof(dsc[1]));
1296 memcpy(&dsc[2], &mode_info.comp_info.dsc_info, sizeof(dsc[2]));
1297 memcpy(&dsc[3], &mode_info.comp_info.dsc_info, sizeof(dsc[3]));
1298
1299 /*
1300 * Since both DSC use same pic dimension, set same pic dimension
1301 * to both DSC structures.
1302 */
1303 _sde_encoder_dsc_update_pic_dim(&dsc[0], roi->w, roi->h);
1304 _sde_encoder_dsc_update_pic_dim(&dsc[1], roi->w, roi->h);
1305 _sde_encoder_dsc_update_pic_dim(&dsc[2], roi->w, roi->h);
1306 _sde_encoder_dsc_update_pic_dim(&dsc[3], roi->w, roi->h);
1307
1308 this_frame_slices = roi->w / dsc[0].slice_width;
1309 intf_ip_w = this_frame_slices * dsc[0].slice_width;
1310
1311 if (!half_panel_partial_update)
1312 intf_ip_w /= 2;
1313
1314 /*
1315 * In this topology when both interfaces are active, they have same
1316 * load so intf_ip_w will be same.
1317 */
1318 _sde_encoder_dsc_pclk_param_calc(&dsc[0], intf_ip_w);
1319 _sde_encoder_dsc_pclk_param_calc(&dsc[1], intf_ip_w);
1320 _sde_encoder_dsc_pclk_param_calc(&dsc[2], intf_ip_w);
1321 _sde_encoder_dsc_pclk_param_calc(&dsc[3], intf_ip_w);
1322
1323 /*
1324 * In this topology, since there is no dsc_merge, uncompressed input
1325 * to encoder and interface is same.
1326 */
1327 enc_ip_w = intf_ip_w;
1328 _sde_encoder_dsc_initial_line_calc(&dsc[0], enc_ip_w);
1329 _sde_encoder_dsc_initial_line_calc(&dsc[1], enc_ip_w);
1330 _sde_encoder_dsc_initial_line_calc(&dsc[2], enc_ip_w);
1331 _sde_encoder_dsc_initial_line_calc(&dsc[3], enc_ip_w);
1332
1333 /*
1334 * __is_ich_reset_override_needed should be called only after
1335 * updating pic dimension, mdss_panel_dsc_update_pic_dim.
1336 */
1337 ich_res = _sde_encoder_dsc_ich_reset_override_needed(
1338 half_panel_partial_update, &dsc[0]);
1339
1340 SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n",
1341 roi->w, roi->h, dsc_common_mode);
1342
1343 _sde_encoder_dsc_pipe_cfg(hw_dsc[0], hw_pp[0], &dsc[0],
1344 dsc_common_mode, ich_res, true);
1345 _sde_encoder_dsc_pipe_cfg(hw_dsc[1], hw_pp[1], &dsc[1],
1346 dsc_common_mode, ich_res, true);
1347 _sde_encoder_dsc_pipe_cfg(hw_dsc[2], hw_pp[2], &dsc[2],
1348 dsc_common_mode, ich_res, true);
1349 _sde_encoder_dsc_pipe_cfg(hw_dsc[3], hw_pp[3], &dsc[3],
1350 dsc_common_mode, ich_res, true);
1351
1352 return 0;
1353}
1354
1355
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001356static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc,
1357 struct sde_encoder_kickoff_params *params)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001358{
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001359 int this_frame_slices;
1360 int intf_ip_w, enc_ip_w;
1361 int ich_res, dsc_common_mode;
1362
1363 struct sde_encoder_phys *enc_master = sde_enc->cur_master;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001364 const struct sde_rect *roi = &sde_enc->cur_conn_roi;
1365 struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
1366 struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
1367 struct msm_display_dsc_info dsc[MAX_CHANNELS_PER_ENC];
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001368 struct msm_mode_info mode_info;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001369 bool half_panel_partial_update;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001370 int i, rc;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001371
Vishnuvardhan Prodduturi6b1803a2019-01-19 16:35:34 +05301372 for (i = 0; i < params->num_channels; i++) {
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001373 hw_pp[i] = sde_enc->hw_pp[i];
1374 hw_dsc[i] = sde_enc->hw_dsc[i];
1375
1376 if (!hw_pp[i] || !hw_dsc[i]) {
1377 SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
1378 return -EINVAL;
1379 }
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001380 }
1381
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001382 rc = _sde_encoder_get_mode_info(&sde_enc->base, &mode_info);
1383 if (rc) {
1384 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
1385 return -EINVAL;
1386 }
1387
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001388 half_panel_partial_update =
1389 hweight_long(params->affected_displays) == 1;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001390
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001391 dsc_common_mode = 0;
1392 if (!half_panel_partial_update)
1393 dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001394 if (enc_master->intf_mode == INTF_MODE_VIDEO)
1395 dsc_common_mode |= DSC_MODE_VIDEO;
1396
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001397 memcpy(&dsc[0], &mode_info.comp_info.dsc_info, sizeof(dsc[0]));
1398 memcpy(&dsc[1], &mode_info.comp_info.dsc_info, sizeof(dsc[1]));
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001399
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001400 /*
1401 * Since both DSC use same pic dimension, set same pic dimension
1402 * to both DSC structures.
1403 */
1404 _sde_encoder_dsc_update_pic_dim(&dsc[0], roi->w, roi->h);
1405 _sde_encoder_dsc_update_pic_dim(&dsc[1], roi->w, roi->h);
1406
1407 this_frame_slices = roi->w / dsc[0].slice_width;
1408 intf_ip_w = this_frame_slices * dsc[0].slice_width;
1409
1410 if (!half_panel_partial_update)
1411 intf_ip_w /= 2;
1412
1413 /*
1414 * In this topology when both interfaces are active, they have same
1415 * load so intf_ip_w will be same.
1416 */
1417 _sde_encoder_dsc_pclk_param_calc(&dsc[0], intf_ip_w);
1418 _sde_encoder_dsc_pclk_param_calc(&dsc[1], intf_ip_w);
1419
1420 /*
1421 * In this topology, since there is no dsc_merge, uncompressed input
1422 * to encoder and interface is same.
1423 */
1424 enc_ip_w = intf_ip_w;
1425 _sde_encoder_dsc_initial_line_calc(&dsc[0], enc_ip_w);
1426 _sde_encoder_dsc_initial_line_calc(&dsc[1], enc_ip_w);
1427
1428 /*
1429 * __is_ich_reset_override_needed should be called only after
1430 * updating pic dimension, mdss_panel_dsc_update_pic_dim.
1431 */
1432 ich_res = _sde_encoder_dsc_ich_reset_override_needed(
1433 half_panel_partial_update, &dsc[0]);
1434
1435 SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n",
1436 roi->w, roi->h, dsc_common_mode);
1437
1438 for (i = 0; i < sde_enc->num_phys_encs; i++) {
1439 bool active = !!((1 << i) & params->affected_displays);
1440
1441 SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h,
1442 dsc_common_mode, i, active);
1443 _sde_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], &dsc[i],
1444 dsc_common_mode, ich_res, active);
1445 }
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001446
1447 return 0;
1448}
1449
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001450static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc,
1451 struct sde_encoder_kickoff_params *params)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001452{
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001453 int this_frame_slices;
1454 int intf_ip_w, enc_ip_w;
1455 int ich_res, dsc_common_mode;
1456
1457 struct sde_encoder_phys *enc_master = sde_enc->cur_master;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001458 const struct sde_rect *roi = &sde_enc->cur_conn_roi;
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001459 struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
1460 struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001461 struct msm_display_dsc_info *dsc = NULL;
1462 struct msm_mode_info mode_info;
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001463 bool half_panel_partial_update;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001464 int i, rc;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001465
Vishnuvardhan Prodduturi6b1803a2019-01-19 16:35:34 +05301466 for (i = 0; i < params->num_channels; i++) {
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001467 hw_pp[i] = sde_enc->hw_pp[i];
1468 hw_dsc[i] = sde_enc->hw_dsc[i];
1469
1470 if (!hw_pp[i] || !hw_dsc[i]) {
1471 SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
1472 return -EINVAL;
1473 }
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001474 }
1475
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001476 rc = _sde_encoder_get_mode_info(&sde_enc->base, &mode_info);
1477 if (rc) {
1478 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
1479 return -EINVAL;
1480 }
1481
1482 dsc = &mode_info.comp_info.dsc_info;
1483
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001484 half_panel_partial_update =
1485 hweight_long(params->affected_displays) == 1;
1486
1487 dsc_common_mode = 0;
1488 if (!half_panel_partial_update)
1489 dsc_common_mode |= DSC_MODE_SPLIT_PANEL | DSC_MODE_MULTIPLEX;
1490 if (enc_master->intf_mode == INTF_MODE_VIDEO)
1491 dsc_common_mode |= DSC_MODE_VIDEO;
1492
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001493 _sde_encoder_dsc_update_pic_dim(dsc, roi->w, roi->h);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001494
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001495 this_frame_slices = roi->w / dsc->slice_width;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001496 intf_ip_w = this_frame_slices * dsc->slice_width;
1497 _sde_encoder_dsc_pclk_param_calc(dsc, intf_ip_w);
1498
1499 /*
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001500 * dsc merge case: when using 2 encoders for the same stream,
1501 * no. of slices need to be same on both the encoders.
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001502 */
1503 enc_ip_w = intf_ip_w / 2;
1504 _sde_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
1505
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001506 ich_res = _sde_encoder_dsc_ich_reset_override_needed(
1507 half_panel_partial_update, dsc);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001508
1509 SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n",
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001510 roi->w, roi->h, dsc_common_mode);
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001511 SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h,
1512 dsc_common_mode, i, params->affected_displays);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001513
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001514 _sde_encoder_dsc_pipe_cfg(hw_dsc[0], hw_pp[0], dsc, dsc_common_mode,
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001515 ich_res, true);
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001516 _sde_encoder_dsc_pipe_cfg(hw_dsc[1], hw_pp[1], dsc, dsc_common_mode,
1517 ich_res, !half_panel_partial_update);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001518
1519 return 0;
1520}
1521
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001522static int _sde_encoder_update_roi(struct drm_encoder *drm_enc)
1523{
1524 struct sde_encoder_virt *sde_enc;
1525 struct drm_connector *drm_conn;
1526 struct drm_display_mode *adj_mode;
1527 struct sde_rect roi;
1528
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001529 if (!drm_enc) {
1530 SDE_ERROR("invalid encoder parameter\n");
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001531 return -EINVAL;
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001532 }
1533
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001534 sde_enc = to_sde_encoder_virt(drm_enc);
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001535 if (!sde_enc->crtc || !sde_enc->crtc->state) {
1536 SDE_ERROR("invalid crtc parameter\n");
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001537 return -EINVAL;
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001538 }
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001539
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001540 if (!sde_enc->cur_master) {
1541 SDE_ERROR("invalid cur_master parameter\n");
1542 return -EINVAL;
1543 }
1544
1545 adj_mode = &sde_enc->cur_master->cached_mode;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001546 drm_conn = sde_enc->cur_master->connector;
1547
1548 _sde_encoder_get_connector_roi(sde_enc, &roi);
1549 if (sde_kms_rect_is_null(&roi)) {
1550 roi.w = adj_mode->hdisplay;
1551 roi.h = adj_mode->vdisplay;
1552 }
1553
1554 memcpy(&sde_enc->prv_conn_roi, &sde_enc->cur_conn_roi,
1555 sizeof(sde_enc->prv_conn_roi));
1556 memcpy(&sde_enc->cur_conn_roi, &roi, sizeof(sde_enc->cur_conn_roi));
1557
1558 return 0;
1559}
1560
1561static int _sde_encoder_dsc_setup(struct sde_encoder_virt *sde_enc,
1562 struct sde_encoder_kickoff_params *params)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001563{
1564 enum sde_rm_topology_name topology;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001565 struct drm_connector *drm_conn;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001566 int ret = 0;
1567
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001568 if (!sde_enc || !params || !sde_enc->phys_encs[0] ||
1569 !sde_enc->phys_encs[0]->connector)
1570 return -EINVAL;
1571
1572 drm_conn = sde_enc->phys_encs[0]->connector;
1573
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001574 topology = sde_connector_get_topology_name(drm_conn);
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001575 if (topology == SDE_RM_TOPOLOGY_NONE) {
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001576 SDE_ERROR_ENC(sde_enc, "topology not set yet\n");
1577 return -EINVAL;
1578 }
1579
Jayant Shekharac7bd942019-02-26 15:44:54 +05301580 params->num_channels =
1581 sde_rm_get_topology_num_encoders(topology);
1582
Ingrid Gallardo83532222017-06-02 16:48:51 -07001583 SDE_DEBUG_ENC(sde_enc, "topology:%d\n", topology);
Lloyd Atkinson5ca13aa2017-10-26 18:12:20 -04001584 SDE_EVT32(DRMID(&sde_enc->base), topology,
1585 sde_enc->cur_conn_roi.x,
1586 sde_enc->cur_conn_roi.y,
1587 sde_enc->cur_conn_roi.w,
1588 sde_enc->cur_conn_roi.h,
1589 sde_enc->prv_conn_roi.x,
1590 sde_enc->prv_conn_roi.y,
1591 sde_enc->prv_conn_roi.w,
1592 sde_enc->prv_conn_roi.h,
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001593 sde_enc->cur_master->cached_mode.hdisplay,
1594 sde_enc->cur_master->cached_mode.vdisplay);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001595
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001596 if (sde_kms_rect_is_equal(&sde_enc->cur_conn_roi,
1597 &sde_enc->prv_conn_roi))
1598 return ret;
1599
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001600 switch (topology) {
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001601 case SDE_RM_TOPOLOGY_SINGLEPIPE_DSC:
Ingrid Gallardo83532222017-06-02 16:48:51 -07001602 case SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC:
1603 ret = _sde_encoder_dsc_n_lm_1_enc_1_intf(sde_enc);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001604 break;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001605 case SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE:
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001606 ret = _sde_encoder_dsc_2_lm_2_enc_1_intf(sde_enc, params);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001607 break;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001608 case SDE_RM_TOPOLOGY_DUALPIPE_DSC:
Kalyan Thota27ec06c2019-03-18 13:19:59 +05301609 case SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC:
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001610 ret = _sde_encoder_dsc_2_lm_2_enc_2_intf(sde_enc, params);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001611 break;
Vishnuvardhan Prodduturi6b1803a2019-01-19 16:35:34 +05301612 case SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE:
1613 ret = _sde_encoder_dsc_4_lm_4_enc_2_intf(sde_enc, params);
1614 break;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001615 default:
1616 SDE_ERROR_ENC(sde_enc, "No DSC support for topology %d",
1617 topology);
1618 return -EINVAL;
1619 };
1620
1621 return ret;
1622}
1623
Dhaval Patelaab9b522017-07-20 12:38:46 -07001624static void _sde_encoder_update_vsync_source(struct sde_encoder_virt *sde_enc,
1625 struct msm_display_info *disp_info, bool is_dummy)
1626{
1627 struct sde_vsync_source_cfg vsync_cfg = { 0 };
1628 struct msm_drm_private *priv;
1629 struct sde_kms *sde_kms;
1630 struct sde_hw_mdp *hw_mdptop;
1631 struct drm_encoder *drm_enc;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001632 struct msm_mode_info mode_info;
1633 int i, rc = 0;
Dhaval Patelaab9b522017-07-20 12:38:46 -07001634
Jayant Shekhar136e0592018-10-09 18:32:33 +05301635 if (!sde_enc || !sde_enc->cur_master || !disp_info) {
Dhaval Patelaab9b522017-07-20 12:38:46 -07001636 SDE_ERROR("invalid param sde_enc:%d or disp_info:%d\n",
1637 sde_enc != NULL, disp_info != NULL);
1638 return;
1639 } else if (sde_enc->num_phys_encs > ARRAY_SIZE(sde_enc->hw_pp)) {
1640 SDE_ERROR("invalid num phys enc %d/%d\n",
1641 sde_enc->num_phys_encs,
1642 (int) ARRAY_SIZE(sde_enc->hw_pp));
1643 return;
1644 }
1645
1646 drm_enc = &sde_enc->base;
1647 /* this pointers are checked in virt_enable_helper */
1648 priv = drm_enc->dev->dev_private;
1649
1650 sde_kms = to_sde_kms(priv->kms);
1651 if (!sde_kms) {
1652 SDE_ERROR("invalid sde_kms\n");
1653 return;
1654 }
1655
1656 hw_mdptop = sde_kms->hw_mdp;
1657 if (!hw_mdptop) {
1658 SDE_ERROR("invalid mdptop\n");
1659 return;
1660 }
1661
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001662 rc = _sde_encoder_get_mode_info(drm_enc, &mode_info);
1663 if (rc) {
1664 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001665 return;
1666 }
1667
Dhaval Patelaab9b522017-07-20 12:38:46 -07001668 if (hw_mdptop->ops.setup_vsync_source &&
1669 disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) {
1670 for (i = 0; i < sde_enc->num_phys_encs; i++)
1671 vsync_cfg.ppnumber[i] = sde_enc->hw_pp[i]->idx;
1672
1673 vsync_cfg.pp_count = sde_enc->num_phys_encs;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001674 vsync_cfg.frame_rate = mode_info.frame_rate;
Kalyan Thotaa02db2c2018-04-27 11:39:18 +05301675 vsync_cfg.vsync_source =
1676 sde_enc->cur_master->hw_pp->caps->te_source;
Dhaval Patelaab9b522017-07-20 12:38:46 -07001677 if (is_dummy)
1678 vsync_cfg.vsync_source = SDE_VSYNC_SOURCE_WD_TIMER_1;
1679 else if (disp_info->is_te_using_watchdog_timer)
1680 vsync_cfg.vsync_source = SDE_VSYNC_SOURCE_WD_TIMER_0;
Kalyan Thotaa02db2c2018-04-27 11:39:18 +05301681
Dhaval Patelaab9b522017-07-20 12:38:46 -07001682 vsync_cfg.is_dummy = is_dummy;
1683
1684 hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
1685 }
1686}
1687
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001688static int _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc)
1689{
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001690 int i, ret = 0;
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001691 struct sde_hw_pingpong *hw_pp = NULL;
1692 struct sde_hw_dsc *hw_dsc = NULL;
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001693
1694 if (!sde_enc || !sde_enc->phys_encs[0] ||
1695 !sde_enc->phys_encs[0]->connector) {
1696 SDE_ERROR("invalid params %d %d\n",
1697 !sde_enc, sde_enc ? !sde_enc->phys_encs[0] : -1);
1698 return -EINVAL;
1699 }
1700
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001701 /* Disable DSC for all the pp's present in this topology */
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001702 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
1703 hw_pp = sde_enc->hw_pp[i];
1704 hw_dsc = sde_enc->hw_dsc[i];
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001705
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001706 if (hw_pp && hw_pp->ops.disable_dsc)
1707 hw_pp->ops.disable_dsc(hw_pp);
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001708
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001709 if (hw_dsc && hw_dsc->ops.dsc_disable)
1710 hw_dsc->ops.dsc_disable(hw_dsc);
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001711 }
1712
1713 return ret;
1714}
1715
Dhaval Patelef58f0b2018-01-22 19:13:52 -08001716static int _sde_encoder_switch_to_watchdog_vsync(struct drm_encoder *drm_enc)
1717{
1718 struct sde_encoder_virt *sde_enc;
1719 struct msm_display_info disp_info;
1720
1721 if (!drm_enc) {
1722 pr_err("invalid drm encoder\n");
1723 return -EINVAL;
1724 }
1725
1726 sde_enc = to_sde_encoder_virt(drm_enc);
1727
1728 sde_encoder_control_te(drm_enc, false);
1729
1730 memcpy(&disp_info, &sde_enc->disp_info, sizeof(disp_info));
1731 disp_info.is_te_using_watchdog_timer = true;
1732 _sde_encoder_update_vsync_source(sde_enc, &disp_info, false);
1733
1734 sde_encoder_control_te(drm_enc, true);
1735
1736 return 0;
1737}
1738
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001739static int _sde_encoder_update_rsc_client(
Alan Kwong56f1a942017-04-04 11:53:42 -07001740 struct drm_encoder *drm_enc,
1741 struct sde_encoder_rsc_config *config, bool enable)
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001742{
1743 struct sde_encoder_virt *sde_enc;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001744 struct drm_crtc *crtc;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001745 enum sde_rsc_state rsc_state;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001746 struct sde_rsc_cmd_config *rsc_config;
1747 int ret, prefill_lines;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001748 struct msm_display_info *disp_info;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001749 struct msm_mode_info mode_info;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001750 int wait_vblank_crtc_id = SDE_RSC_INVALID_CRTC_ID;
1751 int wait_count = 0;
1752 struct drm_crtc *primary_crtc;
1753 int pipe = -1;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001754 int rc = 0;
Ingrid Gallardoe52302c2017-11-28 19:30:47 -08001755 int wait_refcount;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001756
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001757 if (!drm_enc || !drm_enc->dev) {
1758 SDE_ERROR("invalid encoder arguments\n");
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001759 return -EINVAL;
1760 }
1761
1762 sde_enc = to_sde_encoder_virt(drm_enc);
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001763 crtc = sde_enc->crtc;
1764
1765 if (!sde_enc->crtc) {
1766 SDE_ERROR("invalid crtc parameter\n");
1767 return -EINVAL;
1768 }
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001769 disp_info = &sde_enc->disp_info;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001770 rsc_config = &sde_enc->rsc_config;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001771
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001772 if (!sde_enc->rsc_client) {
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001773 SDE_DEBUG_ENC(sde_enc, "rsc client not created\n");
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001774 return 0;
1775 }
1776
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001777 rc = _sde_encoder_get_mode_info(drm_enc, &mode_info);
1778 if (rc) {
1779 SDE_ERROR_ENC(sde_enc, "failed to mode info\n");
1780 return 0;
1781 }
1782
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001783 /**
1784 * only primary command mode panel can request CMD state.
1785 * all other panels/displays can request for VID state including
1786 * secondary command mode panel.
Prabhanjan Kandula77cc0ee2018-04-15 21:44:50 -07001787 * Clone mode encoder can request CLK STATE only.
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001788 */
Prabhanjan Kandula77cc0ee2018-04-15 21:44:50 -07001789 if (sde_encoder_in_clone_mode(drm_enc))
1790 rsc_state = enable ? SDE_RSC_CLK_STATE : SDE_RSC_IDLE_STATE;
1791 else
1792 rsc_state = enable ?
1793 (((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE)
1794 && disp_info->is_primary) ? SDE_RSC_CMD_STATE :
1795 SDE_RSC_VID_STATE) : SDE_RSC_IDLE_STATE;
1796
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001797 prefill_lines = config ? mode_info.prefill_lines +
1798 config->inline_rotate_prefill : mode_info.prefill_lines;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001799
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001800 /* compare specific items and reconfigure the rsc */
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001801 if ((rsc_config->fps != mode_info.frame_rate) ||
1802 (rsc_config->vtotal != mode_info.vtotal) ||
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001803 (rsc_config->prefill_lines != prefill_lines) ||
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001804 (rsc_config->jitter_numer != mode_info.jitter_numer) ||
1805 (rsc_config->jitter_denom != mode_info.jitter_denom)) {
1806 rsc_config->fps = mode_info.frame_rate;
1807 rsc_config->vtotal = mode_info.vtotal;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001808 rsc_config->prefill_lines = prefill_lines;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07001809 rsc_config->jitter_numer = mode_info.jitter_numer;
1810 rsc_config->jitter_denom = mode_info.jitter_denom;
Alan Kwong56f1a942017-04-04 11:53:42 -07001811 sde_enc->rsc_state_init = false;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001812 }
Alan Kwong56f1a942017-04-04 11:53:42 -07001813
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001814 if (rsc_state != SDE_RSC_IDLE_STATE && !sde_enc->rsc_state_init
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001815 && disp_info->is_primary) {
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001816 /* update it only once */
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001817 sde_enc->rsc_state_init = true;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001818
1819 ret = sde_rsc_client_state_update(sde_enc->rsc_client,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001820 rsc_state, rsc_config, crtc->base.id,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001821 &wait_vblank_crtc_id);
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001822 } else {
1823 ret = sde_rsc_client_state_update(sde_enc->rsc_client,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001824 rsc_state, NULL, crtc->base.id,
1825 &wait_vblank_crtc_id);
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001826 }
1827
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001828 /**
1829 * if RSC performed a state change that requires a VBLANK wait, it will
1830 * set wait_vblank_crtc_id to the CRTC whose VBLANK we must wait on.
1831 *
1832 * if we are the primary display, we will need to enable and wait
1833 * locally since we hold the commit thread
1834 *
1835 * if we are an external display, we must send a signal to the primary
1836 * to enable its VBLANK and wait one, since the RSC hardware is driven
1837 * by the primary panel's VBLANK signals
1838 */
1839 SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id);
1840 if (ret) {
1841 SDE_ERROR_ENC(sde_enc,
1842 "sde rsc client update failed ret:%d\n", ret);
1843 return ret;
1844 } else if (wait_vblank_crtc_id == SDE_RSC_INVALID_CRTC_ID) {
1845 return ret;
1846 }
1847
Ingrid Gallardoe52302c2017-11-28 19:30:47 -08001848 if (wait_vblank_crtc_id)
1849 wait_refcount =
1850 sde_rsc_client_get_vsync_refcount(sde_enc->rsc_client);
1851 SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
1852 SDE_EVTLOG_FUNC_ENTRY);
1853
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001854 if (crtc->base.id != wait_vblank_crtc_id) {
1855 primary_crtc = drm_crtc_find(drm_enc->dev, wait_vblank_crtc_id);
1856 if (!primary_crtc) {
1857 SDE_ERROR_ENC(sde_enc,
1858 "failed to find primary crtc id %d\n",
1859 wait_vblank_crtc_id);
1860 return -EINVAL;
1861 }
1862 pipe = drm_crtc_index(primary_crtc);
1863 }
1864
1865 /**
1866 * note: VBLANK is expected to be enabled at this point in
1867 * resource control state machine if on primary CRTC
1868 */
1869 for (wait_count = 0; wait_count < MAX_RSC_WAIT; wait_count++) {
1870 if (sde_rsc_client_is_state_update_complete(
1871 sde_enc->rsc_client))
1872 break;
1873
1874 if (crtc->base.id == wait_vblank_crtc_id)
1875 ret = sde_encoder_wait_for_event(drm_enc,
1876 MSM_ENC_VBLANK);
1877 else
1878 drm_wait_one_vblank(drm_enc->dev, pipe);
1879
1880 if (ret) {
1881 SDE_ERROR_ENC(sde_enc,
1882 "wait for vblank failed ret:%d\n", ret);
Dhaval Patelef58f0b2018-01-22 19:13:52 -08001883 /**
1884 * rsc hardware may hang without vsync. avoid rsc hang
1885 * by generating the vsync from watchdog timer.
1886 */
1887 if (crtc->base.id == wait_vblank_crtc_id)
1888 _sde_encoder_switch_to_watchdog_vsync(drm_enc);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001889 }
1890 }
1891
1892 if (wait_count >= MAX_RSC_WAIT)
1893 SDE_EVT32(DRMID(drm_enc), wait_vblank_crtc_id, wait_count,
1894 SDE_EVTLOG_ERROR);
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001895
Ingrid Gallardoe52302c2017-11-28 19:30:47 -08001896 if (wait_refcount)
1897 sde_rsc_client_reset_vsync_refcount(sde_enc->rsc_client);
1898 SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
1899 SDE_EVTLOG_FUNC_EXIT);
1900
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001901 return ret;
1902}
1903
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001904static void _sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable)
1905{
1906 struct sde_encoder_virt *sde_enc;
1907 int i;
1908
1909 if (!drm_enc) {
1910 SDE_ERROR("invalid encoder\n");
1911 return;
1912 }
1913
1914 sde_enc = to_sde_encoder_virt(drm_enc);
1915
1916 SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable);
1917 for (i = 0; i < sde_enc->num_phys_encs; i++) {
1918 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
1919
1920 if (phys && phys->ops.irq_control)
1921 phys->ops.irq_control(phys, enable);
1922 }
1923
1924}
1925
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07001926/* keep track of the userspace vblank during modeset */
1927static void _sde_encoder_modeset_helper_locked(struct drm_encoder *drm_enc,
1928 u32 sw_event)
1929{
1930 struct sde_encoder_virt *sde_enc;
1931 bool enable;
1932 int i;
1933
1934 if (!drm_enc) {
1935 SDE_ERROR("invalid encoder\n");
1936 return;
1937 }
1938
1939 sde_enc = to_sde_encoder_virt(drm_enc);
1940 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, vblank_enabled:%d\n",
1941 sw_event, sde_enc->vblank_enabled);
1942
1943 /* nothing to do if vblank not enabled by userspace */
1944 if (!sde_enc->vblank_enabled)
1945 return;
1946
1947 /* disable vblank on pre_modeset */
1948 if (sw_event == SDE_ENC_RC_EVENT_PRE_MODESET)
1949 enable = false;
1950 /* enable vblank on post_modeset */
1951 else if (sw_event == SDE_ENC_RC_EVENT_POST_MODESET)
1952 enable = true;
1953 else
1954 return;
1955
1956 for (i = 0; i < sde_enc->num_phys_encs; i++) {
1957 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
1958
1959 if (phys && phys->ops.control_vblank_irq)
1960 phys->ops.control_vblank_irq(phys, enable);
1961 }
1962}
1963
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001964struct sde_rsc_client *sde_encoder_get_rsc_client(struct drm_encoder *drm_enc)
1965{
1966 struct sde_encoder_virt *sde_enc;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001967
1968 if (!drm_enc)
1969 return NULL;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001970 sde_enc = to_sde_encoder_virt(drm_enc);
Dhaval Patel5cd59a02017-06-13 16:29:40 -07001971 return sde_enc->rsc_client;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001972}
1973
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001974static void _sde_encoder_resource_control_rsc_update(
1975 struct drm_encoder *drm_enc, bool enable)
1976{
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001977 struct sde_encoder_rsc_config rsc_cfg = { 0 };
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001978 struct sde_encoder_virt *sde_enc;
1979
1980 if (!drm_enc) {
1981 SDE_ERROR("invalid encoder argument\n");
1982 return;
1983 }
1984 sde_enc = to_sde_encoder_virt(drm_enc);
1985 if (!sde_enc->crtc) {
1986 SDE_ERROR("invalid crtc\n");
1987 return;
1988 }
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001989
1990 if (enable) {
1991 rsc_cfg.inline_rotate_prefill =
Harsh Sahu1e52ed02017-11-28 14:34:22 -08001992 sde_crtc_get_inline_prefill(sde_enc->crtc);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001993
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001994 _sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true);
1995 } else {
1996 _sde_encoder_update_rsc_client(drm_enc, NULL, false);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001997 }
1998}
1999
Alan Kwong1124f1f2017-11-10 18:14:39 -05002000static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002001 bool enable)
2002{
2003 struct msm_drm_private *priv;
2004 struct sde_kms *sde_kms;
2005 struct sde_encoder_virt *sde_enc;
Alan Kwong1124f1f2017-11-10 18:14:39 -05002006 int rc;
Lloyd Atkinson7fdd4c22017-11-16 20:10:17 -05002007 bool is_cmd_mode, is_primary;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002008
2009 sde_enc = to_sde_encoder_virt(drm_enc);
2010 priv = drm_enc->dev->dev_private;
2011 sde_kms = to_sde_kms(priv->kms);
2012
Lloyd Atkinson7fdd4c22017-11-16 20:10:17 -05002013 is_cmd_mode = sde_enc->disp_info.capabilities &
2014 MSM_DISPLAY_CAP_CMD_MODE;
2015 is_primary = sde_enc->disp_info.is_primary;
2016
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002017 SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable);
2018 SDE_EVT32(DRMID(drm_enc), enable);
2019
2020 if (!sde_enc->cur_master) {
2021 SDE_ERROR("encoder master not set\n");
Alan Kwong1124f1f2017-11-10 18:14:39 -05002022 return -EINVAL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002023 }
2024
2025 if (enable) {
2026 /* enable SDE core clks */
Alan Kwong1124f1f2017-11-10 18:14:39 -05002027 rc = sde_power_resource_enable(&priv->phandle,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002028 sde_kms->core_client, true);
Alan Kwong1124f1f2017-11-10 18:14:39 -05002029 if (rc) {
2030 SDE_ERROR("failed to enable power resource %d\n", rc);
2031 SDE_EVT32(rc, SDE_EVTLOG_ERROR);
2032 return rc;
2033 }
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002034
Dhaval Patel30874eb2018-05-31 13:33:31 -07002035 sde_enc->elevated_ahb_vote = true;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002036 /* enable DSI clks */
Alan Kwong1124f1f2017-11-10 18:14:39 -05002037 rc = sde_connector_clk_ctrl(sde_enc->cur_master->connector,
2038 true);
2039 if (rc) {
2040 SDE_ERROR("failed to enable clk control %d\n", rc);
2041 sde_power_resource_enable(&priv->phandle,
2042 sde_kms->core_client, false);
2043 return rc;
2044 }
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002045
2046 /* enable all the irq */
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002047 _sde_encoder_irq_control(drm_enc, true);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002048
Lloyd Atkinson7fdd4c22017-11-16 20:10:17 -05002049 if (is_cmd_mode && is_primary)
2050 _sde_encoder_pm_qos_add_request(drm_enc);
2051
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002052 } else {
Lloyd Atkinson7fdd4c22017-11-16 20:10:17 -05002053 if (is_cmd_mode && is_primary)
2054 _sde_encoder_pm_qos_remove_request(drm_enc);
2055
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002056 /* disable all the irq */
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002057 _sde_encoder_irq_control(drm_enc, false);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002058
2059 /* disable DSI clks */
2060 sde_connector_clk_ctrl(sde_enc->cur_master->connector, false);
2061
2062 /* disable SDE core clks */
2063 sde_power_resource_enable(&priv->phandle,
2064 sde_kms->core_client, false);
2065 }
2066
Alan Kwong1124f1f2017-11-10 18:14:39 -05002067 return 0;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002068}
2069
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002070static void sde_encoder_input_event_handler(struct input_handle *handle,
2071 unsigned int type, unsigned int code, int value)
2072{
2073 struct drm_encoder *drm_enc = NULL;
2074 struct sde_encoder_virt *sde_enc = NULL;
Jayant Shekhar779c7522018-06-13 12:44:44 +05302075 struct msm_drm_thread *event_thread = NULL;
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002076 struct msm_drm_private *priv = NULL;
2077
2078 if (!handle || !handle->handler || !handle->handler->private) {
2079 SDE_ERROR("invalid encoder for the input event\n");
2080 return;
2081 }
2082
2083 drm_enc = (struct drm_encoder *)handle->handler->private;
2084 if (!drm_enc->dev || !drm_enc->dev->dev_private) {
2085 SDE_ERROR("invalid parameters\n");
2086 return;
2087 }
2088
2089 priv = drm_enc->dev->dev_private;
2090 sde_enc = to_sde_encoder_virt(drm_enc);
2091 if (!sde_enc->crtc || (sde_enc->crtc->index
Jayant Shekhar779c7522018-06-13 12:44:44 +05302092 >= ARRAY_SIZE(priv->event_thread))) {
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002093 SDE_DEBUG_ENC(sde_enc,
2094 "invalid cached CRTC: %d or crtc index: %d\n",
2095 sde_enc->crtc == NULL,
2096 sde_enc->crtc ? sde_enc->crtc->index : -EINVAL);
2097 return;
2098 }
2099
2100 SDE_EVT32_VERBOSE(DRMID(drm_enc));
2101
Jayant Shekhar779c7522018-06-13 12:44:44 +05302102 event_thread = &priv->event_thread[sde_enc->crtc->index];
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002103
Jayant Shekhar779c7522018-06-13 12:44:44 +05302104 /* Queue input event work to event thread */
2105 kthread_queue_work(&event_thread->worker,
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002106 &sde_enc->input_event_work);
2107}
2108
Veera Sundaram Sankaran42ac38d2018-07-06 12:42:04 -07002109void sde_encoder_control_idle_pc(struct drm_encoder *drm_enc, bool enable)
2110{
2111 struct sde_encoder_virt *sde_enc;
2112
2113 if (!drm_enc) {
2114 SDE_ERROR("invalid encoder\n");
2115 return;
2116 }
2117 sde_enc = to_sde_encoder_virt(drm_enc);
2118
2119 /* return early if there is no state change */
2120 if (sde_enc->idle_pc_enabled == enable)
2121 return;
2122
2123 sde_enc->idle_pc_enabled = enable;
2124
2125 SDE_DEBUG("idle-pc state:%d\n", sde_enc->idle_pc_enabled);
2126 SDE_EVT32(sde_enc->idle_pc_enabled);
2127}
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002128
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002129static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
2130 u32 sw_event)
2131{
Dhaval Patel99412a52017-07-24 19:16:45 -07002132 bool autorefresh_enabled = false;
Dhaval Patelc9e213b2017-11-02 12:13:12 -07002133 unsigned int lp, idle_pc_duration;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002134 struct sde_encoder_virt *sde_enc;
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002135 struct msm_drm_private *priv;
2136 struct msm_drm_thread *disp_thread;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002137 int ret;
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002138 bool is_vid_mode = false;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002139
Harsh Sahu1e52ed02017-11-28 14:34:22 -08002140 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
2141 SDE_ERROR("invalid encoder parameters, sw_event:%u\n",
2142 sw_event);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002143 return -EINVAL;
2144 }
2145 sde_enc = to_sde_encoder_virt(drm_enc);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002146 priv = drm_enc->dev->dev_private;
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002147 is_vid_mode = sde_enc->disp_info.capabilities &
2148 MSM_DISPLAY_CAP_VID_MODE;
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002149
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002150 /*
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002151 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002152 * events and return early for other events (ie wb display).
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002153 */
Veera Sundaram Sankaran42ac38d2018-07-06 12:42:04 -07002154 if (!sde_enc->idle_pc_enabled &&
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002155 (sw_event != SDE_ENC_RC_EVENT_KICKOFF &&
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002156 sw_event != SDE_ENC_RC_EVENT_PRE_MODESET &&
2157 sw_event != SDE_ENC_RC_EVENT_POST_MODESET &&
2158 sw_event != SDE_ENC_RC_EVENT_STOP &&
2159 sw_event != SDE_ENC_RC_EVENT_PRE_STOP))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002160 return 0;
2161
Veera Sundaram Sankaran42ac38d2018-07-06 12:42:04 -07002162 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc:%d\n",
2163 sw_event, sde_enc->idle_pc_enabled);
2164 SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002165 sde_enc->rc_state, SDE_EVTLOG_FUNC_ENTRY);
2166
2167 switch (sw_event) {
2168 case SDE_ENC_RC_EVENT_KICKOFF:
2169 /* cancel delayed off work, if any */
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002170 if (kthread_cancel_delayed_work_sync(
2171 &sde_enc->delayed_off_work))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002172 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work cancelled\n",
2173 sw_event);
2174
2175 mutex_lock(&sde_enc->rc_lock);
2176
2177 /* return if the resource control is already in ON state */
2178 if (sde_enc->rc_state == SDE_ENC_RC_STATE_ON) {
2179 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in ON state\n",
2180 sw_event);
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002181 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2182 SDE_EVTLOG_FUNC_CASE1);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002183 mutex_unlock(&sde_enc->rc_lock);
2184 return 0;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002185 } else if (sde_enc->rc_state != SDE_ENC_RC_STATE_OFF &&
2186 sde_enc->rc_state != SDE_ENC_RC_STATE_IDLE) {
2187 SDE_ERROR_ENC(sde_enc, "sw_event:%d, rc in state %d\n",
2188 sw_event, sde_enc->rc_state);
2189 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2190 SDE_EVTLOG_ERROR);
2191 mutex_unlock(&sde_enc->rc_lock);
2192 return -EINVAL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002193 }
2194
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002195 if (is_vid_mode && sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
2196 _sde_encoder_irq_control(drm_enc, true);
2197 } else {
2198 /* enable all the clks and resources */
Alan Kwong1124f1f2017-11-10 18:14:39 -05002199 ret = _sde_encoder_resource_control_helper(drm_enc,
2200 true);
2201 if (ret) {
2202 SDE_ERROR_ENC(sde_enc,
2203 "sw_event:%d, rc in state %d\n",
2204 sw_event, sde_enc->rc_state);
2205 SDE_EVT32(DRMID(drm_enc), sw_event,
2206 sde_enc->rc_state,
2207 SDE_EVTLOG_ERROR);
2208 mutex_unlock(&sde_enc->rc_lock);
2209 return ret;
2210 }
2211
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002212 _sde_encoder_resource_control_rsc_update(drm_enc, true);
2213 }
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002214
2215 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2216 SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE1);
2217 sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
2218
2219 mutex_unlock(&sde_enc->rc_lock);
2220 break;
2221
2222 case SDE_ENC_RC_EVENT_FRAME_DONE:
Harsh Sahu1e52ed02017-11-28 14:34:22 -08002223 if (!sde_enc->crtc) {
2224 SDE_ERROR("invalid crtc, sw_event:%u\n", sw_event);
2225 return -EINVAL;
2226 }
2227
2228 if (sde_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
2229 SDE_ERROR("invalid crtc index :%u\n",
2230 sde_enc->crtc->index);
2231 return -EINVAL;
2232 }
2233 disp_thread = &priv->disp_thread[sde_enc->crtc->index];
2234
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002235 /*
2236 * mutex lock is not used as this event happens at interrupt
2237 * context. And locking is not required as, the other events
2238 * like KICKOFF and STOP does a wait-for-idle before executing
2239 * the resource_control
2240 */
2241 if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
2242 SDE_ERROR_ENC(sde_enc, "sw_event:%d,rc:%d-unexpected\n",
2243 sw_event, sde_enc->rc_state);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002244 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2245 SDE_EVTLOG_ERROR);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002246 return -EINVAL;
2247 }
2248
2249 /*
2250 * schedule off work item only when there are no
2251 * frames pending
2252 */
Harsh Sahu1e52ed02017-11-28 14:34:22 -08002253 if (sde_crtc_frame_pending(sde_enc->crtc) > 1) {
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002254 SDE_DEBUG_ENC(sde_enc, "skip schedule work");
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002255 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2256 SDE_EVTLOG_FUNC_CASE2);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002257 return 0;
2258 }
2259
Dhaval Patel99412a52017-07-24 19:16:45 -07002260 /* schedule delayed off work if autorefresh is disabled */
2261 if (sde_enc->cur_master &&
2262 sde_enc->cur_master->ops.is_autorefresh_enabled)
2263 autorefresh_enabled =
2264 sde_enc->cur_master->ops.is_autorefresh_enabled(
2265 sde_enc->cur_master);
2266
Clarence Ip89628132017-07-27 13:33:51 -04002267 /* set idle timeout based on master connector's lp value */
2268 if (sde_enc->cur_master)
2269 lp = sde_connector_get_lp(
2270 sde_enc->cur_master->connector);
2271 else
2272 lp = SDE_MODE_DPMS_ON;
2273
2274 if (lp == SDE_MODE_DPMS_LP2)
Dhaval Patelc9e213b2017-11-02 12:13:12 -07002275 idle_pc_duration = IDLE_SHORT_TIMEOUT;
Clarence Ip89628132017-07-27 13:33:51 -04002276 else
Dhaval Patelc9e213b2017-11-02 12:13:12 -07002277 idle_pc_duration = IDLE_POWERCOLLAPSE_DURATION;
Clarence Ip89628132017-07-27 13:33:51 -04002278
Dhaval Patelc9e213b2017-11-02 12:13:12 -07002279 if (!autorefresh_enabled)
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002280 kthread_mod_delayed_work(
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002281 &disp_thread->worker,
2282 &sde_enc->delayed_off_work,
Dhaval Patelc9e213b2017-11-02 12:13:12 -07002283 msecs_to_jiffies(idle_pc_duration));
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002284 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
Clarence Ip89628132017-07-27 13:33:51 -04002285 autorefresh_enabled,
Dhaval Patelc9e213b2017-11-02 12:13:12 -07002286 idle_pc_duration, SDE_EVTLOG_FUNC_CASE2);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002287 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work scheduled\n",
2288 sw_event);
2289 break;
2290
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002291 case SDE_ENC_RC_EVENT_PRE_STOP:
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002292 /* cancel delayed off work, if any */
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002293 if (kthread_cancel_delayed_work_sync(
2294 &sde_enc->delayed_off_work))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002295 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work cancelled\n",
2296 sw_event);
2297
2298 mutex_lock(&sde_enc->rc_lock);
2299
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002300 if (is_vid_mode &&
2301 sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
2302 _sde_encoder_irq_control(drm_enc, true);
2303 }
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002304 /* skip if is already OFF or IDLE, resources are off already */
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002305 else if (sde_enc->rc_state == SDE_ENC_RC_STATE_OFF ||
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002306 sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
2307 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in %d state\n",
2308 sw_event, sde_enc->rc_state);
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002309 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2310 SDE_EVTLOG_FUNC_CASE3);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002311 mutex_unlock(&sde_enc->rc_lock);
2312 return 0;
2313 }
2314
2315 /**
2316 * IRQs are still enabled currently, which allows wait for
2317 * VBLANK which RSC may require to correctly transition to OFF
2318 */
2319 _sde_encoder_resource_control_rsc_update(drm_enc, false);
2320
2321 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2322 SDE_ENC_RC_STATE_PRE_OFF,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002323 SDE_EVTLOG_FUNC_CASE3);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002324
2325 sde_enc->rc_state = SDE_ENC_RC_STATE_PRE_OFF;
2326
2327 mutex_unlock(&sde_enc->rc_lock);
2328 break;
2329
2330 case SDE_ENC_RC_EVENT_STOP:
Lloyd Atkinson418477a2017-11-07 16:53:39 -05002331 /* cancel vsync event work and timer */
Jayant Shekhar12d908f2017-10-10 12:11:48 +05302332 kthread_cancel_work_sync(&sde_enc->vsync_event_work);
Lloyd Atkinson418477a2017-11-07 16:53:39 -05002333 del_timer_sync(&sde_enc->vsync_event_timer);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002334
Jayant Shekhar12d908f2017-10-10 12:11:48 +05302335 mutex_lock(&sde_enc->rc_lock);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002336 /* return if the resource control is already in OFF state */
2337 if (sde_enc->rc_state == SDE_ENC_RC_STATE_OFF) {
2338 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in OFF state\n",
2339 sw_event);
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002340 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2341 SDE_EVTLOG_FUNC_CASE4);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002342 mutex_unlock(&sde_enc->rc_lock);
2343 return 0;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002344 } else if (sde_enc->rc_state == SDE_ENC_RC_STATE_ON ||
2345 sde_enc->rc_state == SDE_ENC_RC_STATE_MODESET) {
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002346 SDE_ERROR_ENC(sde_enc, "sw_event:%d, rc in state %d\n",
2347 sw_event, sde_enc->rc_state);
2348 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2349 SDE_EVTLOG_ERROR);
2350 mutex_unlock(&sde_enc->rc_lock);
2351 return -EINVAL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002352 }
2353
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002354 /**
2355 * expect to arrive here only if in either idle state or pre-off
2356 * and in IDLE state the resources are already disabled
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002357 */
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002358 if (sde_enc->rc_state == SDE_ENC_RC_STATE_PRE_OFF)
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002359 _sde_encoder_resource_control_helper(drm_enc, false);
2360
2361 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002362 SDE_ENC_RC_STATE_OFF, SDE_EVTLOG_FUNC_CASE4);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002363
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002364 sde_enc->rc_state = SDE_ENC_RC_STATE_OFF;
2365
2366 mutex_unlock(&sde_enc->rc_lock);
2367 break;
2368
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002369 case SDE_ENC_RC_EVENT_PRE_MODESET:
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002370 /* cancel delayed off work, if any */
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002371 if (kthread_cancel_delayed_work_sync(
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002372 &sde_enc->delayed_off_work))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002373 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work cancelled\n",
2374 sw_event);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002375
2376 mutex_lock(&sde_enc->rc_lock);
2377
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002378 /* return if the resource control is already in ON state */
2379 if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
2380 /* enable all the clks and resources */
Alan Kwong1124f1f2017-11-10 18:14:39 -05002381 ret = _sde_encoder_resource_control_helper(drm_enc,
2382 true);
2383 if (ret) {
2384 SDE_ERROR_ENC(sde_enc,
2385 "sw_event:%d, rc in state %d\n",
2386 sw_event, sde_enc->rc_state);
2387 SDE_EVT32(DRMID(drm_enc), sw_event,
2388 sde_enc->rc_state,
2389 SDE_EVTLOG_ERROR);
2390 mutex_unlock(&sde_enc->rc_lock);
2391 return ret;
2392 }
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002393
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002394 _sde_encoder_resource_control_rsc_update(drm_enc, true);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002395
2396 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2397 SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE5);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002398 sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002399 }
2400
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002401 ret = sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
2402 if (ret && ret != -EWOULDBLOCK) {
2403 SDE_ERROR_ENC(sde_enc,
2404 "wait for commit done returned %d\n",
2405 ret);
2406 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2407 ret, SDE_EVTLOG_ERROR);
2408 mutex_unlock(&sde_enc->rc_lock);
2409 return -EINVAL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002410 }
2411
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002412 _sde_encoder_irq_control(drm_enc, false);
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07002413 _sde_encoder_modeset_helper_locked(drm_enc, sw_event);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002414
2415 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2416 SDE_ENC_RC_STATE_MODESET, SDE_EVTLOG_FUNC_CASE5);
2417
2418 sde_enc->rc_state = SDE_ENC_RC_STATE_MODESET;
2419 mutex_unlock(&sde_enc->rc_lock);
2420 break;
2421
2422 case SDE_ENC_RC_EVENT_POST_MODESET:
2423 mutex_lock(&sde_enc->rc_lock);
2424
2425 /* return if the resource control is already in ON state */
2426 if (sde_enc->rc_state != SDE_ENC_RC_STATE_MODESET) {
2427 SDE_ERROR_ENC(sde_enc,
2428 "sw_event:%d, rc:%d !MODESET state\n",
2429 sw_event, sde_enc->rc_state);
2430 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2431 SDE_EVTLOG_ERROR);
2432 mutex_unlock(&sde_enc->rc_lock);
2433 return -EINVAL;
2434 }
2435
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07002436 _sde_encoder_modeset_helper_locked(drm_enc, sw_event);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002437 _sde_encoder_irq_control(drm_enc, true);
2438
2439 _sde_encoder_update_rsc_client(drm_enc, NULL, true);
2440
2441 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2442 SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE6);
2443
2444 sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
2445
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002446 mutex_unlock(&sde_enc->rc_lock);
2447 break;
2448
2449 case SDE_ENC_RC_EVENT_ENTER_IDLE:
2450 mutex_lock(&sde_enc->rc_lock);
2451
2452 if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
Dhaval Patel8a7c3282017-12-05 00:41:58 -08002453 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc:%d !ON state\n",
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002454 sw_event, sde_enc->rc_state);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002455 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2456 SDE_EVTLOG_ERROR);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002457 mutex_unlock(&sde_enc->rc_lock);
2458 return 0;
2459 }
2460
2461 /*
2462 * if we are in ON but a frame was just kicked off,
2463 * ignore the IDLE event, it's probably a stale timer event
2464 */
2465 if (sde_enc->frame_busy_mask[0]) {
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002466 SDE_ERROR_ENC(sde_enc,
Lloyd Atkinsona8781382017-07-17 10:20:43 -04002467 "sw_event:%d, rc:%d frame pending\n",
2468 sw_event, sde_enc->rc_state);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002469 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2470 SDE_EVTLOG_ERROR);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002471 mutex_unlock(&sde_enc->rc_lock);
2472 return 0;
2473 }
2474
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002475 if (is_vid_mode) {
2476 _sde_encoder_irq_control(drm_enc, false);
2477 } else {
2478 /* disable all the clks and resources */
2479 _sde_encoder_resource_control_rsc_update(drm_enc,
2480 false);
2481 _sde_encoder_resource_control_helper(drm_enc, false);
2482 }
2483
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002484 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002485 SDE_ENC_RC_STATE_IDLE, SDE_EVTLOG_FUNC_CASE7);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002486 sde_enc->rc_state = SDE_ENC_RC_STATE_IDLE;
2487
2488 mutex_unlock(&sde_enc->rc_lock);
2489 break;
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002490 case SDE_ENC_RC_EVENT_EARLY_WAKEUP:
2491 if (!sde_enc->crtc ||
2492 sde_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
2493 SDE_DEBUG_ENC(sde_enc,
2494 "invalid crtc:%d or crtc index:%d , sw_event:%u\n",
2495 sde_enc->crtc == NULL,
2496 sde_enc->crtc ? sde_enc->crtc->index : -EINVAL,
2497 sw_event);
2498 return -EINVAL;
2499 }
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002500
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002501 disp_thread = &priv->disp_thread[sde_enc->crtc->index];
2502
2503 mutex_lock(&sde_enc->rc_lock);
2504
2505 if (sde_enc->rc_state == SDE_ENC_RC_STATE_ON) {
2506 if (sde_enc->cur_master &&
2507 sde_enc->cur_master->ops.is_autorefresh_enabled)
2508 autorefresh_enabled =
2509 sde_enc->cur_master->ops.is_autorefresh_enabled(
2510 sde_enc->cur_master);
2511 if (autorefresh_enabled) {
2512 SDE_DEBUG_ENC(sde_enc,
2513 "not handling early wakeup since auto refresh is enabled\n");
Jeykumar Sankaran067b3b92018-01-19 10:35:22 -08002514 mutex_unlock(&sde_enc->rc_lock);
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002515 return 0;
2516 }
2517
2518 if (!sde_crtc_frame_pending(sde_enc->crtc))
2519 kthread_mod_delayed_work(&disp_thread->worker,
2520 &sde_enc->delayed_off_work,
2521 msecs_to_jiffies(
2522 IDLE_POWERCOLLAPSE_DURATION));
2523 } else if (sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
2524 /* enable all the clks and resources */
2525 _sde_encoder_resource_control_rsc_update(drm_enc, true);
2526 _sde_encoder_resource_control_helper(drm_enc, true);
2527
Jayant Shekhar85c40332018-05-08 11:46:36 +05302528 /*
2529 * In some cases, commit comes with slight delay
2530 * (> 80 ms)after early wake up, prevent clock switch
2531 * off to avoid jank in next update. So, increase the
2532 * command mode idle timeout sufficiently to prevent
2533 * such case.
2534 */
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002535 kthread_mod_delayed_work(&disp_thread->worker,
Jayant Shekhar85c40332018-05-08 11:46:36 +05302536 &sde_enc->delayed_off_work,
2537 msecs_to_jiffies(
2538 IDLE_POWERCOLLAPSE_IN_EARLY_WAKEUP));
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08002539
2540 sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
2541 }
2542
2543 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
2544 SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE8);
2545
2546 mutex_unlock(&sde_enc->rc_lock);
2547 break;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002548 default:
Dhaval Patela5f75952017-07-25 11:17:41 -07002549 SDE_EVT32(DRMID(drm_enc), sw_event, SDE_EVTLOG_ERROR);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002550 SDE_ERROR("unexpected sw_event: %d\n", sw_event);
2551 break;
2552 }
2553
Veera Sundaram Sankaran42ac38d2018-07-06 12:42:04 -07002554 SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002555 sde_enc->rc_state, SDE_EVTLOG_FUNC_EXIT);
2556 return 0;
2557}
2558
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002559static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
2560 struct drm_display_mode *mode,
Lloyd Atkinsonaf7952d2016-06-26 22:41:26 -04002561 struct drm_display_mode *adj_mode)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002562{
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002563 struct sde_encoder_virt *sde_enc;
2564 struct msm_drm_private *priv;
2565 struct sde_kms *sde_kms;
2566 struct list_head *connector_list;
2567 struct drm_connector *conn = NULL, *conn_iter;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07002568 struct sde_connector_state *sde_conn_state = NULL;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07002569 struct sde_connector *sde_conn = NULL;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08002570 struct sde_rm_hw_iter dsc_iter, pp_iter;
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002571 int i = 0, ret;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002572
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002573 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -04002574 SDE_ERROR("invalid encoder\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002575 return;
2576 }
2577
Alan Kwong1124f1f2017-11-10 18:14:39 -05002578 if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
2579 SDE_ERROR("power resource is not enabled\n");
2580 return;
2581 }
2582
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002583 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -04002584 SDE_DEBUG_ENC(sde_enc, "\n");
2585
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002586 priv = drm_enc->dev->dev_private;
2587 sde_kms = to_sde_kms(priv->kms);
2588 connector_list = &sde_kms->dev->mode_config.connector_list;
2589
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04002590 SDE_EVT32(DRMID(drm_enc));
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002591
Dhaval Patele514aae2018-01-30 11:46:02 -08002592 /*
2593 * cache the crtc in sde_enc on enable for duration of use case
2594 * for correctly servicing asynchronous irq events and timers
2595 */
2596 if (!drm_enc->crtc) {
2597 SDE_ERROR("invalid crtc\n");
2598 return;
2599 }
2600 sde_enc->crtc = drm_enc->crtc;
2601
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002602 list_for_each_entry(conn_iter, connector_list, head)
2603 if (conn_iter->encoder == drm_enc)
2604 conn = conn_iter;
2605
2606 if (!conn) {
Clarence Ip19af1362016-09-23 14:57:51 -04002607 SDE_ERROR_ENC(sde_enc, "failed to find attached connector\n");
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002608 return;
Lloyd Atkinson55987b02016-08-16 16:57:46 -04002609 } else if (!conn->state) {
2610 SDE_ERROR_ENC(sde_enc, "invalid connector state\n");
2611 return;
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002612 }
2613
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07002614 sde_conn = to_sde_connector(conn);
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07002615 sde_conn_state = to_sde_connector_state(conn->state);
2616 if (sde_conn && sde_conn_state) {
2617 ret = sde_conn->ops.get_mode_info(adj_mode,
2618 &sde_conn_state->mode_info,
Alan Kwongb1bca602017-09-18 17:28:45 -04002619 sde_kms->catalog->max_mixer_width,
2620 sde_conn->display);
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07002621 if (ret) {
2622 SDE_ERROR_ENC(sde_enc,
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07002623 "failed to get mode info from the display\n");
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07002624 return;
2625 }
2626 }
2627
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002628 /* release resources before seamless mode change */
2629 if (msm_is_mode_seamless_dms(adj_mode)) {
2630 /* restore resource state before releasing them */
2631 ret = sde_encoder_resource_control(drm_enc,
2632 SDE_ENC_RC_EVENT_PRE_MODESET);
2633 if (ret) {
2634 SDE_ERROR_ENC(sde_enc,
2635 "sde resource control failed: %d\n",
2636 ret);
2637 return;
2638 }
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07002639
2640 /*
2641 * Disable dsc before switch the mode and after pre_modeset,
2642 * to guarantee that previous kickoff finished.
2643 */
2644 _sde_encoder_dsc_disable(sde_enc);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002645 }
2646
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002647 /* Reserve dynamic resources now. Indicating non-AtomicTest phase */
2648 ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state,
2649 conn->state, false);
2650 if (ret) {
Clarence Ip19af1362016-09-23 14:57:51 -04002651 SDE_ERROR_ENC(sde_enc,
2652 "failed to reserve hw resources, %d\n", ret);
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002653 return;
2654 }
2655
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -07002656 sde_rm_init_hw_iter(&pp_iter, drm_enc->base.id, SDE_HW_BLK_PINGPONG);
2657 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
2658 sde_enc->hw_pp[i] = NULL;
2659 if (!sde_rm_get_hw(&sde_kms->rm, &pp_iter))
2660 break;
2661 sde_enc->hw_pp[i] = (struct sde_hw_pingpong *) pp_iter.hw;
2662 }
2663
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08002664 sde_rm_init_hw_iter(&dsc_iter, drm_enc->base.id, SDE_HW_BLK_DSC);
2665 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
2666 sde_enc->hw_dsc[i] = NULL;
2667 if (!sde_rm_get_hw(&sde_kms->rm, &dsc_iter))
2668 break;
2669 sde_enc->hw_dsc[i] = (struct sde_hw_dsc *) dsc_iter.hw;
2670 }
2671
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002672 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2673 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinsonaf7952d2016-06-26 22:41:26 -04002674
Lloyd Atkinson55987b02016-08-16 16:57:46 -04002675 if (phys) {
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -07002676 if (!sde_enc->hw_pp[i]) {
2677 SDE_ERROR_ENC(sde_enc,
2678 "invalid pingpong block for the encoder\n");
2679 return;
2680 }
2681 phys->hw_pp = sde_enc->hw_pp[i];
Lloyd Atkinson55987b02016-08-16 16:57:46 -04002682 phys->connector = conn->state->connector;
2683 if (phys->ops.mode_set)
2684 phys->ops.mode_set(phys, mode, adj_mode);
2685 }
Lloyd Atkinsonaf7952d2016-06-26 22:41:26 -04002686 }
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07002687
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002688 /* update resources after seamless mode change */
2689 if (msm_is_mode_seamless_dms(adj_mode))
2690 sde_encoder_resource_control(&sde_enc->base,
2691 SDE_ENC_RC_EVENT_POST_MODESET);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002692}
2693
Veera Sundaram Sankaran33db4282017-11-01 12:45:25 -07002694void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable)
2695{
2696 struct sde_encoder_virt *sde_enc;
2697 struct sde_encoder_phys *phys;
2698 int i;
2699
2700 if (!drm_enc) {
2701 SDE_ERROR("invalid parameters\n");
2702 return;
2703 }
2704
2705 sde_enc = to_sde_encoder_virt(drm_enc);
2706 if (!sde_enc) {
2707 SDE_ERROR("invalid sde encoder\n");
2708 return;
2709 }
2710
2711 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2712 phys = sde_enc->phys_encs[i];
2713 if (phys && phys->ops.control_te)
2714 phys->ops.control_te(phys, enable);
2715 }
2716}
2717
Shubhashree Dhar25b05422018-05-30 15:42:04 +05302718static int _sde_encoder_input_connect(struct input_handler *handler,
2719 struct input_dev *dev, const struct input_device_id *id)
2720{
2721 struct input_handle *handle;
2722 int rc = 0;
2723
2724 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
2725 if (!handle)
2726 return -ENOMEM;
2727
2728 handle->dev = dev;
2729 handle->handler = handler;
2730 handle->name = handler->name;
2731
2732 rc = input_register_handle(handle);
2733 if (rc) {
2734 pr_err("failed to register input handle\n");
2735 goto error;
2736 }
2737
2738 rc = input_open_device(handle);
2739 if (rc) {
2740 pr_err("failed to open input device\n");
2741 goto error_unregister;
2742 }
2743
2744 return 0;
2745
2746error_unregister:
2747 input_unregister_handle(handle);
2748
2749error:
2750 kfree(handle);
2751
2752 return rc;
2753}
2754
2755static void _sde_encoder_input_disconnect(struct input_handle *handle)
2756{
2757 input_close_device(handle);
2758 input_unregister_handle(handle);
2759 kfree(handle);
2760}
2761
2762/**
2763 * Structure for specifying event parameters on which to receive callbacks.
2764 * This structure will trigger a callback in case of a touch event (specified by
2765 * EV_ABS) where there is a change in X and Y coordinates,
2766 */
2767static const struct input_device_id sde_input_ids[] = {
2768 {
2769 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
2770 .evbit = { BIT_MASK(EV_ABS) },
2771 .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
2772 BIT_MASK(ABS_MT_POSITION_X) |
2773 BIT_MASK(ABS_MT_POSITION_Y) },
2774 },
2775 { },
2776};
2777
2778static int _sde_encoder_input_handler_register(
2779 struct input_handler *input_handler)
2780{
2781 int rc = 0;
2782
2783 rc = input_register_handler(input_handler);
2784 if (rc) {
2785 pr_err("input_register_handler failed, rc= %d\n", rc);
2786 kfree(input_handler);
2787 return rc;
2788 }
2789
2790 return rc;
2791}
2792
2793static int _sde_encoder_input_handler(
2794 struct sde_encoder_virt *sde_enc)
2795{
2796 struct input_handler *input_handler = NULL;
2797 int rc = 0;
2798
2799 if (sde_enc->input_handler) {
2800 SDE_ERROR_ENC(sde_enc,
2801 "input_handle is active. unexpected\n");
2802 return -EINVAL;
2803 }
2804
2805 input_handler = kzalloc(sizeof(*sde_enc->input_handler), GFP_KERNEL);
2806 if (!input_handler)
2807 return -ENOMEM;
2808
2809 input_handler->event = sde_encoder_input_event_handler;
2810 input_handler->connect = _sde_encoder_input_connect;
2811 input_handler->disconnect = _sde_encoder_input_disconnect;
2812 input_handler->name = "sde";
2813 input_handler->id_table = sde_input_ids;
2814 input_handler->private = sde_enc;
2815
2816 sde_enc->input_handler = input_handler;
Shubhashree Dhar0c6ce3c2018-08-03 19:49:31 +05302817 sde_enc->input_handler_registered = false;
Shubhashree Dhar25b05422018-05-30 15:42:04 +05302818
2819 return rc;
2820}
2821
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002822static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002823{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002824 struct sde_encoder_virt *sde_enc = NULL;
Clarence Ip35348262017-04-28 16:10:46 -07002825 struct msm_drm_private *priv;
2826 struct sde_kms *sde_kms;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002827
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002828 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
2829 SDE_ERROR("invalid parameters\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002830 return;
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002831 }
Dhaval Patelaab9b522017-07-20 12:38:46 -07002832
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002833 priv = drm_enc->dev->dev_private;
Dhaval Patelaab9b522017-07-20 12:38:46 -07002834 sde_kms = to_sde_kms(priv->kms);
2835 if (!sde_kms) {
2836 SDE_ERROR("invalid sde_kms\n");
2837 return;
2838 }
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002839
2840 sde_enc = to_sde_encoder_virt(drm_enc);
2841 if (!sde_enc || !sde_enc->cur_master) {
2842 SDE_ERROR("invalid sde encoder/master\n");
Lloyd Atkinson5217336c2016-09-15 18:21:18 -04002843 return;
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002844 }
2845
Ajay Singh Parmar878ef142017-08-07 16:53:57 -07002846 if (sde_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DisplayPort &&
2847 sde_enc->cur_master->hw_mdptop &&
2848 sde_enc->cur_master->hw_mdptop->ops.intf_audio_select)
2849 sde_enc->cur_master->hw_mdptop->ops.intf_audio_select(
2850 sde_enc->cur_master->hw_mdptop);
2851
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002852 if (sde_enc->cur_master->hw_mdptop &&
2853 sde_enc->cur_master->hw_mdptop->ops.reset_ubwc)
2854 sde_enc->cur_master->hw_mdptop->ops.reset_ubwc(
2855 sde_enc->cur_master->hw_mdptop,
2856 sde_kms->catalog);
2857
Dhaval Patelaab9b522017-07-20 12:38:46 -07002858 _sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info, false);
Veera Sundaram Sankaran33db4282017-11-01 12:45:25 -07002859 sde_encoder_control_te(drm_enc, true);
Lloyd Atkinsonbc01cbd2017-06-05 14:26:57 -04002860
2861 memset(&sde_enc->prv_conn_roi, 0, sizeof(sde_enc->prv_conn_roi));
2862 memset(&sde_enc->cur_conn_roi, 0, sizeof(sde_enc->cur_conn_roi));
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002863}
2864
2865void sde_encoder_virt_restore(struct drm_encoder *drm_enc)
2866{
2867 struct sde_encoder_virt *sde_enc = NULL;
2868 int i;
2869
2870 if (!drm_enc) {
2871 SDE_ERROR("invalid encoder\n");
2872 return;
2873 }
2874 sde_enc = to_sde_encoder_virt(drm_enc);
2875
2876 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2877 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
2878
2879 if (phys && (phys != sde_enc->cur_master) && phys->ops.restore)
2880 phys->ops.restore(phys);
2881 }
2882
2883 if (sde_enc->cur_master && sde_enc->cur_master->ops.restore)
2884 sde_enc->cur_master->ops.restore(sde_enc->cur_master);
2885
2886 _sde_encoder_virt_enable_helper(drm_enc);
2887}
2888
Jayant Shekhar401bcdf2018-07-27 12:15:03 +05302889static void sde_encoder_off_work(struct kthread_work *work)
2890{
2891 struct sde_encoder_virt *sde_enc = container_of(work,
2892 struct sde_encoder_virt, delayed_off_work.work);
2893 struct drm_encoder *drm_enc;
2894
2895 if (!sde_enc) {
2896 SDE_ERROR("invalid sde encoder\n");
2897 return;
2898 }
2899 drm_enc = &sde_enc->base;
2900
2901 sde_encoder_idle_request(drm_enc);
2902}
2903
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002904static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
2905{
2906 struct sde_encoder_virt *sde_enc = NULL;
2907 int i, ret = 0;
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07002908 struct msm_compression_info *comp_info = NULL;
Jeykumar Sankaran69934622017-05-31 18:16:25 -07002909 struct drm_display_mode *cur_mode = NULL;
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07002910 struct msm_mode_info mode_info;
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002911
2912 if (!drm_enc) {
2913 SDE_ERROR("invalid encoder\n");
2914 return;
2915 }
2916 sde_enc = to_sde_encoder_virt(drm_enc);
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07002917
Alan Kwong1124f1f2017-11-10 18:14:39 -05002918 if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
2919 SDE_ERROR("power resource is not enabled\n");
2920 return;
2921 }
2922
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07002923 ret = _sde_encoder_get_mode_info(drm_enc, &mode_info);
2924 if (ret) {
2925 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
2926 return;
2927 }
2928
Dhaval Patelf492c5d2018-02-19 07:56:37 -08002929 if (drm_enc->crtc && !sde_enc->crtc)
2930 sde_enc->crtc = drm_enc->crtc;
2931
Jeykumar Sankaran905ba332017-10-19 10:45:02 -07002932 comp_info = &mode_info.comp_info;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002933 cur_mode = &sde_enc->base.crtc->state->adjusted_mode;
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002934
Clarence Ip19af1362016-09-23 14:57:51 -04002935 SDE_DEBUG_ENC(sde_enc, "\n");
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002936 SDE_EVT32(DRMID(drm_enc), cur_mode->hdisplay, cur_mode->vdisplay);
Jeykumar Sankaran69934622017-05-31 18:16:25 -07002937
Clarence Ipa87f8ec2016-08-23 13:43:19 -04002938 sde_enc->cur_master = NULL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002939 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2940 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
2941
2942 if (phys && phys->ops.is_master && phys->ops.is_master(phys)) {
2943 SDE_DEBUG_ENC(sde_enc, "master is now idx %d\n", i);
2944 sde_enc->cur_master = phys;
2945 break;
2946 }
2947 }
2948
2949 if (!sde_enc->cur_master) {
2950 SDE_ERROR("virt encoder has no master! num_phys %d\n", i);
2951 return;
2952 }
2953
Shubhashree Dhar0c6ce3c2018-08-03 19:49:31 +05302954 if (sde_enc->input_handler && !sde_enc->input_handler_registered) {
Shubhashree Dhar25b05422018-05-30 15:42:04 +05302955 ret = _sde_encoder_input_handler_register(
2956 sde_enc->input_handler);
2957 if (ret)
2958 SDE_ERROR(
2959 "input handler registration failed, rc = %d\n", ret);
Shubhashree Dhar0c6ce3c2018-08-03 19:49:31 +05302960 else
2961 sde_enc->input_handler_registered = true;
Shubhashree Dhar25b05422018-05-30 15:42:04 +05302962 }
2963
Jayant Shekhar71a0acb2018-08-17 08:24:51 +05302964 if (!(msm_is_mode_seamless_vrr(cur_mode)
2965 || msm_is_mode_seamless_dms(cur_mode)))
Jayant Shekhar401bcdf2018-07-27 12:15:03 +05302966 kthread_init_delayed_work(&sde_enc->delayed_off_work,
2967 sde_encoder_off_work);
2968
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002969 ret = sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF);
2970 if (ret) {
2971 SDE_ERROR_ENC(sde_enc, "sde resource control failed: %d\n",
2972 ret);
2973 return;
2974 }
Dhaval Patel020f7e122016-11-15 14:39:18 -08002975
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002976 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2977 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04002978
Jeykumar Sankaran69934622017-05-31 18:16:25 -07002979 if (!phys)
2980 continue;
2981
2982 phys->comp_type = comp_info->comp_type;
2983 if (phys != sde_enc->cur_master) {
2984 /**
2985 * on DMS request, the encoder will be enabled
2986 * already. Invoke restore to reconfigure the
2987 * new mode.
2988 */
2989 if (msm_is_mode_seamless_dms(cur_mode) &&
2990 phys->ops.restore)
2991 phys->ops.restore(phys);
2992 else if (phys->ops.enable)
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07002993 phys->ops.enable(phys);
2994 }
Dhaval Patel010f5172017-08-01 22:40:09 -07002995
2996 if (sde_enc->misr_enable && (sde_enc->disp_info.capabilities &
2997 MSM_DISPLAY_CAP_VID_MODE) && phys->ops.setup_misr)
2998 phys->ops.setup_misr(phys, true,
2999 sde_enc->misr_frame_count);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003000 }
Clarence Ipa87f8ec2016-08-23 13:43:19 -04003001
Jeykumar Sankaran69934622017-05-31 18:16:25 -07003002 if (msm_is_mode_seamless_dms(cur_mode) &&
3003 sde_enc->cur_master->ops.restore)
3004 sde_enc->cur_master->ops.restore(sde_enc->cur_master);
3005 else if (sde_enc->cur_master->ops.enable)
Clarence Ipa87f8ec2016-08-23 13:43:19 -04003006 sde_enc->cur_master->ops.enable(sde_enc->cur_master);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08003007
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07003008 _sde_encoder_virt_enable_helper(drm_enc);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003009}
3010
3011static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
3012{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003013 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson11f34442016-08-11 11:19:52 -04003014 struct msm_drm_private *priv;
3015 struct sde_kms *sde_kms;
Clarence Iped3327b2017-11-01 13:13:58 -04003016 enum sde_intf_mode intf_mode;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003017 int i = 0;
3018
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003019 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -04003020 SDE_ERROR("invalid encoder\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003021 return;
Lloyd Atkinson5217336c2016-09-15 18:21:18 -04003022 } else if (!drm_enc->dev) {
3023 SDE_ERROR("invalid dev\n");
3024 return;
3025 } else if (!drm_enc->dev->dev_private) {
3026 SDE_ERROR("invalid dev_private\n");
3027 return;
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003028 }
3029
Alan Kwong1124f1f2017-11-10 18:14:39 -05003030 if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
3031 SDE_ERROR("power resource is not enabled\n");
3032 return;
3033 }
3034
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003035 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -04003036 SDE_DEBUG_ENC(sde_enc, "\n");
3037
Lloyd Atkinson11f34442016-08-11 11:19:52 -04003038 priv = drm_enc->dev->dev_private;
3039 sde_kms = to_sde_kms(priv->kms);
Clarence Iped3327b2017-11-01 13:13:58 -04003040 intf_mode = sde_encoder_get_intf_mode(drm_enc);
Lloyd Atkinson11f34442016-08-11 11:19:52 -04003041
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04003042 SDE_EVT32(DRMID(drm_enc));
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003043
Shubhashree Dhar0c6ce3c2018-08-03 19:49:31 +05303044 if (sde_enc->input_handler && sde_enc->input_handler_registered) {
Shubhashree Dhar137adbb2018-06-26 18:03:38 +05303045 input_unregister_handler(sde_enc->input_handler);
Shubhashree Dhar0c6ce3c2018-08-03 19:49:31 +05303046 sde_enc->input_handler_registered = false;
3047 }
3048
Shubhashree Dhar137adbb2018-06-26 18:03:38 +05303049
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04003050 /* wait for idle */
3051 sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
3052
Shubhashree Dhar25b05422018-05-30 15:42:04 +05303053 kthread_flush_work(&sde_enc->input_event_work);
3054
Clarence Iped3327b2017-11-01 13:13:58 -04003055 /*
3056 * For primary command mode encoders, execute the resource control
3057 * pre-stop operations before the physical encoders are disabled, to
3058 * allow the rsc to transition its states properly.
3059 *
3060 * For other encoder types, rsc should not be enabled until after
3061 * they have been fully disabled, so delay the pre-stop operations
3062 * until after the physical disable calls have returned.
3063 */
3064 if (sde_enc->disp_info.is_primary && intf_mode == INTF_MODE_CMD) {
3065 sde_encoder_resource_control(drm_enc,
3066 SDE_ENC_RC_EVENT_PRE_STOP);
3067 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3068 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04003069
Clarence Iped3327b2017-11-01 13:13:58 -04003070 if (phys && phys->ops.disable)
3071 phys->ops.disable(phys);
3072 }
3073 } else {
3074 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3075 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003076
Clarence Iped3327b2017-11-01 13:13:58 -04003077 if (phys && phys->ops.disable)
3078 phys->ops.disable(phys);
3079 }
3080 sde_encoder_resource_control(drm_enc,
3081 SDE_ENC_RC_EVENT_PRE_STOP);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003082 }
3083
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07003084 /*
3085 * disable dsc after the transfer is complete (for command mode)
3086 * and after physical encoder is disabled, to make sure timing
3087 * engine is already disabled (for video mode).
3088 */
3089 _sde_encoder_dsc_disable(sde_enc);
3090
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07003091 sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_STOP);
3092
Lloyd Atkinson07099ad2017-08-15 13:32:24 -04003093 for (i = 0; i < sde_enc->num_phys_encs; i++) {
Ingrid Gallardo72cd1632018-02-28 15:26:37 -08003094 if (sde_enc->phys_encs[i]) {
3095 sde_enc->phys_encs[i]->cont_splash_settings = false;
3096 sde_enc->phys_encs[i]->cont_splash_single_flush = 0;
Lloyd Atkinson07099ad2017-08-15 13:32:24 -04003097 sde_enc->phys_encs[i]->connector = NULL;
Ingrid Gallardo72cd1632018-02-28 15:26:37 -08003098 }
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07003099 }
3100
Lloyd Atkinson07099ad2017-08-15 13:32:24 -04003101 sde_enc->cur_master = NULL;
Harsh Sahu1e52ed02017-11-28 14:34:22 -08003102 /*
3103 * clear the cached crtc in sde_enc on use case finish, after all the
3104 * outstanding events and timers have been completed
3105 */
3106 sde_enc->crtc = NULL;
Lloyd Atkinson07099ad2017-08-15 13:32:24 -04003107
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07003108 SDE_DEBUG_ENC(sde_enc, "encoder disabled\n");
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003109
Lloyd Atkinson11f34442016-08-11 11:19:52 -04003110 sde_rm_release(&sde_kms->rm, drm_enc);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003111}
3112
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003113static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003114 enum sde_intf_type type, u32 controller_id)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003115{
3116 int i = 0;
3117
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003118 for (i = 0; i < catalog->intf_count; i++) {
3119 if (catalog->intf[i].type == type
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003120 && catalog->intf[i].controller_id == controller_id) {
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003121 return catalog->intf[i].id;
3122 }
3123 }
3124
3125 return INTF_MAX;
3126}
3127
Alan Kwongbb27c092016-07-20 16:41:25 -04003128static enum sde_wb sde_encoder_get_wb(struct sde_mdss_cfg *catalog,
3129 enum sde_intf_type type, u32 controller_id)
3130{
3131 if (controller_id < catalog->wb_count)
3132 return catalog->wb[controller_id].id;
3133
3134 return WB_MAX;
3135}
3136
Dhaval Patel81e87882016-10-19 21:41:56 -07003137static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc,
3138 struct sde_encoder_phys *phy_enc)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003139{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003140 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003141 unsigned long lock_flags;
3142
Dhaval Patel81e87882016-10-19 21:41:56 -07003143 if (!drm_enc || !phy_enc)
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003144 return;
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003145
Narendra Muppalla77b32932017-05-10 13:53:11 -07003146 SDE_ATRACE_BEGIN("encoder_vblank_callback");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04003147 sde_enc = to_sde_encoder_virt(drm_enc);
3148
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003149 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003150 if (sde_enc->crtc_vblank_cb)
3151 sde_enc->crtc_vblank_cb(sde_enc->crtc_vblank_cb_data);
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003152 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
Dhaval Patel81e87882016-10-19 21:41:56 -07003153
3154 atomic_inc(&phy_enc->vsync_cnt);
Narendra Muppalla77b32932017-05-10 13:53:11 -07003155 SDE_ATRACE_END("encoder_vblank_callback");
Dhaval Patel81e87882016-10-19 21:41:56 -07003156}
3157
3158static void sde_encoder_underrun_callback(struct drm_encoder *drm_enc,
3159 struct sde_encoder_phys *phy_enc)
3160{
3161 if (!phy_enc)
3162 return;
3163
Narendra Muppalla77b32932017-05-10 13:53:11 -07003164 SDE_ATRACE_BEGIN("encoder_underrun_callback");
Dhaval Patel81e87882016-10-19 21:41:56 -07003165 atomic_inc(&phy_enc->underrun_cnt);
Lloyd Atkinson64b07dd2016-12-12 17:10:57 -05003166 SDE_EVT32(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt));
Ingrid Gallardo36ee68d2017-08-30 17:14:33 -07003167
3168 trace_sde_encoder_underrun(DRMID(drm_enc),
3169 atomic_read(&phy_enc->underrun_cnt));
3170
3171 SDE_DBG_CTRL("stop_ftrace");
3172 SDE_DBG_CTRL("panic_underrun");
3173
Narendra Muppalla77b32932017-05-10 13:53:11 -07003174 SDE_ATRACE_END("encoder_underrun_callback");
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003175}
3176
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003177void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
3178 void (*vbl_cb)(void *), void *vbl_data)
3179{
3180 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
3181 unsigned long lock_flags;
3182 bool enable;
3183 int i;
3184
3185 enable = vbl_cb ? true : false;
3186
Clarence Ip19af1362016-09-23 14:57:51 -04003187 if (!drm_enc) {
3188 SDE_ERROR("invalid encoder\n");
3189 return;
3190 }
3191 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04003192 SDE_EVT32(DRMID(drm_enc), enable);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003193
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003194 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003195 sde_enc->crtc_vblank_cb = vbl_cb;
3196 sde_enc->crtc_vblank_cb_data = vbl_data;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003197 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003198
3199 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3200 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
3201
3202 if (phys && phys->ops.control_vblank_irq)
3203 phys->ops.control_vblank_irq(phys, enable);
3204 }
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07003205 sde_enc->vblank_enabled = enable;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003206}
3207
Alan Kwong628d19e2016-10-31 13:50:13 -04003208void sde_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -07003209 void (*frame_event_cb)(void *, u32 event),
3210 struct drm_crtc *crtc)
Alan Kwong628d19e2016-10-31 13:50:13 -04003211{
3212 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
3213 unsigned long lock_flags;
3214 bool enable;
3215
3216 enable = frame_event_cb ? true : false;
3217
3218 if (!drm_enc) {
3219 SDE_ERROR("invalid encoder\n");
3220 return;
3221 }
3222 SDE_DEBUG_ENC(sde_enc, "\n");
3223 SDE_EVT32(DRMID(drm_enc), enable, 0);
3224
3225 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
3226 sde_enc->crtc_frame_event_cb = frame_event_cb;
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -07003227 sde_enc->crtc_frame_event_cb_data.crtc = crtc;
Alan Kwong628d19e2016-10-31 13:50:13 -04003228 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
3229}
3230
3231static void sde_encoder_frame_done_callback(
3232 struct drm_encoder *drm_enc,
3233 struct sde_encoder_phys *ready_phys, u32 event)
3234{
3235 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
3236 unsigned int i;
3237
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -07003238 sde_enc->crtc_frame_event_cb_data.connector =
3239 sde_enc->cur_master->connector;
3240
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07003241 if (event & (SDE_ENCODER_FRAME_EVENT_DONE
3242 | SDE_ENCODER_FRAME_EVENT_ERROR
3243 | SDE_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -05003244
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07003245 if (!sde_enc->frame_busy_mask[0]) {
3246 /**
3247 * suppress frame_done without waiter,
3248 * likely autorefresh
3249 */
3250 SDE_EVT32(DRMID(drm_enc), event, ready_phys->intf_idx);
3251 return;
Alan Kwong628d19e2016-10-31 13:50:13 -04003252 }
3253
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07003254 /* One of the physical encoders has become idle */
3255 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3256 if (sde_enc->phys_encs[i] == ready_phys) {
3257 clear_bit(i, sde_enc->frame_busy_mask);
3258 SDE_EVT32_VERBOSE(DRMID(drm_enc), i,
3259 sde_enc->frame_busy_mask[0]);
3260 }
3261 }
Alan Kwong628d19e2016-10-31 13:50:13 -04003262
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07003263 if (!sde_enc->frame_busy_mask[0]) {
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07003264 sde_encoder_resource_control(drm_enc,
3265 SDE_ENC_RC_EVENT_FRAME_DONE);
3266
3267 if (sde_enc->crtc_frame_event_cb)
3268 sde_enc->crtc_frame_event_cb(
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -07003269 &sde_enc->crtc_frame_event_cb_data,
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07003270 event);
3271 }
3272 } else {
Alan Kwong628d19e2016-10-31 13:50:13 -04003273 if (sde_enc->crtc_frame_event_cb)
3274 sde_enc->crtc_frame_event_cb(
Prabhanjan Kandula199cfcd2018-03-28 11:45:20 -07003275 &sde_enc->crtc_frame_event_cb_data, event);
Alan Kwong628d19e2016-10-31 13:50:13 -04003276 }
3277}
3278
Dhaval Patel8a7c3282017-12-05 00:41:58 -08003279int sde_encoder_idle_request(struct drm_encoder *drm_enc)
3280{
3281 struct sde_encoder_virt *sde_enc;
3282
3283 if (!drm_enc) {
3284 SDE_ERROR("invalid drm encoder\n");
3285 return -EINVAL;
3286 }
3287
3288 sde_enc = to_sde_encoder_virt(drm_enc);
3289 sde_encoder_resource_control(&sde_enc->base,
3290 SDE_ENC_RC_EVENT_ENTER_IDLE);
3291
3292 return 0;
3293}
3294
Krishna Manikandanfb29f692019-04-09 17:00:41 +05303295int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *drm_enc)
3296{
3297 struct sde_encoder_virt *sde_enc = NULL;
3298 int i, count = 0;
3299
3300 if (!drm_enc)
3301 return 0;
3302
3303 sde_enc = to_sde_encoder_virt(drm_enc);
3304
3305 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3306 count += atomic_read(&sde_enc->phys_encs[i]->ctlstart_timeout);
3307 atomic_set(&sde_enc->phys_encs[i]->ctlstart_timeout, 0);
3308 }
3309
3310 return count;
3311}
3312
Clarence Ip110d15c2016-08-16 14:44:41 -04003313/**
3314 * _sde_encoder_trigger_flush - trigger flush for a physical encoder
3315 * drm_enc: Pointer to drm encoder structure
3316 * phys: Pointer to physical encoder structure
3317 * extra_flush_bits: Additional bit mask to include in flush trigger
3318 */
3319static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
3320 struct sde_encoder_phys *phys, uint32_t extra_flush_bits)
3321{
3322 struct sde_hw_ctl *ctl;
Clarence Ip8e69ad02016-12-09 09:43:57 -05003323 int pending_kickoff_cnt;
Clarence Ip110d15c2016-08-16 14:44:41 -04003324
3325 if (!drm_enc || !phys) {
3326 SDE_ERROR("invalid argument(s), drm_enc %d, phys_enc %d\n",
3327 drm_enc != 0, phys != 0);
3328 return;
3329 }
3330
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -04003331 if (!phys->hw_pp) {
3332 SDE_ERROR("invalid pingpong hw\n");
3333 return;
3334 }
3335
Clarence Ip110d15c2016-08-16 14:44:41 -04003336 ctl = phys->hw_ctl;
Alan Kwong4212dd42017-09-19 17:22:33 -04003337 if (!ctl || !phys->ops.trigger_flush) {
3338 SDE_ERROR("missing ctl/trigger cb\n");
Clarence Ip110d15c2016-08-16 14:44:41 -04003339 return;
3340 }
3341
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003342 if (phys->split_role == ENC_ROLE_SKIP) {
3343 SDE_DEBUG_ENC(to_sde_encoder_virt(phys->parent),
3344 "skip flush pp%d ctl%d\n",
3345 phys->hw_pp->idx - PINGPONG_0,
3346 ctl->idx - CTL_0);
3347 return;
3348 }
3349
Clarence Ip8e69ad02016-12-09 09:43:57 -05003350 pending_kickoff_cnt = sde_encoder_phys_inc_pending(phys);
Clarence Ip8e69ad02016-12-09 09:43:57 -05003351
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07003352 if (phys->ops.is_master && phys->ops.is_master(phys))
3353 atomic_inc(&phys->pending_retire_fence_cnt);
3354
Clarence Ip110d15c2016-08-16 14:44:41 -04003355 if (extra_flush_bits && ctl->ops.update_pending_flush)
3356 ctl->ops.update_pending_flush(ctl, extra_flush_bits);
3357
Alan Kwong4212dd42017-09-19 17:22:33 -04003358 phys->ops.trigger_flush(phys);
Dhaval Patel6c666622017-03-21 23:02:59 -07003359
3360 if (ctl->ops.get_pending_flush)
Clarence Ip569d5af2017-10-14 21:09:01 -04003361 SDE_EVT32(DRMID(drm_enc), phys->intf_idx - INTF_0,
3362 pending_kickoff_cnt, ctl->idx - CTL_0,
3363 ctl->ops.get_pending_flush(ctl));
Dhaval Patel6c666622017-03-21 23:02:59 -07003364 else
Clarence Ip569d5af2017-10-14 21:09:01 -04003365 SDE_EVT32(DRMID(drm_enc), phys->intf_idx - INTF_0,
3366 ctl->idx - CTL_0, pending_kickoff_cnt);
Clarence Ip110d15c2016-08-16 14:44:41 -04003367}
3368
3369/**
3370 * _sde_encoder_trigger_start - trigger start for a physical encoder
3371 * phys: Pointer to physical encoder structure
3372 */
3373static inline void _sde_encoder_trigger_start(struct sde_encoder_phys *phys)
3374{
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003375 struct sde_hw_ctl *ctl;
3376
Clarence Ip110d15c2016-08-16 14:44:41 -04003377 if (!phys) {
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -04003378 SDE_ERROR("invalid argument(s)\n");
3379 return;
3380 }
3381
3382 if (!phys->hw_pp) {
3383 SDE_ERROR("invalid pingpong hw\n");
Clarence Ip110d15c2016-08-16 14:44:41 -04003384 return;
3385 }
3386
Prabhanjan Kandula77cc0ee2018-04-15 21:44:50 -07003387 /* avoid ctrl start for encoder in clone mode */
3388 if (phys->in_clone_mode)
3389 return;
3390
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003391 ctl = phys->hw_ctl;
3392 if (phys->split_role == ENC_ROLE_SKIP) {
3393 SDE_DEBUG_ENC(to_sde_encoder_virt(phys->parent),
3394 "skip start pp%d ctl%d\n",
3395 phys->hw_pp->idx - PINGPONG_0,
3396 ctl->idx - CTL_0);
3397 return;
3398 }
Clarence Ip110d15c2016-08-16 14:44:41 -04003399 if (phys->ops.trigger_start && phys->enable_state != SDE_ENC_DISABLED)
3400 phys->ops.trigger_start(phys);
3401}
3402
Alan Kwong4212dd42017-09-19 17:22:33 -04003403void sde_encoder_helper_trigger_flush(struct sde_encoder_phys *phys_enc)
3404{
3405 struct sde_hw_ctl *ctl;
3406
3407 if (!phys_enc) {
3408 SDE_ERROR("invalid encoder\n");
3409 return;
3410 }
3411
3412 ctl = phys_enc->hw_ctl;
3413 if (ctl && ctl->ops.trigger_flush)
3414 ctl->ops.trigger_flush(ctl);
3415}
3416
Clarence Ip110d15c2016-08-16 14:44:41 -04003417void sde_encoder_helper_trigger_start(struct sde_encoder_phys *phys_enc)
3418{
3419 struct sde_hw_ctl *ctl;
Clarence Ip110d15c2016-08-16 14:44:41 -04003420
3421 if (!phys_enc) {
3422 SDE_ERROR("invalid encoder\n");
3423 return;
3424 }
3425
3426 ctl = phys_enc->hw_ctl;
3427 if (ctl && ctl->ops.trigger_start) {
3428 ctl->ops.trigger_start(ctl);
Clarence Ip569d5af2017-10-14 21:09:01 -04003429 SDE_EVT32(DRMID(phys_enc->parent), ctl->idx - CTL_0);
Clarence Ip110d15c2016-08-16 14:44:41 -04003430 }
Clarence Ip110d15c2016-08-16 14:44:41 -04003431}
3432
Raviteja Tamatam3eebe962017-10-26 09:55:24 +05303433static int _sde_encoder_wait_timeout(int32_t drm_id, int32_t hw_id,
3434 s64 timeout_ms, struct sde_encoder_wait_info *info)
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003435{
3436 int rc = 0;
Raviteja Tamatam3eebe962017-10-26 09:55:24 +05303437 s64 wait_time_jiffies = msecs_to_jiffies(timeout_ms);
3438 ktime_t cur_ktime;
3439 ktime_t exp_ktime = ktime_add_ms(ktime_get(), timeout_ms);
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003440
3441 do {
Lloyd Atkinson05ef8232017-03-08 16:35:36 -05003442 rc = wait_event_timeout(*(info->wq),
Raviteja Tamatam3eebe962017-10-26 09:55:24 +05303443 atomic_read(info->atomic_cnt) == 0, wait_time_jiffies);
3444 cur_ktime = ktime_get();
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003445
Raviteja Tamatam3eebe962017-10-26 09:55:24 +05303446 SDE_EVT32(drm_id, hw_id, rc, ktime_to_ms(cur_ktime),
3447 timeout_ms, atomic_read(info->atomic_cnt));
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003448 /* If we timed out, counter is valid and time is less, wait again */
Lloyd Atkinson05ef8232017-03-08 16:35:36 -05003449 } while (atomic_read(info->atomic_cnt) && (rc == 0) &&
Raviteja Tamatam3eebe962017-10-26 09:55:24 +05303450 (ktime_compare_safe(exp_ktime, cur_ktime) > 0));
3451
3452 return rc;
3453}
3454
3455int sde_encoder_helper_wait_event_timeout(int32_t drm_id, int32_t hw_id,
3456 struct sde_encoder_wait_info *info)
3457{
3458 int rc;
3459 ktime_t exp_ktime = ktime_add_ms(ktime_get(), info->timeout_ms);
3460
3461 rc = _sde_encoder_wait_timeout(drm_id, hw_id, info->timeout_ms, info);
3462
3463 /**
3464 * handle disabled irq case where timer irq is also delayed.
3465 * wait for additional timeout of FAULT_TOLERENCE_WAIT_IN_MS
3466 * if it event_timeout expired late detected.
3467 */
3468 if (atomic_read(info->atomic_cnt) && (!rc) &&
3469 (ktime_compare_safe(ktime_get(), ktime_add_ms(exp_ktime,
3470 FAULT_TOLERENCE_DELTA_IN_MS)) > 0))
3471 rc = _sde_encoder_wait_timeout(drm_id, hw_id,
3472 FAULT_TOLERENCE_WAIT_IN_MS, info);
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003473
3474 return rc;
3475}
3476
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003477void sde_encoder_helper_hw_reset(struct sde_encoder_phys *phys_enc)
3478{
3479 struct sde_encoder_virt *sde_enc;
3480 struct sde_connector *sde_con;
3481 void *sde_con_disp;
3482 struct sde_hw_ctl *ctl;
3483 int rc;
3484
3485 if (!phys_enc) {
3486 SDE_ERROR("invalid encoder\n");
3487 return;
3488 }
3489 sde_enc = to_sde_encoder_virt(phys_enc->parent);
3490 ctl = phys_enc->hw_ctl;
3491
3492 if (!ctl || !ctl->ops.reset)
3493 return;
3494
3495 SDE_DEBUG_ENC(sde_enc, "ctl %d reset\n", ctl->idx);
3496 SDE_EVT32(DRMID(phys_enc->parent), ctl->idx);
3497
3498 if (phys_enc->ops.is_master && phys_enc->ops.is_master(phys_enc) &&
3499 phys_enc->connector) {
3500 sde_con = to_sde_connector(phys_enc->connector);
3501 sde_con_disp = sde_connector_get_display(phys_enc->connector);
3502
3503 if (sde_con->ops.soft_reset) {
3504 rc = sde_con->ops.soft_reset(sde_con_disp);
3505 if (rc) {
3506 SDE_ERROR_ENC(sde_enc,
3507 "connector soft reset failure\n");
Dhaval Patel7ca510f2017-07-12 12:57:37 -07003508 SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus",
3509 "panic");
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003510 }
3511 }
3512 }
3513
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003514 phys_enc->enable_state = SDE_ENC_ENABLED;
3515}
3516
Clarence Ip110d15c2016-08-16 14:44:41 -04003517/**
3518 * _sde_encoder_kickoff_phys - handle physical encoder kickoff
3519 * Iterate through the physical encoders and perform consolidated flush
3520 * and/or control start triggering as needed. This is done in the virtual
3521 * encoder rather than the individual physical ones in order to handle
3522 * use cases that require visibility into multiple physical encoders at
3523 * a time.
3524 * sde_enc: Pointer to virtual encoder structure
3525 */
3526static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
3527{
3528 struct sde_hw_ctl *ctl;
3529 uint32_t i, pending_flush;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003530 unsigned long lock_flags;
Dhaval Patel30874eb2018-05-31 13:33:31 -07003531 struct msm_drm_private *priv = NULL;
3532 struct sde_kms *sde_kms = NULL;
Veera Sundaram Sankaran2b64edf2018-08-27 14:01:50 -07003533 bool is_vid_mode = false;
Clarence Ip110d15c2016-08-16 14:44:41 -04003534
3535 if (!sde_enc) {
3536 SDE_ERROR("invalid encoder\n");
3537 return;
3538 }
3539
Veera Sundaram Sankaran2b64edf2018-08-27 14:01:50 -07003540 is_vid_mode = sde_enc->disp_info.capabilities &
3541 MSM_DISPLAY_CAP_VID_MODE;
3542
3543
Clarence Ip110d15c2016-08-16 14:44:41 -04003544 pending_flush = 0x0;
3545
Ingrid Gallardo61210ea2017-10-17 17:29:31 -07003546 /*
3547 * Trigger LUT DMA flush, this might need a wait, so we need
3548 * to do this outside of the atomic context
3549 */
3550 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3551 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Ingrid Gallardo61210ea2017-10-17 17:29:31 -07003552
3553 if (!phys || phys->enable_state == SDE_ENC_DISABLED)
3554 continue;
3555
3556 ctl = phys->hw_ctl;
3557 if (!ctl)
3558 continue;
3559
Veera Sundaram Sankaran2b64edf2018-08-27 14:01:50 -07003560 /* make reg dma kickoff as blocking for vidoe-mode */
Ingrid Gallardo61210ea2017-10-17 17:29:31 -07003561 if (phys->hw_ctl->ops.reg_dma_flush)
3562 phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl,
Veera Sundaram Sankaran2b64edf2018-08-27 14:01:50 -07003563 is_vid_mode);
Ingrid Gallardo61210ea2017-10-17 17:29:31 -07003564 }
3565
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003566 /* update pending counts and trigger kickoff ctl flush atomically */
3567 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
3568
Clarence Ip110d15c2016-08-16 14:44:41 -04003569 /* don't perform flush/start operations for slave encoders */
3570 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3571 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07003572 enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;
Clarence Ip8e69ad02016-12-09 09:43:57 -05003573
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003574 if (!phys || phys->enable_state == SDE_ENC_DISABLED)
3575 continue;
3576
Clarence Ip110d15c2016-08-16 14:44:41 -04003577 ctl = phys->hw_ctl;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003578 if (!ctl)
Clarence Ip110d15c2016-08-16 14:44:41 -04003579 continue;
3580
Lloyd Atkinson8c50e152017-02-01 19:03:17 -05003581 if (phys->connector)
3582 topology = sde_connector_get_topology_name(
3583 phys->connector);
3584
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003585 /*
3586 * don't wait on ppsplit slaves or skipped encoders because
3587 * they dont receive irqs
3588 */
Lloyd Atkinson8c50e152017-02-01 19:03:17 -05003589 if (!(topology == SDE_RM_TOPOLOGY_PPSPLIT &&
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003590 phys->split_role == ENC_ROLE_SLAVE) &&
3591 phys->split_role != ENC_ROLE_SKIP)
Lloyd Atkinson8c50e152017-02-01 19:03:17 -05003592 set_bit(i, sde_enc->frame_busy_mask);
Ingrid Gallardo61210ea2017-10-17 17:29:31 -07003593
Clarence Ip8e69ad02016-12-09 09:43:57 -05003594 if (!phys->ops.needs_single_flush ||
3595 !phys->ops.needs_single_flush(phys))
Clarence Ip110d15c2016-08-16 14:44:41 -04003596 _sde_encoder_trigger_flush(&sde_enc->base, phys, 0x0);
3597 else if (ctl->ops.get_pending_flush)
3598 pending_flush |= ctl->ops.get_pending_flush(ctl);
3599 }
3600
3601 /* for split flush, combine pending flush masks and send to master */
3602 if (pending_flush && sde_enc->cur_master) {
3603 _sde_encoder_trigger_flush(
3604 &sde_enc->base,
3605 sde_enc->cur_master,
3606 pending_flush);
3607 }
3608
3609 _sde_encoder_trigger_start(sde_enc->cur_master);
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003610
3611 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
Dhaval Patel30874eb2018-05-31 13:33:31 -07003612
3613 if (sde_enc->elevated_ahb_vote) {
3614 priv = sde_enc->base.dev->dev_private;
3615 if (priv != NULL) {
3616 sde_kms = to_sde_kms(priv->kms);
3617 if (sde_kms != NULL) {
3618 sde_power_scale_reg_bus(&priv->phandle,
3619 sde_kms->core_client,
3620 VOTE_INDEX_LOW,
3621 false);
3622 }
3623 }
3624 sde_enc->elevated_ahb_vote = false;
3625 }
Clarence Ip110d15c2016-08-16 14:44:41 -04003626}
3627
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -05003628static void _sde_encoder_ppsplit_swap_intf_for_right_only_update(
3629 struct drm_encoder *drm_enc,
3630 unsigned long *affected_displays,
3631 int num_active_phys)
3632{
3633 struct sde_encoder_virt *sde_enc;
3634 struct sde_encoder_phys *master;
3635 enum sde_rm_topology_name topology;
3636 bool is_right_only;
3637
3638 if (!drm_enc || !affected_displays)
3639 return;
3640
3641 sde_enc = to_sde_encoder_virt(drm_enc);
3642 master = sde_enc->cur_master;
3643 if (!master || !master->connector)
3644 return;
3645
3646 topology = sde_connector_get_topology_name(master->connector);
3647 if (topology != SDE_RM_TOPOLOGY_PPSPLIT)
3648 return;
3649
3650 /*
3651 * For pingpong split, the slave pingpong won't generate IRQs. For
3652 * right-only updates, we can't swap pingpongs, or simply swap the
3653 * master/slave assignment, we actually have to swap the interfaces
3654 * so that the master physical encoder will use a pingpong/interface
3655 * that generates irqs on which to wait.
3656 */
3657 is_right_only = !test_bit(0, affected_displays) &&
3658 test_bit(1, affected_displays);
3659
3660 if (is_right_only && !sde_enc->intfs_swapped) {
3661 /* right-only update swap interfaces */
3662 swap(sde_enc->phys_encs[0]->intf_idx,
3663 sde_enc->phys_encs[1]->intf_idx);
3664 sde_enc->intfs_swapped = true;
3665 } else if (!is_right_only && sde_enc->intfs_swapped) {
3666 /* left-only or full update, swap back */
3667 swap(sde_enc->phys_encs[0]->intf_idx,
3668 sde_enc->phys_encs[1]->intf_idx);
3669 sde_enc->intfs_swapped = false;
3670 }
3671
3672 SDE_DEBUG_ENC(sde_enc,
3673 "right_only %d swapped %d phys0->intf%d, phys1->intf%d\n",
3674 is_right_only, sde_enc->intfs_swapped,
3675 sde_enc->phys_encs[0]->intf_idx - INTF_0,
3676 sde_enc->phys_encs[1]->intf_idx - INTF_0);
3677 SDE_EVT32(DRMID(drm_enc), is_right_only, sde_enc->intfs_swapped,
3678 sde_enc->phys_encs[0]->intf_idx - INTF_0,
3679 sde_enc->phys_encs[1]->intf_idx - INTF_0,
3680 *affected_displays);
3681
3682 /* ppsplit always uses master since ppslave invalid for irqs*/
3683 if (num_active_phys == 1)
3684 *affected_displays = BIT(0);
3685}
3686
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003687static void _sde_encoder_update_master(struct drm_encoder *drm_enc,
3688 struct sde_encoder_kickoff_params *params)
3689{
3690 struct sde_encoder_virt *sde_enc;
3691 struct sde_encoder_phys *phys;
3692 int i, num_active_phys;
3693 bool master_assigned = false;
3694
3695 if (!drm_enc || !params)
3696 return;
3697
3698 sde_enc = to_sde_encoder_virt(drm_enc);
3699
3700 if (sde_enc->num_phys_encs <= 1)
3701 return;
3702
3703 /* count bits set */
3704 num_active_phys = hweight_long(params->affected_displays);
3705
3706 SDE_DEBUG_ENC(sde_enc, "affected_displays 0x%lx num_active_phys %d\n",
3707 params->affected_displays, num_active_phys);
Lloyd Atkinson5ca13aa2017-10-26 18:12:20 -04003708 SDE_EVT32_VERBOSE(DRMID(drm_enc), params->affected_displays,
3709 num_active_phys);
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003710
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -05003711 /* for left/right only update, ppsplit master switches interface */
3712 _sde_encoder_ppsplit_swap_intf_for_right_only_update(drm_enc,
3713 &params->affected_displays, num_active_phys);
3714
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003715 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3716 enum sde_enc_split_role prv_role, new_role;
3717 bool active;
3718
3719 phys = sde_enc->phys_encs[i];
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -04003720 if (!phys || !phys->ops.update_split_role || !phys->hw_pp)
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003721 continue;
3722
3723 active = test_bit(i, &params->affected_displays);
3724 prv_role = phys->split_role;
3725
3726 if (active && num_active_phys == 1)
3727 new_role = ENC_ROLE_SOLO;
3728 else if (active && !master_assigned)
3729 new_role = ENC_ROLE_MASTER;
3730 else if (active)
3731 new_role = ENC_ROLE_SLAVE;
3732 else
3733 new_role = ENC_ROLE_SKIP;
3734
3735 phys->ops.update_split_role(phys, new_role);
3736 if (new_role == ENC_ROLE_SOLO || new_role == ENC_ROLE_MASTER) {
3737 sde_enc->cur_master = phys;
3738 master_assigned = true;
3739 }
3740
3741 SDE_DEBUG_ENC(sde_enc, "pp %d role prv %d new %d active %d\n",
3742 phys->hw_pp->idx - PINGPONG_0, prv_role,
3743 phys->split_role, active);
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -05003744 SDE_EVT32(DRMID(drm_enc), params->affected_displays,
3745 phys->hw_pp->idx - PINGPONG_0, prv_role,
3746 phys->split_role, active, num_active_phys);
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003747 }
3748}
3749
Sravanthi Kollukuduru59d431a2017-07-05 00:10:41 +05303750bool sde_encoder_check_mode(struct drm_encoder *drm_enc, u32 mode)
Veera Sundaram Sankaran2c748e62017-06-13 17:01:48 -07003751{
3752 struct sde_encoder_virt *sde_enc;
3753 struct msm_display_info *disp_info;
3754
3755 if (!drm_enc) {
3756 SDE_ERROR("invalid encoder\n");
3757 return false;
3758 }
3759
3760 sde_enc = to_sde_encoder_virt(drm_enc);
3761 disp_info = &sde_enc->disp_info;
3762
Sravanthi Kollukuduru59d431a2017-07-05 00:10:41 +05303763 return (disp_info->capabilities & mode);
Veera Sundaram Sankaran2c748e62017-06-13 17:01:48 -07003764}
3765
Dhaval Patel0e558f42017-04-30 00:51:40 -07003766void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
3767{
3768 struct sde_encoder_virt *sde_enc;
3769 struct sde_encoder_phys *phys;
3770 unsigned int i;
3771 struct sde_hw_ctl *ctl;
3772 struct msm_display_info *disp_info;
3773
3774 if (!drm_enc) {
3775 SDE_ERROR("invalid encoder\n");
3776 return;
3777 }
3778 sde_enc = to_sde_encoder_virt(drm_enc);
3779 disp_info = &sde_enc->disp_info;
3780
3781 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3782 phys = sde_enc->phys_encs[i];
3783
3784 if (phys && phys->hw_ctl) {
3785 ctl = phys->hw_ctl;
3786 if (ctl->ops.clear_pending_flush)
3787 ctl->ops.clear_pending_flush(ctl);
3788
3789 /* update only for command mode primary ctl */
3790 if ((phys == sde_enc->cur_master) &&
3791 (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE)
3792 && ctl->ops.trigger_pending)
3793 ctl->ops.trigger_pending(ctl);
3794 }
3795 }
3796}
3797
Ping Li8430ee12017-02-24 14:14:44 -08003798static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
3799{
3800 void *dither_cfg;
Ping Li16162692018-05-08 14:13:46 -07003801 int ret = 0, rc, i = 0;
Ping Li8430ee12017-02-24 14:14:44 -08003802 size_t len = 0;
3803 enum sde_rm_topology_name topology;
Dhaval Patelc35d9bc2018-03-06 16:39:07 -08003804 struct drm_encoder *drm_enc;
3805 struct msm_mode_info mode_info;
3806 struct msm_display_dsc_info *dsc = NULL;
3807 struct sde_encoder_virt *sde_enc;
Ping Li16162692018-05-08 14:13:46 -07003808 struct sde_hw_pingpong *hw_pp;
Ping Li8430ee12017-02-24 14:14:44 -08003809
3810 if (!phys || !phys->connector || !phys->hw_pp ||
Dhaval Patelc35d9bc2018-03-06 16:39:07 -08003811 !phys->hw_pp->ops.setup_dither || !phys->parent)
Ping Li8430ee12017-02-24 14:14:44 -08003812 return;
Dhaval Patelc35d9bc2018-03-06 16:39:07 -08003813
Ping Li8430ee12017-02-24 14:14:44 -08003814 topology = sde_connector_get_topology_name(phys->connector);
3815 if ((topology == SDE_RM_TOPOLOGY_PPSPLIT) &&
3816 (phys->split_role == ENC_ROLE_SLAVE))
3817 return;
3818
Dhaval Patelc35d9bc2018-03-06 16:39:07 -08003819 drm_enc = phys->parent;
3820 sde_enc = to_sde_encoder_virt(drm_enc);
3821 rc = _sde_encoder_get_mode_info(&sde_enc->base, &mode_info);
3822 if (rc) {
3823 SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
3824 return;
3825 }
3826
3827 dsc = &mode_info.comp_info.dsc_info;
3828 /* disable dither for 10 bpp or 10bpc dsc config */
3829 if (dsc->bpp == 10 || dsc->bpc == 10) {
3830 phys->hw_pp->ops.setup_dither(phys->hw_pp, NULL, 0);
Ping Li16162692018-05-08 14:13:46 -07003831 return;
3832 }
3833
3834 ret = sde_connector_get_dither_cfg(phys->connector,
3835 phys->connector->state, &dither_cfg, &len);
3836 if (ret)
3837 return;
3838
3839 if (TOPOLOGY_DUALPIPE_MERGE_MODE(topology)) {
3840 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
3841 hw_pp = sde_enc->hw_pp[i];
3842 if (hw_pp) {
3843 phys->hw_pp->ops.setup_dither(hw_pp, dither_cfg,
3844 len);
3845 }
3846 }
Dhaval Patelc35d9bc2018-03-06 16:39:07 -08003847 } else {
Ping Li16162692018-05-08 14:13:46 -07003848 phys->hw_pp->ops.setup_dither(phys->hw_pp, dither_cfg, len);
Dhaval Patelc35d9bc2018-03-06 16:39:07 -08003849 }
Ping Li8430ee12017-02-24 14:14:44 -08003850}
3851
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003852static u32 _sde_encoder_calculate_linetime(struct sde_encoder_virt *sde_enc,
3853 struct drm_display_mode *mode)
3854{
3855 u64 pclk_rate;
3856 u32 pclk_period;
3857 u32 line_time;
3858
3859 /*
3860 * For linetime calculation, only operate on master encoder.
3861 */
3862 if (!sde_enc->cur_master)
3863 return 0;
3864
3865 if (!sde_enc->cur_master->ops.get_line_count) {
3866 SDE_ERROR("get_line_count function not defined\n");
3867 return 0;
3868 }
3869
3870 pclk_rate = mode->clock; /* pixel clock in kHz */
3871 if (pclk_rate == 0) {
3872 SDE_ERROR("pclk is 0, cannot calculate line time\n");
3873 return 0;
3874 }
3875
3876 pclk_period = DIV_ROUND_UP_ULL(1000000000ull, pclk_rate);
3877 if (pclk_period == 0) {
3878 SDE_ERROR("pclk period is 0\n");
3879 return 0;
3880 }
3881
3882 /*
3883 * Line time calculation based on Pixel clock and HTOTAL.
3884 * Final unit is in ns.
3885 */
3886 line_time = (pclk_period * mode->htotal) / 1000;
3887 if (line_time == 0) {
3888 SDE_ERROR("line time calculation is 0\n");
3889 return 0;
3890 }
3891
3892 SDE_DEBUG_ENC(sde_enc,
3893 "clk_rate=%lldkHz, clk_period=%d, linetime=%dns\n",
3894 pclk_rate, pclk_period, line_time);
3895
3896 return line_time;
3897}
3898
3899static int _sde_encoder_wakeup_time(struct drm_encoder *drm_enc,
3900 ktime_t *wakeup_time)
3901{
3902 struct drm_display_mode *mode;
3903 struct sde_encoder_virt *sde_enc;
3904 u32 cur_line;
3905 u32 line_time;
3906 u32 vtotal, time_to_vsync;
3907 ktime_t cur_time;
3908
3909 sde_enc = to_sde_encoder_virt(drm_enc);
Harsh Sahu1e52ed02017-11-28 14:34:22 -08003910 mode = &sde_enc->cur_master->cached_mode;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003911
3912 line_time = _sde_encoder_calculate_linetime(sde_enc, mode);
3913 if (!line_time)
3914 return -EINVAL;
3915
3916 cur_line = sde_enc->cur_master->ops.get_line_count(sde_enc->cur_master);
3917
3918 vtotal = mode->vtotal;
3919 if (cur_line >= vtotal)
3920 time_to_vsync = line_time * vtotal;
3921 else
3922 time_to_vsync = line_time * (vtotal - cur_line);
3923
3924 if (time_to_vsync == 0) {
3925 SDE_ERROR("time to vsync should not be zero, vtotal=%d\n",
3926 vtotal);
3927 return -EINVAL;
3928 }
3929
3930 cur_time = ktime_get();
3931 *wakeup_time = ktime_add_ns(cur_time, time_to_vsync);
3932
3933 SDE_DEBUG_ENC(sde_enc,
3934 "cur_line=%u vtotal=%u time_to_vsync=%u, cur_time=%lld, wakeup_time=%lld\n",
3935 cur_line, vtotal, time_to_vsync,
3936 ktime_to_ms(cur_time),
3937 ktime_to_ms(*wakeup_time));
3938 return 0;
3939}
3940
3941static void sde_encoder_vsync_event_handler(unsigned long data)
3942{
3943 struct drm_encoder *drm_enc = (struct drm_encoder *) data;
3944 struct sde_encoder_virt *sde_enc;
3945 struct msm_drm_private *priv;
3946 struct msm_drm_thread *event_thread;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003947
Harsh Sahu1e52ed02017-11-28 14:34:22 -08003948 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
3949 SDE_ERROR("invalid encoder parameters\n");
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003950 return;
3951 }
3952
3953 sde_enc = to_sde_encoder_virt(drm_enc);
3954 priv = drm_enc->dev->dev_private;
Harsh Sahu1e52ed02017-11-28 14:34:22 -08003955 if (!sde_enc->crtc) {
3956 SDE_ERROR("invalid crtc");
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003957 return;
3958 }
Harsh Sahu1e52ed02017-11-28 14:34:22 -08003959
3960 if (sde_enc->crtc->index >= ARRAY_SIZE(priv->event_thread)) {
3961 SDE_ERROR("invalid crtc index:%u\n",
3962 sde_enc->crtc->index);
3963 return;
3964 }
3965 event_thread = &priv->event_thread[sde_enc->crtc->index];
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003966 if (!event_thread) {
3967 SDE_ERROR("event_thread not found for crtc:%d\n",
Harsh Sahu1e52ed02017-11-28 14:34:22 -08003968 sde_enc->crtc->index);
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003969 return;
3970 }
3971
Jayant Shekhar12d908f2017-10-10 12:11:48 +05303972 kthread_queue_work(&event_thread->worker,
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003973 &sde_enc->vsync_event_work);
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003974}
3975
Dhaval Patel222023e2018-02-27 12:24:07 -08003976static void sde_encoder_esd_trigger_work_handler(struct kthread_work *work)
3977{
3978 struct sde_encoder_virt *sde_enc = container_of(work,
3979 struct sde_encoder_virt, esd_trigger_work);
3980
3981 if (!sde_enc) {
3982 SDE_ERROR("invalid sde encoder\n");
3983 return;
3984 }
3985
3986 sde_encoder_resource_control(&sde_enc->base,
3987 SDE_ENC_RC_EVENT_KICKOFF);
3988}
3989
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08003990static void sde_encoder_input_event_work_handler(struct kthread_work *work)
3991{
3992 struct sde_encoder_virt *sde_enc = container_of(work,
3993 struct sde_encoder_virt, input_event_work);
3994
3995 if (!sde_enc) {
3996 SDE_ERROR("invalid sde encoder\n");
3997 return;
3998 }
3999
4000 sde_encoder_resource_control(&sde_enc->base,
4001 SDE_ENC_RC_EVENT_EARLY_WAKEUP);
4002}
4003
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004004static void sde_encoder_vsync_event_work_handler(struct kthread_work *work)
4005{
4006 struct sde_encoder_virt *sde_enc = container_of(work,
4007 struct sde_encoder_virt, vsync_event_work);
Jayant Shekhar12d908f2017-10-10 12:11:48 +05304008 bool autorefresh_enabled = false;
4009 int rc = 0;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004010 ktime_t wakeup_time;
4011
4012 if (!sde_enc) {
4013 SDE_ERROR("invalid sde encoder\n");
4014 return;
4015 }
4016
Jayant Shekhar12d908f2017-10-10 12:11:48 +05304017 rc = _sde_encoder_power_enable(sde_enc, true);
4018 if (rc) {
4019 SDE_ERROR_ENC(sde_enc, "sde enc power enabled failed:%d\n", rc);
4020 return;
4021 }
4022
4023 if (sde_enc->cur_master &&
4024 sde_enc->cur_master->ops.is_autorefresh_enabled)
4025 autorefresh_enabled =
4026 sde_enc->cur_master->ops.is_autorefresh_enabled(
4027 sde_enc->cur_master);
4028
Jayant Shekhar12d908f2017-10-10 12:11:48 +05304029 /* Update timer if autorefresh is enabled else return */
4030 if (!autorefresh_enabled)
Lloyd Atkinson349f7412017-11-07 16:55:57 -05004031 goto exit;
Jayant Shekhar12d908f2017-10-10 12:11:48 +05304032
Lloyd Atkinson349f7412017-11-07 16:55:57 -05004033 rc = _sde_encoder_wakeup_time(&sde_enc->base, &wakeup_time);
4034 if (rc)
4035 goto exit;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004036
4037 SDE_EVT32_VERBOSE(ktime_to_ms(wakeup_time));
4038 mod_timer(&sde_enc->vsync_event_timer,
4039 nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
Lloyd Atkinson349f7412017-11-07 16:55:57 -05004040
4041exit:
4042 _sde_encoder_power_enable(sde_enc, false);
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004043}
4044
Clarence Ip5adc0fb2017-12-15 16:08:01 -05004045int sde_encoder_poll_line_counts(struct drm_encoder *drm_enc)
4046{
4047 static const uint64_t timeout_us = 50000;
4048 static const uint64_t sleep_us = 20;
4049 struct sde_encoder_virt *sde_enc;
4050 ktime_t cur_ktime, exp_ktime;
4051 uint32_t line_count, tmp, i;
4052
4053 if (!drm_enc) {
4054 SDE_ERROR("invalid encoder\n");
4055 return -EINVAL;
4056 }
4057 sde_enc = to_sde_encoder_virt(drm_enc);
4058 if (!sde_enc->cur_master ||
4059 !sde_enc->cur_master->ops.get_line_count) {
4060 SDE_DEBUG_ENC(sde_enc, "can't get master line count\n");
4061 SDE_EVT32(DRMID(drm_enc), SDE_EVTLOG_ERROR);
4062 return -EINVAL;
4063 }
4064
4065 exp_ktime = ktime_add_ms(ktime_get(), timeout_us / 1000);
4066
4067 line_count = sde_enc->cur_master->ops.get_line_count(
4068 sde_enc->cur_master);
4069
4070 for (i = 0; i < (timeout_us * 2 / sleep_us); ++i) {
4071 tmp = line_count;
4072 line_count = sde_enc->cur_master->ops.get_line_count(
4073 sde_enc->cur_master);
4074 if (line_count < tmp) {
4075 SDE_EVT32(DRMID(drm_enc), line_count);
4076 return 0;
4077 }
4078
4079 cur_ktime = ktime_get();
4080 if (ktime_compare_safe(exp_ktime, cur_ktime) <= 0)
4081 break;
4082
4083 usleep_range(sleep_us / 2, sleep_us);
4084 }
4085
4086 SDE_EVT32(DRMID(drm_enc), line_count, SDE_EVTLOG_ERROR);
4087 return -ETIMEDOUT;
4088}
4089
Clarence Ip85f4f4532017-10-04 12:10:13 -04004090int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
Alan Kwong4aacd532017-02-04 18:51:33 -08004091 struct sde_encoder_kickoff_params *params)
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004092{
4093 struct sde_encoder_virt *sde_enc;
4094 struct sde_encoder_phys *phys;
Jeykumar Sankarand920ec72017-11-18 20:01:39 -08004095 struct sde_kms *sde_kms = NULL;
4096 struct msm_drm_private *priv = NULL;
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05004097 bool needs_hw_reset = false;
Clarence Ip5e3df1d2017-11-07 21:28:25 -05004098 uint32_t ln_cnt1, ln_cnt2;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004099 unsigned int i;
Clarence Ip85f4f4532017-10-04 12:10:13 -04004100 int rc, ret = 0;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004101
Jeykumar Sankarand920ec72017-11-18 20:01:39 -08004102 if (!drm_enc || !params || !drm_enc->dev ||
4103 !drm_enc->dev->dev_private) {
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05004104 SDE_ERROR("invalid args\n");
Clarence Ip85f4f4532017-10-04 12:10:13 -04004105 return -EINVAL;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004106 }
4107 sde_enc = to_sde_encoder_virt(drm_enc);
Jeykumar Sankarand920ec72017-11-18 20:01:39 -08004108 priv = drm_enc->dev->dev_private;
4109 sde_kms = to_sde_kms(priv->kms);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004110
Clarence Ip19af1362016-09-23 14:57:51 -04004111 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04004112 SDE_EVT32(DRMID(drm_enc));
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004113
Clarence Ip5e3df1d2017-11-07 21:28:25 -05004114 /* save this for later, in case of errors */
4115 if (sde_enc->cur_master && sde_enc->cur_master->ops.get_wr_line_count)
4116 ln_cnt1 = sde_enc->cur_master->ops.get_wr_line_count(
4117 sde_enc->cur_master);
4118 else
4119 ln_cnt1 = -EINVAL;
4120
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05004121 /* prepare for next kickoff, may include waiting on previous kickoff */
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07004122 SDE_ATRACE_BEGIN("enc_prepare_for_kickoff");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004123 for (i = 0; i < sde_enc->num_phys_encs; i++) {
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004124 phys = sde_enc->phys_encs[i];
Jayant Shekhar98e78a82018-01-12 17:50:55 +05304125 params->is_primary = sde_enc->disp_info.is_primary;
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05004126 if (phys) {
Clarence Ip85f4f4532017-10-04 12:10:13 -04004127 if (phys->ops.prepare_for_kickoff) {
4128 rc = phys->ops.prepare_for_kickoff(
4129 phys, params);
4130 if (rc)
4131 ret = rc;
4132 }
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05004133 if (phys->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET)
4134 needs_hw_reset = true;
Ping Li8430ee12017-02-24 14:14:44 -08004135 _sde_encoder_setup_dither(phys);
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05004136 }
4137 }
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07004138 SDE_ATRACE_END("enc_prepare_for_kickoff");
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05004139
Alan Kwong1124f1f2017-11-10 18:14:39 -05004140 rc = sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF);
4141 if (rc) {
4142 SDE_ERROR_ENC(sde_enc, "resource kickoff failed rc %d\n", rc);
4143 return rc;
4144 }
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07004145
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05004146 /* if any phys needs reset, reset all phys, in-order */
4147 if (needs_hw_reset) {
Clarence Ip5e3df1d2017-11-07 21:28:25 -05004148 /* query line count before cur_master is updated */
4149 if (sde_enc->cur_master &&
4150 sde_enc->cur_master->ops.get_wr_line_count)
4151 ln_cnt2 = sde_enc->cur_master->ops.get_wr_line_count(
4152 sde_enc->cur_master);
4153 else
4154 ln_cnt2 = -EINVAL;
4155
4156 SDE_EVT32(DRMID(drm_enc), ln_cnt1, ln_cnt2,
4157 SDE_EVTLOG_FUNC_CASE1);
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05004158 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4159 phys = sde_enc->phys_encs[i];
4160 if (phys && phys->ops.hw_reset)
4161 phys->ops.hw_reset(phys);
4162 }
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004163 }
Lloyd Atkinson05d75512017-01-17 14:45:51 -05004164
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05004165 _sde_encoder_update_master(drm_enc, params);
4166
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04004167 _sde_encoder_update_roi(drm_enc);
4168
Lloyd Atkinson05d75512017-01-17 14:45:51 -05004169 if (sde_enc->cur_master && sde_enc->cur_master->connector) {
4170 rc = sde_connector_pre_kickoff(sde_enc->cur_master->connector);
Clarence Ip85f4f4532017-10-04 12:10:13 -04004171 if (rc) {
Lloyd Atkinson05d75512017-01-17 14:45:51 -05004172 SDE_ERROR_ENC(sde_enc, "kickoff conn%d failed rc %d\n",
4173 sde_enc->cur_master->connector->base.id,
4174 rc);
Clarence Ip85f4f4532017-10-04 12:10:13 -04004175 ret = rc;
4176 }
Lloyd Atkinson05d75512017-01-17 14:45:51 -05004177 }
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04004178
Jeykumar Sankarand920ec72017-11-18 20:01:39 -08004179 if (_sde_encoder_is_dsc_enabled(drm_enc) &&
4180 !sde_kms->splash_data.cont_splash_en) {
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04004181 rc = _sde_encoder_dsc_setup(sde_enc, params);
Clarence Ip85f4f4532017-10-04 12:10:13 -04004182 if (rc) {
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04004183 SDE_ERROR_ENC(sde_enc, "failed to setup DSC: %d\n", rc);
Clarence Ip85f4f4532017-10-04 12:10:13 -04004184 ret = rc;
4185 }
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04004186 }
Clarence Ip85f4f4532017-10-04 12:10:13 -04004187
4188 return ret;
Alan Kwong628d19e2016-10-31 13:50:13 -04004189}
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004190
Clarence Ip662698e2017-09-12 18:34:16 -04004191/**
4192 * _sde_encoder_reset_ctl_hw - reset h/w configuration for all ctl's associated
4193 * with the specified encoder, and unstage all pipes from it
4194 * @encoder: encoder pointer
4195 * Returns: 0 on success
4196 */
4197static int _sde_encoder_reset_ctl_hw(struct drm_encoder *drm_enc)
4198{
4199 struct sde_encoder_virt *sde_enc;
4200 struct sde_encoder_phys *phys;
4201 unsigned int i;
4202 int rc = 0;
4203
4204 if (!drm_enc) {
4205 SDE_ERROR("invalid encoder\n");
4206 return -EINVAL;
4207 }
4208
4209 sde_enc = to_sde_encoder_virt(drm_enc);
4210
4211 SDE_ATRACE_BEGIN("encoder_release_lm");
4212 SDE_DEBUG_ENC(sde_enc, "\n");
4213
4214 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4215 phys = sde_enc->phys_encs[i];
4216 if (!phys)
4217 continue;
4218
4219 SDE_EVT32(DRMID(drm_enc), phys->intf_idx - INTF_0);
4220
4221 rc = sde_encoder_helper_reset_mixers(phys, NULL);
4222 if (rc)
4223 SDE_EVT32(DRMID(drm_enc), rc, SDE_EVTLOG_ERROR);
4224 }
4225
4226 SDE_ATRACE_END("encoder_release_lm");
4227 return rc;
4228}
4229
4230void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error)
Alan Kwong628d19e2016-10-31 13:50:13 -04004231{
4232 struct sde_encoder_virt *sde_enc;
4233 struct sde_encoder_phys *phys;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004234 ktime_t wakeup_time;
Alan Kwong628d19e2016-10-31 13:50:13 -04004235 unsigned int i;
4236
4237 if (!drm_enc) {
4238 SDE_ERROR("invalid encoder\n");
4239 return;
4240 }
Narendra Muppalla77b32932017-05-10 13:53:11 -07004241 SDE_ATRACE_BEGIN("encoder_kickoff");
Alan Kwong628d19e2016-10-31 13:50:13 -04004242 sde_enc = to_sde_encoder_virt(drm_enc);
4243
4244 SDE_DEBUG_ENC(sde_enc, "\n");
4245
Clarence Ip662698e2017-09-12 18:34:16 -04004246 /* create a 'no pipes' commit to release buffers on errors */
4247 if (is_error)
4248 _sde_encoder_reset_ctl_hw(drm_enc);
4249
Alan Kwong628d19e2016-10-31 13:50:13 -04004250 /* All phys encs are ready to go, trigger the kickoff */
Clarence Ip110d15c2016-08-16 14:44:41 -04004251 _sde_encoder_kickoff_phys(sde_enc);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004252
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05004253 /* allow phys encs to handle any post-kickoff business */
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004254 for (i = 0; i < sde_enc->num_phys_encs; i++) {
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05004255 phys = sde_enc->phys_encs[i];
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004256 if (phys && phys->ops.handle_post_kickoff)
4257 phys->ops.handle_post_kickoff(phys);
4258 }
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004259
4260 if (sde_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DSI &&
Tharun Raj Soma88b6dfc2018-05-11 14:19:49 +05304261 sde_enc->disp_info.is_primary &&
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004262 !_sde_encoder_wakeup_time(drm_enc, &wakeup_time)) {
4263 SDE_EVT32_VERBOSE(ktime_to_ms(wakeup_time));
4264 mod_timer(&sde_enc->vsync_event_timer,
4265 nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
4266 }
4267
Narendra Muppalla77b32932017-05-10 13:53:11 -07004268 SDE_ATRACE_END("encoder_kickoff");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004269}
4270
Clarence Ip662698e2017-09-12 18:34:16 -04004271int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc,
Clarence Ip9c65f7b2017-03-20 06:48:15 -07004272 struct drm_framebuffer *fb)
4273{
4274 struct drm_encoder *drm_enc;
4275 struct sde_hw_mixer_cfg mixer;
4276 struct sde_rm_hw_iter lm_iter;
4277 bool lm_valid = false;
4278
4279 if (!phys_enc || !phys_enc->parent) {
4280 SDE_ERROR("invalid encoder\n");
4281 return -EINVAL;
4282 }
4283
4284 drm_enc = phys_enc->parent;
4285 memset(&mixer, 0, sizeof(mixer));
4286
4287 /* reset associated CTL/LMs */
Clarence Ip9c65f7b2017-03-20 06:48:15 -07004288 if (phys_enc->hw_ctl->ops.clear_all_blendstages)
4289 phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl);
4290
4291 sde_rm_init_hw_iter(&lm_iter, drm_enc->base.id, SDE_HW_BLK_LM);
4292 while (sde_rm_get_hw(&phys_enc->sde_kms->rm, &lm_iter)) {
4293 struct sde_hw_mixer *hw_lm = (struct sde_hw_mixer *)lm_iter.hw;
4294
4295 if (!hw_lm)
4296 continue;
4297
4298 /* need to flush LM to remove it */
4299 if (phys_enc->hw_ctl->ops.get_bitmask_mixer &&
4300 phys_enc->hw_ctl->ops.update_pending_flush)
4301 phys_enc->hw_ctl->ops.update_pending_flush(
4302 phys_enc->hw_ctl,
4303 phys_enc->hw_ctl->ops.get_bitmask_mixer(
4304 phys_enc->hw_ctl, hw_lm->idx));
4305
4306 if (fb) {
4307 /* assume a single LM if targeting a frame buffer */
4308 if (lm_valid)
4309 continue;
4310
4311 mixer.out_height = fb->height;
4312 mixer.out_width = fb->width;
4313
4314 if (hw_lm->ops.setup_mixer_out)
4315 hw_lm->ops.setup_mixer_out(hw_lm, &mixer);
4316 }
4317
4318 lm_valid = true;
4319
4320 /* only enable border color on LM */
4321 if (phys_enc->hw_ctl->ops.setup_blendstage)
4322 phys_enc->hw_ctl->ops.setup_blendstage(
Nirmal Abraham39621b02019-05-03 14:46:30 +05304323 phys_enc->hw_ctl, hw_lm->idx,
4324 hw_lm->cfg.flags, NULL);
Clarence Ip9c65f7b2017-03-20 06:48:15 -07004325 }
4326
4327 if (!lm_valid) {
Clarence Ip662698e2017-09-12 18:34:16 -04004328 SDE_ERROR_ENC(to_sde_encoder_virt(drm_enc), "lm not found\n");
Clarence Ip9c65f7b2017-03-20 06:48:15 -07004329 return -EFAULT;
4330 }
4331 return 0;
4332}
4333
Lloyd Atkinsone123c172017-02-27 13:19:08 -05004334void sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
4335{
4336 struct sde_encoder_virt *sde_enc;
4337 struct sde_encoder_phys *phys;
4338 int i;
4339
4340 if (!drm_enc) {
4341 SDE_ERROR("invalid encoder\n");
4342 return;
4343 }
4344 sde_enc = to_sde_encoder_virt(drm_enc);
4345
4346 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4347 phys = sde_enc->phys_encs[i];
4348 if (phys && phys->ops.prepare_commit)
4349 phys->ops.prepare_commit(phys);
4350 }
4351}
4352
Lloyd Atkinsonc9fb3382017-03-24 08:08:30 -07004353#ifdef CONFIG_DEBUG_FS
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004354static int _sde_encoder_status_show(struct seq_file *s, void *data)
4355{
4356 struct sde_encoder_virt *sde_enc;
4357 int i;
4358
4359 if (!s || !s->private)
4360 return -EINVAL;
4361
4362 sde_enc = s->private;
4363
4364 mutex_lock(&sde_enc->enc_lock);
4365 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4366 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
4367
4368 if (!phys)
4369 continue;
4370
4371 seq_printf(s, "intf:%d vsync:%8d underrun:%8d ",
4372 phys->intf_idx - INTF_0,
4373 atomic_read(&phys->vsync_cnt),
4374 atomic_read(&phys->underrun_cnt));
4375
4376 switch (phys->intf_mode) {
4377 case INTF_MODE_VIDEO:
4378 seq_puts(s, "mode: video\n");
4379 break;
4380 case INTF_MODE_CMD:
4381 seq_puts(s, "mode: command\n");
4382 break;
4383 case INTF_MODE_WB_BLOCK:
4384 seq_puts(s, "mode: wb block\n");
4385 break;
4386 case INTF_MODE_WB_LINE:
4387 seq_puts(s, "mode: wb line\n");
4388 break;
4389 default:
4390 seq_puts(s, "mode: ???\n");
4391 break;
4392 }
4393 }
4394 mutex_unlock(&sde_enc->enc_lock);
4395
4396 return 0;
4397}
4398
4399static int _sde_encoder_debugfs_status_open(struct inode *inode,
4400 struct file *file)
4401{
4402 return single_open(file, _sde_encoder_status_show, inode->i_private);
4403}
4404
Dhaval Patelf9245d62017-03-28 16:24:00 -07004405static ssize_t _sde_encoder_misr_setup(struct file *file,
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304406 const char __user *user_buf, size_t count, loff_t *ppos)
4407{
4408 struct sde_encoder_virt *sde_enc;
Dhaval Patelf9245d62017-03-28 16:24:00 -07004409 int i = 0, rc;
4410 char buf[MISR_BUFF_SIZE + 1];
4411 size_t buff_copy;
4412 u32 frame_count, enable;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304413
Dhaval Patelf9245d62017-03-28 16:24:00 -07004414 if (!file || !file->private_data)
4415 return -EINVAL;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304416
Dhaval Patelf9245d62017-03-28 16:24:00 -07004417 sde_enc = file->private_data;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304418
Dhaval Patelf9245d62017-03-28 16:24:00 -07004419 buff_copy = min_t(size_t, count, MISR_BUFF_SIZE);
4420 if (copy_from_user(buf, user_buf, buff_copy))
4421 return -EINVAL;
4422
4423 buf[buff_copy] = 0; /* end of string */
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304424
4425 if (sscanf(buf, "%u %u", &enable, &frame_count) != 2)
Dhaval Patelf9245d62017-03-28 16:24:00 -07004426 return -EINVAL;
4427
4428 rc = _sde_encoder_power_enable(sde_enc, true);
4429 if (rc)
4430 return rc;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304431
4432 mutex_lock(&sde_enc->enc_lock);
Dhaval Patelf9245d62017-03-28 16:24:00 -07004433 sde_enc->misr_enable = enable;
Dhaval Patel010f5172017-08-01 22:40:09 -07004434 sde_enc->misr_frame_count = frame_count;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304435 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4436 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
4437
Dhaval Patelf9245d62017-03-28 16:24:00 -07004438 if (!phys || !phys->ops.setup_misr)
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304439 continue;
4440
Dhaval Patelf9245d62017-03-28 16:24:00 -07004441 phys->ops.setup_misr(phys, enable, frame_count);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304442 }
4443 mutex_unlock(&sde_enc->enc_lock);
Dhaval Patelf9245d62017-03-28 16:24:00 -07004444 _sde_encoder_power_enable(sde_enc, false);
4445
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304446 return count;
4447}
4448
Dhaval Patelf9245d62017-03-28 16:24:00 -07004449static ssize_t _sde_encoder_misr_read(struct file *file,
4450 char __user *user_buff, size_t count, loff_t *ppos)
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304451{
4452 struct sde_encoder_virt *sde_enc;
Dhaval Patelf9245d62017-03-28 16:24:00 -07004453 int i = 0, len = 0;
4454 char buf[MISR_BUFF_SIZE + 1] = {'\0'};
4455 int rc;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304456
4457 if (*ppos)
4458 return 0;
4459
Dhaval Patelf9245d62017-03-28 16:24:00 -07004460 if (!file || !file->private_data)
4461 return -EINVAL;
4462
4463 sde_enc = file->private_data;
4464
4465 rc = _sde_encoder_power_enable(sde_enc, true);
4466 if (rc)
4467 return rc;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304468
4469 mutex_lock(&sde_enc->enc_lock);
Dhaval Patelf9245d62017-03-28 16:24:00 -07004470 if (!sde_enc->misr_enable) {
4471 len += snprintf(buf + len, MISR_BUFF_SIZE - len,
4472 "disabled\n");
4473 goto buff_check;
4474 } else if (sde_enc->disp_info.capabilities &
4475 ~MSM_DISPLAY_CAP_VID_MODE) {
4476 len += snprintf(buf + len, MISR_BUFF_SIZE - len,
4477 "unsupported\n");
4478 goto buff_check;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304479 }
4480
Dhaval Patelf9245d62017-03-28 16:24:00 -07004481 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4482 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08004483
Dhaval Patelf9245d62017-03-28 16:24:00 -07004484 if (!phys || !phys->ops.collect_misr)
4485 continue;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304486
Dhaval Patelf9245d62017-03-28 16:24:00 -07004487 len += snprintf(buf + len, MISR_BUFF_SIZE - len,
4488 "Intf idx:%d\n", phys->intf_idx - INTF_0);
4489 len += snprintf(buf + len, MISR_BUFF_SIZE - len, "0x%x\n",
4490 phys->ops.collect_misr(phys));
4491 }
4492
4493buff_check:
4494 if (count <= len) {
4495 len = 0;
4496 goto end;
4497 }
4498
4499 if (copy_to_user(user_buff, buf, len)) {
4500 len = -EFAULT;
4501 goto end;
4502 }
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304503
4504 *ppos += len; /* increase offset */
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304505
Dhaval Patelf9245d62017-03-28 16:24:00 -07004506end:
4507 mutex_unlock(&sde_enc->enc_lock);
4508 _sde_encoder_power_enable(sde_enc, false);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304509 return len;
4510}
4511
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004512static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc)
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004513{
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004514 struct sde_encoder_virt *sde_enc;
4515 struct msm_drm_private *priv;
4516 struct sde_kms *sde_kms;
Alan Kwongf2debb02017-04-05 06:19:29 -07004517 int i;
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004518
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004519 static const struct file_operations debugfs_status_fops = {
4520 .open = _sde_encoder_debugfs_status_open,
4521 .read = seq_read,
4522 .llseek = seq_lseek,
4523 .release = single_release,
4524 };
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304525
4526 static const struct file_operations debugfs_misr_fops = {
4527 .open = simple_open,
4528 .read = _sde_encoder_misr_read,
Dhaval Patelf9245d62017-03-28 16:24:00 -07004529 .write = _sde_encoder_misr_setup,
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304530 };
4531
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004532 char name[SDE_NAME_SIZE];
4533
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004534 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004535 SDE_ERROR("invalid encoder or kms\n");
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004536 return -EINVAL;
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004537 }
4538
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004539 sde_enc = to_sde_encoder_virt(drm_enc);
4540 priv = drm_enc->dev->dev_private;
4541 sde_kms = to_sde_kms(priv->kms);
4542
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004543 snprintf(name, SDE_NAME_SIZE, "encoder%u", drm_enc->base.id);
4544
4545 /* create overall sub-directory for the encoder */
4546 sde_enc->debugfs_root = debugfs_create_dir(name,
Lloyd Atkinson09e64bf2017-04-13 14:09:59 -07004547 drm_enc->dev->primary->debugfs_root);
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004548 if (!sde_enc->debugfs_root)
4549 return -ENOMEM;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304550
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004551 /* don't error check these */
Lloyd Atkinson8de415a2017-05-23 11:31:16 -04004552 debugfs_create_file("status", 0600,
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004553 sde_enc->debugfs_root, sde_enc, &debugfs_status_fops);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05304554
Lloyd Atkinson8de415a2017-05-23 11:31:16 -04004555 debugfs_create_file("misr_data", 0600,
Dhaval Patelf9245d62017-03-28 16:24:00 -07004556 sde_enc->debugfs_root, sde_enc, &debugfs_misr_fops);
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004557
Alan Kwongf2debb02017-04-05 06:19:29 -07004558 for (i = 0; i < sde_enc->num_phys_encs; i++)
4559 if (sde_enc->phys_encs[i] &&
4560 sde_enc->phys_encs[i]->ops.late_register)
4561 sde_enc->phys_encs[i]->ops.late_register(
4562 sde_enc->phys_encs[i],
4563 sde_enc->debugfs_root);
4564
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004565 return 0;
4566}
4567
4568static void _sde_encoder_destroy_debugfs(struct drm_encoder *drm_enc)
4569{
4570 struct sde_encoder_virt *sde_enc;
4571
4572 if (!drm_enc)
4573 return;
4574
4575 sde_enc = to_sde_encoder_virt(drm_enc);
4576 debugfs_remove_recursive(sde_enc->debugfs_root);
4577}
4578#else
4579static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc)
4580{
4581 return 0;
4582}
4583
Lloyd Atkinsonc9fb3382017-03-24 08:08:30 -07004584static void _sde_encoder_destroy_debugfs(struct drm_encoder *drm_enc)
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004585{
4586}
4587#endif
4588
4589static int sde_encoder_late_register(struct drm_encoder *encoder)
4590{
4591 return _sde_encoder_init_debugfs(encoder);
4592}
4593
4594static void sde_encoder_early_unregister(struct drm_encoder *encoder)
4595{
4596 _sde_encoder_destroy_debugfs(encoder);
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004597}
4598
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004599static int sde_encoder_virt_add_phys_encs(
Clarence Ipa4039322016-07-15 16:23:59 -04004600 u32 display_caps,
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004601 struct sde_encoder_virt *sde_enc,
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004602 struct sde_enc_phys_init_params *params)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004603{
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004604 struct sde_encoder_phys *enc = NULL;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004605
Clarence Ip19af1362016-09-23 14:57:51 -04004606 SDE_DEBUG_ENC(sde_enc, "\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004607
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004608 /*
4609 * We may create up to NUM_PHYS_ENCODER_TYPES physical encoder types
4610 * in this function, check up-front.
4611 */
4612 if (sde_enc->num_phys_encs + NUM_PHYS_ENCODER_TYPES >=
4613 ARRAY_SIZE(sde_enc->phys_encs)) {
Clarence Ip19af1362016-09-23 14:57:51 -04004614 SDE_ERROR_ENC(sde_enc, "too many physical encoders %d\n",
Lloyd Atkinson09fed912016-06-24 18:14:13 -04004615 sde_enc->num_phys_encs);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004616 return -EINVAL;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004617 }
Lloyd Atkinson09fed912016-06-24 18:14:13 -04004618
Clarence Ipa4039322016-07-15 16:23:59 -04004619 if (display_caps & MSM_DISPLAY_CAP_VID_MODE) {
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004620 enc = sde_encoder_phys_vid_init(params);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004621
4622 if (IS_ERR_OR_NULL(enc)) {
Clarence Ip19af1362016-09-23 14:57:51 -04004623 SDE_ERROR_ENC(sde_enc, "failed to init vid enc: %ld\n",
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004624 PTR_ERR(enc));
4625 return enc == 0 ? -EINVAL : PTR_ERR(enc);
4626 }
4627
4628 sde_enc->phys_encs[sde_enc->num_phys_encs] = enc;
4629 ++sde_enc->num_phys_encs;
4630 }
4631
Clarence Ipa4039322016-07-15 16:23:59 -04004632 if (display_caps & MSM_DISPLAY_CAP_CMD_MODE) {
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004633 enc = sde_encoder_phys_cmd_init(params);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -04004634
4635 if (IS_ERR_OR_NULL(enc)) {
Clarence Ip19af1362016-09-23 14:57:51 -04004636 SDE_ERROR_ENC(sde_enc, "failed to init cmd enc: %ld\n",
Lloyd Atkinsona59eead2016-05-30 14:37:06 -04004637 PTR_ERR(enc));
4638 return enc == 0 ? -EINVAL : PTR_ERR(enc);
4639 }
4640
4641 sde_enc->phys_encs[sde_enc->num_phys_encs] = enc;
4642 ++sde_enc->num_phys_encs;
4643 }
4644
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004645 return 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004646}
4647
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004648static int sde_encoder_virt_add_phys_enc_wb(struct sde_encoder_virt *sde_enc,
4649 struct sde_enc_phys_init_params *params)
Alan Kwongbb27c092016-07-20 16:41:25 -04004650{
4651 struct sde_encoder_phys *enc = NULL;
Alan Kwongbb27c092016-07-20 16:41:25 -04004652
Clarence Ip19af1362016-09-23 14:57:51 -04004653 if (!sde_enc) {
4654 SDE_ERROR("invalid encoder\n");
4655 return -EINVAL;
4656 }
4657
4658 SDE_DEBUG_ENC(sde_enc, "\n");
Alan Kwongbb27c092016-07-20 16:41:25 -04004659
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004660 if (sde_enc->num_phys_encs + 1 >= ARRAY_SIZE(sde_enc->phys_encs)) {
Clarence Ip19af1362016-09-23 14:57:51 -04004661 SDE_ERROR_ENC(sde_enc, "too many physical encoders %d\n",
Alan Kwongbb27c092016-07-20 16:41:25 -04004662 sde_enc->num_phys_encs);
4663 return -EINVAL;
4664 }
4665
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004666 enc = sde_encoder_phys_wb_init(params);
Alan Kwongbb27c092016-07-20 16:41:25 -04004667
4668 if (IS_ERR_OR_NULL(enc)) {
Clarence Ip19af1362016-09-23 14:57:51 -04004669 SDE_ERROR_ENC(sde_enc, "failed to init wb enc: %ld\n",
Alan Kwongbb27c092016-07-20 16:41:25 -04004670 PTR_ERR(enc));
4671 return enc == 0 ? -EINVAL : PTR_ERR(enc);
4672 }
4673
4674 sde_enc->phys_encs[sde_enc->num_phys_encs] = enc;
4675 ++sde_enc->num_phys_encs;
4676
4677 return 0;
4678}
4679
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004680static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004681 struct sde_kms *sde_kms,
Clarence Ipa4039322016-07-15 16:23:59 -04004682 struct msm_display_info *disp_info,
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004683 int *drm_enc_mode)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004684{
4685 int ret = 0;
4686 int i = 0;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004687 enum sde_intf_type intf_type;
4688 struct sde_encoder_virt_ops parent_ops = {
4689 sde_encoder_vblank_callback,
Dhaval Patel81e87882016-10-19 21:41:56 -07004690 sde_encoder_underrun_callback,
Alan Kwong628d19e2016-10-31 13:50:13 -04004691 sde_encoder_frame_done_callback,
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004692 };
4693 struct sde_enc_phys_init_params phys_params;
4694
Clarence Ip19af1362016-09-23 14:57:51 -04004695 if (!sde_enc || !sde_kms) {
4696 SDE_ERROR("invalid arg(s), enc %d kms %d\n",
4697 sde_enc != 0, sde_kms != 0);
4698 return -EINVAL;
4699 }
4700
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004701 memset(&phys_params, 0, sizeof(phys_params));
4702 phys_params.sde_kms = sde_kms;
4703 phys_params.parent = &sde_enc->base;
4704 phys_params.parent_ops = parent_ops;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04004705 phys_params.enc_spinlock = &sde_enc->enc_spinlock;
Raviteja Tamatam3ea60b82018-04-27 15:41:18 +05304706 phys_params.vblank_ctl_lock = &sde_enc->vblank_ctl_lock;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004707
Clarence Ip19af1362016-09-23 14:57:51 -04004708 SDE_DEBUG("\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004709
Clarence Ipa4039322016-07-15 16:23:59 -04004710 if (disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) {
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004711 *drm_enc_mode = DRM_MODE_ENCODER_DSI;
4712 intf_type = INTF_DSI;
Clarence Ipa4039322016-07-15 16:23:59 -04004713 } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_HDMIA) {
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004714 *drm_enc_mode = DRM_MODE_ENCODER_TMDS;
4715 intf_type = INTF_HDMI;
Padmanabhan Komanduru63758612017-05-23 01:47:18 -07004716 } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_DisplayPort) {
4717 *drm_enc_mode = DRM_MODE_ENCODER_TMDS;
4718 intf_type = INTF_DP;
Alan Kwongbb27c092016-07-20 16:41:25 -04004719 } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_VIRTUAL) {
4720 *drm_enc_mode = DRM_MODE_ENCODER_VIRTUAL;
4721 intf_type = INTF_WB;
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004722 } else {
Clarence Ip19af1362016-09-23 14:57:51 -04004723 SDE_ERROR_ENC(sde_enc, "unsupported display interface type\n");
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004724 return -EINVAL;
4725 }
4726
Clarence Ip88270a62016-06-26 10:09:34 -04004727 WARN_ON(disp_info->num_of_h_tiles < 1);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004728
Lloyd Atkinson11f34442016-08-11 11:19:52 -04004729 sde_enc->display_num_of_h_tiles = disp_info->num_of_h_tiles;
4730
Clarence Ip19af1362016-09-23 14:57:51 -04004731 SDE_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004732
Dhaval Patele17e0ee2017-08-23 18:01:42 -07004733 if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) ||
4734 (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE))
Veera Sundaram Sankaran42ac38d2018-07-06 12:42:04 -07004735 sde_enc->idle_pc_enabled = sde_kms->catalog->has_idle_pc;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07004736
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004737 mutex_lock(&sde_enc->enc_lock);
Clarence Ip88270a62016-06-26 10:09:34 -04004738 for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004739 /*
4740 * Left-most tile is at index 0, content is controller id
4741 * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right
4742 * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right
4743 */
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004744 u32 controller_id = disp_info->h_tile_instance[i];
4745
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004746 if (disp_info->num_of_h_tiles > 1) {
4747 if (i == 0)
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004748 phys_params.split_role = ENC_ROLE_MASTER;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004749 else
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004750 phys_params.split_role = ENC_ROLE_SLAVE;
4751 } else {
4752 phys_params.split_role = ENC_ROLE_SOLO;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004753 }
4754
Clarence Ip19af1362016-09-23 14:57:51 -04004755 SDE_DEBUG("h_tile_instance %d = %d, split_role %d\n",
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004756 i, controller_id, phys_params.split_role);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004757
Alan Kwongbb27c092016-07-20 16:41:25 -04004758 if (intf_type == INTF_WB) {
Lloyd Atkinson11f34442016-08-11 11:19:52 -04004759 phys_params.intf_idx = INTF_MAX;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004760 phys_params.wb_idx = sde_encoder_get_wb(
4761 sde_kms->catalog,
Alan Kwongbb27c092016-07-20 16:41:25 -04004762 intf_type, controller_id);
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004763 if (phys_params.wb_idx == WB_MAX) {
Clarence Ip19af1362016-09-23 14:57:51 -04004764 SDE_ERROR_ENC(sde_enc,
4765 "could not get wb: type %d, id %d\n",
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004766 intf_type, controller_id);
Alan Kwongbb27c092016-07-20 16:41:25 -04004767 ret = -EINVAL;
4768 }
Alan Kwongbb27c092016-07-20 16:41:25 -04004769 } else {
Lloyd Atkinson11f34442016-08-11 11:19:52 -04004770 phys_params.wb_idx = WB_MAX;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004771 phys_params.intf_idx = sde_encoder_get_intf(
4772 sde_kms->catalog, intf_type,
4773 controller_id);
4774 if (phys_params.intf_idx == INTF_MAX) {
Clarence Ip19af1362016-09-23 14:57:51 -04004775 SDE_ERROR_ENC(sde_enc,
4776 "could not get wb: type %d, id %d\n",
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004777 intf_type, controller_id);
Alan Kwongbb27c092016-07-20 16:41:25 -04004778 ret = -EINVAL;
4779 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004780 }
4781
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004782 if (!ret) {
Alan Kwongbb27c092016-07-20 16:41:25 -04004783 if (intf_type == INTF_WB)
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004784 ret = sde_encoder_virt_add_phys_enc_wb(sde_enc,
4785 &phys_params);
Alan Kwongbb27c092016-07-20 16:41:25 -04004786 else
4787 ret = sde_encoder_virt_add_phys_encs(
4788 disp_info->capabilities,
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04004789 sde_enc,
4790 &phys_params);
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004791 if (ret)
Clarence Ip19af1362016-09-23 14:57:51 -04004792 SDE_ERROR_ENC(sde_enc,
4793 "failed to add phys encs\n");
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004794 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004795 }
Dhaval Pateld4e583a2017-03-10 14:46:44 -08004796
4797 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4798 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
4799
4800 if (phys) {
4801 atomic_set(&phys->vsync_cnt, 0);
4802 atomic_set(&phys->underrun_cnt, 0);
4803 }
4804 }
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004805 mutex_unlock(&sde_enc->enc_lock);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004806
4807 return ret;
4808}
4809
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07004810static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = {
4811 .mode_set = sde_encoder_virt_mode_set,
4812 .disable = sde_encoder_virt_disable,
4813 .enable = sde_encoder_virt_enable,
4814 .atomic_check = sde_encoder_virt_atomic_check,
4815};
4816
4817static const struct drm_encoder_funcs sde_encoder_funcs = {
4818 .destroy = sde_encoder_destroy,
4819 .late_register = sde_encoder_late_register,
4820 .early_unregister = sde_encoder_early_unregister,
4821};
4822
Clarence Ip3649f8b2016-10-31 09:59:44 -04004823struct drm_encoder *sde_encoder_init(
4824 struct drm_device *dev,
4825 struct msm_display_info *disp_info)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004826{
4827 struct msm_drm_private *priv = dev->dev_private;
Ben Chan78647cd2016-06-26 22:02:47 -04004828 struct sde_kms *sde_kms = to_sde_kms(priv->kms);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004829 struct drm_encoder *drm_enc = NULL;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04004830 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004831 int drm_enc_mode = DRM_MODE_ENCODER_NONE;
Dhaval Patel020f7e122016-11-15 14:39:18 -08004832 char name[SDE_NAME_SIZE];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004833 int ret = 0;
4834
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004835 sde_enc = kzalloc(sizeof(*sde_enc), GFP_KERNEL);
4836 if (!sde_enc) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07004837 ret = -ENOMEM;
4838 goto fail;
4839 }
4840
Dhaval Patel22ef6df2016-10-20 14:42:52 -07004841 mutex_init(&sde_enc->enc_lock);
Lloyd Atkinson9a840312016-06-26 10:11:08 -04004842 ret = sde_encoder_setup_display(sde_enc, sde_kms, disp_info,
4843 &drm_enc_mode);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004844 if (ret)
4845 goto fail;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07004846
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004847 sde_enc->cur_master = NULL;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04004848 spin_lock_init(&sde_enc->enc_spinlock);
Raviteja Tamatam3ea60b82018-04-27 15:41:18 +05304849 mutex_init(&sde_enc->vblank_ctl_lock);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004850 drm_enc = &sde_enc->base;
Dhaval Patel04c7e8e2016-09-26 20:14:31 -07004851 drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, drm_enc_mode, NULL);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004852 drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07004853
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004854 if ((disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) &&
4855 disp_info->is_primary)
4856 setup_timer(&sde_enc->vsync_event_timer,
4857 sde_encoder_vsync_event_handler,
4858 (unsigned long)sde_enc);
4859
Dhaval Patel020f7e122016-11-15 14:39:18 -08004860 snprintf(name, SDE_NAME_SIZE, "rsc_enc%u", drm_enc->base.id);
4861 sde_enc->rsc_client = sde_rsc_client_create(SDE_RSC_INDEX, name,
Dhaval Patel82c8dbc2017-02-18 23:15:10 -08004862 disp_info->is_primary);
Dhaval Patel020f7e122016-11-15 14:39:18 -08004863 if (IS_ERR_OR_NULL(sde_enc->rsc_client)) {
Dhaval Patel49ef6d72017-03-26 09:35:53 -07004864 SDE_DEBUG("sde rsc client create failed :%ld\n",
Dhaval Patel020f7e122016-11-15 14:39:18 -08004865 PTR_ERR(sde_enc->rsc_client));
4866 sde_enc->rsc_client = NULL;
4867 }
Dhaval Patel82c8dbc2017-02-18 23:15:10 -08004868
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08004869 if (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) {
4870 ret = _sde_encoder_input_handler(sde_enc);
4871 if (ret)
4872 SDE_ERROR(
4873 "input handler registration failed, rc = %d\n", ret);
4874 }
4875
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07004876 mutex_init(&sde_enc->rc_lock);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04004877 kthread_init_delayed_work(&sde_enc->delayed_off_work,
4878 sde_encoder_off_work);
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07004879 sde_enc->vblank_enabled = false;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04004880
4881 kthread_init_work(&sde_enc->vsync_event_work,
4882 sde_encoder_vsync_event_work_handler);
4883
Jeykumar Sankaranf8298f32017-12-08 10:39:51 -08004884 kthread_init_work(&sde_enc->input_event_work,
4885 sde_encoder_input_event_work_handler);
4886
Dhaval Patel222023e2018-02-27 12:24:07 -08004887 kthread_init_work(&sde_enc->esd_trigger_work,
4888 sde_encoder_esd_trigger_work_handler);
4889
Dhaval Patel020f7e122016-11-15 14:39:18 -08004890 memcpy(&sde_enc->disp_info, disp_info, sizeof(*disp_info));
4891
Clarence Ip19af1362016-09-23 14:57:51 -04004892 SDE_DEBUG_ENC(sde_enc, "created\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004893
4894 return drm_enc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07004895
4896fail:
Clarence Ip19af1362016-09-23 14:57:51 -04004897 SDE_ERROR("failed to create encoder\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004898 if (drm_enc)
4899 sde_encoder_destroy(drm_enc);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07004900
4901 return ERR_PTR(ret);
4902}
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04004903
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07004904int sde_encoder_wait_for_event(struct drm_encoder *drm_enc,
4905 enum msm_event_wait event)
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04004906{
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07004907 int (*fn_wait)(struct sde_encoder_phys *phys_enc) = NULL;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004908 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004909 int i, ret = 0;
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04004910
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004911 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -04004912 SDE_ERROR("invalid encoder\n");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004913 return -EINVAL;
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04004914 }
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004915 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -04004916 SDE_DEBUG_ENC(sde_enc, "\n");
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04004917
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004918 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4919 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04004920
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07004921 switch (event) {
4922 case MSM_ENC_COMMIT_DONE:
4923 fn_wait = phys->ops.wait_for_commit_done;
4924 break;
4925 case MSM_ENC_TX_COMPLETE:
4926 fn_wait = phys->ops.wait_for_tx_complete;
4927 break;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04004928 case MSM_ENC_VBLANK:
4929 fn_wait = phys->ops.wait_for_vblank;
4930 break;
Sandeep Panda11b20d82017-06-19 12:57:27 +05304931 case MSM_ENC_ACTIVE_REGION:
4932 fn_wait = phys->ops.wait_for_active;
4933 break;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04004934 default:
4935 SDE_ERROR_ENC(sde_enc, "unknown wait event %d\n",
4936 event);
4937 return -EINVAL;
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07004938 };
4939
4940 if (phys && fn_wait) {
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07004941 SDE_ATRACE_BEGIN("wait_for_completion_event");
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07004942 ret = fn_wait(phys);
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07004943 SDE_ATRACE_END("wait_for_completion_event");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04004944 if (ret)
4945 return ret;
4946 }
4947 }
4948
4949 return ret;
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04004950}
4951
Alan Kwong67a3f792016-11-01 23:16:53 -04004952enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder)
4953{
4954 struct sde_encoder_virt *sde_enc = NULL;
4955 int i;
4956
4957 if (!encoder) {
4958 SDE_ERROR("invalid encoder\n");
4959 return INTF_MODE_NONE;
4960 }
4961 sde_enc = to_sde_encoder_virt(encoder);
4962
4963 if (sde_enc->cur_master)
4964 return sde_enc->cur_master->intf_mode;
4965
4966 for (i = 0; i < sde_enc->num_phys_encs; i++) {
4967 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
4968
4969 if (phys)
4970 return phys->intf_mode;
4971 }
4972
4973 return INTF_MODE_NONE;
4974}
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -07004975
4976/**
4977 * sde_encoder_update_caps_for_cont_splash - update encoder settings during
4978 * device bootup when cont_splash is enabled
4979 * @drm_enc: Pointer to drm encoder structure
4980 * @Return: true if successful in updating the encoder structure
4981 */
4982int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder)
4983{
4984 struct sde_encoder_virt *sde_enc;
4985 struct msm_drm_private *priv;
4986 struct sde_kms *sde_kms;
4987 struct drm_connector *conn = NULL;
4988 struct sde_connector *sde_conn = NULL;
4989 struct sde_connector_state *sde_conn_state = NULL;
4990 struct drm_display_mode *drm_mode = NULL;
4991 struct sde_rm_hw_iter dsc_iter, pp_iter, ctl_iter;
4992 int ret = 0, i;
4993
4994 if (!encoder) {
4995 SDE_ERROR("invalid drm enc\n");
4996 return -EINVAL;
4997 }
4998
4999 if (!encoder->dev || !encoder->dev->dev_private) {
5000 SDE_ERROR("drm device invalid\n");
5001 return -EINVAL;
5002 }
5003
5004 priv = encoder->dev->dev_private;
5005 if (!priv->kms) {
5006 SDE_ERROR("invalid kms\n");
5007 return -EINVAL;
5008 }
5009
5010 sde_kms = to_sde_kms(priv->kms);
5011 sde_enc = to_sde_encoder_virt(encoder);
5012 if (!priv->num_connectors) {
5013 SDE_ERROR_ENC(sde_enc, "No connectors registered\n");
5014 return -EINVAL;
5015 }
5016 SDE_DEBUG_ENC(sde_enc,
5017 "num of connectors: %d\n", priv->num_connectors);
5018
5019 for (i = 0; i < priv->num_connectors; i++) {
5020 SDE_DEBUG_ENC(sde_enc, "connector id: %d\n",
5021 priv->connectors[i]->base.id);
5022 sde_conn = to_sde_connector(priv->connectors[i]);
5023 if (!sde_conn->encoder) {
5024 SDE_DEBUG_ENC(sde_enc,
5025 "encoder not attached to connector\n");
5026 continue;
5027 }
5028 if (sde_conn->encoder->base.id
5029 == encoder->base.id) {
5030 conn = (priv->connectors[i]);
5031 break;
5032 }
5033 }
5034
5035 if (!conn || !conn->state) {
5036 SDE_ERROR_ENC(sde_enc, "connector not found\n");
5037 return -EINVAL;
5038 }
5039
5040 sde_conn_state = to_sde_connector_state(conn->state);
5041
5042 if (!sde_conn->ops.get_mode_info) {
5043 SDE_ERROR_ENC(sde_enc, "conn: get_mode_info ops not found\n");
5044 return -EINVAL;
5045 }
5046
5047 ret = sde_conn->ops.get_mode_info(&encoder->crtc->state->adjusted_mode,
5048 &sde_conn_state->mode_info,
5049 sde_kms->catalog->max_mixer_width,
5050 sde_conn->display);
5051 if (ret) {
5052 SDE_ERROR_ENC(sde_enc,
5053 "conn: ->get_mode_info failed. ret=%d\n", ret);
5054 return ret;
5055 }
5056
5057 ret = sde_rm_reserve(&sde_kms->rm, encoder, encoder->crtc->state,
5058 conn->state, false);
5059 if (ret) {
5060 SDE_ERROR_ENC(sde_enc,
5061 "failed to reserve hw resources, %d\n", ret);
5062 return ret;
5063 }
5064
Jeykumar Sankarand920ec72017-11-18 20:01:39 -08005065 if (sde_conn->encoder) {
5066 conn->state->best_encoder = sde_conn->encoder;
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -07005067 SDE_DEBUG_ENC(sde_enc,
5068 "configured cstate->best_encoder to ID = %d\n",
5069 conn->state->best_encoder->base.id);
5070 } else {
5071 SDE_ERROR_ENC(sde_enc, "No encoder mapped to connector=%d\n",
5072 conn->base.id);
5073 }
5074
5075 SDE_DEBUG_ENC(sde_enc, "connector topology = %llu\n",
5076 sde_connector_get_topology_name(conn));
5077 drm_mode = &encoder->crtc->state->adjusted_mode;
5078 SDE_DEBUG_ENC(sde_enc, "hdisplay = %d, vdisplay = %d\n",
5079 drm_mode->hdisplay, drm_mode->vdisplay);
5080 drm_set_preferred_mode(conn, drm_mode->hdisplay, drm_mode->vdisplay);
5081
5082 if (encoder->bridge) {
5083 SDE_DEBUG_ENC(sde_enc, "Bridge mapped to encoder\n");
5084 /*
5085 * For cont-splash use case, we update the mode
5086 * configurations manually. This will skip the
5087 * usually mode set call when actual frame is
5088 * pushed from framework. The bridge needs to
5089 * be updated with the current drm mode by
5090 * calling the bridge mode set ops.
5091 */
5092 if (encoder->bridge->funcs) {
5093 SDE_DEBUG_ENC(sde_enc, "calling mode_set\n");
5094 encoder->bridge->funcs->mode_set(encoder->bridge,
5095 drm_mode, drm_mode);
5096 }
5097 } else {
5098 SDE_ERROR_ENC(sde_enc, "No bridge attached to encoder\n");
5099 }
5100
5101 sde_rm_init_hw_iter(&pp_iter, encoder->base.id, SDE_HW_BLK_PINGPONG);
5102 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
5103 sde_enc->hw_pp[i] = NULL;
5104 if (!sde_rm_get_hw(&sde_kms->rm, &pp_iter))
5105 break;
5106 sde_enc->hw_pp[i] = (struct sde_hw_pingpong *) pp_iter.hw;
5107 }
5108
5109 sde_rm_init_hw_iter(&dsc_iter, encoder->base.id, SDE_HW_BLK_DSC);
5110 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
5111 sde_enc->hw_dsc[i] = NULL;
5112 if (!sde_rm_get_hw(&sde_kms->rm, &dsc_iter))
5113 break;
5114 sde_enc->hw_dsc[i] = (struct sde_hw_dsc *) dsc_iter.hw;
5115 }
5116
5117 sde_rm_init_hw_iter(&ctl_iter, encoder->base.id, SDE_HW_BLK_CTL);
5118 for (i = 0; i < sde_enc->num_phys_encs; i++) {
5119 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
5120
5121 phys->hw_ctl = NULL;
5122 if (!sde_rm_get_hw(&sde_kms->rm, &ctl_iter))
5123 break;
5124 phys->hw_ctl = (struct sde_hw_ctl *) ctl_iter.hw;
5125 }
5126
5127 for (i = 0; i < sde_enc->num_phys_encs; i++) {
5128 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
5129
5130 if (!phys) {
5131 SDE_ERROR_ENC(sde_enc,
5132 "phys encoders not initialized\n");
5133 return -EINVAL;
5134 }
5135
Ingrid Gallardo72cd1632018-02-28 15:26:37 -08005136 /* update connector for master and slave phys encoders */
5137 phys->connector = conn;
5138 phys->cont_splash_single_flush =
5139 sde_kms->splash_data.single_flush_en;
5140 phys->cont_splash_settings = true;
5141
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -07005142 phys->hw_pp = sde_enc->hw_pp[i];
5143 if (phys->ops.cont_splash_mode_set)
5144 phys->ops.cont_splash_mode_set(phys, drm_mode);
5145
Ingrid Gallardo72cd1632018-02-28 15:26:37 -08005146 if (phys->ops.is_master && phys->ops.is_master(phys))
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -07005147 sde_enc->cur_master = phys;
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -07005148 }
5149
5150 return ret;
5151}
Dhaval Patelef58f0b2018-01-22 19:13:52 -08005152
5153int sde_encoder_display_failure_notification(struct drm_encoder *enc)
5154{
Jayant Shekhar00a28e92018-06-04 12:15:23 +05305155 struct msm_drm_thread *event_thread = NULL;
Dhaval Patel222023e2018-02-27 12:24:07 -08005156 struct msm_drm_private *priv = NULL;
5157 struct sde_encoder_virt *sde_enc = NULL;
5158
5159 if (!enc || !enc->dev || !enc->dev->dev_private) {
5160 SDE_ERROR("invalid parameters\n");
5161 return -EINVAL;
5162 }
5163
5164 priv = enc->dev->dev_private;
5165 sde_enc = to_sde_encoder_virt(enc);
5166 if (!sde_enc->crtc || (sde_enc->crtc->index
Jayant Shekhar00a28e92018-06-04 12:15:23 +05305167 >= ARRAY_SIZE(priv->event_thread))) {
Dhaval Patel222023e2018-02-27 12:24:07 -08005168 SDE_DEBUG_ENC(sde_enc,
5169 "invalid cached CRTC: %d or crtc index: %d\n",
5170 sde_enc->crtc == NULL,
5171 sde_enc->crtc ? sde_enc->crtc->index : -EINVAL);
5172 return -EINVAL;
5173 }
5174
5175 SDE_EVT32_VERBOSE(DRMID(enc));
5176
Jayant Shekhar00a28e92018-06-04 12:15:23 +05305177 event_thread = &priv->event_thread[sde_enc->crtc->index];
5178
5179 kthread_queue_work(&event_thread->worker,
5180 &sde_enc->esd_trigger_work);
5181 kthread_flush_work(&sde_enc->esd_trigger_work);
5182
Dhaval Patelef58f0b2018-01-22 19:13:52 -08005183 /**
5184 * panel may stop generating te signal (vsync) during esd failure. rsc
5185 * hardware may hang without vsync. Avoid rsc hang by generating the
5186 * vsync from watchdog timer instead of panel.
5187 */
5188 _sde_encoder_switch_to_watchdog_vsync(enc);
5189
5190 sde_encoder_wait_for_event(enc, MSM_ENC_TX_COMPLETE);
5191
5192 return 0;
5193}
Chirag Khuranaed859f52019-11-20 18:18:12 +05305194
5195/**
5196 * sde_encoder_phys_setup_cdm - setup chroma down block
5197 * @phys_enc: Pointer to physical encoder
5198 * @output_type: HDMI/WB
5199 * @format: Output format
5200 * @roi: Output size
5201 */
5202void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
5203 const struct sde_format *format, u32 output_type,
5204 struct sde_rect *roi)
5205{
5206 struct drm_encoder *encoder = phys_enc->parent;
5207 struct sde_encoder_virt *sde_enc = NULL;
5208 struct sde_hw_cdm *hw_cdm = phys_enc->hw_cdm;
5209 struct sde_hw_cdm_cfg *cdm_cfg = &phys_enc->cdm_cfg;
Chirag Khuranace2aa512019-11-20 18:27:03 +05305210 struct drm_connector *connector = phys_enc->connector;
Chirag Khuranaed859f52019-11-20 18:18:12 +05305211 int ret;
5212 u32 csc_type = 0;
5213
5214 if (!encoder) {
5215 SDE_ERROR("invalid encoder\n");
5216 return;
5217 }
5218 sde_enc = to_sde_encoder_virt(encoder);
5219
5220 if (!SDE_FORMAT_IS_YUV(format)) {
5221 SDE_DEBUG_ENC(sde_enc, "[cdm_disable fmt:%x]\n",
5222 format->base.pixel_format);
5223
5224 if (hw_cdm && hw_cdm->ops.disable)
5225 hw_cdm->ops.disable(hw_cdm);
5226
5227 return;
5228 }
5229
5230 memset(cdm_cfg, 0, sizeof(struct sde_hw_cdm_cfg));
5231
5232 cdm_cfg->output_width = roi->w;
5233 cdm_cfg->output_height = roi->h;
5234 cdm_cfg->output_fmt = format;
5235 cdm_cfg->output_type = output_type;
5236 cdm_cfg->output_bit_depth = SDE_FORMAT_IS_DX(format) ?
5237 CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT;
5238
5239 /* enable 10 bit logic */
5240 switch (cdm_cfg->output_fmt->chroma_sample) {
5241 case SDE_CHROMA_RGB:
5242 cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
5243 cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
5244 break;
5245 case SDE_CHROMA_H2V1:
5246 cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
5247 cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
5248 break;
5249 case SDE_CHROMA_420:
5250 cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
5251 cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE;
5252 break;
5253 case SDE_CHROMA_H1V2:
5254 default:
5255 SDE_ERROR("unsupported chroma sampling type\n");
5256 cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
5257 cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
5258 break;
5259 }
5260
5261 SDE_DEBUG_ENC(sde_enc, "[cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n",
5262 cdm_cfg->output_width,
5263 cdm_cfg->output_height,
5264 cdm_cfg->output_fmt->base.pixel_format,
5265 cdm_cfg->output_type,
5266 cdm_cfg->output_bit_depth,
5267 cdm_cfg->h_cdwn_type,
5268 cdm_cfg->v_cdwn_type);
5269
Chirag Khuranace2aa512019-11-20 18:27:03 +05305270 /**
5271 * Choose CSC matrix based on following rules:
5272 * 1. If connector supports quantization select,
5273 * pick Full-Range for better quality.
5274 * 2. If non-CEA mode, then pick Full-Range as per CEA spec
5275 * 3. Otherwise, pick Limited-Range as all other CEA modes
5276 * need a limited range
5277 */
5278
5279 if (output_type == CDM_CDWN_OUTPUT_HDMI) {
5280 if (connector && connector->yuv_qs)
5281 csc_type = SDE_CSC_RGB2YUV_601FR;
5282 else if (connector &&
5283 sde_connector_mode_needs_full_range(connector))
5284 csc_type = SDE_CSC_RGB2YUV_601FR;
5285 else
5286 csc_type = SDE_CSC_RGB2YUV_601L;
5287 } else if (output_type == CDM_CDWN_OUTPUT_WB) {
Chirag Khuranaed859f52019-11-20 18:18:12 +05305288 csc_type = SDE_CSC_RGB2YUV_601L;
Chirag Khuranace2aa512019-11-20 18:27:03 +05305289 }
Chirag Khuranaed859f52019-11-20 18:18:12 +05305290
5291 if (hw_cdm && hw_cdm->ops.setup_csc_data) {
5292 ret = hw_cdm->ops.setup_csc_data(hw_cdm,
5293 &sde_csc_10bit_convert[csc_type]);
5294 if (ret < 0) {
5295 SDE_ERROR("failed to setup CSC %d\n", ret);
5296 return;
5297 }
5298 }
5299
5300 if (hw_cdm && hw_cdm->ops.setup_cdwn) {
5301 ret = hw_cdm->ops.setup_cdwn(hw_cdm, cdm_cfg);
5302 if (ret < 0) {
5303 SDE_ERROR("failed to setup CDM %d\n", ret);
5304 return;
5305 }
5306 }
5307
5308 if (hw_cdm && hw_cdm->ops.enable) {
5309 ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg);
5310 if (ret < 0) {
5311 SDE_ERROR("failed to enable CDM %d\n", ret);
5312 return;
5313 }
5314 }
5315}