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