blob: 8855859012c28647105ef6f640d343e97d827012 [file] [log] [blame]
Dhaval Patel14d46ce2017-01-17 16:28:12 -08001/*
2 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
3 * 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
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -070070#define MAX_CHANNELS_PER_ENC 2
71
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
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -040076/* Maximum number of VSYNC wait attempts for RSC state transition */
77#define MAX_RSC_WAIT 5
78
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -070079/**
80 * enum sde_enc_rc_events - events for resource control state machine
81 * @SDE_ENC_RC_EVENT_KICKOFF:
82 * This event happens at NORMAL priority.
83 * Event that signals the start of the transfer. When this event is
84 * received, enable MDP/DSI core clocks and request RSC with CMD state.
85 * Regardless of the previous state, the resource should be in ON state
86 * at the end of this event.
87 * @SDE_ENC_RC_EVENT_FRAME_DONE:
88 * This event happens at INTERRUPT level.
89 * Event signals the end of the data transfer after the PP FRAME_DONE
90 * event. At the end of this event, a delayed work is scheduled to go to
91 * IDLE_PC state after IDLE_TIMEOUT time.
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -040092 * @SDE_ENC_RC_EVENT_PRE_STOP:
93 * This event happens at NORMAL priority.
94 * This event, when received during the ON state, set RSC to IDLE, and
95 * and leave the RC STATE in the PRE_OFF state.
96 * It should be followed by the STOP event as part of encoder disable.
97 * If received during IDLE or OFF states, it will do nothing.
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -070098 * @SDE_ENC_RC_EVENT_STOP:
99 * This event happens at NORMAL priority.
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400100 * When this event is received, disable all the MDP/DSI core clocks, and
101 * disable IRQs. It should be called from the PRE_OFF or IDLE states.
102 * IDLE is expected when IDLE_PC has run, and PRE_OFF did nothing.
103 * PRE_OFF is expected when PRE_STOP was executed during the ON state.
104 * Resource state should be in OFF at the end of the event.
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700105 * @SDE_ENC_RC_EVENT_PRE_MODESET:
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700106 * This event happens at NORMAL priority from a work item.
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700107 * Event signals that there is a seamless mode switch is in prgoress. A
108 * client needs to turn of only irq - leave clocks ON to reduce the mode
109 * switch latency.
110 * @SDE_ENC_RC_EVENT_POST_MODESET:
111 * This event happens at NORMAL priority from a work item.
112 * Event signals that seamless mode switch is complete and resources are
113 * acquired. Clients wants to turn on the irq again and update the rsc
114 * with new vtotal.
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700115 * @SDE_ENC_RC_EVENT_ENTER_IDLE:
116 * This event happens at NORMAL priority from a work item.
117 * Event signals that there were no frame updates for IDLE_TIMEOUT time.
118 * This would disable MDP/DSI core clocks and request RSC with IDLE state
119 * and change the resource state to IDLE.
120 */
121enum sde_enc_rc_events {
122 SDE_ENC_RC_EVENT_KICKOFF = 1,
123 SDE_ENC_RC_EVENT_FRAME_DONE,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400124 SDE_ENC_RC_EVENT_PRE_STOP,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700125 SDE_ENC_RC_EVENT_STOP,
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700126 SDE_ENC_RC_EVENT_PRE_MODESET,
127 SDE_ENC_RC_EVENT_POST_MODESET,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700128 SDE_ENC_RC_EVENT_ENTER_IDLE
129};
130
131/*
132 * enum sde_enc_rc_states - states that the resource control maintains
133 * @SDE_ENC_RC_STATE_OFF: Resource is in OFF state
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400134 * @SDE_ENC_RC_STATE_PRE_OFF: Resource is transitioning to OFF state
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700135 * @SDE_ENC_RC_STATE_ON: Resource is in ON state
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700136 * @SDE_ENC_RC_STATE_MODESET: Resource is in modeset state
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700137 * @SDE_ENC_RC_STATE_IDLE: Resource is in IDLE state
138 */
139enum sde_enc_rc_states {
140 SDE_ENC_RC_STATE_OFF,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400141 SDE_ENC_RC_STATE_PRE_OFF,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700142 SDE_ENC_RC_STATE_ON,
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700143 SDE_ENC_RC_STATE_MODESET,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700144 SDE_ENC_RC_STATE_IDLE
145};
146
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400147/**
148 * struct sde_encoder_virt - virtual encoder. Container of one or more physical
149 * encoders. Virtual encoder manages one "logical" display. Physical
150 * encoders manage one intf block, tied to a specific panel/sub-panel.
151 * Virtual encoder defers as much as possible to the physical encoders.
152 * Virtual encoder registers itself with the DRM Framework as the encoder.
153 * @base: drm_encoder base class for registration with DRM
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400154 * @enc_spin_lock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400155 * @bus_scaling_client: Client handle to the bus scaling interface
156 * @num_phys_encs: Actual number of physical encoders contained.
157 * @phys_encs: Container of physical encoders managed.
158 * @cur_master: Pointer to the current master in this mode. Optimization
159 * Only valid after enable. Cleared as disable.
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700160 * @hw_pp Handle to the pingpong blocks used for the display. No.
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500161 * pingpong blocks can be different than num_phys_encs.
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800162 * @hw_dsc: Array of DSC block handles used for the display.
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500163 * @intfs_swapped Whether or not the phys_enc interfaces have been swapped
164 * for partial update right-only cases, such as pingpong
165 * split where virtual pingpong does not generate IRQs
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400166 * @crtc_vblank_cb: Callback into the upper layer / CRTC for
167 * notification of the VBLANK
168 * @crtc_vblank_cb_data: Data from upper layer for VBLANK notification
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400169 * @crtc_kickoff_cb: Callback into CRTC that will flush & start
170 * all CTL paths
171 * @crtc_kickoff_cb_data: Opaque user data given to crtc_kickoff_cb
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700172 * @debugfs_root: Debug file system root file node
173 * @enc_lock: Lock around physical encoder create/destroy and
174 access.
Alan Kwong628d19e2016-10-31 13:50:13 -0400175 * @frame_busy_mask: Bitmask tracking which phys_enc we are still
176 * busy processing current command.
177 * Bit0 = phys_encs[0] etc.
178 * @crtc_frame_event_cb: callback handler for frame event
179 * @crtc_frame_event_cb_data: callback handler private data
Alan Kwong628d19e2016-10-31 13:50:13 -0400180 * @frame_done_timeout: frame done timeout in Hz
181 * @frame_done_timer: watchdog timer for frame done event
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400182 * @vsync_event_timer: vsync timer
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700183 * @rsc_client: rsc client pointer
184 * @rsc_state_init: boolean to indicate rsc config init
185 * @disp_info: local copy of msm_display_info struct
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -0700186 * @mode_info: local copy of msm_mode_info struct
Dhaval Patelf9245d62017-03-28 16:24:00 -0700187 * @misr_enable: misr enable/disable status
Dhaval Patel010f5172017-08-01 22:40:09 -0700188 * @misr_frame_count: misr frame count before start capturing the data
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700189 * @idle_pc_supported: indicate if idle power collaps is supported
190 * @rc_lock: resource control mutex lock to protect
191 * virt encoder over various state changes
192 * @rc_state: resource controller state
193 * @delayed_off_work: delayed worker to schedule disabling of
194 * clks and resources after IDLE_TIMEOUT time.
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400195 * @vsync_event_work: worker to handle vsync event for autorefresh
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700196 * @topology: topology of the display
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -0700197 * @vblank_enabled: boolean to track userspace vblank vote
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700198 * @rsc_config: rsc configuration for display vtotal, fps, etc.
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400199 * @cur_conn_roi: current connector roi
200 * @prv_conn_roi: previous connector roi to optimize if unchanged
Dhaval Patele17e0ee2017-08-23 18:01:42 -0700201 * @idle_timeout: idle timeout duration in milliseconds
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400202 */
203struct sde_encoder_virt {
204 struct drm_encoder base;
Lloyd Atkinson7d070942016-07-26 18:35:12 -0400205 spinlock_t enc_spinlock;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400206 uint32_t bus_scaling_client;
207
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400208 uint32_t display_num_of_h_tiles;
209
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400210 unsigned int num_phys_encs;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400211 struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
212 struct sde_encoder_phys *cur_master;
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -0700213 struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800214 struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400215
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500216 bool intfs_swapped;
217
Lloyd Atkinson5d722782016-05-30 14:09:41 -0400218 void (*crtc_vblank_cb)(void *);
219 void *crtc_vblank_cb_data;
220
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700221 struct dentry *debugfs_root;
222 struct mutex enc_lock;
Alan Kwong628d19e2016-10-31 13:50:13 -0400223 DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
224 void (*crtc_frame_event_cb)(void *, u32 event);
225 void *crtc_frame_event_cb_data;
Alan Kwong628d19e2016-10-31 13:50:13 -0400226
227 atomic_t frame_done_timeout;
228 struct timer_list frame_done_timer;
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400229 struct timer_list vsync_event_timer;
Dhaval Patel020f7e122016-11-15 14:39:18 -0800230
231 struct sde_rsc_client *rsc_client;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700232 bool rsc_state_init;
Dhaval Patel020f7e122016-11-15 14:39:18 -0800233 struct msm_display_info disp_info;
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -0700234 struct msm_mode_info mode_info;
Dhaval Patelf9245d62017-03-28 16:24:00 -0700235 bool misr_enable;
Dhaval Patel010f5172017-08-01 22:40:09 -0700236 u32 misr_frame_count;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -0700237
238 bool idle_pc_supported;
239 struct mutex rc_lock;
240 enum sde_enc_rc_states rc_state;
Lloyd Atkinsona8781382017-07-17 10:20:43 -0400241 struct kthread_delayed_work delayed_off_work;
Benjamin Chan9cd866d2017-08-15 14:56:34 -0400242 struct kthread_work vsync_event_work;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700243 struct msm_display_topology topology;
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -0700244 bool vblank_enabled;
Alan Kwong56f1a942017-04-04 11:53:42 -0700245
Dhaval Patel1b5605b2017-07-26 18:19:50 -0700246 struct sde_rsc_cmd_config rsc_config;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400247 struct sde_rect cur_conn_roi;
248 struct sde_rect prv_conn_roi;
Dhaval Patele17e0ee2017-08-23 18:01:42 -0700249
250 u32 idle_timeout;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400251};
252
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400253#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700254
Lloyd Atkinson094780d2017-04-24 17:25:08 -0400255bool sde_encoder_is_dsc_enabled(struct drm_encoder *drm_enc)
256
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800257{
Lloyd Atkinson094780d2017-04-24 17:25:08 -0400258 struct sde_encoder_virt *sde_enc;
259 struct msm_compression_info *comp_info;
260
261 if (!drm_enc)
262 return false;
263
264 sde_enc = to_sde_encoder_virt(drm_enc);
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -0700265 comp_info = &sde_enc->mode_info.comp_info;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800266
267 return (comp_info->comp_type == MSM_DISPLAY_COMPRESSION_DSC);
268}
269
Dhaval Patele17e0ee2017-08-23 18:01:42 -0700270void sde_encoder_set_idle_timeout(struct drm_encoder *drm_enc, u32 idle_timeout)
271{
272 struct sde_encoder_virt *sde_enc;
273
274 if (!drm_enc)
275 return;
276
277 sde_enc = to_sde_encoder_virt(drm_enc);
278 sde_enc->idle_timeout = idle_timeout;
279}
280
Lloyd Atkinson094780d2017-04-24 17:25:08 -0400281bool sde_encoder_is_dsc_merge(struct drm_encoder *drm_enc)
282{
283 enum sde_rm_topology_name topology;
284 struct sde_encoder_virt *sde_enc;
285 struct drm_connector *drm_conn;
286
287 if (!drm_enc)
288 return false;
289
290 sde_enc = to_sde_encoder_virt(drm_enc);
291 if (!sde_enc->cur_master)
292 return false;
293
294 drm_conn = sde_enc->cur_master->connector;
295 if (!drm_conn)
296 return false;
297
298 topology = sde_connector_get_topology_name(drm_conn);
299 if (topology == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE)
300 return true;
301
302 return false;
303}
304
Dhaval Patelf9245d62017-03-28 16:24:00 -0700305static inline int _sde_encoder_power_enable(struct sde_encoder_virt *sde_enc,
306 bool enable)
307{
308 struct drm_encoder *drm_enc;
309 struct msm_drm_private *priv;
310 struct sde_kms *sde_kms;
311
312 if (!sde_enc) {
313 SDE_ERROR("invalid sde enc\n");
314 return -EINVAL;
315 }
316
317 drm_enc = &sde_enc->base;
318 if (!drm_enc->dev || !drm_enc->dev->dev_private) {
319 SDE_ERROR("drm device invalid\n");
320 return -EINVAL;
321 }
322
323 priv = drm_enc->dev->dev_private;
324 if (!priv->kms) {
325 SDE_ERROR("invalid kms\n");
326 return -EINVAL;
327 }
328
329 sde_kms = to_sde_kms(priv->kms);
330
331 return sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
332 enable);
333}
334
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500335void sde_encoder_helper_report_irq_timeout(struct sde_encoder_phys *phys_enc,
336 enum sde_intr_idx intr_idx)
337{
338 SDE_EVT32(DRMID(phys_enc->parent),
339 phys_enc->intf_idx - INTF_0,
340 phys_enc->hw_pp->idx - PINGPONG_0,
341 intr_idx);
342 SDE_ERROR_PHYS(phys_enc, "irq %d timeout\n", intr_idx);
343
344 if (phys_enc->parent_ops.handle_frame_done)
345 phys_enc->parent_ops.handle_frame_done(
346 phys_enc->parent, phys_enc,
347 SDE_ENCODER_FRAME_EVENT_ERROR);
348}
349
350int sde_encoder_helper_wait_for_irq(struct sde_encoder_phys *phys_enc,
351 enum sde_intr_idx intr_idx,
352 struct sde_encoder_wait_info *wait_info)
353{
354 struct sde_encoder_irq *irq;
355 u32 irq_status;
356 int ret;
357
358 if (!phys_enc || !wait_info || intr_idx >= INTR_IDX_MAX) {
359 SDE_ERROR("invalid params\n");
360 return -EINVAL;
361 }
362 irq = &phys_enc->irq[intr_idx];
363
364 /* note: do master / slave checking outside */
365
366 /* return EWOULDBLOCK since we know the wait isn't necessary */
367 if (phys_enc->enable_state == SDE_ENC_DISABLED) {
368 SDE_ERROR_PHYS(phys_enc, "encoder is disabled\n");
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -0400369 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
370 irq->irq_idx, intr_idx, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500371 return -EWOULDBLOCK;
372 }
373
374 if (irq->irq_idx < 0) {
375 SDE_DEBUG_PHYS(phys_enc, "irq %s hw %d disabled, skip wait\n",
376 irq->name, irq->hw_idx);
377 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
378 irq->irq_idx);
379 return 0;
380 }
381
382 SDE_DEBUG_PHYS(phys_enc, "pending_cnt %d\n",
383 atomic_read(wait_info->atomic_cnt));
Dhaval Patela5f75952017-07-25 11:17:41 -0700384 SDE_EVT32_VERBOSE(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
385 irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
386 atomic_read(wait_info->atomic_cnt), SDE_EVTLOG_FUNC_ENTRY);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500387
388 ret = sde_encoder_helper_wait_event_timeout(
389 DRMID(phys_enc->parent),
390 irq->hw_idx,
391 wait_info);
392
393 if (ret <= 0) {
394 irq_status = sde_core_irq_read(phys_enc->sde_kms,
395 irq->irq_idx, true);
396 if (irq_status) {
397 unsigned long flags;
398
Dhaval Patela5f75952017-07-25 11:17:41 -0700399 SDE_EVT32(DRMID(phys_enc->parent), intr_idx,
400 irq->hw_idx, irq->irq_idx,
401 phys_enc->hw_pp->idx - PINGPONG_0,
402 atomic_read(wait_info->atomic_cnt));
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500403 SDE_DEBUG_PHYS(phys_enc,
404 "done but irq %d not triggered\n",
405 irq->irq_idx);
406 local_irq_save(flags);
407 irq->cb.func(phys_enc, irq->irq_idx);
408 local_irq_restore(flags);
409 ret = 0;
410 } else {
411 ret = -ETIMEDOUT;
Dhaval Patela5f75952017-07-25 11:17:41 -0700412 SDE_EVT32(DRMID(phys_enc->parent), intr_idx,
413 irq->hw_idx, irq->irq_idx,
414 phys_enc->hw_pp->idx - PINGPONG_0,
415 atomic_read(wait_info->atomic_cnt), irq_status,
416 SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500417 }
418 } else {
419 ret = 0;
Dhaval Patela5f75952017-07-25 11:17:41 -0700420 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
421 irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
422 atomic_read(wait_info->atomic_cnt));
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500423 }
424
Dhaval Patela5f75952017-07-25 11:17:41 -0700425 SDE_EVT32_VERBOSE(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
426 irq->irq_idx, ret, phys_enc->hw_pp->idx - PINGPONG_0,
427 atomic_read(wait_info->atomic_cnt), SDE_EVTLOG_FUNC_EXIT);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500428
429 return ret;
430}
431
432int sde_encoder_helper_register_irq(struct sde_encoder_phys *phys_enc,
433 enum sde_intr_idx intr_idx)
434{
435 struct sde_encoder_irq *irq;
436 int ret = 0;
437
438 if (!phys_enc || intr_idx >= INTR_IDX_MAX) {
439 SDE_ERROR("invalid params\n");
440 return -EINVAL;
441 }
442 irq = &phys_enc->irq[intr_idx];
443
444 if (irq->irq_idx >= 0) {
Raviteja Tamatam68892de2017-06-20 04:47:19 +0530445 SDE_DEBUG_PHYS(phys_enc,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500446 "skipping already registered irq %s type %d\n",
447 irq->name, irq->intr_type);
448 return 0;
449 }
450
451 irq->irq_idx = sde_core_irq_idx_lookup(phys_enc->sde_kms,
452 irq->intr_type, irq->hw_idx);
453 if (irq->irq_idx < 0) {
454 SDE_ERROR_PHYS(phys_enc,
455 "failed to lookup IRQ index for %s type:%d\n",
456 irq->name, irq->intr_type);
457 return -EINVAL;
458 }
459
460 ret = sde_core_irq_register_callback(phys_enc->sde_kms, irq->irq_idx,
461 &irq->cb);
462 if (ret) {
463 SDE_ERROR_PHYS(phys_enc,
464 "failed to register IRQ callback for %s\n",
465 irq->name);
466 irq->irq_idx = -EINVAL;
467 return ret;
468 }
469
470 ret = sde_core_irq_enable(phys_enc->sde_kms, &irq->irq_idx, 1);
471 if (ret) {
472 SDE_ERROR_PHYS(phys_enc,
473 "enable IRQ for intr:%s failed, irq_idx %d\n",
474 irq->name, irq->irq_idx);
475
476 sde_core_irq_unregister_callback(phys_enc->sde_kms,
477 irq->irq_idx, &irq->cb);
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400478
479 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
480 irq->irq_idx, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500481 irq->irq_idx = -EINVAL;
482 return ret;
483 }
484
485 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx, irq->irq_idx);
486 SDE_DEBUG_PHYS(phys_enc, "registered irq %s idx: %d\n",
487 irq->name, irq->irq_idx);
488
489 return ret;
490}
491
492int sde_encoder_helper_unregister_irq(struct sde_encoder_phys *phys_enc,
493 enum sde_intr_idx intr_idx)
494{
495 struct sde_encoder_irq *irq;
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400496 int ret;
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500497
498 if (!phys_enc) {
499 SDE_ERROR("invalid encoder\n");
500 return -EINVAL;
501 }
502 irq = &phys_enc->irq[intr_idx];
503
504 /* silently skip irqs that weren't registered */
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400505 if (irq->irq_idx < 0) {
506 SDE_ERROR(
507 "extra unregister irq, enc%d intr_idx:0x%x hw_idx:0x%x irq_idx:0x%x\n",
508 DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
509 irq->irq_idx);
510 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
511 irq->irq_idx, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500512 return 0;
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400513 }
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500514
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400515 ret = sde_core_irq_disable(phys_enc->sde_kms, &irq->irq_idx, 1);
516 if (ret)
517 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
518 irq->irq_idx, ret, SDE_EVTLOG_ERROR);
519
520 ret = sde_core_irq_unregister_callback(phys_enc->sde_kms, irq->irq_idx,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500521 &irq->cb);
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400522 if (ret)
523 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
524 irq->irq_idx, ret, SDE_EVTLOG_ERROR);
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500525
526 SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx, irq->irq_idx);
527 SDE_DEBUG_PHYS(phys_enc, "unregistered %d\n", irq->irq_idx);
528
Lloyd Atkinsonde4270ab2017-06-27 16:43:53 -0400529 irq->irq_idx = -EINVAL;
530
Lloyd Atkinson05ef8232017-03-08 16:35:36 -0500531 return 0;
532}
533
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400534void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc,
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400535 struct sde_encoder_hw_resources *hw_res,
536 struct drm_connector_state *conn_state)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400537{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400538 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400539 int i = 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400540
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400541 if (!hw_res || !drm_enc || !conn_state) {
Clarence Ip19af1362016-09-23 14:57:51 -0400542 SDE_ERROR("invalid argument(s), drm_enc %d, res %d, state %d\n",
543 drm_enc != 0, hw_res != 0, conn_state != 0);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400544 return;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400545 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400546
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400547 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -0400548 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400549
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400550 /* Query resources used by phys encs, expected to be without overlap */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400551 memset(hw_res, 0, sizeof(*hw_res));
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400552 hw_res->display_num_of_h_tiles = sde_enc->display_num_of_h_tiles;
553
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400554 for (i = 0; i < sde_enc->num_phys_encs; i++) {
555 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
556
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400557 if (phys && phys->ops.get_hw_resources)
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400558 phys->ops.get_hw_resources(phys, hw_res, conn_state);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400559 }
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700560
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -0700561 hw_res->topology = sde_enc->mode_info.topology;
Jeykumar Sankaran6f215d42017-09-12 16:15:23 -0700562 hw_res->is_primary = sde_enc->disp_info.is_primary;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400563}
564
Clarence Ip3649f8b2016-10-31 09:59:44 -0400565void sde_encoder_destroy(struct drm_encoder *drm_enc)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400566{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400567 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400568 int i = 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400569
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400570 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -0400571 SDE_ERROR("invalid encoder\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400572 return;
573 }
574
575 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -0400576 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -0400577
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700578 mutex_lock(&sde_enc->enc_lock);
Dhaval Patel020f7e122016-11-15 14:39:18 -0800579 sde_rsc_client_destroy(sde_enc->rsc_client);
580
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700581 for (i = 0; i < sde_enc->num_phys_encs; i++) {
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400582 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
583
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -0400584 if (phys && phys->ops.destroy) {
585 phys->ops.destroy(phys);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400586 --sde_enc->num_phys_encs;
587 sde_enc->phys_encs[i] = NULL;
588 }
589 }
590
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700591 if (sde_enc->num_phys_encs)
Clarence Ip19af1362016-09-23 14:57:51 -0400592 SDE_ERROR_ENC(sde_enc, "expected 0 num_phys_encs not %d\n",
Abhijit Kulkarni40e38162016-06-26 22:12:09 -0400593 sde_enc->num_phys_encs);
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700594 sde_enc->num_phys_encs = 0;
595 mutex_unlock(&sde_enc->enc_lock);
Lloyd Atkinson09fed912016-06-24 18:14:13 -0400596
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400597 drm_encoder_cleanup(drm_enc);
Dhaval Patel22ef6df2016-10-20 14:42:52 -0700598 mutex_destroy(&sde_enc->enc_lock);
599
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400600 kfree(sde_enc);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700601}
602
Clarence Ip8e69ad02016-12-09 09:43:57 -0500603void sde_encoder_helper_split_config(
604 struct sde_encoder_phys *phys_enc,
605 enum sde_intf interface)
606{
607 struct sde_encoder_virt *sde_enc;
608 struct split_pipe_cfg cfg = { 0 };
609 struct sde_hw_mdp *hw_mdptop;
610 enum sde_rm_topology_name topology;
Dhaval Patel5cd59a02017-06-13 16:29:40 -0700611 struct msm_display_info *disp_info;
Clarence Ip8e69ad02016-12-09 09:43:57 -0500612
613 if (!phys_enc || !phys_enc->hw_mdptop || !phys_enc->parent) {
614 SDE_ERROR("invalid arg(s), encoder %d\n", phys_enc != 0);
615 return;
616 }
617
618 sde_enc = to_sde_encoder_virt(phys_enc->parent);
619 hw_mdptop = phys_enc->hw_mdptop;
Dhaval Patel5cd59a02017-06-13 16:29:40 -0700620 disp_info = &sde_enc->disp_info;
621
622 if (disp_info->intf_type != DRM_MODE_CONNECTOR_DSI)
623 return;
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500624
625 /**
626 * disable split modes since encoder will be operating in as the only
627 * encoder, either for the entire use case in the case of, for example,
628 * single DSI, or for this frame in the case of left/right only partial
629 * update.
630 */
631 if (phys_enc->split_role == ENC_ROLE_SOLO) {
632 if (hw_mdptop->ops.setup_split_pipe)
633 hw_mdptop->ops.setup_split_pipe(hw_mdptop, &cfg);
634 if (hw_mdptop->ops.setup_pp_split)
635 hw_mdptop->ops.setup_pp_split(hw_mdptop, &cfg);
636 return;
637 }
638
639 cfg.en = true;
Clarence Ip8e69ad02016-12-09 09:43:57 -0500640 cfg.mode = phys_enc->intf_mode;
641 cfg.intf = interface;
642
643 if (cfg.en && phys_enc->ops.needs_single_flush &&
644 phys_enc->ops.needs_single_flush(phys_enc))
645 cfg.split_flush_en = true;
646
647 topology = sde_connector_get_topology_name(phys_enc->connector);
648 if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
649 cfg.pp_split_slave = cfg.intf;
650 else
651 cfg.pp_split_slave = INTF_MAX;
652
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -0500653 if (phys_enc->split_role == ENC_ROLE_MASTER) {
Clarence Ip8e69ad02016-12-09 09:43:57 -0500654 SDE_DEBUG_ENC(sde_enc, "enable %d\n", cfg.en);
655
656 if (hw_mdptop->ops.setup_split_pipe)
657 hw_mdptop->ops.setup_split_pipe(hw_mdptop, &cfg);
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -0400658 } else if (sde_enc->hw_pp[0]) {
Clarence Ip8e69ad02016-12-09 09:43:57 -0500659 /*
660 * slave encoder
661 * - determine split index from master index,
662 * assume master is first pp
663 */
664 cfg.pp_split_index = sde_enc->hw_pp[0]->idx - PINGPONG_0;
665 SDE_DEBUG_ENC(sde_enc, "master using pp%d\n",
666 cfg.pp_split_index);
667
668 if (hw_mdptop->ops.setup_pp_split)
669 hw_mdptop->ops.setup_pp_split(hw_mdptop, &cfg);
670 }
671}
672
Jeykumar Sankaraneb49ff32017-04-12 16:33:25 -0700673static void _sde_encoder_adjust_mode(struct drm_connector *connector,
674 struct drm_display_mode *adj_mode)
675{
676 struct drm_display_mode *cur_mode;
677
678 if (!connector || !adj_mode)
679 return;
680
681 list_for_each_entry(cur_mode, &connector->modes, head) {
682 if (cur_mode->vdisplay == adj_mode->vdisplay &&
683 cur_mode->hdisplay == adj_mode->hdisplay &&
684 cur_mode->vrefresh == adj_mode->vrefresh) {
685 adj_mode->private = cur_mode->private;
Jeykumar Sankaran69934622017-05-31 18:16:25 -0700686 adj_mode->private_flags |= cur_mode->private_flags;
Jeykumar Sankaraneb49ff32017-04-12 16:33:25 -0700687 }
688 }
689}
690
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400691static int sde_encoder_virt_atomic_check(
692 struct drm_encoder *drm_enc,
693 struct drm_crtc_state *crtc_state,
694 struct drm_connector_state *conn_state)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400695{
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400696 struct sde_encoder_virt *sde_enc;
697 struct msm_drm_private *priv;
698 struct sde_kms *sde_kms;
Alan Kwongbb27c092016-07-20 16:41:25 -0400699 const struct drm_display_mode *mode;
700 struct drm_display_mode *adj_mode;
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700701 struct sde_connector *sde_conn = NULL;
Alan Kwongbb27c092016-07-20 16:41:25 -0400702 int i = 0;
703 int ret = 0;
704
Alan Kwongbb27c092016-07-20 16:41:25 -0400705 if (!drm_enc || !crtc_state || !conn_state) {
Clarence Ip19af1362016-09-23 14:57:51 -0400706 SDE_ERROR("invalid arg(s), drm_enc %d, crtc/conn state %d/%d\n",
707 drm_enc != 0, crtc_state != 0, conn_state != 0);
Alan Kwongbb27c092016-07-20 16:41:25 -0400708 return -EINVAL;
709 }
710
711 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -0400712 SDE_DEBUG_ENC(sde_enc, "\n");
713
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400714 priv = drm_enc->dev->dev_private;
715 sde_kms = to_sde_kms(priv->kms);
Alan Kwongbb27c092016-07-20 16:41:25 -0400716 mode = &crtc_state->mode;
717 adj_mode = &crtc_state->adjusted_mode;
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700718 sde_conn = to_sde_connector(conn_state->connector);
Lloyd Atkinson5d40d312016-09-06 08:34:13 -0400719 SDE_EVT32(DRMID(drm_enc));
Alan Kwongbb27c092016-07-20 16:41:25 -0400720
Jeykumar Sankaraneb49ff32017-04-12 16:33:25 -0700721 /*
722 * display drivers may populate private fields of the drm display mode
723 * structure while registering possible modes of a connector with DRM.
724 * These private fields are not populated back while DRM invokes
725 * the mode_set callbacks. This module retrieves and populates the
726 * private fields of the given mode.
727 */
728 _sde_encoder_adjust_mode(conn_state->connector, adj_mode);
729
Alan Kwongbb27c092016-07-20 16:41:25 -0400730 /* perform atomic check on the first physical encoder (master) */
731 for (i = 0; i < sde_enc->num_phys_encs; i++) {
732 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
733
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400734 if (phys && phys->ops.atomic_check)
Alan Kwongbb27c092016-07-20 16:41:25 -0400735 ret = phys->ops.atomic_check(phys, crtc_state,
736 conn_state);
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400737 else if (phys && phys->ops.mode_fixup)
738 if (!phys->ops.mode_fixup(phys, mode, adj_mode))
Alan Kwongbb27c092016-07-20 16:41:25 -0400739 ret = -EINVAL;
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400740
741 if (ret) {
Clarence Ip19af1362016-09-23 14:57:51 -0400742 SDE_ERROR_ENC(sde_enc,
743 "mode unsupported, phys idx %d\n", i);
Alan Kwongbb27c092016-07-20 16:41:25 -0400744 break;
745 }
746 }
747
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700748
749 if (!ret && sde_conn && drm_atomic_crtc_needs_modeset(crtc_state)) {
750 struct msm_display_topology *topology = NULL;
751
752 ret = sde_conn->ops.get_mode_info(adj_mode,
753 &sde_enc->mode_info,
Alan Kwongb1bca602017-09-18 17:28:45 -0400754 sde_kms->catalog->max_mixer_width,
755 sde_conn->display);
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700756 if (ret) {
757 SDE_ERROR_ENC(sde_enc,
758 "failed to get mode info, rc = %d\n", ret);
759 return ret;
760 }
761
762 /* Reserve dynamic resources, indicating atomic_check phase */
763 ret = sde_rm_reserve(&sde_kms->rm, drm_enc, crtc_state,
764 conn_state, true);
765 if (ret) {
766 SDE_ERROR_ENC(sde_enc,
767 "RM failed to reserve resources, rc = %d\n",
768 ret);
769 return ret;
770 }
771
772 /**
773 * Update connector state with the topology selected for the
774 * resource set validated. Reset the topology if we are
775 * de-activating crtc.
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700776 */
Jeykumar Sankaran586d0922017-09-18 15:01:33 -0700777 if (crtc_state->active)
778 topology = &sde_enc->mode_info.topology;
779
780 ret = sde_rm_update_topology(conn_state, topology);
781 if (ret) {
782 SDE_ERROR_ENC(sde_enc,
783 "RM failed to update topology, rc: %d\n", ret);
784 return ret;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -0700785 }
786 }
Lloyd Atkinson11f34442016-08-11 11:19:52 -0400787
Gopikrishnaiah Anandan703eb902016-10-06 18:43:57 -0700788 if (!ret)
Gopikrishnaiah Anandane0e5e0c2016-05-25 11:05:33 -0700789 drm_mode_set_crtcinfo(adj_mode, 0);
Alan Kwongbb27c092016-07-20 16:41:25 -0400790
Lloyd Atkinson5d40d312016-09-06 08:34:13 -0400791 SDE_EVT32(DRMID(drm_enc), adj_mode->flags, adj_mode->private_flags);
Alan Kwongbb27c092016-07-20 16:41:25 -0400792
793 return ret;
794}
795
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800796static int _sde_encoder_dsc_update_pic_dim(struct msm_display_dsc_info *dsc,
797 int pic_width, int pic_height)
798{
799 if (!dsc || !pic_width || !pic_height) {
800 SDE_ERROR("invalid input: pic_width=%d pic_height=%d\n",
801 pic_width, pic_height);
802 return -EINVAL;
803 }
804
805 if ((pic_width % dsc->slice_width) ||
806 (pic_height % dsc->slice_height)) {
807 SDE_ERROR("pic_dim=%dx%d has to be multiple of slice=%dx%d\n",
808 pic_width, pic_height,
809 dsc->slice_width, dsc->slice_height);
810 return -EINVAL;
811 }
812
813 dsc->pic_width = pic_width;
814 dsc->pic_height = pic_height;
815
816 return 0;
817}
818
819static void _sde_encoder_dsc_pclk_param_calc(struct msm_display_dsc_info *dsc,
820 int intf_width)
821{
822 int slice_per_pkt, slice_per_intf;
823 int bytes_in_slice, total_bytes_per_intf;
824
825 if (!dsc || !dsc->slice_width || !dsc->slice_per_pkt ||
826 (intf_width < dsc->slice_width)) {
827 SDE_ERROR("invalid input: intf_width=%d slice_width=%d\n",
828 intf_width, dsc ? dsc->slice_width : -1);
829 return;
830 }
831
832 slice_per_pkt = dsc->slice_per_pkt;
833 slice_per_intf = DIV_ROUND_UP(intf_width, dsc->slice_width);
834
835 /*
836 * If slice_per_pkt is greater than slice_per_intf then default to 1.
837 * This can happen during partial update.
838 */
839 if (slice_per_pkt > slice_per_intf)
840 slice_per_pkt = 1;
841
842 bytes_in_slice = DIV_ROUND_UP(dsc->slice_width * dsc->bpp, 8);
843 total_bytes_per_intf = bytes_in_slice * slice_per_intf;
844
845 dsc->eol_byte_num = total_bytes_per_intf % 3;
846 dsc->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3);
847 dsc->bytes_in_slice = bytes_in_slice;
848 dsc->bytes_per_pkt = bytes_in_slice * slice_per_pkt;
849 dsc->pkt_per_line = slice_per_intf / slice_per_pkt;
850}
851
852static int _sde_encoder_dsc_initial_line_calc(struct msm_display_dsc_info *dsc,
853 int enc_ip_width)
854{
855 int ssm_delay, total_pixels, soft_slice_per_enc;
856
857 soft_slice_per_enc = enc_ip_width / dsc->slice_width;
858
859 /*
860 * minimum number of initial line pixels is a sum of:
861 * 1. sub-stream multiplexer delay (83 groups for 8bpc,
862 * 91 for 10 bpc) * 3
863 * 2. for two soft slice cases, add extra sub-stream multiplexer * 3
864 * 3. the initial xmit delay
865 * 4. total pipeline delay through the "lock step" of encoder (47)
866 * 5. 6 additional pixels as the output of the rate buffer is
867 * 48 bits wide
868 */
869 ssm_delay = ((dsc->bpc < 10) ? 84 : 92);
870 total_pixels = ssm_delay * 3 + dsc->initial_xmit_delay + 47;
871 if (soft_slice_per_enc > 1)
872 total_pixels += (ssm_delay * 3);
873 dsc->initial_lines = DIV_ROUND_UP(total_pixels, dsc->slice_width);
874 return 0;
875}
876
877static bool _sde_encoder_dsc_ich_reset_override_needed(bool pu_en,
878 struct msm_display_dsc_info *dsc)
879{
880 /*
881 * As per the DSC spec, ICH_RESET can be either end of the slice line
882 * or at the end of the slice. HW internally generates ich_reset at
883 * end of the slice line if DSC_MERGE is used or encoder has two
884 * soft slices. However, if encoder has only 1 soft slice and DSC_MERGE
885 * is not used then it will generate ich_reset at the end of slice.
886 *
887 * Now as per the spec, during one PPS session, position where
888 * ich_reset is generated should not change. Now if full-screen frame
889 * has more than 1 soft slice then HW will automatically generate
890 * ich_reset at the end of slice_line. But for the same panel, if
891 * partial frame is enabled and only 1 encoder is used with 1 slice,
892 * then HW will generate ich_reset at end of the slice. This is a
893 * mismatch. Prevent this by overriding HW's decision.
894 */
895 return pu_en && dsc && (dsc->full_frame_slices > 1) &&
896 (dsc->slice_width == dsc->pic_width);
897}
898
899static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc,
900 struct sde_hw_pingpong *hw_pp, struct msm_display_dsc_info *dsc,
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400901 u32 common_mode, bool ich_reset, bool enable)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800902{
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400903 if (!enable) {
904 if (hw_pp->ops.disable_dsc)
905 hw_pp->ops.disable_dsc(hw_pp);
906 return;
907 }
908
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800909 if (hw_dsc->ops.dsc_config)
910 hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, ich_reset);
911
912 if (hw_dsc->ops.dsc_config_thresh)
913 hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc);
914
915 if (hw_pp->ops.setup_dsc)
916 hw_pp->ops.setup_dsc(hw_pp);
917
918 if (hw_pp->ops.enable_dsc)
919 hw_pp->ops.enable_dsc(hw_pp);
920}
921
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400922static void _sde_encoder_get_connector_roi(
923 struct sde_encoder_virt *sde_enc,
924 struct sde_rect *merged_conn_roi)
925{
926 struct drm_connector *drm_conn;
927 struct sde_connector_state *c_state;
928
929 if (!sde_enc || !merged_conn_roi)
930 return;
931
932 drm_conn = sde_enc->phys_encs[0]->connector;
933
934 if (!drm_conn || !drm_conn->state)
935 return;
936
937 c_state = to_sde_connector_state(drm_conn->state);
938 sde_kms_rect_merge_rectangles(&c_state->rois, merged_conn_roi);
939}
940
Ingrid Gallardo83532222017-06-02 16:48:51 -0700941static int _sde_encoder_dsc_n_lm_1_enc_1_intf(struct sde_encoder_virt *sde_enc)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800942{
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800943 int this_frame_slices;
944 int intf_ip_w, enc_ip_w;
945 int ich_res, dsc_common_mode = 0;
946
947 struct sde_hw_pingpong *hw_pp = sde_enc->hw_pp[0];
948 struct sde_hw_dsc *hw_dsc = sde_enc->hw_dsc[0];
949 struct sde_encoder_phys *enc_master = sde_enc->cur_master;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400950 const struct sde_rect *roi = &sde_enc->cur_conn_roi;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800951 struct msm_display_dsc_info *dsc =
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -0700952 &sde_enc->mode_info.comp_info.dsc_info;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800953
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400954 if (dsc == NULL || hw_dsc == NULL || hw_pp == NULL || !enc_master) {
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800955 SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
956 return -EINVAL;
957 }
958
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400959 _sde_encoder_dsc_update_pic_dim(dsc, roi->w, roi->h);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800960
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400961 this_frame_slices = roi->w / dsc->slice_width;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800962 intf_ip_w = this_frame_slices * dsc->slice_width;
963 _sde_encoder_dsc_pclk_param_calc(dsc, intf_ip_w);
964
965 enc_ip_w = intf_ip_w;
966 _sde_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
967
968 ich_res = _sde_encoder_dsc_ich_reset_override_needed(false, dsc);
969
970 if (enc_master->intf_mode == INTF_MODE_VIDEO)
971 dsc_common_mode = DSC_MODE_VIDEO;
972
973 SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n",
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400974 roi->w, roi->h, dsc_common_mode);
975 SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800976
977 _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode,
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400978 ich_res, true);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800979
980 return 0;
981}
Ingrid Gallardo83532222017-06-02 16:48:51 -0700982
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400983static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc,
984 struct sde_encoder_kickoff_params *params)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800985{
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800986 int this_frame_slices;
987 int intf_ip_w, enc_ip_w;
988 int ich_res, dsc_common_mode;
989
990 struct sde_encoder_phys *enc_master = sde_enc->cur_master;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400991 const struct sde_rect *roi = &sde_enc->cur_conn_roi;
992 struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
993 struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
994 struct msm_display_dsc_info dsc[MAX_CHANNELS_PER_ENC];
995 bool half_panel_partial_update;
996 int i;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -0800997
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -0400998 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
999 hw_pp[i] = sde_enc->hw_pp[i];
1000 hw_dsc[i] = sde_enc->hw_dsc[i];
1001
1002 if (!hw_pp[i] || !hw_dsc[i]) {
1003 SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
1004 return -EINVAL;
1005 }
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001006 }
1007
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001008 half_panel_partial_update =
1009 hweight_long(params->affected_displays) == 1;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001010
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001011 dsc_common_mode = 0;
1012 if (!half_panel_partial_update)
1013 dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001014 if (enc_master->intf_mode == INTF_MODE_VIDEO)
1015 dsc_common_mode |= DSC_MODE_VIDEO;
1016
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001017 memcpy(&dsc[0], &sde_enc->mode_info.comp_info.dsc_info, sizeof(dsc[0]));
1018 memcpy(&dsc[1], &sde_enc->mode_info.comp_info.dsc_info, sizeof(dsc[1]));
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001019
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001020 /*
1021 * Since both DSC use same pic dimension, set same pic dimension
1022 * to both DSC structures.
1023 */
1024 _sde_encoder_dsc_update_pic_dim(&dsc[0], roi->w, roi->h);
1025 _sde_encoder_dsc_update_pic_dim(&dsc[1], roi->w, roi->h);
1026
1027 this_frame_slices = roi->w / dsc[0].slice_width;
1028 intf_ip_w = this_frame_slices * dsc[0].slice_width;
1029
1030 if (!half_panel_partial_update)
1031 intf_ip_w /= 2;
1032
1033 /*
1034 * In this topology when both interfaces are active, they have same
1035 * load so intf_ip_w will be same.
1036 */
1037 _sde_encoder_dsc_pclk_param_calc(&dsc[0], intf_ip_w);
1038 _sde_encoder_dsc_pclk_param_calc(&dsc[1], intf_ip_w);
1039
1040 /*
1041 * In this topology, since there is no dsc_merge, uncompressed input
1042 * to encoder and interface is same.
1043 */
1044 enc_ip_w = intf_ip_w;
1045 _sde_encoder_dsc_initial_line_calc(&dsc[0], enc_ip_w);
1046 _sde_encoder_dsc_initial_line_calc(&dsc[1], enc_ip_w);
1047
1048 /*
1049 * __is_ich_reset_override_needed should be called only after
1050 * updating pic dimension, mdss_panel_dsc_update_pic_dim.
1051 */
1052 ich_res = _sde_encoder_dsc_ich_reset_override_needed(
1053 half_panel_partial_update, &dsc[0]);
1054
1055 SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n",
1056 roi->w, roi->h, dsc_common_mode);
1057
1058 for (i = 0; i < sde_enc->num_phys_encs; i++) {
1059 bool active = !!((1 << i) & params->affected_displays);
1060
1061 SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h,
1062 dsc_common_mode, i, active);
1063 _sde_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], &dsc[i],
1064 dsc_common_mode, ich_res, active);
1065 }
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001066
1067 return 0;
1068}
1069
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001070static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc,
1071 struct sde_encoder_kickoff_params *params)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001072{
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001073 int this_frame_slices;
1074 int intf_ip_w, enc_ip_w;
1075 int ich_res, dsc_common_mode;
1076
1077 struct sde_encoder_phys *enc_master = sde_enc->cur_master;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001078 const struct sde_rect *roi = &sde_enc->cur_conn_roi;
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001079 struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
1080 struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001081 struct msm_display_dsc_info *dsc =
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001082 &sde_enc->mode_info.comp_info.dsc_info;
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001083 bool half_panel_partial_update;
1084 int i;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001085
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001086 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
1087 hw_pp[i] = sde_enc->hw_pp[i];
1088 hw_dsc[i] = sde_enc->hw_dsc[i];
1089
1090 if (!hw_pp[i] || !hw_dsc[i]) {
1091 SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
1092 return -EINVAL;
1093 }
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001094 }
1095
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001096 half_panel_partial_update =
1097 hweight_long(params->affected_displays) == 1;
1098
1099 dsc_common_mode = 0;
1100 if (!half_panel_partial_update)
1101 dsc_common_mode |= DSC_MODE_SPLIT_PANEL | DSC_MODE_MULTIPLEX;
1102 if (enc_master->intf_mode == INTF_MODE_VIDEO)
1103 dsc_common_mode |= DSC_MODE_VIDEO;
1104
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001105 _sde_encoder_dsc_update_pic_dim(dsc, roi->w, roi->h);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001106
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001107 this_frame_slices = roi->w / dsc->slice_width;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001108 intf_ip_w = this_frame_slices * dsc->slice_width;
1109 _sde_encoder_dsc_pclk_param_calc(dsc, intf_ip_w);
1110
1111 /*
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001112 * dsc merge case: when using 2 encoders for the same stream,
1113 * no. of slices need to be same on both the encoders.
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001114 */
1115 enc_ip_w = intf_ip_w / 2;
1116 _sde_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
1117
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001118 ich_res = _sde_encoder_dsc_ich_reset_override_needed(
1119 half_panel_partial_update, dsc);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001120
1121 SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n",
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001122 roi->w, roi->h, dsc_common_mode);
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001123 SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h,
1124 dsc_common_mode, i, params->affected_displays);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001125
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001126 _sde_encoder_dsc_pipe_cfg(hw_dsc[0], hw_pp[0], dsc, dsc_common_mode,
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001127 ich_res, true);
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001128 _sde_encoder_dsc_pipe_cfg(hw_dsc[1], hw_pp[1], dsc, dsc_common_mode,
1129 ich_res, !half_panel_partial_update);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001130
1131 return 0;
1132}
1133
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001134static int _sde_encoder_update_roi(struct drm_encoder *drm_enc)
1135{
1136 struct sde_encoder_virt *sde_enc;
1137 struct drm_connector *drm_conn;
1138 struct drm_display_mode *adj_mode;
1139 struct sde_rect roi;
1140
1141 if (!drm_enc || !drm_enc->crtc || !drm_enc->crtc->state)
1142 return -EINVAL;
1143 sde_enc = to_sde_encoder_virt(drm_enc);
1144
1145 if (!sde_enc->cur_master)
1146 return -EINVAL;
1147
1148 adj_mode = &sde_enc->base.crtc->state->adjusted_mode;
1149 drm_conn = sde_enc->cur_master->connector;
1150
1151 _sde_encoder_get_connector_roi(sde_enc, &roi);
1152 if (sde_kms_rect_is_null(&roi)) {
1153 roi.w = adj_mode->hdisplay;
1154 roi.h = adj_mode->vdisplay;
1155 }
1156
1157 memcpy(&sde_enc->prv_conn_roi, &sde_enc->cur_conn_roi,
1158 sizeof(sde_enc->prv_conn_roi));
1159 memcpy(&sde_enc->cur_conn_roi, &roi, sizeof(sde_enc->cur_conn_roi));
1160
1161 return 0;
1162}
1163
1164static int _sde_encoder_dsc_setup(struct sde_encoder_virt *sde_enc,
1165 struct sde_encoder_kickoff_params *params)
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001166{
1167 enum sde_rm_topology_name topology;
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001168 struct drm_connector *drm_conn;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001169 int ret = 0;
1170
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001171 if (!sde_enc || !params || !sde_enc->phys_encs[0] ||
1172 !sde_enc->phys_encs[0]->connector)
1173 return -EINVAL;
1174
1175 drm_conn = sde_enc->phys_encs[0]->connector;
1176
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001177 topology = sde_connector_get_topology_name(drm_conn);
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001178 if (topology == SDE_RM_TOPOLOGY_NONE) {
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001179 SDE_ERROR_ENC(sde_enc, "topology not set yet\n");
1180 return -EINVAL;
1181 }
1182
Ingrid Gallardo83532222017-06-02 16:48:51 -07001183 SDE_DEBUG_ENC(sde_enc, "topology:%d\n", topology);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001184 SDE_EVT32(DRMID(&sde_enc->base));
1185
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001186 if (sde_kms_rect_is_equal(&sde_enc->cur_conn_roi,
1187 &sde_enc->prv_conn_roi))
1188 return ret;
1189
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001190 switch (topology) {
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001191 case SDE_RM_TOPOLOGY_SINGLEPIPE_DSC:
Ingrid Gallardo83532222017-06-02 16:48:51 -07001192 case SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC:
1193 ret = _sde_encoder_dsc_n_lm_1_enc_1_intf(sde_enc);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001194 break;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001195 case SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE:
Lloyd Atkinson094780d2017-04-24 17:25:08 -04001196 ret = _sde_encoder_dsc_2_lm_2_enc_1_intf(sde_enc, params);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001197 break;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001198 case SDE_RM_TOPOLOGY_DUALPIPE_DSC:
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04001199 ret = _sde_encoder_dsc_2_lm_2_enc_2_intf(sde_enc, params);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001200 break;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001201 default:
1202 SDE_ERROR_ENC(sde_enc, "No DSC support for topology %d",
1203 topology);
1204 return -EINVAL;
1205 };
1206
1207 return ret;
1208}
1209
Dhaval Patelaab9b522017-07-20 12:38:46 -07001210static void _sde_encoder_update_vsync_source(struct sde_encoder_virt *sde_enc,
1211 struct msm_display_info *disp_info, bool is_dummy)
1212{
1213 struct sde_vsync_source_cfg vsync_cfg = { 0 };
1214 struct msm_drm_private *priv;
1215 struct sde_kms *sde_kms;
1216 struct sde_hw_mdp *hw_mdptop;
1217 struct drm_encoder *drm_enc;
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001218 struct msm_mode_info *mode_info;
Dhaval Patelaab9b522017-07-20 12:38:46 -07001219 int i;
1220
1221 if (!sde_enc || !disp_info) {
1222 SDE_ERROR("invalid param sde_enc:%d or disp_info:%d\n",
1223 sde_enc != NULL, disp_info != NULL);
1224 return;
1225 } else if (sde_enc->num_phys_encs > ARRAY_SIZE(sde_enc->hw_pp)) {
1226 SDE_ERROR("invalid num phys enc %d/%d\n",
1227 sde_enc->num_phys_encs,
1228 (int) ARRAY_SIZE(sde_enc->hw_pp));
1229 return;
1230 }
1231
1232 drm_enc = &sde_enc->base;
1233 /* this pointers are checked in virt_enable_helper */
1234 priv = drm_enc->dev->dev_private;
1235
1236 sde_kms = to_sde_kms(priv->kms);
1237 if (!sde_kms) {
1238 SDE_ERROR("invalid sde_kms\n");
1239 return;
1240 }
1241
1242 hw_mdptop = sde_kms->hw_mdp;
1243 if (!hw_mdptop) {
1244 SDE_ERROR("invalid mdptop\n");
1245 return;
1246 }
1247
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001248 mode_info = &sde_enc->mode_info;
1249 if (!mode_info) {
1250 SDE_ERROR("invalid mode info\n");
1251 return;
1252 }
1253
Dhaval Patelaab9b522017-07-20 12:38:46 -07001254 if (hw_mdptop->ops.setup_vsync_source &&
1255 disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) {
1256 for (i = 0; i < sde_enc->num_phys_encs; i++)
1257 vsync_cfg.ppnumber[i] = sde_enc->hw_pp[i]->idx;
1258
1259 vsync_cfg.pp_count = sde_enc->num_phys_encs;
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001260 vsync_cfg.frame_rate = mode_info->frame_rate;
Dhaval Patelaab9b522017-07-20 12:38:46 -07001261 if (is_dummy)
1262 vsync_cfg.vsync_source = SDE_VSYNC_SOURCE_WD_TIMER_1;
1263 else if (disp_info->is_te_using_watchdog_timer)
1264 vsync_cfg.vsync_source = SDE_VSYNC_SOURCE_WD_TIMER_0;
1265 else
1266 vsync_cfg.vsync_source = SDE_VSYNC0_SOURCE_GPIO;
1267 vsync_cfg.is_dummy = is_dummy;
1268
1269 hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
1270 }
1271}
1272
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001273static int _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc)
1274{
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001275 int i, ret = 0;
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001276 struct sde_hw_pingpong *hw_pp = NULL;
1277 struct sde_hw_dsc *hw_dsc = NULL;
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001278
1279 if (!sde_enc || !sde_enc->phys_encs[0] ||
1280 !sde_enc->phys_encs[0]->connector) {
1281 SDE_ERROR("invalid params %d %d\n",
1282 !sde_enc, sde_enc ? !sde_enc->phys_encs[0] : -1);
1283 return -EINVAL;
1284 }
1285
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001286 /* Disable DSC for all the pp's present in this topology */
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001287 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
1288 hw_pp = sde_enc->hw_pp[i];
1289 hw_dsc = sde_enc->hw_dsc[i];
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001290
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001291 if (hw_pp && hw_pp->ops.disable_dsc)
1292 hw_pp->ops.disable_dsc(hw_pp);
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001293
Jeykumar Sankaran586d0922017-09-18 15:01:33 -07001294 if (hw_dsc && hw_dsc->ops.dsc_disable)
1295 hw_dsc->ops.dsc_disable(hw_dsc);
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001296 }
1297
1298 return ret;
1299}
1300
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001301static int _sde_encoder_update_rsc_client(
Alan Kwong56f1a942017-04-04 11:53:42 -07001302 struct drm_encoder *drm_enc,
1303 struct sde_encoder_rsc_config *config, bool enable)
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001304{
1305 struct sde_encoder_virt *sde_enc;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001306 struct drm_crtc *crtc;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001307 enum sde_rsc_state rsc_state;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001308 struct sde_rsc_cmd_config *rsc_config;
1309 int ret, prefill_lines;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001310 struct msm_display_info *disp_info;
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001311 struct msm_mode_info *mode_info;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001312 int wait_vblank_crtc_id = SDE_RSC_INVALID_CRTC_ID;
1313 int wait_count = 0;
1314 struct drm_crtc *primary_crtc;
1315 int pipe = -1;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001316
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001317 if (!drm_enc || !drm_enc->crtc || !drm_enc->dev) {
1318 SDE_ERROR("invalid arguments\n");
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001319 return -EINVAL;
1320 }
1321
1322 sde_enc = to_sde_encoder_virt(drm_enc);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001323 crtc = drm_enc->crtc;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001324 disp_info = &sde_enc->disp_info;
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001325 mode_info = &sde_enc->mode_info;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001326 rsc_config = &sde_enc->rsc_config;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001327
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001328 if (!sde_enc->rsc_client) {
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001329 SDE_DEBUG_ENC(sde_enc, "rsc client not created\n");
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001330 return 0;
1331 }
1332
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001333 /**
1334 * only primary command mode panel can request CMD state.
1335 * all other panels/displays can request for VID state including
1336 * secondary command mode panel.
1337 */
1338 rsc_state = enable ?
1339 (((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) &&
1340 disp_info->is_primary) ? SDE_RSC_CMD_STATE :
1341 SDE_RSC_VID_STATE) : SDE_RSC_IDLE_STATE;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001342 prefill_lines = config ? mode_info->prefill_lines +
1343 config->inline_rotate_prefill : mode_info->prefill_lines;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001344
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001345 /* compare specific items and reconfigure the rsc */
1346 if ((rsc_config->fps != mode_info->frame_rate) ||
1347 (rsc_config->vtotal != mode_info->vtotal) ||
1348 (rsc_config->prefill_lines != prefill_lines) ||
1349 (rsc_config->jitter_numer != mode_info->jitter_numer) ||
1350 (rsc_config->jitter_denom != mode_info->jitter_denom)) {
1351 rsc_config->fps = mode_info->frame_rate;
1352 rsc_config->vtotal = mode_info->vtotal;
1353 rsc_config->prefill_lines = prefill_lines;
1354 rsc_config->jitter_numer = mode_info->jitter_numer;
1355 rsc_config->jitter_denom = mode_info->jitter_denom;
Alan Kwong56f1a942017-04-04 11:53:42 -07001356 sde_enc->rsc_state_init = false;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001357 }
Alan Kwong56f1a942017-04-04 11:53:42 -07001358
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001359 if (rsc_state != SDE_RSC_IDLE_STATE && !sde_enc->rsc_state_init
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001360 && disp_info->is_primary) {
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001361 /* update it only once */
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001362 sde_enc->rsc_state_init = true;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001363
1364 ret = sde_rsc_client_state_update(sde_enc->rsc_client,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001365 rsc_state, rsc_config, crtc->base.id,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001366 &wait_vblank_crtc_id);
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001367 } else {
1368 ret = sde_rsc_client_state_update(sde_enc->rsc_client,
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001369 rsc_state, NULL, crtc->base.id,
1370 &wait_vblank_crtc_id);
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001371 }
1372
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001373 /**
1374 * if RSC performed a state change that requires a VBLANK wait, it will
1375 * set wait_vblank_crtc_id to the CRTC whose VBLANK we must wait on.
1376 *
1377 * if we are the primary display, we will need to enable and wait
1378 * locally since we hold the commit thread
1379 *
1380 * if we are an external display, we must send a signal to the primary
1381 * to enable its VBLANK and wait one, since the RSC hardware is driven
1382 * by the primary panel's VBLANK signals
1383 */
1384 SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id);
1385 if (ret) {
1386 SDE_ERROR_ENC(sde_enc,
1387 "sde rsc client update failed ret:%d\n", ret);
1388 return ret;
1389 } else if (wait_vblank_crtc_id == SDE_RSC_INVALID_CRTC_ID) {
1390 return ret;
1391 }
1392
1393 if (crtc->base.id != wait_vblank_crtc_id) {
1394 primary_crtc = drm_crtc_find(drm_enc->dev, wait_vblank_crtc_id);
1395 if (!primary_crtc) {
1396 SDE_ERROR_ENC(sde_enc,
1397 "failed to find primary crtc id %d\n",
1398 wait_vblank_crtc_id);
1399 return -EINVAL;
1400 }
1401 pipe = drm_crtc_index(primary_crtc);
1402 }
1403
1404 /**
1405 * note: VBLANK is expected to be enabled at this point in
1406 * resource control state machine if on primary CRTC
1407 */
1408 for (wait_count = 0; wait_count < MAX_RSC_WAIT; wait_count++) {
1409 if (sde_rsc_client_is_state_update_complete(
1410 sde_enc->rsc_client))
1411 break;
1412
1413 if (crtc->base.id == wait_vblank_crtc_id)
1414 ret = sde_encoder_wait_for_event(drm_enc,
1415 MSM_ENC_VBLANK);
1416 else
1417 drm_wait_one_vblank(drm_enc->dev, pipe);
1418
1419 if (ret) {
1420 SDE_ERROR_ENC(sde_enc,
1421 "wait for vblank failed ret:%d\n", ret);
1422 break;
1423 }
1424 }
1425
1426 if (wait_count >= MAX_RSC_WAIT)
1427 SDE_EVT32(DRMID(drm_enc), wait_vblank_crtc_id, wait_count,
1428 SDE_EVTLOG_ERROR);
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001429
1430 return ret;
1431}
1432
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001433static void _sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable)
1434{
1435 struct sde_encoder_virt *sde_enc;
1436 int i;
1437
1438 if (!drm_enc) {
1439 SDE_ERROR("invalid encoder\n");
1440 return;
1441 }
1442
1443 sde_enc = to_sde_encoder_virt(drm_enc);
1444
1445 SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable);
1446 for (i = 0; i < sde_enc->num_phys_encs; i++) {
1447 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
1448
1449 if (phys && phys->ops.irq_control)
1450 phys->ops.irq_control(phys, enable);
1451 }
1452
1453}
1454
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07001455/* keep track of the userspace vblank during modeset */
1456static void _sde_encoder_modeset_helper_locked(struct drm_encoder *drm_enc,
1457 u32 sw_event)
1458{
1459 struct sde_encoder_virt *sde_enc;
1460 bool enable;
1461 int i;
1462
1463 if (!drm_enc) {
1464 SDE_ERROR("invalid encoder\n");
1465 return;
1466 }
1467
1468 sde_enc = to_sde_encoder_virt(drm_enc);
1469 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, vblank_enabled:%d\n",
1470 sw_event, sde_enc->vblank_enabled);
1471
1472 /* nothing to do if vblank not enabled by userspace */
1473 if (!sde_enc->vblank_enabled)
1474 return;
1475
1476 /* disable vblank on pre_modeset */
1477 if (sw_event == SDE_ENC_RC_EVENT_PRE_MODESET)
1478 enable = false;
1479 /* enable vblank on post_modeset */
1480 else if (sw_event == SDE_ENC_RC_EVENT_POST_MODESET)
1481 enable = true;
1482 else
1483 return;
1484
1485 for (i = 0; i < sde_enc->num_phys_encs; i++) {
1486 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
1487
1488 if (phys && phys->ops.control_vblank_irq)
1489 phys->ops.control_vblank_irq(phys, enable);
1490 }
1491}
1492
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001493struct sde_rsc_client *sde_encoder_get_rsc_client(struct drm_encoder *drm_enc)
1494{
1495 struct sde_encoder_virt *sde_enc;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001496
1497 if (!drm_enc)
1498 return NULL;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001499 sde_enc = to_sde_encoder_virt(drm_enc);
Dhaval Patel5cd59a02017-06-13 16:29:40 -07001500 return sde_enc->rsc_client;
Dhaval Patel30fae8a2017-04-21 18:42:41 -07001501}
1502
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001503static void _sde_encoder_resource_control_rsc_update(
1504 struct drm_encoder *drm_enc, bool enable)
1505{
1506 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
1507 struct sde_encoder_rsc_config rsc_cfg = { 0 };
Dhaval Patelc1e4bfc2017-09-15 14:51:36 -07001508 int i;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001509
1510 if (enable) {
1511 rsc_cfg.inline_rotate_prefill =
1512 sde_crtc_get_inline_prefill(drm_enc->crtc);
1513
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001514 _sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true);
1515 } else {
1516 _sde_encoder_update_rsc_client(drm_enc, NULL, false);
1517
1518 /**
Dhaval Patelc1e4bfc2017-09-15 14:51:36 -07001519 * disable the vsync source after updating the rsc state. rsc
1520 * state update might have vsync wait and vsync source must be
1521 * disabled after it. It will avoid generating any vsync from
1522 * this point till mode-2 entry. It is SW workaround for
1523 * HW limitation and should not be removed without checking the
1524 * updated design.
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001525 */
Dhaval Patelc1e4bfc2017-09-15 14:51:36 -07001526 for (i = 0; i < sde_enc->num_phys_encs; i++) {
1527 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
1528
1529 if (phys && phys->ops.prepare_idle_pc)
1530 phys->ops.prepare_idle_pc(phys);
1531 }
1532
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001533 }
1534}
1535
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001536static void _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
1537 bool enable)
1538{
1539 struct msm_drm_private *priv;
1540 struct sde_kms *sde_kms;
1541 struct sde_encoder_virt *sde_enc;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001542
1543 sde_enc = to_sde_encoder_virt(drm_enc);
1544 priv = drm_enc->dev->dev_private;
1545 sde_kms = to_sde_kms(priv->kms);
1546
1547 SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable);
1548 SDE_EVT32(DRMID(drm_enc), enable);
1549
1550 if (!sde_enc->cur_master) {
1551 SDE_ERROR("encoder master not set\n");
1552 return;
1553 }
1554
1555 if (enable) {
1556 /* enable SDE core clks */
1557 sde_power_resource_enable(&priv->phandle,
1558 sde_kms->core_client, true);
1559
1560 /* enable DSI clks */
1561 sde_connector_clk_ctrl(sde_enc->cur_master->connector, true);
1562
1563 /* enable all the irq */
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001564 _sde_encoder_irq_control(drm_enc, true);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001565
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001566 } else {
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001567 /* disable all the irq */
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001568 _sde_encoder_irq_control(drm_enc, false);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001569
1570 /* disable DSI clks */
1571 sde_connector_clk_ctrl(sde_enc->cur_master->connector, false);
1572
1573 /* disable SDE core clks */
1574 sde_power_resource_enable(&priv->phandle,
1575 sde_kms->core_client, false);
1576 }
1577
1578}
1579
1580static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
1581 u32 sw_event)
1582{
Dhaval Patel99412a52017-07-24 19:16:45 -07001583 bool autorefresh_enabled = false;
Clarence Ip89628132017-07-27 13:33:51 -04001584 unsigned int lp, idle_timeout;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001585 struct sde_encoder_virt *sde_enc;
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001586 struct msm_drm_private *priv;
1587 struct msm_drm_thread *disp_thread;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001588 int ret;
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001589 bool is_vid_mode = false;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001590
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001591 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
1592 !drm_enc->crtc) {
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001593 SDE_ERROR("invalid parameters\n");
1594 return -EINVAL;
1595 }
1596 sde_enc = to_sde_encoder_virt(drm_enc);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001597 priv = drm_enc->dev->dev_private;
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001598 is_vid_mode = sde_enc->disp_info.capabilities &
1599 MSM_DISPLAY_CAP_VID_MODE;
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001600
1601 if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
1602 SDE_ERROR("invalid crtc index\n");
1603 return -EINVAL;
1604 }
1605 disp_thread = &priv->disp_thread[drm_enc->crtc->index];
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001606
1607 /*
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001608 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001609 * events and return early for other events (ie wb display).
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001610 */
1611 if (!sde_enc->idle_pc_supported &&
1612 (sw_event != SDE_ENC_RC_EVENT_KICKOFF &&
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001613 sw_event != SDE_ENC_RC_EVENT_PRE_MODESET &&
1614 sw_event != SDE_ENC_RC_EVENT_POST_MODESET &&
1615 sw_event != SDE_ENC_RC_EVENT_STOP &&
1616 sw_event != SDE_ENC_RC_EVENT_PRE_STOP))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001617 return 0;
1618
1619 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc_supported:%d\n", sw_event,
1620 sde_enc->idle_pc_supported);
Dhaval Patela5f75952017-07-25 11:17:41 -07001621 SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001622 sde_enc->rc_state, SDE_EVTLOG_FUNC_ENTRY);
1623
1624 switch (sw_event) {
1625 case SDE_ENC_RC_EVENT_KICKOFF:
1626 /* cancel delayed off work, if any */
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001627 if (kthread_cancel_delayed_work_sync(
1628 &sde_enc->delayed_off_work))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001629 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work cancelled\n",
1630 sw_event);
1631
1632 mutex_lock(&sde_enc->rc_lock);
1633
1634 /* return if the resource control is already in ON state */
1635 if (sde_enc->rc_state == SDE_ENC_RC_STATE_ON) {
1636 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in ON state\n",
1637 sw_event);
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001638 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1639 SDE_EVTLOG_FUNC_CASE1);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001640 mutex_unlock(&sde_enc->rc_lock);
1641 return 0;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001642 } else if (sde_enc->rc_state != SDE_ENC_RC_STATE_OFF &&
1643 sde_enc->rc_state != SDE_ENC_RC_STATE_IDLE) {
1644 SDE_ERROR_ENC(sde_enc, "sw_event:%d, rc in state %d\n",
1645 sw_event, sde_enc->rc_state);
1646 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1647 SDE_EVTLOG_ERROR);
1648 mutex_unlock(&sde_enc->rc_lock);
1649 return -EINVAL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001650 }
1651
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001652 if (is_vid_mode && sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
1653 _sde_encoder_irq_control(drm_enc, true);
1654 } else {
1655 /* enable all the clks and resources */
1656 _sde_encoder_resource_control_helper(drm_enc, true);
1657 _sde_encoder_resource_control_rsc_update(drm_enc, true);
1658 }
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001659
1660 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1661 SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE1);
1662 sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
1663
1664 mutex_unlock(&sde_enc->rc_lock);
1665 break;
1666
1667 case SDE_ENC_RC_EVENT_FRAME_DONE:
1668 /*
1669 * mutex lock is not used as this event happens at interrupt
1670 * context. And locking is not required as, the other events
1671 * like KICKOFF and STOP does a wait-for-idle before executing
1672 * the resource_control
1673 */
1674 if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
1675 SDE_ERROR_ENC(sde_enc, "sw_event:%d,rc:%d-unexpected\n",
1676 sw_event, sde_enc->rc_state);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001677 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1678 SDE_EVTLOG_ERROR);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001679 return -EINVAL;
1680 }
1681
1682 /*
1683 * schedule off work item only when there are no
1684 * frames pending
1685 */
1686 if (sde_crtc_frame_pending(drm_enc->crtc) > 1) {
1687 SDE_DEBUG_ENC(sde_enc, "skip schedule work");
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001688 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1689 SDE_EVTLOG_FUNC_CASE2);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001690 return 0;
1691 }
1692
Dhaval Patel99412a52017-07-24 19:16:45 -07001693 /* schedule delayed off work if autorefresh is disabled */
1694 if (sde_enc->cur_master &&
1695 sde_enc->cur_master->ops.is_autorefresh_enabled)
1696 autorefresh_enabled =
1697 sde_enc->cur_master->ops.is_autorefresh_enabled(
1698 sde_enc->cur_master);
1699
Clarence Ip89628132017-07-27 13:33:51 -04001700 /* set idle timeout based on master connector's lp value */
1701 if (sde_enc->cur_master)
1702 lp = sde_connector_get_lp(
1703 sde_enc->cur_master->connector);
1704 else
1705 lp = SDE_MODE_DPMS_ON;
1706
1707 if (lp == SDE_MODE_DPMS_LP2)
1708 idle_timeout = IDLE_SHORT_TIMEOUT;
1709 else
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001710 idle_timeout = sde_enc->idle_timeout;
Clarence Ip89628132017-07-27 13:33:51 -04001711
Sravanthi Kollukuduru247adcf2017-10-11 16:19:23 +05301712 if (!autorefresh_enabled && idle_timeout)
Dhaval Patel99412a52017-07-24 19:16:45 -07001713 kthread_queue_delayed_work(
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001714 &disp_thread->worker,
1715 &sde_enc->delayed_off_work,
Clarence Ip89628132017-07-27 13:33:51 -04001716 msecs_to_jiffies(idle_timeout));
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001717 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
Clarence Ip89628132017-07-27 13:33:51 -04001718 autorefresh_enabled,
1719 idle_timeout, SDE_EVTLOG_FUNC_CASE2);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001720 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work scheduled\n",
1721 sw_event);
1722 break;
1723
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001724 case SDE_ENC_RC_EVENT_PRE_STOP:
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001725 /* cancel delayed off work, if any */
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001726 if (kthread_cancel_delayed_work_sync(
1727 &sde_enc->delayed_off_work))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001728 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work cancelled\n",
1729 sw_event);
1730
1731 mutex_lock(&sde_enc->rc_lock);
1732
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001733 if (is_vid_mode &&
1734 sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
1735 _sde_encoder_irq_control(drm_enc, true);
1736 }
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001737 /* skip if is already OFF or IDLE, resources are off already */
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001738 else if (sde_enc->rc_state == SDE_ENC_RC_STATE_OFF ||
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001739 sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) {
1740 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in %d state\n",
1741 sw_event, sde_enc->rc_state);
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001742 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1743 SDE_EVTLOG_FUNC_CASE3);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001744 mutex_unlock(&sde_enc->rc_lock);
1745 return 0;
1746 }
1747
1748 /**
1749 * IRQs are still enabled currently, which allows wait for
1750 * VBLANK which RSC may require to correctly transition to OFF
1751 */
1752 _sde_encoder_resource_control_rsc_update(drm_enc, false);
1753
1754 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1755 SDE_ENC_RC_STATE_PRE_OFF,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001756 SDE_EVTLOG_FUNC_CASE3);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001757
1758 sde_enc->rc_state = SDE_ENC_RC_STATE_PRE_OFF;
1759
1760 mutex_unlock(&sde_enc->rc_lock);
1761 break;
1762
1763 case SDE_ENC_RC_EVENT_STOP:
1764 mutex_lock(&sde_enc->rc_lock);
1765
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001766 /* return if the resource control is already in OFF state */
1767 if (sde_enc->rc_state == SDE_ENC_RC_STATE_OFF) {
1768 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in OFF state\n",
1769 sw_event);
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001770 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1771 SDE_EVTLOG_FUNC_CASE4);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001772 mutex_unlock(&sde_enc->rc_lock);
1773 return 0;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001774 } else if (sde_enc->rc_state == SDE_ENC_RC_STATE_ON ||
1775 sde_enc->rc_state == SDE_ENC_RC_STATE_MODESET) {
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001776 SDE_ERROR_ENC(sde_enc, "sw_event:%d, rc in state %d\n",
1777 sw_event, sde_enc->rc_state);
1778 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1779 SDE_EVTLOG_ERROR);
1780 mutex_unlock(&sde_enc->rc_lock);
1781 return -EINVAL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001782 }
1783
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001784 /**
1785 * expect to arrive here only if in either idle state or pre-off
1786 * and in IDLE state the resources are already disabled
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001787 */
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001788 if (sde_enc->rc_state == SDE_ENC_RC_STATE_PRE_OFF)
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001789 _sde_encoder_resource_control_helper(drm_enc, false);
1790
1791 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001792 SDE_ENC_RC_STATE_OFF, SDE_EVTLOG_FUNC_CASE4);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001793
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001794 sde_enc->rc_state = SDE_ENC_RC_STATE_OFF;
1795
1796 mutex_unlock(&sde_enc->rc_lock);
1797 break;
1798
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001799 case SDE_ENC_RC_EVENT_PRE_MODESET:
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001800 /* cancel delayed off work, if any */
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001801 if (kthread_cancel_delayed_work_sync(
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001802 &sde_enc->delayed_off_work))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001803 SDE_DEBUG_ENC(sde_enc, "sw_event:%d, work cancelled\n",
1804 sw_event);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001805
1806 mutex_lock(&sde_enc->rc_lock);
1807
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001808 /* return if the resource control is already in ON state */
1809 if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
1810 /* enable all the clks and resources */
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001811 _sde_encoder_resource_control_helper(drm_enc, true);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001812
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001813 _sde_encoder_resource_control_rsc_update(drm_enc, true);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001814
1815 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1816 SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE5);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001817 sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001818 }
1819
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001820 ret = sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
1821 if (ret && ret != -EWOULDBLOCK) {
1822 SDE_ERROR_ENC(sde_enc,
1823 "wait for commit done returned %d\n",
1824 ret);
1825 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1826 ret, SDE_EVTLOG_ERROR);
1827 mutex_unlock(&sde_enc->rc_lock);
1828 return -EINVAL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001829 }
1830
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001831 _sde_encoder_irq_control(drm_enc, false);
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07001832 _sde_encoder_modeset_helper_locked(drm_enc, sw_event);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001833
1834 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1835 SDE_ENC_RC_STATE_MODESET, SDE_EVTLOG_FUNC_CASE5);
1836
1837 sde_enc->rc_state = SDE_ENC_RC_STATE_MODESET;
1838 mutex_unlock(&sde_enc->rc_lock);
1839 break;
1840
1841 case SDE_ENC_RC_EVENT_POST_MODESET:
1842 mutex_lock(&sde_enc->rc_lock);
1843
1844 /* return if the resource control is already in ON state */
1845 if (sde_enc->rc_state != SDE_ENC_RC_STATE_MODESET) {
1846 SDE_ERROR_ENC(sde_enc,
1847 "sw_event:%d, rc:%d !MODESET state\n",
1848 sw_event, sde_enc->rc_state);
1849 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1850 SDE_EVTLOG_ERROR);
1851 mutex_unlock(&sde_enc->rc_lock);
1852 return -EINVAL;
1853 }
1854
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07001855 _sde_encoder_modeset_helper_locked(drm_enc, sw_event);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001856 _sde_encoder_irq_control(drm_enc, true);
1857
1858 _sde_encoder_update_rsc_client(drm_enc, NULL, true);
1859
1860 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1861 SDE_ENC_RC_STATE_ON, SDE_EVTLOG_FUNC_CASE6);
1862
1863 sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
1864
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001865 mutex_unlock(&sde_enc->rc_lock);
1866 break;
1867
1868 case SDE_ENC_RC_EVENT_ENTER_IDLE:
1869 mutex_lock(&sde_enc->rc_lock);
1870
1871 if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001872 SDE_ERROR_ENC(sde_enc, "sw_event:%d, rc:%d !ON state\n",
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001873 sw_event, sde_enc->rc_state);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001874 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1875 SDE_EVTLOG_ERROR);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001876 mutex_unlock(&sde_enc->rc_lock);
1877 return 0;
1878 }
1879
1880 /*
1881 * if we are in ON but a frame was just kicked off,
1882 * ignore the IDLE event, it's probably a stale timer event
1883 */
1884 if (sde_enc->frame_busy_mask[0]) {
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001885 SDE_ERROR_ENC(sde_enc,
Lloyd Atkinsona8781382017-07-17 10:20:43 -04001886 "sw_event:%d, rc:%d frame pending\n",
1887 sw_event, sde_enc->rc_state);
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04001888 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
1889 SDE_EVTLOG_ERROR);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001890 mutex_unlock(&sde_enc->rc_lock);
1891 return 0;
1892 }
1893
Dhaval Patele17e0ee2017-08-23 18:01:42 -07001894 if (is_vid_mode) {
1895 _sde_encoder_irq_control(drm_enc, false);
1896 } else {
1897 /* disable all the clks and resources */
1898 _sde_encoder_resource_control_rsc_update(drm_enc,
1899 false);
1900 _sde_encoder_resource_control_helper(drm_enc, false);
1901 }
1902
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001903 SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001904 SDE_ENC_RC_STATE_IDLE, SDE_EVTLOG_FUNC_CASE7);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001905 sde_enc->rc_state = SDE_ENC_RC_STATE_IDLE;
1906
1907 mutex_unlock(&sde_enc->rc_lock);
1908 break;
1909
1910 default:
Dhaval Patela5f75952017-07-25 11:17:41 -07001911 SDE_EVT32(DRMID(drm_enc), sw_event, SDE_EVTLOG_ERROR);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001912 SDE_ERROR("unexpected sw_event: %d\n", sw_event);
1913 break;
1914 }
1915
Dhaval Patela5f75952017-07-25 11:17:41 -07001916 SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported,
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07001917 sde_enc->rc_state, SDE_EVTLOG_FUNC_EXIT);
1918 return 0;
1919}
1920
Lloyd Atkinson09fed912016-06-24 18:14:13 -04001921static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
1922 struct drm_display_mode *mode,
Lloyd Atkinsonaf7952d2016-06-26 22:41:26 -04001923 struct drm_display_mode *adj_mode)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04001924{
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001925 struct sde_encoder_virt *sde_enc;
1926 struct msm_drm_private *priv;
1927 struct sde_kms *sde_kms;
1928 struct list_head *connector_list;
1929 struct drm_connector *conn = NULL, *conn_iter;
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001930 struct sde_connector *sde_conn = NULL;
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08001931 struct sde_rm_hw_iter dsc_iter, pp_iter;
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001932 int i = 0, ret;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04001933
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04001934 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -04001935 SDE_ERROR("invalid encoder\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04001936 return;
1937 }
1938
1939 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -04001940 SDE_DEBUG_ENC(sde_enc, "\n");
1941
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001942 priv = drm_enc->dev->dev_private;
1943 sde_kms = to_sde_kms(priv->kms);
1944 connector_list = &sde_kms->dev->mode_config.connector_list;
1945
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04001946 SDE_EVT32(DRMID(drm_enc));
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04001947
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001948 list_for_each_entry(conn_iter, connector_list, head)
1949 if (conn_iter->encoder == drm_enc)
1950 conn = conn_iter;
1951
1952 if (!conn) {
Clarence Ip19af1362016-09-23 14:57:51 -04001953 SDE_ERROR_ENC(sde_enc, "failed to find attached connector\n");
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001954 return;
Lloyd Atkinson55987b02016-08-16 16:57:46 -04001955 } else if (!conn->state) {
1956 SDE_ERROR_ENC(sde_enc, "invalid connector state\n");
1957 return;
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001958 }
1959
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001960 sde_conn = to_sde_connector(conn);
1961 if (sde_conn) {
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07001962 ret = sde_conn->ops.get_mode_info(adj_mode, &sde_enc->mode_info,
Alan Kwongb1bca602017-09-18 17:28:45 -04001963 sde_kms->catalog->max_mixer_width,
1964 sde_conn->display);
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07001965 if (ret) {
1966 SDE_ERROR_ENC(sde_enc,
1967 "invalid topology for the mode\n");
1968 return;
1969 }
1970 }
1971
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001972 /* release resources before seamless mode change */
1973 if (msm_is_mode_seamless_dms(adj_mode)) {
1974 /* restore resource state before releasing them */
1975 ret = sde_encoder_resource_control(drm_enc,
1976 SDE_ENC_RC_EVENT_PRE_MODESET);
1977 if (ret) {
1978 SDE_ERROR_ENC(sde_enc,
1979 "sde resource control failed: %d\n",
1980 ret);
1981 return;
1982 }
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07001983
1984 /*
1985 * Disable dsc before switch the mode and after pre_modeset,
1986 * to guarantee that previous kickoff finished.
1987 */
1988 _sde_encoder_dsc_disable(sde_enc);
Dhaval Patel1b5605b2017-07-26 18:19:50 -07001989 }
1990
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001991 /* Reserve dynamic resources now. Indicating non-AtomicTest phase */
1992 ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state,
1993 conn->state, false);
1994 if (ret) {
Clarence Ip19af1362016-09-23 14:57:51 -04001995 SDE_ERROR_ENC(sde_enc,
1996 "failed to reserve hw resources, %d\n", ret);
Lloyd Atkinson11f34442016-08-11 11:19:52 -04001997 return;
1998 }
1999
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -07002000 sde_rm_init_hw_iter(&pp_iter, drm_enc->base.id, SDE_HW_BLK_PINGPONG);
2001 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
2002 sde_enc->hw_pp[i] = NULL;
2003 if (!sde_rm_get_hw(&sde_kms->rm, &pp_iter))
2004 break;
2005 sde_enc->hw_pp[i] = (struct sde_hw_pingpong *) pp_iter.hw;
2006 }
2007
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08002008 sde_rm_init_hw_iter(&dsc_iter, drm_enc->base.id, SDE_HW_BLK_DSC);
2009 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
2010 sde_enc->hw_dsc[i] = NULL;
2011 if (!sde_rm_get_hw(&sde_kms->rm, &dsc_iter))
2012 break;
2013 sde_enc->hw_dsc[i] = (struct sde_hw_dsc *) dsc_iter.hw;
2014 }
2015
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002016 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2017 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinsonaf7952d2016-06-26 22:41:26 -04002018
Lloyd Atkinson55987b02016-08-16 16:57:46 -04002019 if (phys) {
Jeykumar Sankaranfdd77a92016-11-02 12:34:29 -07002020 if (!sde_enc->hw_pp[i]) {
2021 SDE_ERROR_ENC(sde_enc,
2022 "invalid pingpong block for the encoder\n");
2023 return;
2024 }
2025 phys->hw_pp = sde_enc->hw_pp[i];
Lloyd Atkinson55987b02016-08-16 16:57:46 -04002026 phys->connector = conn->state->connector;
2027 if (phys->ops.mode_set)
2028 phys->ops.mode_set(phys, mode, adj_mode);
2029 }
Lloyd Atkinsonaf7952d2016-06-26 22:41:26 -04002030 }
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07002031
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002032 /* update resources after seamless mode change */
2033 if (msm_is_mode_seamless_dms(adj_mode))
2034 sde_encoder_resource_control(&sde_enc->base,
2035 SDE_ENC_RC_EVENT_POST_MODESET);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002036}
2037
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002038static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002039{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002040 struct sde_encoder_virt *sde_enc = NULL;
Clarence Ip35348262017-04-28 16:10:46 -07002041 struct msm_drm_private *priv;
2042 struct sde_kms *sde_kms;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002043
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002044 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
2045 SDE_ERROR("invalid parameters\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002046 return;
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002047 }
Dhaval Patelaab9b522017-07-20 12:38:46 -07002048
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002049 priv = drm_enc->dev->dev_private;
Dhaval Patelaab9b522017-07-20 12:38:46 -07002050 sde_kms = to_sde_kms(priv->kms);
2051 if (!sde_kms) {
2052 SDE_ERROR("invalid sde_kms\n");
2053 return;
2054 }
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002055
2056 sde_enc = to_sde_encoder_virt(drm_enc);
2057 if (!sde_enc || !sde_enc->cur_master) {
2058 SDE_ERROR("invalid sde encoder/master\n");
Lloyd Atkinson5217336c2016-09-15 18:21:18 -04002059 return;
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002060 }
2061
Ajay Singh Parmar878ef142017-08-07 16:53:57 -07002062 if (sde_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DisplayPort &&
2063 sde_enc->cur_master->hw_mdptop &&
2064 sde_enc->cur_master->hw_mdptop->ops.intf_audio_select)
2065 sde_enc->cur_master->hw_mdptop->ops.intf_audio_select(
2066 sde_enc->cur_master->hw_mdptop);
2067
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002068 if (sde_enc->cur_master->hw_mdptop &&
2069 sde_enc->cur_master->hw_mdptop->ops.reset_ubwc)
2070 sde_enc->cur_master->hw_mdptop->ops.reset_ubwc(
2071 sde_enc->cur_master->hw_mdptop,
2072 sde_kms->catalog);
2073
Dhaval Patelaab9b522017-07-20 12:38:46 -07002074 _sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info, false);
Lloyd Atkinsonbc01cbd2017-06-05 14:26:57 -04002075
2076 memset(&sde_enc->prv_conn_roi, 0, sizeof(sde_enc->prv_conn_roi));
2077 memset(&sde_enc->cur_conn_roi, 0, sizeof(sde_enc->cur_conn_roi));
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002078}
2079
2080void sde_encoder_virt_restore(struct drm_encoder *drm_enc)
2081{
2082 struct sde_encoder_virt *sde_enc = NULL;
2083 int i;
2084
2085 if (!drm_enc) {
2086 SDE_ERROR("invalid encoder\n");
2087 return;
2088 }
2089 sde_enc = to_sde_encoder_virt(drm_enc);
2090
2091 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2092 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
2093
2094 if (phys && (phys != sde_enc->cur_master) && phys->ops.restore)
2095 phys->ops.restore(phys);
2096 }
2097
2098 if (sde_enc->cur_master && sde_enc->cur_master->ops.restore)
2099 sde_enc->cur_master->ops.restore(sde_enc->cur_master);
2100
2101 _sde_encoder_virt_enable_helper(drm_enc);
2102}
2103
2104static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
2105{
2106 struct sde_encoder_virt *sde_enc = NULL;
2107 int i, ret = 0;
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07002108 struct msm_compression_info *comp_info = NULL;
Jeykumar Sankaran69934622017-05-31 18:16:25 -07002109 struct drm_display_mode *cur_mode = NULL;
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002110
2111 if (!drm_enc) {
2112 SDE_ERROR("invalid encoder\n");
2113 return;
2114 }
2115 sde_enc = to_sde_encoder_virt(drm_enc);
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07002116 comp_info = &sde_enc->mode_info.comp_info;
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002117 cur_mode = &sde_enc->base.crtc->state->adjusted_mode;
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002118
Clarence Ip19af1362016-09-23 14:57:51 -04002119 SDE_DEBUG_ENC(sde_enc, "\n");
Dhaval Patel1b5605b2017-07-26 18:19:50 -07002120 SDE_EVT32(DRMID(drm_enc), cur_mode->hdisplay, cur_mode->vdisplay);
Jeykumar Sankaran69934622017-05-31 18:16:25 -07002121
Clarence Ipa87f8ec2016-08-23 13:43:19 -04002122 sde_enc->cur_master = NULL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002123 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2124 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
2125
2126 if (phys && phys->ops.is_master && phys->ops.is_master(phys)) {
2127 SDE_DEBUG_ENC(sde_enc, "master is now idx %d\n", i);
2128 sde_enc->cur_master = phys;
2129 break;
2130 }
2131 }
2132
2133 if (!sde_enc->cur_master) {
2134 SDE_ERROR("virt encoder has no master! num_phys %d\n", i);
2135 return;
2136 }
2137
2138 ret = sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF);
2139 if (ret) {
2140 SDE_ERROR_ENC(sde_enc, "sde resource control failed: %d\n",
2141 ret);
2142 return;
2143 }
Dhaval Patel020f7e122016-11-15 14:39:18 -08002144
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002145 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2146 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04002147
Jeykumar Sankaran69934622017-05-31 18:16:25 -07002148 if (!phys)
2149 continue;
2150
2151 phys->comp_type = comp_info->comp_type;
2152 if (phys != sde_enc->cur_master) {
2153 /**
2154 * on DMS request, the encoder will be enabled
2155 * already. Invoke restore to reconfigure the
2156 * new mode.
2157 */
2158 if (msm_is_mode_seamless_dms(cur_mode) &&
2159 phys->ops.restore)
2160 phys->ops.restore(phys);
2161 else if (phys->ops.enable)
Jeykumar Sankaran446a5f12017-05-09 20:30:39 -07002162 phys->ops.enable(phys);
2163 }
Dhaval Patel010f5172017-08-01 22:40:09 -07002164
2165 if (sde_enc->misr_enable && (sde_enc->disp_info.capabilities &
2166 MSM_DISPLAY_CAP_VID_MODE) && phys->ops.setup_misr)
2167 phys->ops.setup_misr(phys, true,
2168 sde_enc->misr_frame_count);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002169 }
Clarence Ipa87f8ec2016-08-23 13:43:19 -04002170
Jeykumar Sankaran69934622017-05-31 18:16:25 -07002171 if (msm_is_mode_seamless_dms(cur_mode) &&
2172 sde_enc->cur_master->ops.restore)
2173 sde_enc->cur_master->ops.restore(sde_enc->cur_master);
2174 else if (sde_enc->cur_master->ops.enable)
Clarence Ipa87f8ec2016-08-23 13:43:19 -04002175 sde_enc->cur_master->ops.enable(sde_enc->cur_master);
Jeykumar Sankaran5c2f0702017-03-09 18:03:15 -08002176
Veera Sundaram Sankaran82916e02017-03-29 18:44:22 -07002177 _sde_encoder_virt_enable_helper(drm_enc);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002178}
2179
2180static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
2181{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002182 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002183 struct msm_drm_private *priv;
2184 struct sde_kms *sde_kms;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002185 int i = 0;
2186
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002187 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -04002188 SDE_ERROR("invalid encoder\n");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002189 return;
Lloyd Atkinson5217336c2016-09-15 18:21:18 -04002190 } else if (!drm_enc->dev) {
2191 SDE_ERROR("invalid dev\n");
2192 return;
2193 } else if (!drm_enc->dev->dev_private) {
2194 SDE_ERROR("invalid dev_private\n");
2195 return;
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002196 }
2197
2198 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -04002199 SDE_DEBUG_ENC(sde_enc, "\n");
2200
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002201 priv = drm_enc->dev->dev_private;
2202 sde_kms = to_sde_kms(priv->kms);
2203
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04002204 SDE_EVT32(DRMID(drm_enc));
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002205
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002206 /* wait for idle */
2207 sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
2208
2209 sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_PRE_STOP);
2210
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002211 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2212 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
2213
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04002214 if (phys && phys->ops.disable)
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002215 phys->ops.disable(phys);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002216 }
2217
Ingrid Gallardo2a2befb2017-08-07 15:02:51 -07002218 /*
2219 * disable dsc after the transfer is complete (for command mode)
2220 * and after physical encoder is disabled, to make sure timing
2221 * engine is already disabled (for video mode).
2222 */
2223 _sde_encoder_dsc_disable(sde_enc);
2224
Lloyd Atkinson03810e32017-03-14 13:38:06 -07002225 /* after phys waits for frame-done, should be no more frames pending */
2226 if (atomic_xchg(&sde_enc->frame_done_timeout, 0)) {
2227 SDE_ERROR("enc%d timeout pending\n", drm_enc->base.id);
2228 del_timer_sync(&sde_enc->frame_done_timer);
2229 }
2230
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002231 sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_STOP);
2232
Lloyd Atkinson07099ad2017-08-15 13:32:24 -04002233 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2234 if (sde_enc->phys_encs[i])
2235 sde_enc->phys_encs[i]->connector = NULL;
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002236 }
2237
Lloyd Atkinson07099ad2017-08-15 13:32:24 -04002238 sde_enc->cur_master = NULL;
2239
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002240 SDE_DEBUG_ENC(sde_enc, "encoder disabled\n");
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04002241
Lloyd Atkinson11f34442016-08-11 11:19:52 -04002242 sde_rm_release(&sde_kms->rm, drm_enc);
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002243}
2244
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002245static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
Lloyd Atkinson9a840312016-06-26 10:11:08 -04002246 enum sde_intf_type type, u32 controller_id)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002247{
2248 int i = 0;
2249
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002250 for (i = 0; i < catalog->intf_count; i++) {
2251 if (catalog->intf[i].type == type
Lloyd Atkinson9a840312016-06-26 10:11:08 -04002252 && catalog->intf[i].controller_id == controller_id) {
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002253 return catalog->intf[i].id;
2254 }
2255 }
2256
2257 return INTF_MAX;
2258}
2259
Alan Kwongbb27c092016-07-20 16:41:25 -04002260static enum sde_wb sde_encoder_get_wb(struct sde_mdss_cfg *catalog,
2261 enum sde_intf_type type, u32 controller_id)
2262{
2263 if (controller_id < catalog->wb_count)
2264 return catalog->wb[controller_id].id;
2265
2266 return WB_MAX;
2267}
2268
Dhaval Patel81e87882016-10-19 21:41:56 -07002269static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc,
2270 struct sde_encoder_phys *phy_enc)
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002271{
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002272 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002273 unsigned long lock_flags;
2274
Dhaval Patel81e87882016-10-19 21:41:56 -07002275 if (!drm_enc || !phy_enc)
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002276 return;
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002277
Narendra Muppalla77b32932017-05-10 13:53:11 -07002278 SDE_ATRACE_BEGIN("encoder_vblank_callback");
Lloyd Atkinsonf30546e2016-06-26 10:08:25 -04002279 sde_enc = to_sde_encoder_virt(drm_enc);
2280
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002281 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04002282 if (sde_enc->crtc_vblank_cb)
2283 sde_enc->crtc_vblank_cb(sde_enc->crtc_vblank_cb_data);
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002284 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
Dhaval Patel81e87882016-10-19 21:41:56 -07002285
2286 atomic_inc(&phy_enc->vsync_cnt);
Narendra Muppalla77b32932017-05-10 13:53:11 -07002287 SDE_ATRACE_END("encoder_vblank_callback");
Dhaval Patel81e87882016-10-19 21:41:56 -07002288}
2289
2290static void sde_encoder_underrun_callback(struct drm_encoder *drm_enc,
2291 struct sde_encoder_phys *phy_enc)
2292{
2293 if (!phy_enc)
2294 return;
2295
Narendra Muppalla77b32932017-05-10 13:53:11 -07002296 SDE_ATRACE_BEGIN("encoder_underrun_callback");
Dhaval Patel81e87882016-10-19 21:41:56 -07002297 atomic_inc(&phy_enc->underrun_cnt);
Lloyd Atkinson64b07dd2016-12-12 17:10:57 -05002298 SDE_EVT32(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt));
Narendra Muppalla77b32932017-05-10 13:53:11 -07002299 SDE_ATRACE_END("encoder_underrun_callback");
Lloyd Atkinson09fed912016-06-24 18:14:13 -04002300}
2301
Lloyd Atkinson5d722782016-05-30 14:09:41 -04002302void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
2303 void (*vbl_cb)(void *), void *vbl_data)
2304{
2305 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
2306 unsigned long lock_flags;
2307 bool enable;
2308 int i;
2309
2310 enable = vbl_cb ? true : false;
2311
Clarence Ip19af1362016-09-23 14:57:51 -04002312 if (!drm_enc) {
2313 SDE_ERROR("invalid encoder\n");
2314 return;
2315 }
2316 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04002317 SDE_EVT32(DRMID(drm_enc), enable);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04002318
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002319 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04002320 sde_enc->crtc_vblank_cb = vbl_cb;
2321 sde_enc->crtc_vblank_cb_data = vbl_data;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002322 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04002323
2324 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2325 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
2326
2327 if (phys && phys->ops.control_vblank_irq)
2328 phys->ops.control_vblank_irq(phys, enable);
2329 }
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07002330 sde_enc->vblank_enabled = enable;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04002331}
2332
Alan Kwong628d19e2016-10-31 13:50:13 -04002333void sde_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
2334 void (*frame_event_cb)(void *, u32 event),
2335 void *frame_event_cb_data)
2336{
2337 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
2338 unsigned long lock_flags;
2339 bool enable;
2340
2341 enable = frame_event_cb ? true : false;
2342
2343 if (!drm_enc) {
2344 SDE_ERROR("invalid encoder\n");
2345 return;
2346 }
2347 SDE_DEBUG_ENC(sde_enc, "\n");
2348 SDE_EVT32(DRMID(drm_enc), enable, 0);
2349
2350 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
2351 sde_enc->crtc_frame_event_cb = frame_event_cb;
2352 sde_enc->crtc_frame_event_cb_data = frame_event_cb_data;
2353 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
2354}
2355
2356static void sde_encoder_frame_done_callback(
2357 struct drm_encoder *drm_enc,
2358 struct sde_encoder_phys *ready_phys, u32 event)
2359{
2360 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
2361 unsigned int i;
2362
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07002363 if (event & (SDE_ENCODER_FRAME_EVENT_DONE
2364 | SDE_ENCODER_FRAME_EVENT_ERROR
2365 | SDE_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
Lloyd Atkinsond0fedd02017-03-01 13:25:40 -05002366
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07002367 if (!sde_enc->frame_busy_mask[0]) {
2368 /**
2369 * suppress frame_done without waiter,
2370 * likely autorefresh
2371 */
2372 SDE_EVT32(DRMID(drm_enc), event, ready_phys->intf_idx);
2373 return;
Alan Kwong628d19e2016-10-31 13:50:13 -04002374 }
2375
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07002376 /* One of the physical encoders has become idle */
2377 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2378 if (sde_enc->phys_encs[i] == ready_phys) {
2379 clear_bit(i, sde_enc->frame_busy_mask);
2380 SDE_EVT32_VERBOSE(DRMID(drm_enc), i,
2381 sde_enc->frame_busy_mask[0]);
2382 }
2383 }
Alan Kwong628d19e2016-10-31 13:50:13 -04002384
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07002385 if (!sde_enc->frame_busy_mask[0]) {
2386 atomic_set(&sde_enc->frame_done_timeout, 0);
2387 del_timer(&sde_enc->frame_done_timer);
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07002388
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07002389 sde_encoder_resource_control(drm_enc,
2390 SDE_ENC_RC_EVENT_FRAME_DONE);
2391
2392 if (sde_enc->crtc_frame_event_cb)
2393 sde_enc->crtc_frame_event_cb(
2394 sde_enc->crtc_frame_event_cb_data,
2395 event);
2396 }
2397 } else {
Alan Kwong628d19e2016-10-31 13:50:13 -04002398 if (sde_enc->crtc_frame_event_cb)
2399 sde_enc->crtc_frame_event_cb(
Ingrid Gallardo79b44392017-05-30 16:30:52 -07002400 sde_enc->crtc_frame_event_cb_data, event);
Alan Kwong628d19e2016-10-31 13:50:13 -04002401 }
2402}
2403
Dhaval Patele17e0ee2017-08-23 18:01:42 -07002404static void sde_encoder_off_work(struct kthread_work *work)
2405{
2406 struct sde_encoder_virt *sde_enc = container_of(work,
2407 struct sde_encoder_virt, delayed_off_work.work);
2408
2409 if (!sde_enc) {
2410 SDE_ERROR("invalid sde encoder\n");
2411 return;
2412 }
2413
2414 sde_encoder_resource_control(&sde_enc->base,
2415 SDE_ENC_RC_EVENT_ENTER_IDLE);
2416
2417 sde_encoder_frame_done_callback(&sde_enc->base, NULL,
2418 SDE_ENCODER_FRAME_EVENT_IDLE);
2419}
2420
Clarence Ip110d15c2016-08-16 14:44:41 -04002421/**
2422 * _sde_encoder_trigger_flush - trigger flush for a physical encoder
2423 * drm_enc: Pointer to drm encoder structure
2424 * phys: Pointer to physical encoder structure
2425 * extra_flush_bits: Additional bit mask to include in flush trigger
2426 */
2427static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
2428 struct sde_encoder_phys *phys, uint32_t extra_flush_bits)
2429{
2430 struct sde_hw_ctl *ctl;
Clarence Ip8e69ad02016-12-09 09:43:57 -05002431 int pending_kickoff_cnt;
Clarence Ip110d15c2016-08-16 14:44:41 -04002432
2433 if (!drm_enc || !phys) {
2434 SDE_ERROR("invalid argument(s), drm_enc %d, phys_enc %d\n",
2435 drm_enc != 0, phys != 0);
2436 return;
2437 }
2438
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -04002439 if (!phys->hw_pp) {
2440 SDE_ERROR("invalid pingpong hw\n");
2441 return;
2442 }
2443
Clarence Ip110d15c2016-08-16 14:44:41 -04002444 ctl = phys->hw_ctl;
Alan Kwong4212dd42017-09-19 17:22:33 -04002445 if (!ctl || !phys->ops.trigger_flush) {
2446 SDE_ERROR("missing ctl/trigger cb\n");
Clarence Ip110d15c2016-08-16 14:44:41 -04002447 return;
2448 }
2449
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002450 if (phys->split_role == ENC_ROLE_SKIP) {
2451 SDE_DEBUG_ENC(to_sde_encoder_virt(phys->parent),
2452 "skip flush pp%d ctl%d\n",
2453 phys->hw_pp->idx - PINGPONG_0,
2454 ctl->idx - CTL_0);
2455 return;
2456 }
2457
Clarence Ip8e69ad02016-12-09 09:43:57 -05002458 pending_kickoff_cnt = sde_encoder_phys_inc_pending(phys);
Clarence Ip8e69ad02016-12-09 09:43:57 -05002459
Veera Sundaram Sankaran675ff622017-06-21 21:44:46 -07002460 if (phys->ops.is_master && phys->ops.is_master(phys))
2461 atomic_inc(&phys->pending_retire_fence_cnt);
2462
Clarence Ip110d15c2016-08-16 14:44:41 -04002463 if (extra_flush_bits && ctl->ops.update_pending_flush)
2464 ctl->ops.update_pending_flush(ctl, extra_flush_bits);
2465
Alan Kwong4212dd42017-09-19 17:22:33 -04002466 phys->ops.trigger_flush(phys);
Dhaval Patel6c666622017-03-21 23:02:59 -07002467
2468 if (ctl->ops.get_pending_flush)
2469 SDE_EVT32(DRMID(drm_enc), phys->intf_idx, pending_kickoff_cnt,
2470 ctl->idx, ctl->ops.get_pending_flush(ctl));
2471 else
2472 SDE_EVT32(DRMID(drm_enc), phys->intf_idx, ctl->idx,
2473 pending_kickoff_cnt);
Clarence Ip110d15c2016-08-16 14:44:41 -04002474}
2475
2476/**
2477 * _sde_encoder_trigger_start - trigger start for a physical encoder
2478 * phys: Pointer to physical encoder structure
2479 */
2480static inline void _sde_encoder_trigger_start(struct sde_encoder_phys *phys)
2481{
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002482 struct sde_hw_ctl *ctl;
2483
Clarence Ip110d15c2016-08-16 14:44:41 -04002484 if (!phys) {
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -04002485 SDE_ERROR("invalid argument(s)\n");
2486 return;
2487 }
2488
2489 if (!phys->hw_pp) {
2490 SDE_ERROR("invalid pingpong hw\n");
Clarence Ip110d15c2016-08-16 14:44:41 -04002491 return;
2492 }
2493
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002494 ctl = phys->hw_ctl;
2495 if (phys->split_role == ENC_ROLE_SKIP) {
2496 SDE_DEBUG_ENC(to_sde_encoder_virt(phys->parent),
2497 "skip start pp%d ctl%d\n",
2498 phys->hw_pp->idx - PINGPONG_0,
2499 ctl->idx - CTL_0);
2500 return;
2501 }
Clarence Ip110d15c2016-08-16 14:44:41 -04002502 if (phys->ops.trigger_start && phys->enable_state != SDE_ENC_DISABLED)
2503 phys->ops.trigger_start(phys);
2504}
2505
Alan Kwong4212dd42017-09-19 17:22:33 -04002506void sde_encoder_helper_trigger_flush(struct sde_encoder_phys *phys_enc)
2507{
2508 struct sde_hw_ctl *ctl;
2509
2510 if (!phys_enc) {
2511 SDE_ERROR("invalid encoder\n");
2512 return;
2513 }
2514
2515 ctl = phys_enc->hw_ctl;
2516 if (ctl && ctl->ops.trigger_flush)
2517 ctl->ops.trigger_flush(ctl);
2518}
2519
Clarence Ip110d15c2016-08-16 14:44:41 -04002520void sde_encoder_helper_trigger_start(struct sde_encoder_phys *phys_enc)
2521{
2522 struct sde_hw_ctl *ctl;
Clarence Ip110d15c2016-08-16 14:44:41 -04002523
2524 if (!phys_enc) {
2525 SDE_ERROR("invalid encoder\n");
2526 return;
2527 }
2528
2529 ctl = phys_enc->hw_ctl;
2530 if (ctl && ctl->ops.trigger_start) {
2531 ctl->ops.trigger_start(ctl);
Dhaval Patel6c666622017-03-21 23:02:59 -07002532 SDE_EVT32(DRMID(phys_enc->parent), ctl->idx);
Clarence Ip110d15c2016-08-16 14:44:41 -04002533 }
Clarence Ip110d15c2016-08-16 14:44:41 -04002534}
2535
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05002536int sde_encoder_helper_wait_event_timeout(
2537 int32_t drm_id,
2538 int32_t hw_id,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -05002539 struct sde_encoder_wait_info *info)
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05002540{
2541 int rc = 0;
Lloyd Atkinson05ef8232017-03-08 16:35:36 -05002542 s64 expected_time = ktime_to_ms(ktime_get()) + info->timeout_ms;
2543 s64 jiffies = msecs_to_jiffies(info->timeout_ms);
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05002544 s64 time;
2545
2546 do {
Lloyd Atkinson05ef8232017-03-08 16:35:36 -05002547 rc = wait_event_timeout(*(info->wq),
2548 atomic_read(info->atomic_cnt) == 0, jiffies);
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05002549 time = ktime_to_ms(ktime_get());
2550
Dhaval Patela5f75952017-07-25 11:17:41 -07002551 SDE_EVT32_VERBOSE(drm_id, hw_id, rc, time, expected_time,
Lloyd Atkinson05ef8232017-03-08 16:35:36 -05002552 atomic_read(info->atomic_cnt));
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05002553 /* If we timed out, counter is valid and time is less, wait again */
Lloyd Atkinson05ef8232017-03-08 16:35:36 -05002554 } while (atomic_read(info->atomic_cnt) && (rc == 0) &&
2555 (time < expected_time));
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05002556
2557 return rc;
2558}
2559
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05002560void sde_encoder_helper_hw_reset(struct sde_encoder_phys *phys_enc)
2561{
2562 struct sde_encoder_virt *sde_enc;
2563 struct sde_connector *sde_con;
2564 void *sde_con_disp;
2565 struct sde_hw_ctl *ctl;
2566 int rc;
2567
2568 if (!phys_enc) {
2569 SDE_ERROR("invalid encoder\n");
2570 return;
2571 }
2572 sde_enc = to_sde_encoder_virt(phys_enc->parent);
2573 ctl = phys_enc->hw_ctl;
2574
2575 if (!ctl || !ctl->ops.reset)
2576 return;
2577
2578 SDE_DEBUG_ENC(sde_enc, "ctl %d reset\n", ctl->idx);
2579 SDE_EVT32(DRMID(phys_enc->parent), ctl->idx);
2580
2581 if (phys_enc->ops.is_master && phys_enc->ops.is_master(phys_enc) &&
2582 phys_enc->connector) {
2583 sde_con = to_sde_connector(phys_enc->connector);
2584 sde_con_disp = sde_connector_get_display(phys_enc->connector);
2585
2586 if (sde_con->ops.soft_reset) {
2587 rc = sde_con->ops.soft_reset(sde_con_disp);
2588 if (rc) {
2589 SDE_ERROR_ENC(sde_enc,
2590 "connector soft reset failure\n");
Dhaval Patel7ca510f2017-07-12 12:57:37 -07002591 SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus",
2592 "panic");
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05002593 }
2594 }
2595 }
2596
2597 rc = ctl->ops.reset(ctl);
2598 if (rc) {
2599 SDE_ERROR_ENC(sde_enc, "ctl %d reset failure\n", ctl->idx);
Dhaval Patel7ca510f2017-07-12 12:57:37 -07002600 SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05002601 }
2602
2603 phys_enc->enable_state = SDE_ENC_ENABLED;
2604}
2605
Clarence Ip110d15c2016-08-16 14:44:41 -04002606/**
2607 * _sde_encoder_kickoff_phys - handle physical encoder kickoff
2608 * Iterate through the physical encoders and perform consolidated flush
2609 * and/or control start triggering as needed. This is done in the virtual
2610 * encoder rather than the individual physical ones in order to handle
2611 * use cases that require visibility into multiple physical encoders at
2612 * a time.
2613 * sde_enc: Pointer to virtual encoder structure
2614 */
2615static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
2616{
2617 struct sde_hw_ctl *ctl;
2618 uint32_t i, pending_flush;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002619 unsigned long lock_flags;
Clarence Ip110d15c2016-08-16 14:44:41 -04002620
2621 if (!sde_enc) {
2622 SDE_ERROR("invalid encoder\n");
2623 return;
2624 }
2625
2626 pending_flush = 0x0;
2627
Ingrid Gallardo61210ea2017-10-17 17:29:31 -07002628 /*
2629 * Trigger LUT DMA flush, this might need a wait, so we need
2630 * to do this outside of the atomic context
2631 */
2632 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2633 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
2634 bool wait_for_dma = false;
2635
2636 if (!phys || phys->enable_state == SDE_ENC_DISABLED)
2637 continue;
2638
2639 ctl = phys->hw_ctl;
2640 if (!ctl)
2641 continue;
2642
2643 if (phys->ops.wait_dma_trigger)
2644 wait_for_dma = phys->ops.wait_dma_trigger(phys);
2645
2646 if (phys->hw_ctl->ops.reg_dma_flush)
2647 phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl,
2648 wait_for_dma);
2649 }
2650
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002651 /* update pending counts and trigger kickoff ctl flush atomically */
2652 spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
2653
Clarence Ip110d15c2016-08-16 14:44:41 -04002654 /* don't perform flush/start operations for slave encoders */
2655 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2656 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Jeykumar Sankaran2b098072017-03-16 17:25:59 -07002657 enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;
Clarence Ip8e69ad02016-12-09 09:43:57 -05002658
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002659 if (!phys || phys->enable_state == SDE_ENC_DISABLED)
2660 continue;
2661
Clarence Ip110d15c2016-08-16 14:44:41 -04002662 ctl = phys->hw_ctl;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002663 if (!ctl)
Clarence Ip110d15c2016-08-16 14:44:41 -04002664 continue;
2665
Lloyd Atkinson8c50e152017-02-01 19:03:17 -05002666 if (phys->connector)
2667 topology = sde_connector_get_topology_name(
2668 phys->connector);
2669
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002670 /*
2671 * don't wait on ppsplit slaves or skipped encoders because
2672 * they dont receive irqs
2673 */
Lloyd Atkinson8c50e152017-02-01 19:03:17 -05002674 if (!(topology == SDE_RM_TOPOLOGY_PPSPLIT &&
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002675 phys->split_role == ENC_ROLE_SLAVE) &&
2676 phys->split_role != ENC_ROLE_SKIP)
Lloyd Atkinson8c50e152017-02-01 19:03:17 -05002677 set_bit(i, sde_enc->frame_busy_mask);
Ingrid Gallardo61210ea2017-10-17 17:29:31 -07002678
Clarence Ip8e69ad02016-12-09 09:43:57 -05002679 if (!phys->ops.needs_single_flush ||
2680 !phys->ops.needs_single_flush(phys))
Clarence Ip110d15c2016-08-16 14:44:41 -04002681 _sde_encoder_trigger_flush(&sde_enc->base, phys, 0x0);
2682 else if (ctl->ops.get_pending_flush)
2683 pending_flush |= ctl->ops.get_pending_flush(ctl);
2684 }
2685
2686 /* for split flush, combine pending flush masks and send to master */
2687 if (pending_flush && sde_enc->cur_master) {
2688 _sde_encoder_trigger_flush(
2689 &sde_enc->base,
2690 sde_enc->cur_master,
2691 pending_flush);
2692 }
2693
2694 _sde_encoder_trigger_start(sde_enc->cur_master);
Lloyd Atkinson7d070942016-07-26 18:35:12 -04002695
2696 spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
Clarence Ip110d15c2016-08-16 14:44:41 -04002697}
2698
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -05002699static void _sde_encoder_ppsplit_swap_intf_for_right_only_update(
2700 struct drm_encoder *drm_enc,
2701 unsigned long *affected_displays,
2702 int num_active_phys)
2703{
2704 struct sde_encoder_virt *sde_enc;
2705 struct sde_encoder_phys *master;
2706 enum sde_rm_topology_name topology;
2707 bool is_right_only;
2708
2709 if (!drm_enc || !affected_displays)
2710 return;
2711
2712 sde_enc = to_sde_encoder_virt(drm_enc);
2713 master = sde_enc->cur_master;
2714 if (!master || !master->connector)
2715 return;
2716
2717 topology = sde_connector_get_topology_name(master->connector);
2718 if (topology != SDE_RM_TOPOLOGY_PPSPLIT)
2719 return;
2720
2721 /*
2722 * For pingpong split, the slave pingpong won't generate IRQs. For
2723 * right-only updates, we can't swap pingpongs, or simply swap the
2724 * master/slave assignment, we actually have to swap the interfaces
2725 * so that the master physical encoder will use a pingpong/interface
2726 * that generates irqs on which to wait.
2727 */
2728 is_right_only = !test_bit(0, affected_displays) &&
2729 test_bit(1, affected_displays);
2730
2731 if (is_right_only && !sde_enc->intfs_swapped) {
2732 /* right-only update swap interfaces */
2733 swap(sde_enc->phys_encs[0]->intf_idx,
2734 sde_enc->phys_encs[1]->intf_idx);
2735 sde_enc->intfs_swapped = true;
2736 } else if (!is_right_only && sde_enc->intfs_swapped) {
2737 /* left-only or full update, swap back */
2738 swap(sde_enc->phys_encs[0]->intf_idx,
2739 sde_enc->phys_encs[1]->intf_idx);
2740 sde_enc->intfs_swapped = false;
2741 }
2742
2743 SDE_DEBUG_ENC(sde_enc,
2744 "right_only %d swapped %d phys0->intf%d, phys1->intf%d\n",
2745 is_right_only, sde_enc->intfs_swapped,
2746 sde_enc->phys_encs[0]->intf_idx - INTF_0,
2747 sde_enc->phys_encs[1]->intf_idx - INTF_0);
2748 SDE_EVT32(DRMID(drm_enc), is_right_only, sde_enc->intfs_swapped,
2749 sde_enc->phys_encs[0]->intf_idx - INTF_0,
2750 sde_enc->phys_encs[1]->intf_idx - INTF_0,
2751 *affected_displays);
2752
2753 /* ppsplit always uses master since ppslave invalid for irqs*/
2754 if (num_active_phys == 1)
2755 *affected_displays = BIT(0);
2756}
2757
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002758static void _sde_encoder_update_master(struct drm_encoder *drm_enc,
2759 struct sde_encoder_kickoff_params *params)
2760{
2761 struct sde_encoder_virt *sde_enc;
2762 struct sde_encoder_phys *phys;
2763 int i, num_active_phys;
2764 bool master_assigned = false;
2765
2766 if (!drm_enc || !params)
2767 return;
2768
2769 sde_enc = to_sde_encoder_virt(drm_enc);
2770
2771 if (sde_enc->num_phys_encs <= 1)
2772 return;
2773
2774 /* count bits set */
2775 num_active_phys = hweight_long(params->affected_displays);
2776
2777 SDE_DEBUG_ENC(sde_enc, "affected_displays 0x%lx num_active_phys %d\n",
2778 params->affected_displays, num_active_phys);
2779
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -05002780 /* for left/right only update, ppsplit master switches interface */
2781 _sde_encoder_ppsplit_swap_intf_for_right_only_update(drm_enc,
2782 &params->affected_displays, num_active_phys);
2783
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002784 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2785 enum sde_enc_split_role prv_role, new_role;
2786 bool active;
2787
2788 phys = sde_enc->phys_encs[i];
Lloyd Atkinson6a5359d2017-06-21 10:18:08 -04002789 if (!phys || !phys->ops.update_split_role || !phys->hw_pp)
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002790 continue;
2791
2792 active = test_bit(i, &params->affected_displays);
2793 prv_role = phys->split_role;
2794
2795 if (active && num_active_phys == 1)
2796 new_role = ENC_ROLE_SOLO;
2797 else if (active && !master_assigned)
2798 new_role = ENC_ROLE_MASTER;
2799 else if (active)
2800 new_role = ENC_ROLE_SLAVE;
2801 else
2802 new_role = ENC_ROLE_SKIP;
2803
2804 phys->ops.update_split_role(phys, new_role);
2805 if (new_role == ENC_ROLE_SOLO || new_role == ENC_ROLE_MASTER) {
2806 sde_enc->cur_master = phys;
2807 master_assigned = true;
2808 }
2809
2810 SDE_DEBUG_ENC(sde_enc, "pp %d role prv %d new %d active %d\n",
2811 phys->hw_pp->idx - PINGPONG_0, prv_role,
2812 phys->split_role, active);
Lloyd Atkinson66e7dde2017-02-08 15:52:53 -05002813 SDE_EVT32(DRMID(drm_enc), params->affected_displays,
2814 phys->hw_pp->idx - PINGPONG_0, prv_role,
2815 phys->split_role, active, num_active_phys);
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05002816 }
2817}
2818
Sravanthi Kollukuduru59d431a2017-07-05 00:10:41 +05302819bool sde_encoder_check_mode(struct drm_encoder *drm_enc, u32 mode)
Veera Sundaram Sankaran2c748e62017-06-13 17:01:48 -07002820{
2821 struct sde_encoder_virt *sde_enc;
2822 struct msm_display_info *disp_info;
2823
2824 if (!drm_enc) {
2825 SDE_ERROR("invalid encoder\n");
2826 return false;
2827 }
2828
2829 sde_enc = to_sde_encoder_virt(drm_enc);
2830 disp_info = &sde_enc->disp_info;
2831
Sravanthi Kollukuduru59d431a2017-07-05 00:10:41 +05302832 return (disp_info->capabilities & mode);
Veera Sundaram Sankaran2c748e62017-06-13 17:01:48 -07002833}
2834
Dhaval Patel0e558f42017-04-30 00:51:40 -07002835void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
2836{
2837 struct sde_encoder_virt *sde_enc;
2838 struct sde_encoder_phys *phys;
2839 unsigned int i;
2840 struct sde_hw_ctl *ctl;
2841 struct msm_display_info *disp_info;
2842
2843 if (!drm_enc) {
2844 SDE_ERROR("invalid encoder\n");
2845 return;
2846 }
2847 sde_enc = to_sde_encoder_virt(drm_enc);
2848 disp_info = &sde_enc->disp_info;
2849
2850 for (i = 0; i < sde_enc->num_phys_encs; i++) {
2851 phys = sde_enc->phys_encs[i];
2852
2853 if (phys && phys->hw_ctl) {
2854 ctl = phys->hw_ctl;
2855 if (ctl->ops.clear_pending_flush)
2856 ctl->ops.clear_pending_flush(ctl);
2857
2858 /* update only for command mode primary ctl */
2859 if ((phys == sde_enc->cur_master) &&
2860 (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE)
2861 && ctl->ops.trigger_pending)
2862 ctl->ops.trigger_pending(ctl);
2863 }
2864 }
2865}
2866
Ping Li8430ee12017-02-24 14:14:44 -08002867static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
2868{
2869 void *dither_cfg;
2870 int ret = 0;
2871 size_t len = 0;
2872 enum sde_rm_topology_name topology;
2873
2874 if (!phys || !phys->connector || !phys->hw_pp ||
2875 !phys->hw_pp->ops.setup_dither)
2876 return;
2877 topology = sde_connector_get_topology_name(phys->connector);
2878 if ((topology == SDE_RM_TOPOLOGY_PPSPLIT) &&
2879 (phys->split_role == ENC_ROLE_SLAVE))
2880 return;
2881
2882 ret = sde_connector_get_dither_cfg(phys->connector,
2883 phys->connector->state, &dither_cfg, &len);
2884 if (!ret)
2885 phys->hw_pp->ops.setup_dither(phys->hw_pp, dither_cfg, len);
2886}
2887
Benjamin Chan9cd866d2017-08-15 14:56:34 -04002888static u32 _sde_encoder_calculate_linetime(struct sde_encoder_virt *sde_enc,
2889 struct drm_display_mode *mode)
2890{
2891 u64 pclk_rate;
2892 u32 pclk_period;
2893 u32 line_time;
2894
2895 /*
2896 * For linetime calculation, only operate on master encoder.
2897 */
2898 if (!sde_enc->cur_master)
2899 return 0;
2900
2901 if (!sde_enc->cur_master->ops.get_line_count) {
2902 SDE_ERROR("get_line_count function not defined\n");
2903 return 0;
2904 }
2905
2906 pclk_rate = mode->clock; /* pixel clock in kHz */
2907 if (pclk_rate == 0) {
2908 SDE_ERROR("pclk is 0, cannot calculate line time\n");
2909 return 0;
2910 }
2911
2912 pclk_period = DIV_ROUND_UP_ULL(1000000000ull, pclk_rate);
2913 if (pclk_period == 0) {
2914 SDE_ERROR("pclk period is 0\n");
2915 return 0;
2916 }
2917
2918 /*
2919 * Line time calculation based on Pixel clock and HTOTAL.
2920 * Final unit is in ns.
2921 */
2922 line_time = (pclk_period * mode->htotal) / 1000;
2923 if (line_time == 0) {
2924 SDE_ERROR("line time calculation is 0\n");
2925 return 0;
2926 }
2927
2928 SDE_DEBUG_ENC(sde_enc,
2929 "clk_rate=%lldkHz, clk_period=%d, linetime=%dns\n",
2930 pclk_rate, pclk_period, line_time);
2931
2932 return line_time;
2933}
2934
2935static int _sde_encoder_wakeup_time(struct drm_encoder *drm_enc,
2936 ktime_t *wakeup_time)
2937{
2938 struct drm_display_mode *mode;
2939 struct sde_encoder_virt *sde_enc;
2940 u32 cur_line;
2941 u32 line_time;
2942 u32 vtotal, time_to_vsync;
2943 ktime_t cur_time;
2944
2945 sde_enc = to_sde_encoder_virt(drm_enc);
2946
2947 if (!drm_enc->crtc || !drm_enc->crtc->state) {
2948 SDE_ERROR("crtc/crtc state object is NULL\n");
2949 return -EINVAL;
2950 }
2951 mode = &drm_enc->crtc->state->adjusted_mode;
2952
2953 line_time = _sde_encoder_calculate_linetime(sde_enc, mode);
2954 if (!line_time)
2955 return -EINVAL;
2956
2957 cur_line = sde_enc->cur_master->ops.get_line_count(sde_enc->cur_master);
2958
2959 vtotal = mode->vtotal;
2960 if (cur_line >= vtotal)
2961 time_to_vsync = line_time * vtotal;
2962 else
2963 time_to_vsync = line_time * (vtotal - cur_line);
2964
2965 if (time_to_vsync == 0) {
2966 SDE_ERROR("time to vsync should not be zero, vtotal=%d\n",
2967 vtotal);
2968 return -EINVAL;
2969 }
2970
2971 cur_time = ktime_get();
2972 *wakeup_time = ktime_add_ns(cur_time, time_to_vsync);
2973
2974 SDE_DEBUG_ENC(sde_enc,
2975 "cur_line=%u vtotal=%u time_to_vsync=%u, cur_time=%lld, wakeup_time=%lld\n",
2976 cur_line, vtotal, time_to_vsync,
2977 ktime_to_ms(cur_time),
2978 ktime_to_ms(*wakeup_time));
2979 return 0;
2980}
2981
2982static void sde_encoder_vsync_event_handler(unsigned long data)
2983{
2984 struct drm_encoder *drm_enc = (struct drm_encoder *) data;
2985 struct sde_encoder_virt *sde_enc;
2986 struct msm_drm_private *priv;
2987 struct msm_drm_thread *event_thread;
2988 bool autorefresh_enabled = false;
2989
2990 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
2991 !drm_enc->crtc) {
2992 SDE_ERROR("invalid parameters\n");
2993 return;
2994 }
2995
2996 sde_enc = to_sde_encoder_virt(drm_enc);
2997 priv = drm_enc->dev->dev_private;
2998
2999 if (drm_enc->crtc->index >= ARRAY_SIZE(priv->event_thread)) {
3000 SDE_ERROR("invalid crtc index\n");
3001 return;
3002 }
3003 event_thread = &priv->event_thread[drm_enc->crtc->index];
3004 if (!event_thread) {
3005 SDE_ERROR("event_thread not found for crtc:%d\n",
3006 drm_enc->crtc->index);
3007 return;
3008 }
3009
3010 if (sde_enc->cur_master &&
3011 sde_enc->cur_master->ops.is_autorefresh_enabled)
3012 autorefresh_enabled =
3013 sde_enc->cur_master->ops.is_autorefresh_enabled(
3014 sde_enc->cur_master);
3015
3016 /*
3017 * Queue work to update the vsync event timer
3018 * if autorefresh is enabled.
3019 */
3020 SDE_EVT32_VERBOSE(autorefresh_enabled);
3021 if (autorefresh_enabled)
3022 kthread_queue_work(&event_thread->worker,
3023 &sde_enc->vsync_event_work);
3024 else
3025 del_timer(&sde_enc->vsync_event_timer);
3026}
3027
3028static void sde_encoder_vsync_event_work_handler(struct kthread_work *work)
3029{
3030 struct sde_encoder_virt *sde_enc = container_of(work,
3031 struct sde_encoder_virt, vsync_event_work);
3032 ktime_t wakeup_time;
3033
3034 if (!sde_enc) {
3035 SDE_ERROR("invalid sde encoder\n");
3036 return;
3037 }
3038
3039 if (_sde_encoder_wakeup_time(&sde_enc->base, &wakeup_time))
3040 return;
3041
3042 SDE_EVT32_VERBOSE(ktime_to_ms(wakeup_time));
3043 mod_timer(&sde_enc->vsync_event_timer,
3044 nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
3045}
3046
Clarence Ip85f4f4532017-10-04 12:10:13 -04003047int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
Alan Kwong4aacd532017-02-04 18:51:33 -08003048 struct sde_encoder_kickoff_params *params)
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003049{
3050 struct sde_encoder_virt *sde_enc;
3051 struct sde_encoder_phys *phys;
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003052 bool needs_hw_reset = false;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003053 unsigned int i;
Clarence Ip85f4f4532017-10-04 12:10:13 -04003054 int rc, ret = 0;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003055
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003056 if (!drm_enc || !params) {
3057 SDE_ERROR("invalid args\n");
Clarence Ip85f4f4532017-10-04 12:10:13 -04003058 return -EINVAL;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003059 }
3060 sde_enc = to_sde_encoder_virt(drm_enc);
3061
Clarence Ip19af1362016-09-23 14:57:51 -04003062 SDE_DEBUG_ENC(sde_enc, "\n");
Lloyd Atkinson5d40d312016-09-06 08:34:13 -04003063 SDE_EVT32(DRMID(drm_enc));
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003064
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003065 /* prepare for next kickoff, may include waiting on previous kickoff */
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07003066 SDE_ATRACE_BEGIN("enc_prepare_for_kickoff");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003067 for (i = 0; i < sde_enc->num_phys_encs; i++) {
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003068 phys = sde_enc->phys_encs[i];
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003069 if (phys) {
Clarence Ip85f4f4532017-10-04 12:10:13 -04003070 if (phys->ops.prepare_for_kickoff) {
3071 rc = phys->ops.prepare_for_kickoff(
3072 phys, params);
3073 if (rc)
3074 ret = rc;
3075 }
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003076 if (phys->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET)
3077 needs_hw_reset = true;
Ping Li8430ee12017-02-24 14:14:44 -08003078 _sde_encoder_setup_dither(phys);
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003079 }
3080 }
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07003081 SDE_ATRACE_END("enc_prepare_for_kickoff");
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003082
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07003083 sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF);
3084
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003085 /* if any phys needs reset, reset all phys, in-order */
3086 if (needs_hw_reset) {
Dhaval Patel0e558f42017-04-30 00:51:40 -07003087 SDE_EVT32(DRMID(drm_enc), SDE_EVTLOG_FUNC_CASE1);
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003088 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3089 phys = sde_enc->phys_encs[i];
3090 if (phys && phys->ops.hw_reset)
3091 phys->ops.hw_reset(phys);
3092 }
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003093 }
Lloyd Atkinson05d75512017-01-17 14:45:51 -05003094
Lloyd Atkinson73fb8092017-02-08 16:02:55 -05003095 _sde_encoder_update_master(drm_enc, params);
3096
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04003097 _sde_encoder_update_roi(drm_enc);
3098
Lloyd Atkinson05d75512017-01-17 14:45:51 -05003099 if (sde_enc->cur_master && sde_enc->cur_master->connector) {
3100 rc = sde_connector_pre_kickoff(sde_enc->cur_master->connector);
Clarence Ip85f4f4532017-10-04 12:10:13 -04003101 if (rc) {
Lloyd Atkinson05d75512017-01-17 14:45:51 -05003102 SDE_ERROR_ENC(sde_enc, "kickoff conn%d failed rc %d\n",
3103 sde_enc->cur_master->connector->base.id,
3104 rc);
Clarence Ip85f4f4532017-10-04 12:10:13 -04003105 ret = rc;
3106 }
Lloyd Atkinson05d75512017-01-17 14:45:51 -05003107 }
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04003108
Lloyd Atkinson094780d2017-04-24 17:25:08 -04003109 if (sde_encoder_is_dsc_enabled(drm_enc)) {
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04003110 rc = _sde_encoder_dsc_setup(sde_enc, params);
Clarence Ip85f4f4532017-10-04 12:10:13 -04003111 if (rc) {
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04003112 SDE_ERROR_ENC(sde_enc, "failed to setup DSC: %d\n", rc);
Clarence Ip85f4f4532017-10-04 12:10:13 -04003113 ret = rc;
3114 }
Lloyd Atkinsonb22f9a42017-05-17 17:29:56 -04003115 }
Clarence Ip85f4f4532017-10-04 12:10:13 -04003116
3117 return ret;
Alan Kwong628d19e2016-10-31 13:50:13 -04003118}
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003119
Clarence Ip662698e2017-09-12 18:34:16 -04003120/**
3121 * _sde_encoder_reset_ctl_hw - reset h/w configuration for all ctl's associated
3122 * with the specified encoder, and unstage all pipes from it
3123 * @encoder: encoder pointer
3124 * Returns: 0 on success
3125 */
3126static int _sde_encoder_reset_ctl_hw(struct drm_encoder *drm_enc)
3127{
3128 struct sde_encoder_virt *sde_enc;
3129 struct sde_encoder_phys *phys;
3130 unsigned int i;
3131 int rc = 0;
3132
3133 if (!drm_enc) {
3134 SDE_ERROR("invalid encoder\n");
3135 return -EINVAL;
3136 }
3137
3138 sde_enc = to_sde_encoder_virt(drm_enc);
3139
3140 SDE_ATRACE_BEGIN("encoder_release_lm");
3141 SDE_DEBUG_ENC(sde_enc, "\n");
3142
3143 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3144 phys = sde_enc->phys_encs[i];
3145 if (!phys)
3146 continue;
3147
3148 SDE_EVT32(DRMID(drm_enc), phys->intf_idx - INTF_0);
3149
3150 rc = sde_encoder_helper_reset_mixers(phys, NULL);
3151 if (rc)
3152 SDE_EVT32(DRMID(drm_enc), rc, SDE_EVTLOG_ERROR);
3153 }
3154
3155 SDE_ATRACE_END("encoder_release_lm");
3156 return rc;
3157}
3158
3159void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error)
Alan Kwong628d19e2016-10-31 13:50:13 -04003160{
3161 struct sde_encoder_virt *sde_enc;
3162 struct sde_encoder_phys *phys;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003163 ktime_t wakeup_time;
Alan Kwong628d19e2016-10-31 13:50:13 -04003164 unsigned int i;
3165
3166 if (!drm_enc) {
3167 SDE_ERROR("invalid encoder\n");
3168 return;
3169 }
Narendra Muppalla77b32932017-05-10 13:53:11 -07003170 SDE_ATRACE_BEGIN("encoder_kickoff");
Alan Kwong628d19e2016-10-31 13:50:13 -04003171 sde_enc = to_sde_encoder_virt(drm_enc);
3172
3173 SDE_DEBUG_ENC(sde_enc, "\n");
3174
3175 atomic_set(&sde_enc->frame_done_timeout,
Veera Sundaram Sankaran7ee99092017-06-13 11:19:36 -07003176 SDE_FRAME_DONE_TIMEOUT * 1000 /
Alan Kwong628d19e2016-10-31 13:50:13 -04003177 drm_enc->crtc->state->adjusted_mode.vrefresh);
3178 mod_timer(&sde_enc->frame_done_timer, jiffies +
3179 ((atomic_read(&sde_enc->frame_done_timeout) * HZ) / 1000));
3180
Clarence Ip662698e2017-09-12 18:34:16 -04003181 /* create a 'no pipes' commit to release buffers on errors */
3182 if (is_error)
3183 _sde_encoder_reset_ctl_hw(drm_enc);
3184
Alan Kwong628d19e2016-10-31 13:50:13 -04003185 /* All phys encs are ready to go, trigger the kickoff */
Clarence Ip110d15c2016-08-16 14:44:41 -04003186 _sde_encoder_kickoff_phys(sde_enc);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003187
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003188 /* allow phys encs to handle any post-kickoff business */
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003189 for (i = 0; i < sde_enc->num_phys_encs; i++) {
Lloyd Atkinsonaa0dce92016-11-23 20:16:47 -05003190 phys = sde_enc->phys_encs[i];
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003191 if (phys && phys->ops.handle_post_kickoff)
3192 phys->ops.handle_post_kickoff(phys);
3193 }
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003194
3195 if (sde_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DSI &&
3196 !_sde_encoder_wakeup_time(drm_enc, &wakeup_time)) {
3197 SDE_EVT32_VERBOSE(ktime_to_ms(wakeup_time));
3198 mod_timer(&sde_enc->vsync_event_timer,
3199 nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
3200 }
3201
Narendra Muppalla77b32932017-05-10 13:53:11 -07003202 SDE_ATRACE_END("encoder_kickoff");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003203}
3204
Clarence Ip662698e2017-09-12 18:34:16 -04003205int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc,
Clarence Ip9c65f7b2017-03-20 06:48:15 -07003206 struct drm_framebuffer *fb)
3207{
3208 struct drm_encoder *drm_enc;
3209 struct sde_hw_mixer_cfg mixer;
3210 struct sde_rm_hw_iter lm_iter;
3211 bool lm_valid = false;
3212
3213 if (!phys_enc || !phys_enc->parent) {
3214 SDE_ERROR("invalid encoder\n");
3215 return -EINVAL;
3216 }
3217
3218 drm_enc = phys_enc->parent;
3219 memset(&mixer, 0, sizeof(mixer));
3220
3221 /* reset associated CTL/LMs */
Clarence Ip9c65f7b2017-03-20 06:48:15 -07003222 if (phys_enc->hw_ctl->ops.clear_all_blendstages)
3223 phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl);
3224
3225 sde_rm_init_hw_iter(&lm_iter, drm_enc->base.id, SDE_HW_BLK_LM);
3226 while (sde_rm_get_hw(&phys_enc->sde_kms->rm, &lm_iter)) {
3227 struct sde_hw_mixer *hw_lm = (struct sde_hw_mixer *)lm_iter.hw;
3228
3229 if (!hw_lm)
3230 continue;
3231
3232 /* need to flush LM to remove it */
3233 if (phys_enc->hw_ctl->ops.get_bitmask_mixer &&
3234 phys_enc->hw_ctl->ops.update_pending_flush)
3235 phys_enc->hw_ctl->ops.update_pending_flush(
3236 phys_enc->hw_ctl,
3237 phys_enc->hw_ctl->ops.get_bitmask_mixer(
3238 phys_enc->hw_ctl, hw_lm->idx));
3239
3240 if (fb) {
3241 /* assume a single LM if targeting a frame buffer */
3242 if (lm_valid)
3243 continue;
3244
3245 mixer.out_height = fb->height;
3246 mixer.out_width = fb->width;
3247
3248 if (hw_lm->ops.setup_mixer_out)
3249 hw_lm->ops.setup_mixer_out(hw_lm, &mixer);
3250 }
3251
3252 lm_valid = true;
3253
3254 /* only enable border color on LM */
3255 if (phys_enc->hw_ctl->ops.setup_blendstage)
3256 phys_enc->hw_ctl->ops.setup_blendstage(
Dhaval Patel572cfd22017-06-12 19:33:39 -07003257 phys_enc->hw_ctl, hw_lm->idx, NULL);
Clarence Ip9c65f7b2017-03-20 06:48:15 -07003258 }
3259
3260 if (!lm_valid) {
Clarence Ip662698e2017-09-12 18:34:16 -04003261 SDE_ERROR_ENC(to_sde_encoder_virt(drm_enc), "lm not found\n");
Clarence Ip9c65f7b2017-03-20 06:48:15 -07003262 return -EFAULT;
3263 }
3264 return 0;
3265}
3266
Lloyd Atkinsone123c172017-02-27 13:19:08 -05003267void sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
3268{
3269 struct sde_encoder_virt *sde_enc;
3270 struct sde_encoder_phys *phys;
3271 int i;
3272
3273 if (!drm_enc) {
3274 SDE_ERROR("invalid encoder\n");
3275 return;
3276 }
3277 sde_enc = to_sde_encoder_virt(drm_enc);
3278
3279 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3280 phys = sde_enc->phys_encs[i];
3281 if (phys && phys->ops.prepare_commit)
3282 phys->ops.prepare_commit(phys);
3283 }
3284}
3285
Lloyd Atkinsonc9fb3382017-03-24 08:08:30 -07003286#ifdef CONFIG_DEBUG_FS
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003287static int _sde_encoder_status_show(struct seq_file *s, void *data)
3288{
3289 struct sde_encoder_virt *sde_enc;
3290 int i;
3291
3292 if (!s || !s->private)
3293 return -EINVAL;
3294
3295 sde_enc = s->private;
3296
3297 mutex_lock(&sde_enc->enc_lock);
3298 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3299 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
3300
3301 if (!phys)
3302 continue;
3303
3304 seq_printf(s, "intf:%d vsync:%8d underrun:%8d ",
3305 phys->intf_idx - INTF_0,
3306 atomic_read(&phys->vsync_cnt),
3307 atomic_read(&phys->underrun_cnt));
3308
3309 switch (phys->intf_mode) {
3310 case INTF_MODE_VIDEO:
3311 seq_puts(s, "mode: video\n");
3312 break;
3313 case INTF_MODE_CMD:
3314 seq_puts(s, "mode: command\n");
3315 break;
3316 case INTF_MODE_WB_BLOCK:
3317 seq_puts(s, "mode: wb block\n");
3318 break;
3319 case INTF_MODE_WB_LINE:
3320 seq_puts(s, "mode: wb line\n");
3321 break;
3322 default:
3323 seq_puts(s, "mode: ???\n");
3324 break;
3325 }
3326 }
3327 mutex_unlock(&sde_enc->enc_lock);
3328
3329 return 0;
3330}
3331
3332static int _sde_encoder_debugfs_status_open(struct inode *inode,
3333 struct file *file)
3334{
3335 return single_open(file, _sde_encoder_status_show, inode->i_private);
3336}
3337
Dhaval Patelf9245d62017-03-28 16:24:00 -07003338static ssize_t _sde_encoder_misr_setup(struct file *file,
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303339 const char __user *user_buf, size_t count, loff_t *ppos)
3340{
3341 struct sde_encoder_virt *sde_enc;
Dhaval Patelf9245d62017-03-28 16:24:00 -07003342 int i = 0, rc;
3343 char buf[MISR_BUFF_SIZE + 1];
3344 size_t buff_copy;
3345 u32 frame_count, enable;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303346
Dhaval Patelf9245d62017-03-28 16:24:00 -07003347 if (!file || !file->private_data)
3348 return -EINVAL;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303349
Dhaval Patelf9245d62017-03-28 16:24:00 -07003350 sde_enc = file->private_data;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303351
Dhaval Patelf9245d62017-03-28 16:24:00 -07003352 buff_copy = min_t(size_t, count, MISR_BUFF_SIZE);
3353 if (copy_from_user(buf, user_buf, buff_copy))
3354 return -EINVAL;
3355
3356 buf[buff_copy] = 0; /* end of string */
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303357
3358 if (sscanf(buf, "%u %u", &enable, &frame_count) != 2)
Dhaval Patelf9245d62017-03-28 16:24:00 -07003359 return -EINVAL;
3360
3361 rc = _sde_encoder_power_enable(sde_enc, true);
3362 if (rc)
3363 return rc;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303364
3365 mutex_lock(&sde_enc->enc_lock);
Dhaval Patelf9245d62017-03-28 16:24:00 -07003366 sde_enc->misr_enable = enable;
Dhaval Patel010f5172017-08-01 22:40:09 -07003367 sde_enc->misr_frame_count = frame_count;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303368 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3369 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
3370
Dhaval Patelf9245d62017-03-28 16:24:00 -07003371 if (!phys || !phys->ops.setup_misr)
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303372 continue;
3373
Dhaval Patelf9245d62017-03-28 16:24:00 -07003374 phys->ops.setup_misr(phys, enable, frame_count);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303375 }
3376 mutex_unlock(&sde_enc->enc_lock);
Dhaval Patelf9245d62017-03-28 16:24:00 -07003377 _sde_encoder_power_enable(sde_enc, false);
3378
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303379 return count;
3380}
3381
Dhaval Patelf9245d62017-03-28 16:24:00 -07003382static ssize_t _sde_encoder_misr_read(struct file *file,
3383 char __user *user_buff, size_t count, loff_t *ppos)
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303384{
3385 struct sde_encoder_virt *sde_enc;
Dhaval Patelf9245d62017-03-28 16:24:00 -07003386 int i = 0, len = 0;
3387 char buf[MISR_BUFF_SIZE + 1] = {'\0'};
3388 int rc;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303389
3390 if (*ppos)
3391 return 0;
3392
Dhaval Patelf9245d62017-03-28 16:24:00 -07003393 if (!file || !file->private_data)
3394 return -EINVAL;
3395
3396 sde_enc = file->private_data;
3397
3398 rc = _sde_encoder_power_enable(sde_enc, true);
3399 if (rc)
3400 return rc;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303401
3402 mutex_lock(&sde_enc->enc_lock);
Dhaval Patelf9245d62017-03-28 16:24:00 -07003403 if (!sde_enc->misr_enable) {
3404 len += snprintf(buf + len, MISR_BUFF_SIZE - len,
3405 "disabled\n");
3406 goto buff_check;
3407 } else if (sde_enc->disp_info.capabilities &
3408 ~MSM_DISPLAY_CAP_VID_MODE) {
3409 len += snprintf(buf + len, MISR_BUFF_SIZE - len,
3410 "unsupported\n");
3411 goto buff_check;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303412 }
3413
Dhaval Patelf9245d62017-03-28 16:24:00 -07003414 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3415 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
3416 if (!phys || !phys->ops.collect_misr)
3417 continue;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303418
Dhaval Patelf9245d62017-03-28 16:24:00 -07003419 len += snprintf(buf + len, MISR_BUFF_SIZE - len,
3420 "Intf idx:%d\n", phys->intf_idx - INTF_0);
3421 len += snprintf(buf + len, MISR_BUFF_SIZE - len, "0x%x\n",
3422 phys->ops.collect_misr(phys));
3423 }
3424
3425buff_check:
3426 if (count <= len) {
3427 len = 0;
3428 goto end;
3429 }
3430
3431 if (copy_to_user(user_buff, buf, len)) {
3432 len = -EFAULT;
3433 goto end;
3434 }
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303435
3436 *ppos += len; /* increase offset */
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303437
Dhaval Patelf9245d62017-03-28 16:24:00 -07003438end:
3439 mutex_unlock(&sde_enc->enc_lock);
3440 _sde_encoder_power_enable(sde_enc, false);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303441 return len;
3442}
3443
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003444static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc)
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003445{
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003446 struct sde_encoder_virt *sde_enc;
3447 struct msm_drm_private *priv;
3448 struct sde_kms *sde_kms;
Alan Kwongf2debb02017-04-05 06:19:29 -07003449 int i;
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003450
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003451 static const struct file_operations debugfs_status_fops = {
3452 .open = _sde_encoder_debugfs_status_open,
3453 .read = seq_read,
3454 .llseek = seq_lseek,
3455 .release = single_release,
3456 };
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303457
3458 static const struct file_operations debugfs_misr_fops = {
3459 .open = simple_open,
3460 .read = _sde_encoder_misr_read,
Dhaval Patelf9245d62017-03-28 16:24:00 -07003461 .write = _sde_encoder_misr_setup,
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303462 };
3463
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003464 char name[SDE_NAME_SIZE];
3465
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003466 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003467 SDE_ERROR("invalid encoder or kms\n");
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003468 return -EINVAL;
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003469 }
3470
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003471 sde_enc = to_sde_encoder_virt(drm_enc);
3472 priv = drm_enc->dev->dev_private;
3473 sde_kms = to_sde_kms(priv->kms);
3474
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003475 snprintf(name, SDE_NAME_SIZE, "encoder%u", drm_enc->base.id);
3476
3477 /* create overall sub-directory for the encoder */
3478 sde_enc->debugfs_root = debugfs_create_dir(name,
Lloyd Atkinson09e64bf2017-04-13 14:09:59 -07003479 drm_enc->dev->primary->debugfs_root);
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003480 if (!sde_enc->debugfs_root)
3481 return -ENOMEM;
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303482
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003483 /* don't error check these */
Lloyd Atkinson8de415a2017-05-23 11:31:16 -04003484 debugfs_create_file("status", 0600,
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003485 sde_enc->debugfs_root, sde_enc, &debugfs_status_fops);
Jayant Shekhar1d50ed22016-11-04 18:41:12 +05303486
Lloyd Atkinson8de415a2017-05-23 11:31:16 -04003487 debugfs_create_file("misr_data", 0600,
Dhaval Patelf9245d62017-03-28 16:24:00 -07003488 sde_enc->debugfs_root, sde_enc, &debugfs_misr_fops);
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003489
Alan Kwongf2debb02017-04-05 06:19:29 -07003490 for (i = 0; i < sde_enc->num_phys_encs; i++)
3491 if (sde_enc->phys_encs[i] &&
3492 sde_enc->phys_encs[i]->ops.late_register)
3493 sde_enc->phys_encs[i]->ops.late_register(
3494 sde_enc->phys_encs[i],
3495 sde_enc->debugfs_root);
3496
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003497 return 0;
3498}
3499
3500static void _sde_encoder_destroy_debugfs(struct drm_encoder *drm_enc)
3501{
3502 struct sde_encoder_virt *sde_enc;
3503
3504 if (!drm_enc)
3505 return;
3506
3507 sde_enc = to_sde_encoder_virt(drm_enc);
3508 debugfs_remove_recursive(sde_enc->debugfs_root);
3509}
3510#else
3511static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc)
3512{
3513 return 0;
3514}
3515
Lloyd Atkinsonc9fb3382017-03-24 08:08:30 -07003516static void _sde_encoder_destroy_debugfs(struct drm_encoder *drm_enc)
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003517{
3518}
3519#endif
3520
3521static int sde_encoder_late_register(struct drm_encoder *encoder)
3522{
3523 return _sde_encoder_init_debugfs(encoder);
3524}
3525
3526static void sde_encoder_early_unregister(struct drm_encoder *encoder)
3527{
3528 _sde_encoder_destroy_debugfs(encoder);
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003529}
3530
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003531static int sde_encoder_virt_add_phys_encs(
Clarence Ipa4039322016-07-15 16:23:59 -04003532 u32 display_caps,
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003533 struct sde_encoder_virt *sde_enc,
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003534 struct sde_enc_phys_init_params *params)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003535{
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003536 struct sde_encoder_phys *enc = NULL;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003537
Clarence Ip19af1362016-09-23 14:57:51 -04003538 SDE_DEBUG_ENC(sde_enc, "\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003539
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003540 /*
3541 * We may create up to NUM_PHYS_ENCODER_TYPES physical encoder types
3542 * in this function, check up-front.
3543 */
3544 if (sde_enc->num_phys_encs + NUM_PHYS_ENCODER_TYPES >=
3545 ARRAY_SIZE(sde_enc->phys_encs)) {
Clarence Ip19af1362016-09-23 14:57:51 -04003546 SDE_ERROR_ENC(sde_enc, "too many physical encoders %d\n",
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003547 sde_enc->num_phys_encs);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003548 return -EINVAL;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003549 }
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003550
Clarence Ipa4039322016-07-15 16:23:59 -04003551 if (display_caps & MSM_DISPLAY_CAP_VID_MODE) {
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003552 enc = sde_encoder_phys_vid_init(params);
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003553
3554 if (IS_ERR_OR_NULL(enc)) {
Clarence Ip19af1362016-09-23 14:57:51 -04003555 SDE_ERROR_ENC(sde_enc, "failed to init vid enc: %ld\n",
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003556 PTR_ERR(enc));
3557 return enc == 0 ? -EINVAL : PTR_ERR(enc);
3558 }
3559
3560 sde_enc->phys_encs[sde_enc->num_phys_encs] = enc;
3561 ++sde_enc->num_phys_encs;
3562 }
3563
Clarence Ipa4039322016-07-15 16:23:59 -04003564 if (display_caps & MSM_DISPLAY_CAP_CMD_MODE) {
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003565 enc = sde_encoder_phys_cmd_init(params);
Lloyd Atkinsona59eead2016-05-30 14:37:06 -04003566
3567 if (IS_ERR_OR_NULL(enc)) {
Clarence Ip19af1362016-09-23 14:57:51 -04003568 SDE_ERROR_ENC(sde_enc, "failed to init cmd enc: %ld\n",
Lloyd Atkinsona59eead2016-05-30 14:37:06 -04003569 PTR_ERR(enc));
3570 return enc == 0 ? -EINVAL : PTR_ERR(enc);
3571 }
3572
3573 sde_enc->phys_encs[sde_enc->num_phys_encs] = enc;
3574 ++sde_enc->num_phys_encs;
3575 }
3576
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003577 return 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003578}
3579
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003580static int sde_encoder_virt_add_phys_enc_wb(struct sde_encoder_virt *sde_enc,
3581 struct sde_enc_phys_init_params *params)
Alan Kwongbb27c092016-07-20 16:41:25 -04003582{
3583 struct sde_encoder_phys *enc = NULL;
Alan Kwongbb27c092016-07-20 16:41:25 -04003584
Clarence Ip19af1362016-09-23 14:57:51 -04003585 if (!sde_enc) {
3586 SDE_ERROR("invalid encoder\n");
3587 return -EINVAL;
3588 }
3589
3590 SDE_DEBUG_ENC(sde_enc, "\n");
Alan Kwongbb27c092016-07-20 16:41:25 -04003591
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003592 if (sde_enc->num_phys_encs + 1 >= ARRAY_SIZE(sde_enc->phys_encs)) {
Clarence Ip19af1362016-09-23 14:57:51 -04003593 SDE_ERROR_ENC(sde_enc, "too many physical encoders %d\n",
Alan Kwongbb27c092016-07-20 16:41:25 -04003594 sde_enc->num_phys_encs);
3595 return -EINVAL;
3596 }
3597
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003598 enc = sde_encoder_phys_wb_init(params);
Alan Kwongbb27c092016-07-20 16:41:25 -04003599
3600 if (IS_ERR_OR_NULL(enc)) {
Clarence Ip19af1362016-09-23 14:57:51 -04003601 SDE_ERROR_ENC(sde_enc, "failed to init wb enc: %ld\n",
Alan Kwongbb27c092016-07-20 16:41:25 -04003602 PTR_ERR(enc));
3603 return enc == 0 ? -EINVAL : PTR_ERR(enc);
3604 }
3605
3606 sde_enc->phys_encs[sde_enc->num_phys_encs] = enc;
3607 ++sde_enc->num_phys_encs;
3608
3609 return 0;
3610}
3611
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003612static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003613 struct sde_kms *sde_kms,
Clarence Ipa4039322016-07-15 16:23:59 -04003614 struct msm_display_info *disp_info,
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003615 int *drm_enc_mode)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003616{
3617 int ret = 0;
3618 int i = 0;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003619 enum sde_intf_type intf_type;
3620 struct sde_encoder_virt_ops parent_ops = {
3621 sde_encoder_vblank_callback,
Dhaval Patel81e87882016-10-19 21:41:56 -07003622 sde_encoder_underrun_callback,
Alan Kwong628d19e2016-10-31 13:50:13 -04003623 sde_encoder_frame_done_callback,
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003624 };
3625 struct sde_enc_phys_init_params phys_params;
3626
Clarence Ip19af1362016-09-23 14:57:51 -04003627 if (!sde_enc || !sde_kms) {
3628 SDE_ERROR("invalid arg(s), enc %d kms %d\n",
3629 sde_enc != 0, sde_kms != 0);
3630 return -EINVAL;
3631 }
3632
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003633 memset(&phys_params, 0, sizeof(phys_params));
3634 phys_params.sde_kms = sde_kms;
3635 phys_params.parent = &sde_enc->base;
3636 phys_params.parent_ops = parent_ops;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003637 phys_params.enc_spinlock = &sde_enc->enc_spinlock;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003638
Clarence Ip19af1362016-09-23 14:57:51 -04003639 SDE_DEBUG("\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003640
Clarence Ipa4039322016-07-15 16:23:59 -04003641 if (disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) {
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003642 *drm_enc_mode = DRM_MODE_ENCODER_DSI;
3643 intf_type = INTF_DSI;
Clarence Ipa4039322016-07-15 16:23:59 -04003644 } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_HDMIA) {
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003645 *drm_enc_mode = DRM_MODE_ENCODER_TMDS;
3646 intf_type = INTF_HDMI;
Padmanabhan Komanduru63758612017-05-23 01:47:18 -07003647 } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_DisplayPort) {
3648 *drm_enc_mode = DRM_MODE_ENCODER_TMDS;
3649 intf_type = INTF_DP;
Alan Kwongbb27c092016-07-20 16:41:25 -04003650 } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_VIRTUAL) {
3651 *drm_enc_mode = DRM_MODE_ENCODER_VIRTUAL;
3652 intf_type = INTF_WB;
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003653 } else {
Clarence Ip19af1362016-09-23 14:57:51 -04003654 SDE_ERROR_ENC(sde_enc, "unsupported display interface type\n");
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003655 return -EINVAL;
3656 }
3657
Clarence Ip88270a62016-06-26 10:09:34 -04003658 WARN_ON(disp_info->num_of_h_tiles < 1);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003659
Lloyd Atkinson11f34442016-08-11 11:19:52 -04003660 sde_enc->display_num_of_h_tiles = disp_info->num_of_h_tiles;
3661
Clarence Ip19af1362016-09-23 14:57:51 -04003662 SDE_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003663
Dhaval Patele17e0ee2017-08-23 18:01:42 -07003664 if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) ||
3665 (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE))
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07003666 sde_enc->idle_pc_supported = sde_kms->catalog->has_idle_pc;
3667
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003668 mutex_lock(&sde_enc->enc_lock);
Clarence Ip88270a62016-06-26 10:09:34 -04003669 for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003670 /*
3671 * Left-most tile is at index 0, content is controller id
3672 * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right
3673 * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right
3674 */
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003675 u32 controller_id = disp_info->h_tile_instance[i];
3676
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003677 if (disp_info->num_of_h_tiles > 1) {
3678 if (i == 0)
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003679 phys_params.split_role = ENC_ROLE_MASTER;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003680 else
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003681 phys_params.split_role = ENC_ROLE_SLAVE;
3682 } else {
3683 phys_params.split_role = ENC_ROLE_SOLO;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003684 }
3685
Clarence Ip19af1362016-09-23 14:57:51 -04003686 SDE_DEBUG("h_tile_instance %d = %d, split_role %d\n",
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003687 i, controller_id, phys_params.split_role);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003688
Alan Kwongbb27c092016-07-20 16:41:25 -04003689 if (intf_type == INTF_WB) {
Lloyd Atkinson11f34442016-08-11 11:19:52 -04003690 phys_params.intf_idx = INTF_MAX;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003691 phys_params.wb_idx = sde_encoder_get_wb(
3692 sde_kms->catalog,
Alan Kwongbb27c092016-07-20 16:41:25 -04003693 intf_type, controller_id);
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003694 if (phys_params.wb_idx == WB_MAX) {
Clarence Ip19af1362016-09-23 14:57:51 -04003695 SDE_ERROR_ENC(sde_enc,
3696 "could not get wb: type %d, id %d\n",
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003697 intf_type, controller_id);
Alan Kwongbb27c092016-07-20 16:41:25 -04003698 ret = -EINVAL;
3699 }
Alan Kwongbb27c092016-07-20 16:41:25 -04003700 } else {
Lloyd Atkinson11f34442016-08-11 11:19:52 -04003701 phys_params.wb_idx = WB_MAX;
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003702 phys_params.intf_idx = sde_encoder_get_intf(
3703 sde_kms->catalog, intf_type,
3704 controller_id);
3705 if (phys_params.intf_idx == INTF_MAX) {
Clarence Ip19af1362016-09-23 14:57:51 -04003706 SDE_ERROR_ENC(sde_enc,
3707 "could not get wb: type %d, id %d\n",
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003708 intf_type, controller_id);
Alan Kwongbb27c092016-07-20 16:41:25 -04003709 ret = -EINVAL;
3710 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003711 }
3712
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003713 if (!ret) {
Alan Kwongbb27c092016-07-20 16:41:25 -04003714 if (intf_type == INTF_WB)
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003715 ret = sde_encoder_virt_add_phys_enc_wb(sde_enc,
3716 &phys_params);
Alan Kwongbb27c092016-07-20 16:41:25 -04003717 else
3718 ret = sde_encoder_virt_add_phys_encs(
3719 disp_info->capabilities,
Lloyd Atkinson6ef6cb52016-07-06 11:49:18 -04003720 sde_enc,
3721 &phys_params);
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003722 if (ret)
Clarence Ip19af1362016-09-23 14:57:51 -04003723 SDE_ERROR_ENC(sde_enc,
3724 "failed to add phys encs\n");
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003725 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003726 }
Dhaval Pateld4e583a2017-03-10 14:46:44 -08003727
3728 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3729 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
3730
3731 if (phys) {
3732 atomic_set(&phys->vsync_cnt, 0);
3733 atomic_set(&phys->underrun_cnt, 0);
3734 }
3735 }
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003736 mutex_unlock(&sde_enc->enc_lock);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003737
3738 return ret;
3739}
3740
Alan Kwong628d19e2016-10-31 13:50:13 -04003741static void sde_encoder_frame_done_timeout(unsigned long data)
3742{
3743 struct drm_encoder *drm_enc = (struct drm_encoder *) data;
3744 struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
3745 struct msm_drm_private *priv;
Ingrid Gallardo79b44392017-05-30 16:30:52 -07003746 u32 event;
Alan Kwong628d19e2016-10-31 13:50:13 -04003747
3748 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
3749 SDE_ERROR("invalid parameters\n");
3750 return;
3751 }
3752 priv = drm_enc->dev->dev_private;
3753
3754 if (!sde_enc->frame_busy_mask[0] || !sde_enc->crtc_frame_event_cb) {
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003755 SDE_DEBUG_ENC(sde_enc, "invalid timeout\n");
3756 SDE_EVT32(DRMID(drm_enc), sde_enc->frame_busy_mask[0], 0);
Alan Kwong628d19e2016-10-31 13:50:13 -04003757 return;
3758 } else if (!atomic_xchg(&sde_enc->frame_done_timeout, 0)) {
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003759 SDE_ERROR_ENC(sde_enc, "invalid timeout\n");
Alan Kwong628d19e2016-10-31 13:50:13 -04003760 SDE_EVT32(DRMID(drm_enc), 0, 1);
3761 return;
3762 }
3763
Ingrid Gallardo79b44392017-05-30 16:30:52 -07003764 SDE_ERROR_ENC(sde_enc, "frame done timeout\n");
Lloyd Atkinson8c49c582016-11-18 14:23:54 -05003765
Veera Sundaram Sankaran7ee99092017-06-13 11:19:36 -07003766 event = SDE_ENCODER_FRAME_EVENT_ERROR;
Ingrid Gallardo79b44392017-05-30 16:30:52 -07003767 SDE_EVT32(DRMID(drm_enc), event);
3768 sde_enc->crtc_frame_event_cb(sde_enc->crtc_frame_event_cb_data, event);
Alan Kwong628d19e2016-10-31 13:50:13 -04003769}
3770
Lloyd Atkinsonb020e0f2017-03-14 08:05:18 -07003771static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = {
3772 .mode_set = sde_encoder_virt_mode_set,
3773 .disable = sde_encoder_virt_disable,
3774 .enable = sde_encoder_virt_enable,
3775 .atomic_check = sde_encoder_virt_atomic_check,
3776};
3777
3778static const struct drm_encoder_funcs sde_encoder_funcs = {
3779 .destroy = sde_encoder_destroy,
3780 .late_register = sde_encoder_late_register,
3781 .early_unregister = sde_encoder_early_unregister,
3782};
3783
Clarence Ip3649f8b2016-10-31 09:59:44 -04003784struct drm_encoder *sde_encoder_init(
3785 struct drm_device *dev,
3786 struct msm_display_info *disp_info)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003787{
3788 struct msm_drm_private *priv = dev->dev_private;
Ben Chan78647cd2016-06-26 22:02:47 -04003789 struct sde_kms *sde_kms = to_sde_kms(priv->kms);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003790 struct drm_encoder *drm_enc = NULL;
Lloyd Atkinson09fed912016-06-24 18:14:13 -04003791 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003792 int drm_enc_mode = DRM_MODE_ENCODER_NONE;
Dhaval Patel020f7e122016-11-15 14:39:18 -08003793 char name[SDE_NAME_SIZE];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003794 int ret = 0;
3795
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003796 sde_enc = kzalloc(sizeof(*sde_enc), GFP_KERNEL);
3797 if (!sde_enc) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07003798 ret = -ENOMEM;
3799 goto fail;
3800 }
3801
Dhaval Patel22ef6df2016-10-20 14:42:52 -07003802 mutex_init(&sde_enc->enc_lock);
Lloyd Atkinson9a840312016-06-26 10:11:08 -04003803 ret = sde_encoder_setup_display(sde_enc, sde_kms, disp_info,
3804 &drm_enc_mode);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003805 if (ret)
3806 goto fail;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07003807
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003808 sde_enc->cur_master = NULL;
Lloyd Atkinson7d070942016-07-26 18:35:12 -04003809 spin_lock_init(&sde_enc->enc_spinlock);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003810 drm_enc = &sde_enc->base;
Dhaval Patel04c7e8e2016-09-26 20:14:31 -07003811 drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, drm_enc_mode, NULL);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003812 drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07003813
Alan Kwong628d19e2016-10-31 13:50:13 -04003814 atomic_set(&sde_enc->frame_done_timeout, 0);
3815 setup_timer(&sde_enc->frame_done_timer, sde_encoder_frame_done_timeout,
3816 (unsigned long) sde_enc);
3817
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003818 if ((disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) &&
3819 disp_info->is_primary)
3820 setup_timer(&sde_enc->vsync_event_timer,
3821 sde_encoder_vsync_event_handler,
3822 (unsigned long)sde_enc);
3823
Dhaval Patel020f7e122016-11-15 14:39:18 -08003824 snprintf(name, SDE_NAME_SIZE, "rsc_enc%u", drm_enc->base.id);
3825 sde_enc->rsc_client = sde_rsc_client_create(SDE_RSC_INDEX, name,
Dhaval Patel82c8dbc2017-02-18 23:15:10 -08003826 disp_info->is_primary);
Dhaval Patel020f7e122016-11-15 14:39:18 -08003827 if (IS_ERR_OR_NULL(sde_enc->rsc_client)) {
Dhaval Patel49ef6d72017-03-26 09:35:53 -07003828 SDE_DEBUG("sde rsc client create failed :%ld\n",
Dhaval Patel020f7e122016-11-15 14:39:18 -08003829 PTR_ERR(sde_enc->rsc_client));
3830 sde_enc->rsc_client = NULL;
3831 }
Dhaval Patel82c8dbc2017-02-18 23:15:10 -08003832
Veera Sundaram Sankaranc9efbec2017-03-29 18:59:05 -07003833 mutex_init(&sde_enc->rc_lock);
Lloyd Atkinsona8781382017-07-17 10:20:43 -04003834 kthread_init_delayed_work(&sde_enc->delayed_off_work,
3835 sde_encoder_off_work);
Dhaval Patele17e0ee2017-08-23 18:01:42 -07003836 sde_enc->idle_timeout = IDLE_TIMEOUT;
Veera Sundaram Sankarandf79cc92017-10-10 22:32:46 -07003837 sde_enc->vblank_enabled = false;
Benjamin Chan9cd866d2017-08-15 14:56:34 -04003838
3839 kthread_init_work(&sde_enc->vsync_event_work,
3840 sde_encoder_vsync_event_work_handler);
3841
Dhaval Patel020f7e122016-11-15 14:39:18 -08003842 memcpy(&sde_enc->disp_info, disp_info, sizeof(*disp_info));
3843
Clarence Ip19af1362016-09-23 14:57:51 -04003844 SDE_DEBUG_ENC(sde_enc, "created\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003845
3846 return drm_enc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07003847
3848fail:
Clarence Ip19af1362016-09-23 14:57:51 -04003849 SDE_ERROR("failed to create encoder\n");
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003850 if (drm_enc)
3851 sde_encoder_destroy(drm_enc);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07003852
3853 return ERR_PTR(ret);
3854}
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04003855
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07003856int sde_encoder_wait_for_event(struct drm_encoder *drm_enc,
3857 enum msm_event_wait event)
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04003858{
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07003859 int (*fn_wait)(struct sde_encoder_phys *phys_enc) = NULL;
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003860 struct sde_encoder_virt *sde_enc = NULL;
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003861 int i, ret = 0;
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04003862
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003863 if (!drm_enc) {
Clarence Ip19af1362016-09-23 14:57:51 -04003864 SDE_ERROR("invalid encoder\n");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003865 return -EINVAL;
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04003866 }
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003867 sde_enc = to_sde_encoder_virt(drm_enc);
Clarence Ip19af1362016-09-23 14:57:51 -04003868 SDE_DEBUG_ENC(sde_enc, "\n");
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04003869
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003870 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3871 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
Lloyd Atkinsone5c2c0b2016-07-05 12:23:29 -04003872
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07003873 switch (event) {
3874 case MSM_ENC_COMMIT_DONE:
3875 fn_wait = phys->ops.wait_for_commit_done;
3876 break;
3877 case MSM_ENC_TX_COMPLETE:
3878 fn_wait = phys->ops.wait_for_tx_complete;
3879 break;
Lloyd Atkinsonf68a2132017-07-17 10:16:30 -04003880 case MSM_ENC_VBLANK:
3881 fn_wait = phys->ops.wait_for_vblank;
3882 break;
3883 default:
3884 SDE_ERROR_ENC(sde_enc, "unknown wait event %d\n",
3885 event);
3886 return -EINVAL;
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07003887 };
3888
3889 if (phys && fn_wait) {
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07003890 SDE_ATRACE_BEGIN("wait_for_completion_event");
Jeykumar Sankarandfaeec92017-06-06 15:21:51 -07003891 ret = fn_wait(phys);
Veera Sundaram Sankarana90e1392017-07-06 15:00:09 -07003892 SDE_ATRACE_END("wait_for_completion_event");
Lloyd Atkinson5d722782016-05-30 14:09:41 -04003893 if (ret)
3894 return ret;
3895 }
3896 }
3897
3898 return ret;
Abhijit Kulkarni40e38162016-06-26 22:12:09 -04003899}
3900
Alan Kwong67a3f792016-11-01 23:16:53 -04003901enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder)
3902{
3903 struct sde_encoder_virt *sde_enc = NULL;
3904 int i;
3905
3906 if (!encoder) {
3907 SDE_ERROR("invalid encoder\n");
3908 return INTF_MODE_NONE;
3909 }
3910 sde_enc = to_sde_encoder_virt(encoder);
3911
3912 if (sde_enc->cur_master)
3913 return sde_enc->cur_master->intf_mode;
3914
3915 for (i = 0; i < sde_enc->num_phys_encs; i++) {
3916 struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
3917
3918 if (phys)
3919 return phys->intf_mode;
3920 }
3921
3922 return INTF_MODE_NONE;
3923}