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