1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights reserved.
4  */
5 
6 #define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
7 #include <linux/delay.h>
8 #include "dpu_encoder_phys.h"
9 #include "dpu_hw_interrupts.h"
10 #include "dpu_hw_pingpong.h"
11 #include "dpu_core_irq.h"
12 #include "dpu_formats.h"
13 #include "dpu_trace.h"
14 #include "disp/msm_disp_snapshot.h"
15 
16 #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
17 		(e) && (e)->base.parent ? \
18 		(e)->base.parent->base.id : -1, \
19 		(e) ? (e)->base.intf_idx - INTF_0 : -1, ##__VA_ARGS__)
20 
21 #define DPU_ERROR_CMDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \
22 		(e) && (e)->base.parent ? \
23 		(e)->base.parent->base.id : -1, \
24 		(e) ? (e)->base.intf_idx - INTF_0 : -1, ##__VA_ARGS__)
25 
26 #define to_dpu_encoder_phys_cmd(x) \
27 	container_of(x, struct dpu_encoder_phys_cmd, base)
28 
29 #define PP_TIMEOUT_MAX_TRIALS	10
30 
31 /*
32  * Tearcheck sync start and continue thresholds are empirically found
33  * based on common panels In the future, may want to allow panels to override
34  * these default values
35  */
36 #define DEFAULT_TEARCHECK_SYNC_THRESH_START	4
37 #define DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE	4
38 
39 #define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000
40 
41 #define DPU_ENC_MAX_POLL_TIMEOUT_US	2000
42 
43 static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc)
44 {
45 	return (phys_enc->split_role != ENC_ROLE_SLAVE);
46 }
47 
48 static void _dpu_encoder_phys_cmd_update_intf_cfg(
49 		struct dpu_encoder_phys *phys_enc)
50 {
51 	struct dpu_encoder_phys_cmd *cmd_enc =
52 			to_dpu_encoder_phys_cmd(phys_enc);
53 	struct dpu_hw_ctl *ctl;
54 	struct dpu_hw_intf_cfg intf_cfg = { 0 };
55 
56 	ctl = phys_enc->hw_ctl;
57 	if (!ctl->ops.setup_intf_cfg)
58 		return;
59 
60 	intf_cfg.intf = phys_enc->intf_idx;
61 	intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;
62 	intf_cfg.stream_sel = cmd_enc->stream_sel;
63 	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
64 	intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
65 	ctl->ops.setup_intf_cfg(ctl, &intf_cfg);
66 
67 	/* setup which pp blk will connect to this intf */
68 	if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) && phys_enc->hw_intf->ops.bind_pingpong_blk)
69 		phys_enc->hw_intf->ops.bind_pingpong_blk(
70 				phys_enc->hw_intf,
71 				true,
72 				phys_enc->hw_pp->idx);
73 }
74 
75 static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
76 {
77 	struct dpu_encoder_phys *phys_enc = arg;
78 	unsigned long lock_flags;
79 	int new_cnt;
80 	u32 event = DPU_ENCODER_FRAME_EVENT_DONE;
81 
82 	if (!phys_enc->hw_pp)
83 		return;
84 
85 	DPU_ATRACE_BEGIN("pp_done_irq");
86 	/* notify all synchronous clients first, then asynchronous clients */
87 	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
88 
89 	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
90 	new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
91 	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
92 
93 	trace_dpu_enc_phys_cmd_pp_tx_done(DRMID(phys_enc->parent),
94 					  phys_enc->hw_pp->idx - PINGPONG_0,
95 					  new_cnt, event);
96 
97 	/* Signal any waiting atomic commit thread */
98 	wake_up_all(&phys_enc->pending_kickoff_wq);
99 	DPU_ATRACE_END("pp_done_irq");
100 }
101 
102 static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
103 {
104 	struct dpu_encoder_phys *phys_enc = arg;
105 	struct dpu_encoder_phys_cmd *cmd_enc;
106 
107 	if (!phys_enc->hw_pp)
108 		return;
109 
110 	DPU_ATRACE_BEGIN("rd_ptr_irq");
111 	cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
112 
113 	dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
114 
115 	atomic_add_unless(&cmd_enc->pending_vblank_cnt, -1, 0);
116 	wake_up_all(&cmd_enc->pending_vblank_wq);
117 	DPU_ATRACE_END("rd_ptr_irq");
118 }
119 
120 static void dpu_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx)
121 {
122 	struct dpu_encoder_phys *phys_enc = arg;
123 
124 	DPU_ATRACE_BEGIN("ctl_start_irq");
125 
126 	atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
127 
128 	/* Signal any waiting ctl start interrupt */
129 	wake_up_all(&phys_enc->pending_kickoff_wq);
130 	DPU_ATRACE_END("ctl_start_irq");
131 }
132 
133 static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
134 {
135 	struct dpu_encoder_phys *phys_enc = arg;
136 
137 	dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
138 }
139 
140 static void dpu_encoder_phys_cmd_atomic_mode_set(
141 		struct dpu_encoder_phys *phys_enc,
142 		struct drm_crtc_state *crtc_state,
143 		struct drm_connector_state *conn_state)
144 {
145 	phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
146 
147 	phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
148 
149 	phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
150 
151 	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
152 }
153 
154 static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
155 		struct dpu_encoder_phys *phys_enc)
156 {
157 	struct dpu_encoder_phys_cmd *cmd_enc =
158 			to_dpu_encoder_phys_cmd(phys_enc);
159 	u32 frame_event = DPU_ENCODER_FRAME_EVENT_ERROR;
160 	bool do_log = false;
161 	struct drm_encoder *drm_enc;
162 
163 	if (!phys_enc->hw_pp)
164 		return -EINVAL;
165 
166 	drm_enc = phys_enc->parent;
167 
168 	cmd_enc->pp_timeout_report_cnt++;
169 	if (cmd_enc->pp_timeout_report_cnt == PP_TIMEOUT_MAX_TRIALS) {
170 		frame_event |= DPU_ENCODER_FRAME_EVENT_PANEL_DEAD;
171 		do_log = true;
172 	} else if (cmd_enc->pp_timeout_report_cnt == 1) {
173 		do_log = true;
174 	}
175 
176 	trace_dpu_enc_phys_cmd_pdone_timeout(DRMID(drm_enc),
177 		     phys_enc->hw_pp->idx - PINGPONG_0,
178 		     cmd_enc->pp_timeout_report_cnt,
179 		     atomic_read(&phys_enc->pending_kickoff_cnt),
180 		     frame_event);
181 
182 	/* to avoid flooding, only log first time, and "dead" time */
183 	if (do_log) {
184 		DRM_ERROR("id:%d pp:%d kickoff timeout %d cnt %d koff_cnt %d\n",
185 			  DRMID(drm_enc),
186 			  phys_enc->hw_pp->idx - PINGPONG_0,
187 			  phys_enc->hw_ctl->idx - CTL_0,
188 			  cmd_enc->pp_timeout_report_cnt,
189 			  atomic_read(&phys_enc->pending_kickoff_cnt));
190 		msm_disp_snapshot_state(drm_enc->dev);
191 		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
192 				phys_enc->irq[INTR_IDX_RDPTR]);
193 	}
194 
195 	atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
196 
197 	/* request a ctl reset before the next kickoff */
198 	phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET;
199 
200 	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
201 
202 	return -ETIMEDOUT;
203 }
204 
205 static int _dpu_encoder_phys_cmd_wait_for_idle(
206 		struct dpu_encoder_phys *phys_enc)
207 {
208 	struct dpu_encoder_phys_cmd *cmd_enc =
209 			to_dpu_encoder_phys_cmd(phys_enc);
210 	struct dpu_encoder_wait_info wait_info;
211 	int ret;
212 
213 	wait_info.wq = &phys_enc->pending_kickoff_wq;
214 	wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
215 	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
216 
217 	ret = dpu_encoder_helper_wait_for_irq(phys_enc,
218 			phys_enc->irq[INTR_IDX_PINGPONG],
219 			dpu_encoder_phys_cmd_pp_tx_done_irq,
220 			&wait_info);
221 	if (ret == -ETIMEDOUT)
222 		_dpu_encoder_phys_cmd_handle_ppdone_timeout(phys_enc);
223 	else if (!ret)
224 		cmd_enc->pp_timeout_report_cnt = 0;
225 
226 	return ret;
227 }
228 
229 static int dpu_encoder_phys_cmd_control_vblank_irq(
230 		struct dpu_encoder_phys *phys_enc,
231 		bool enable)
232 {
233 	int ret = 0;
234 	int refcount;
235 
236 	if (!phys_enc->hw_pp) {
237 		DPU_ERROR("invalid encoder\n");
238 		return -EINVAL;
239 	}
240 
241 	refcount = atomic_read(&phys_enc->vblank_refcount);
242 
243 	/* Slave encoders don't report vblank */
244 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
245 		goto end;
246 
247 	/* protect against negative */
248 	if (!enable && refcount == 0) {
249 		ret = -EINVAL;
250 		goto end;
251 	}
252 
253 	DRM_DEBUG_KMS("id:%u pp:%d enable=%s/%d\n", DRMID(phys_enc->parent),
254 		      phys_enc->hw_pp->idx - PINGPONG_0,
255 		      enable ? "true" : "false", refcount);
256 
257 	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
258 		ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
259 				phys_enc->irq[INTR_IDX_RDPTR],
260 				dpu_encoder_phys_cmd_pp_rd_ptr_irq,
261 				phys_enc);
262 	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
263 		ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
264 				phys_enc->irq[INTR_IDX_RDPTR]);
265 
266 end:
267 	if (ret) {
268 		DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n",
269 			  DRMID(phys_enc->parent),
270 			  phys_enc->hw_pp->idx - PINGPONG_0, ret,
271 			  enable ? "true" : "false", refcount);
272 	}
273 
274 	return ret;
275 }
276 
277 static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
278 		bool enable)
279 {
280 	trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
281 			phys_enc->hw_pp->idx - PINGPONG_0,
282 			enable, atomic_read(&phys_enc->vblank_refcount));
283 
284 	if (enable) {
285 		dpu_core_irq_register_callback(phys_enc->dpu_kms,
286 				phys_enc->irq[INTR_IDX_PINGPONG],
287 				dpu_encoder_phys_cmd_pp_tx_done_irq,
288 				phys_enc);
289 		dpu_core_irq_register_callback(phys_enc->dpu_kms,
290 				phys_enc->irq[INTR_IDX_UNDERRUN],
291 				dpu_encoder_phys_cmd_underrun_irq,
292 				phys_enc);
293 		dpu_encoder_phys_cmd_control_vblank_irq(phys_enc, true);
294 
295 		if (dpu_encoder_phys_cmd_is_master(phys_enc))
296 			dpu_core_irq_register_callback(phys_enc->dpu_kms,
297 					phys_enc->irq[INTR_IDX_CTL_START],
298 					dpu_encoder_phys_cmd_ctl_start_irq,
299 					phys_enc);
300 	} else {
301 		if (dpu_encoder_phys_cmd_is_master(phys_enc))
302 			dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
303 					phys_enc->irq[INTR_IDX_CTL_START]);
304 
305 		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
306 				phys_enc->irq[INTR_IDX_UNDERRUN]);
307 		dpu_encoder_phys_cmd_control_vblank_irq(phys_enc, false);
308 		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
309 				phys_enc->irq[INTR_IDX_PINGPONG]);
310 	}
311 }
312 
313 static void dpu_encoder_phys_cmd_tearcheck_config(
314 		struct dpu_encoder_phys *phys_enc)
315 {
316 	struct dpu_encoder_phys_cmd *cmd_enc =
317 		to_dpu_encoder_phys_cmd(phys_enc);
318 	struct dpu_hw_tear_check tc_cfg = { 0 };
319 	struct drm_display_mode *mode;
320 	bool tc_enable = true;
321 	u32 vsync_hz;
322 	struct dpu_kms *dpu_kms;
323 
324 	if (!phys_enc->hw_pp) {
325 		DPU_ERROR("invalid encoder\n");
326 		return;
327 	}
328 	mode = &phys_enc->cached_mode;
329 
330 	DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
331 
332 	if (!phys_enc->hw_pp->ops.setup_tearcheck ||
333 		!phys_enc->hw_pp->ops.enable_tearcheck) {
334 		DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
335 		return;
336 	}
337 
338 	dpu_kms = phys_enc->dpu_kms;
339 
340 	/*
341 	 * TE default: dsi byte clock calculated base on 70 fps;
342 	 * around 14 ms to complete a kickoff cycle if te disabled;
343 	 * vclk_line base on 60 fps; write is faster than read;
344 	 * init == start == rdptr;
345 	 *
346 	 * vsync_count is ratio of MDP VSYNC clock frequency to LCD panel
347 	 * frequency divided by the no. of rows (lines) in the LCDpanel.
348 	 */
349 	vsync_hz = dpu_kms_get_clk_rate(dpu_kms, "vsync");
350 	if (vsync_hz <= 0) {
351 		DPU_DEBUG_CMDENC(cmd_enc, "invalid - vsync_hz %u\n",
352 				 vsync_hz);
353 		return;
354 	}
355 
356 	tc_cfg.vsync_count = vsync_hz /
357 				(mode->vtotal * drm_mode_vrefresh(mode));
358 
359 	/*
360 	 * Set the sync_cfg_height to twice vtotal so that if we lose a
361 	 * TE event coming from the display TE pin we won't stall immediately
362 	 */
363 	tc_cfg.hw_vsync_mode = 1;
364 	tc_cfg.sync_cfg_height = mode->vtotal * 2;
365 	tc_cfg.vsync_init_val = mode->vdisplay;
366 	tc_cfg.sync_threshold_start = DEFAULT_TEARCHECK_SYNC_THRESH_START;
367 	tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE;
368 	tc_cfg.start_pos = mode->vdisplay;
369 	tc_cfg.rd_ptr_irq = mode->vdisplay + 1;
370 
371 	DPU_DEBUG_CMDENC(cmd_enc,
372 		"tc %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n",
373 		phys_enc->hw_pp->idx - PINGPONG_0, vsync_hz,
374 		mode->vtotal, drm_mode_vrefresh(mode));
375 	DPU_DEBUG_CMDENC(cmd_enc,
376 		"tc %d enable %u start_pos %u rd_ptr_irq %u\n",
377 		phys_enc->hw_pp->idx - PINGPONG_0, tc_enable, tc_cfg.start_pos,
378 		tc_cfg.rd_ptr_irq);
379 	DPU_DEBUG_CMDENC(cmd_enc,
380 		"tc %d hw_vsync_mode %u vsync_count %u vsync_init_val %u\n",
381 		phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.hw_vsync_mode,
382 		tc_cfg.vsync_count, tc_cfg.vsync_init_val);
383 	DPU_DEBUG_CMDENC(cmd_enc,
384 		"tc %d cfgheight %u thresh_start %u thresh_cont %u\n",
385 		phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height,
386 		tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue);
387 
388 	phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg);
389 	phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable);
390 }
391 
392 static void _dpu_encoder_phys_cmd_pingpong_config(
393 		struct dpu_encoder_phys *phys_enc)
394 {
395 	struct dpu_encoder_phys_cmd *cmd_enc =
396 		to_dpu_encoder_phys_cmd(phys_enc);
397 
398 	if (!phys_enc->hw_pp || !phys_enc->hw_ctl->ops.setup_intf_cfg) {
399 		DPU_ERROR("invalid arg(s), enc %d\n", phys_enc != NULL);
400 		return;
401 	}
402 
403 	DPU_DEBUG_CMDENC(cmd_enc, "pp %d, enabling mode:\n",
404 			phys_enc->hw_pp->idx - PINGPONG_0);
405 	drm_mode_debug_printmodeline(&phys_enc->cached_mode);
406 
407 	_dpu_encoder_phys_cmd_update_intf_cfg(phys_enc);
408 	dpu_encoder_phys_cmd_tearcheck_config(phys_enc);
409 }
410 
411 static bool dpu_encoder_phys_cmd_needs_single_flush(
412 		struct dpu_encoder_phys *phys_enc)
413 {
414 	/**
415 	 * we do separate flush for each CTL and let
416 	 * CTL_START synchronize them
417 	 */
418 	return false;
419 }
420 
421 static void dpu_encoder_phys_cmd_enable_helper(
422 		struct dpu_encoder_phys *phys_enc)
423 {
424 	struct dpu_hw_ctl *ctl;
425 
426 	if (!phys_enc->hw_pp) {
427 		DPU_ERROR("invalid arg(s), encoder %d\n", phys_enc != NULL);
428 		return;
429 	}
430 
431 	dpu_encoder_helper_split_config(phys_enc, phys_enc->intf_idx);
432 
433 	_dpu_encoder_phys_cmd_pingpong_config(phys_enc);
434 
435 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
436 		return;
437 
438 	ctl = phys_enc->hw_ctl;
439 	ctl->ops.update_pending_flush_intf(ctl, phys_enc->intf_idx);
440 }
441 
442 static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc)
443 {
444 	struct dpu_encoder_phys_cmd *cmd_enc =
445 		to_dpu_encoder_phys_cmd(phys_enc);
446 
447 	if (!phys_enc->hw_pp) {
448 		DPU_ERROR("invalid phys encoder\n");
449 		return;
450 	}
451 
452 	DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
453 
454 	if (phys_enc->enable_state == DPU_ENC_ENABLED) {
455 		DPU_ERROR("already enabled\n");
456 		return;
457 	}
458 
459 	dpu_encoder_phys_cmd_enable_helper(phys_enc);
460 	phys_enc->enable_state = DPU_ENC_ENABLED;
461 }
462 
463 static void _dpu_encoder_phys_cmd_connect_te(
464 		struct dpu_encoder_phys *phys_enc, bool enable)
465 {
466 	if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te)
467 		return;
468 
469 	trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
470 	phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
471 }
472 
473 static void dpu_encoder_phys_cmd_prepare_idle_pc(
474 		struct dpu_encoder_phys *phys_enc)
475 {
476 	_dpu_encoder_phys_cmd_connect_te(phys_enc, false);
477 }
478 
479 static int dpu_encoder_phys_cmd_get_line_count(
480 		struct dpu_encoder_phys *phys_enc)
481 {
482 	struct dpu_hw_pingpong *hw_pp;
483 
484 	if (!phys_enc->hw_pp)
485 		return -EINVAL;
486 
487 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
488 		return -EINVAL;
489 
490 	hw_pp = phys_enc->hw_pp;
491 	if (!hw_pp->ops.get_line_count)
492 		return -EINVAL;
493 
494 	return hw_pp->ops.get_line_count(hw_pp);
495 }
496 
497 static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc)
498 {
499 	struct dpu_encoder_phys_cmd *cmd_enc =
500 		to_dpu_encoder_phys_cmd(phys_enc);
501 	struct dpu_hw_ctl *ctl;
502 
503 	if (!phys_enc->hw_pp) {
504 		DPU_ERROR("invalid encoder\n");
505 		return;
506 	}
507 	DRM_DEBUG_KMS("id:%u pp:%d state:%d\n", DRMID(phys_enc->parent),
508 		      phys_enc->hw_pp->idx - PINGPONG_0,
509 		      phys_enc->enable_state);
510 
511 	if (phys_enc->enable_state == DPU_ENC_DISABLED) {
512 		DPU_ERROR_CMDENC(cmd_enc, "already disabled\n");
513 		return;
514 	}
515 
516 	if (phys_enc->hw_pp->ops.enable_tearcheck)
517 		phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, false);
518 
519 	if (phys_enc->hw_intf->ops.bind_pingpong_blk) {
520 		phys_enc->hw_intf->ops.bind_pingpong_blk(
521 				phys_enc->hw_intf,
522 				false,
523 				phys_enc->hw_pp->idx);
524 
525 		ctl = phys_enc->hw_ctl;
526 		ctl->ops.update_pending_flush_intf(ctl, phys_enc->intf_idx);
527 	}
528 
529 	phys_enc->enable_state = DPU_ENC_DISABLED;
530 }
531 
532 static void dpu_encoder_phys_cmd_destroy(struct dpu_encoder_phys *phys_enc)
533 {
534 	struct dpu_encoder_phys_cmd *cmd_enc =
535 		to_dpu_encoder_phys_cmd(phys_enc);
536 
537 	kfree(cmd_enc);
538 }
539 
540 static void dpu_encoder_phys_cmd_prepare_for_kickoff(
541 		struct dpu_encoder_phys *phys_enc)
542 {
543 	struct dpu_encoder_phys_cmd *cmd_enc =
544 			to_dpu_encoder_phys_cmd(phys_enc);
545 	int ret;
546 
547 	if (!phys_enc->hw_pp) {
548 		DPU_ERROR("invalid encoder\n");
549 		return;
550 	}
551 	DRM_DEBUG_KMS("id:%u pp:%d pending_cnt:%d\n", DRMID(phys_enc->parent),
552 		      phys_enc->hw_pp->idx - PINGPONG_0,
553 		      atomic_read(&phys_enc->pending_kickoff_cnt));
554 
555 	/*
556 	 * Mark kickoff request as outstanding. If there are more than one,
557 	 * outstanding, then we have to wait for the previous one to complete
558 	 */
559 	ret = _dpu_encoder_phys_cmd_wait_for_idle(phys_enc);
560 	if (ret) {
561 		/* force pending_kickoff_cnt 0 to discard failed kickoff */
562 		atomic_set(&phys_enc->pending_kickoff_cnt, 0);
563 		DRM_ERROR("failed wait_for_idle: id:%u ret:%d pp:%d\n",
564 			  DRMID(phys_enc->parent), ret,
565 			  phys_enc->hw_pp->idx - PINGPONG_0);
566 	}
567 
568 	DPU_DEBUG_CMDENC(cmd_enc, "pp:%d pending_cnt %d\n",
569 			phys_enc->hw_pp->idx - PINGPONG_0,
570 			atomic_read(&phys_enc->pending_kickoff_cnt));
571 }
572 
573 static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
574 		struct dpu_encoder_phys *phys_enc)
575 {
576 	struct dpu_hw_pp_vsync_info info;
577 
578 	if (!phys_enc)
579 		return false;
580 
581 	phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
582 	if (info.wr_ptr_line_count > 0 &&
583 	    info.wr_ptr_line_count < phys_enc->cached_mode.vdisplay)
584 		return true;
585 
586 	return false;
587 }
588 
589 static void dpu_encoder_phys_cmd_prepare_commit(
590 		struct dpu_encoder_phys *phys_enc)
591 {
592 	struct dpu_encoder_phys_cmd *cmd_enc =
593 		to_dpu_encoder_phys_cmd(phys_enc);
594 	int trial = 0;
595 
596 	if (!phys_enc)
597 		return;
598 	if (!phys_enc->hw_pp)
599 		return;
600 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
601 		return;
602 
603 	/* If autorefresh is already disabled, we have nothing to do */
604 	if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
605 		return;
606 
607 	/*
608 	 * If autorefresh is enabled, disable it and make sure it is safe to
609 	 * proceed with current frame commit/push. Sequence fallowed is,
610 	 * 1. Disable TE
611 	 * 2. Disable autorefresh config
612 	 * 4. Poll for frame transfer ongoing to be false
613 	 * 5. Enable TE back
614 	 */
615 	_dpu_encoder_phys_cmd_connect_te(phys_enc, false);
616 	phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false);
617 
618 	do {
619 		udelay(DPU_ENC_MAX_POLL_TIMEOUT_US);
620 		if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US)
621 				> (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) {
622 			DPU_ERROR_CMDENC(cmd_enc,
623 					"disable autorefresh failed\n");
624 			break;
625 		}
626 
627 		trial++;
628 	} while (dpu_encoder_phys_cmd_is_ongoing_pptx(phys_enc));
629 
630 	_dpu_encoder_phys_cmd_connect_te(phys_enc, true);
631 
632 	DPU_DEBUG_CMDENC(to_dpu_encoder_phys_cmd(phys_enc),
633 			 "disabled autorefresh\n");
634 }
635 
636 static int _dpu_encoder_phys_cmd_wait_for_ctl_start(
637 		struct dpu_encoder_phys *phys_enc)
638 {
639 	struct dpu_encoder_phys_cmd *cmd_enc =
640 			to_dpu_encoder_phys_cmd(phys_enc);
641 	struct dpu_encoder_wait_info wait_info;
642 	int ret;
643 
644 	wait_info.wq = &phys_enc->pending_kickoff_wq;
645 	wait_info.atomic_cnt = &phys_enc->pending_ctlstart_cnt;
646 	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
647 
648 	ret = dpu_encoder_helper_wait_for_irq(phys_enc,
649 			phys_enc->irq[INTR_IDX_CTL_START],
650 			dpu_encoder_phys_cmd_ctl_start_irq,
651 			&wait_info);
652 	if (ret == -ETIMEDOUT) {
653 		DPU_ERROR_CMDENC(cmd_enc, "ctl start interrupt wait failed\n");
654 		ret = -EINVAL;
655 	} else if (!ret)
656 		ret = 0;
657 
658 	return ret;
659 }
660 
661 static int dpu_encoder_phys_cmd_wait_for_tx_complete(
662 		struct dpu_encoder_phys *phys_enc)
663 {
664 	int rc;
665 
666 	rc = _dpu_encoder_phys_cmd_wait_for_idle(phys_enc);
667 	if (rc) {
668 		DRM_ERROR("failed wait_for_idle: id:%u ret:%d intf:%d\n",
669 			  DRMID(phys_enc->parent), rc,
670 			  phys_enc->intf_idx - INTF_0);
671 	}
672 
673 	return rc;
674 }
675 
676 static int dpu_encoder_phys_cmd_wait_for_commit_done(
677 		struct dpu_encoder_phys *phys_enc)
678 {
679 	/* only required for master controller */
680 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
681 		return 0;
682 
683 	if (phys_enc->hw_ctl->ops.is_started(phys_enc->hw_ctl))
684 		return dpu_encoder_phys_cmd_wait_for_tx_complete(phys_enc);
685 
686 	return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
687 }
688 
689 static int dpu_encoder_phys_cmd_wait_for_vblank(
690 		struct dpu_encoder_phys *phys_enc)
691 {
692 	int rc = 0;
693 	struct dpu_encoder_phys_cmd *cmd_enc;
694 	struct dpu_encoder_wait_info wait_info;
695 
696 	cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
697 
698 	/* only required for master controller */
699 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
700 		return rc;
701 
702 	wait_info.wq = &cmd_enc->pending_vblank_wq;
703 	wait_info.atomic_cnt = &cmd_enc->pending_vblank_cnt;
704 	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
705 
706 	atomic_inc(&cmd_enc->pending_vblank_cnt);
707 
708 	rc = dpu_encoder_helper_wait_for_irq(phys_enc,
709 			phys_enc->irq[INTR_IDX_RDPTR],
710 			dpu_encoder_phys_cmd_pp_rd_ptr_irq,
711 			&wait_info);
712 
713 	return rc;
714 }
715 
716 static void dpu_encoder_phys_cmd_handle_post_kickoff(
717 		struct dpu_encoder_phys *phys_enc)
718 {
719 	/**
720 	 * re-enable external TE, either for the first time after enabling
721 	 * or if disabled for Autorefresh
722 	 */
723 	_dpu_encoder_phys_cmd_connect_te(phys_enc, true);
724 }
725 
726 static void dpu_encoder_phys_cmd_trigger_start(
727 		struct dpu_encoder_phys *phys_enc)
728 {
729 	dpu_encoder_helper_trigger_start(phys_enc);
730 }
731 
732 static void dpu_encoder_phys_cmd_init_ops(
733 		struct dpu_encoder_phys_ops *ops)
734 {
735 	ops->prepare_commit = dpu_encoder_phys_cmd_prepare_commit;
736 	ops->is_master = dpu_encoder_phys_cmd_is_master;
737 	ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
738 	ops->enable = dpu_encoder_phys_cmd_enable;
739 	ops->disable = dpu_encoder_phys_cmd_disable;
740 	ops->destroy = dpu_encoder_phys_cmd_destroy;
741 	ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
742 	ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done;
743 	ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
744 	ops->wait_for_tx_complete = dpu_encoder_phys_cmd_wait_for_tx_complete;
745 	ops->wait_for_vblank = dpu_encoder_phys_cmd_wait_for_vblank;
746 	ops->trigger_start = dpu_encoder_phys_cmd_trigger_start;
747 	ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush;
748 	ops->irq_control = dpu_encoder_phys_cmd_irq_control;
749 	ops->restore = dpu_encoder_phys_cmd_enable_helper;
750 	ops->prepare_idle_pc = dpu_encoder_phys_cmd_prepare_idle_pc;
751 	ops->handle_post_kickoff = dpu_encoder_phys_cmd_handle_post_kickoff;
752 	ops->get_line_count = dpu_encoder_phys_cmd_get_line_count;
753 }
754 
755 struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
756 		struct dpu_enc_phys_init_params *p)
757 {
758 	struct dpu_encoder_phys *phys_enc = NULL;
759 	struct dpu_encoder_phys_cmd *cmd_enc = NULL;
760 	int i, ret = 0;
761 
762 	DPU_DEBUG("intf %d\n", p->intf_idx - INTF_0);
763 
764 	cmd_enc = kzalloc(sizeof(*cmd_enc), GFP_KERNEL);
765 	if (!cmd_enc) {
766 		ret = -ENOMEM;
767 		DPU_ERROR("failed to allocate\n");
768 		return ERR_PTR(ret);
769 	}
770 	phys_enc = &cmd_enc->base;
771 	phys_enc->hw_mdptop = p->dpu_kms->hw_mdp;
772 	phys_enc->intf_idx = p->intf_idx;
773 
774 	dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
775 	phys_enc->parent = p->parent;
776 	phys_enc->dpu_kms = p->dpu_kms;
777 	phys_enc->split_role = p->split_role;
778 	phys_enc->intf_mode = INTF_MODE_CMD;
779 	phys_enc->enc_spinlock = p->enc_spinlock;
780 	cmd_enc->stream_sel = 0;
781 	phys_enc->enable_state = DPU_ENC_DISABLED;
782 	for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++)
783 		phys_enc->irq[i] = -EINVAL;
784 
785 	atomic_set(&phys_enc->vblank_refcount, 0);
786 	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
787 	atomic_set(&phys_enc->pending_ctlstart_cnt, 0);
788 	atomic_set(&cmd_enc->pending_vblank_cnt, 0);
789 	init_waitqueue_head(&phys_enc->pending_kickoff_wq);
790 	init_waitqueue_head(&cmd_enc->pending_vblank_wq);
791 
792 	DPU_DEBUG_CMDENC(cmd_enc, "created\n");
793 
794 	return phys_enc;
795 }
796