1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights reserved. 3 */ 4 5 #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ 6 #include "dpu_encoder_phys.h" 7 #include "dpu_hw_interrupts.h" 8 #include "dpu_hw_merge3d.h" 9 #include "dpu_core_irq.h" 10 #include "dpu_formats.h" 11 #include "dpu_trace.h" 12 #include "disp/msm_disp_snapshot.h" 13 14 #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ 15 (e) && (e)->parent ? \ 16 (e)->parent->base.id : -1, \ 17 (e) && (e)->hw_intf ? \ 18 (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) 19 20 #define DPU_ERROR_VIDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \ 21 (e) && (e)->parent ? \ 22 (e)->parent->base.id : -1, \ 23 (e) && (e)->hw_intf ? \ 24 (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) 25 26 #define to_dpu_encoder_phys_vid(x) \ 27 container_of(x, struct dpu_encoder_phys_vid, base) 28 29 static bool dpu_encoder_phys_vid_is_master( 30 struct dpu_encoder_phys *phys_enc) 31 { 32 bool ret = false; 33 34 if (phys_enc->split_role != ENC_ROLE_SLAVE) 35 ret = true; 36 37 return ret; 38 } 39 40 static void drm_mode_to_intf_timing_params( 41 const struct dpu_encoder_phys *phys_enc, 42 const struct drm_display_mode *mode, 43 struct dpu_hw_intf_timing_params *timing) 44 { 45 memset(timing, 0, sizeof(*timing)); 46 47 if ((mode->htotal < mode->hsync_end) 48 || (mode->hsync_start < mode->hdisplay) 49 || (mode->vtotal < mode->vsync_end) 50 || (mode->vsync_start < mode->vdisplay) 51 || (mode->hsync_end < mode->hsync_start) 52 || (mode->vsync_end < mode->vsync_start)) { 53 DPU_ERROR( 54 "invalid params - hstart:%d,hend:%d,htot:%d,hdisplay:%d\n", 55 mode->hsync_start, mode->hsync_end, 56 mode->htotal, mode->hdisplay); 57 DPU_ERROR("vstart:%d,vend:%d,vtot:%d,vdisplay:%d\n", 58 mode->vsync_start, mode->vsync_end, 59 mode->vtotal, mode->vdisplay); 60 return; 61 } 62 63 /* 64 * https://www.kernel.org/doc/htmldocs/drm/ch02s05.html 65 * Active Region Front Porch Sync Back Porch 66 * <-----------------><------------><-----><-----------> 67 * <- [hv]display ---> 68 * <--------- [hv]sync_start ------> 69 * <----------------- [hv]sync_end -------> 70 * <---------------------------- [hv]total -------------> 71 */ 72 timing->width = mode->hdisplay; /* active width */ 73 timing->height = mode->vdisplay; /* active height */ 74 timing->xres = timing->width; 75 timing->yres = timing->height; 76 timing->h_back_porch = mode->htotal - mode->hsync_end; 77 timing->h_front_porch = mode->hsync_start - mode->hdisplay; 78 timing->v_back_porch = mode->vtotal - mode->vsync_end; 79 timing->v_front_porch = mode->vsync_start - mode->vdisplay; 80 timing->hsync_pulse_width = mode->hsync_end - mode->hsync_start; 81 timing->vsync_pulse_width = mode->vsync_end - mode->vsync_start; 82 timing->hsync_polarity = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0; 83 timing->vsync_polarity = (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0; 84 timing->border_clr = 0; 85 timing->underflow_clr = 0xff; 86 timing->hsync_skew = mode->hskew; 87 88 /* DSI controller cannot handle active-low sync signals. */ 89 if (phys_enc->hw_intf->cap->type == INTF_DSI) { 90 timing->hsync_polarity = 0; 91 timing->vsync_polarity = 0; 92 } 93 94 /* for DP/EDP, Shift timings to align it to bottom right */ 95 if (phys_enc->hw_intf->cap->type == INTF_DP) { 96 timing->h_back_porch += timing->h_front_porch; 97 timing->h_front_porch = 0; 98 timing->v_back_porch += timing->v_front_porch; 99 timing->v_front_porch = 0; 100 } 101 102 timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); 103 timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent); 104 105 /* 106 * for DP, divide the horizonal parameters by 2 when 107 * widebus is enabled 108 */ 109 if (phys_enc->hw_intf->cap->type == INTF_DP && timing->wide_bus_en) { 110 timing->width = timing->width >> 1; 111 timing->xres = timing->xres >> 1; 112 timing->h_back_porch = timing->h_back_porch >> 1; 113 timing->h_front_porch = timing->h_front_porch >> 1; 114 timing->hsync_pulse_width = timing->hsync_pulse_width >> 1; 115 } 116 } 117 118 static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing) 119 { 120 u32 active = timing->xres; 121 u32 inactive = 122 timing->h_back_porch + timing->h_front_porch + 123 timing->hsync_pulse_width; 124 return active + inactive; 125 } 126 127 static u32 get_vertical_total(const struct dpu_hw_intf_timing_params *timing) 128 { 129 u32 active = timing->yres; 130 u32 inactive = 131 timing->v_back_porch + timing->v_front_porch + 132 timing->vsync_pulse_width; 133 return active + inactive; 134 } 135 136 /* 137 * programmable_fetch_get_num_lines: 138 * Number of fetch lines in vertical front porch 139 * @timing: Pointer to the intf timing information for the requested mode 140 * 141 * Returns the number of fetch lines in vertical front porch at which mdp 142 * can start fetching the next frame. 143 * 144 * Number of needed prefetch lines is anything that cannot be absorbed in the 145 * start of frame time (back porch + vsync pulse width). 146 * 147 * Some panels have very large VFP, however we only need a total number of 148 * lines based on the chip worst case latencies. 149 */ 150 static u32 programmable_fetch_get_num_lines( 151 struct dpu_encoder_phys *phys_enc, 152 const struct dpu_hw_intf_timing_params *timing) 153 { 154 u32 worst_case_needed_lines = 155 phys_enc->hw_intf->cap->prog_fetch_lines_worst_case; 156 u32 start_of_frame_lines = 157 timing->v_back_porch + timing->vsync_pulse_width; 158 u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines; 159 u32 actual_vfp_lines = 0; 160 161 /* Fetch must be outside active lines, otherwise undefined. */ 162 if (start_of_frame_lines >= worst_case_needed_lines) { 163 DPU_DEBUG_VIDENC(phys_enc, 164 "prog fetch is not needed, large vbp+vsw\n"); 165 actual_vfp_lines = 0; 166 } else if (timing->v_front_porch < needed_vfp_lines) { 167 /* Warn fetch needed, but not enough porch in panel config */ 168 pr_warn_once 169 ("low vbp+vfp may lead to perf issues in some cases\n"); 170 DPU_DEBUG_VIDENC(phys_enc, 171 "less vfp than fetch req, using entire vfp\n"); 172 actual_vfp_lines = timing->v_front_porch; 173 } else { 174 DPU_DEBUG_VIDENC(phys_enc, "room in vfp for needed prefetch\n"); 175 actual_vfp_lines = needed_vfp_lines; 176 } 177 178 DPU_DEBUG_VIDENC(phys_enc, 179 "v_front_porch %u v_back_porch %u vsync_pulse_width %u\n", 180 timing->v_front_porch, timing->v_back_porch, 181 timing->vsync_pulse_width); 182 DPU_DEBUG_VIDENC(phys_enc, 183 "wc_lines %u needed_vfp_lines %u actual_vfp_lines %u\n", 184 worst_case_needed_lines, needed_vfp_lines, actual_vfp_lines); 185 186 return actual_vfp_lines; 187 } 188 189 /* 190 * programmable_fetch_config: Programs HW to prefetch lines by offsetting 191 * the start of fetch into the vertical front porch for cases where the 192 * vsync pulse width and vertical back porch time is insufficient 193 * 194 * Gets # of lines to pre-fetch, then calculate VSYNC counter value. 195 * HW layer requires VSYNC counter of first pixel of tgt VFP line. 196 * 197 * @timing: Pointer to the intf timing information for the requested mode 198 */ 199 static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc, 200 const struct dpu_hw_intf_timing_params *timing) 201 { 202 struct dpu_hw_intf_prog_fetch f = { 0 }; 203 u32 vfp_fetch_lines = 0; 204 u32 horiz_total = 0; 205 u32 vert_total = 0; 206 u32 vfp_fetch_start_vsync_counter = 0; 207 unsigned long lock_flags; 208 209 if (WARN_ON_ONCE(!phys_enc->hw_intf->ops.setup_prg_fetch)) 210 return; 211 212 vfp_fetch_lines = programmable_fetch_get_num_lines(phys_enc, timing); 213 if (vfp_fetch_lines) { 214 vert_total = get_vertical_total(timing); 215 horiz_total = get_horizontal_total(timing); 216 vfp_fetch_start_vsync_counter = 217 (vert_total - vfp_fetch_lines) * horiz_total + 1; 218 f.enable = 1; 219 f.fetch_start = vfp_fetch_start_vsync_counter; 220 } 221 222 DPU_DEBUG_VIDENC(phys_enc, 223 "vfp_fetch_lines %u vfp_fetch_start_vsync_counter %u\n", 224 vfp_fetch_lines, vfp_fetch_start_vsync_counter); 225 226 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 227 phys_enc->hw_intf->ops.setup_prg_fetch(phys_enc->hw_intf, &f); 228 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 229 } 230 231 static void dpu_encoder_phys_vid_setup_timing_engine( 232 struct dpu_encoder_phys *phys_enc) 233 { 234 struct drm_display_mode mode; 235 struct dpu_hw_intf_timing_params timing_params = { 0 }; 236 const struct dpu_format *fmt = NULL; 237 u32 fmt_fourcc = DRM_FORMAT_RGB888; 238 unsigned long lock_flags; 239 struct dpu_hw_intf_cfg intf_cfg = { 0 }; 240 241 drm_mode_init(&mode, &phys_enc->cached_mode); 242 243 if (!phys_enc->hw_ctl->ops.setup_intf_cfg) { 244 DPU_ERROR("invalid encoder %d\n", phys_enc != NULL); 245 return; 246 } 247 248 if (!phys_enc->hw_intf->ops.setup_timing_gen) { 249 DPU_ERROR("timing engine setup is not supported\n"); 250 return; 251 } 252 253 DPU_DEBUG_VIDENC(phys_enc, "enabling mode:\n"); 254 drm_mode_debug_printmodeline(&mode); 255 256 if (phys_enc->split_role != ENC_ROLE_SOLO) { 257 mode.hdisplay >>= 1; 258 mode.htotal >>= 1; 259 mode.hsync_start >>= 1; 260 mode.hsync_end >>= 1; 261 mode.hskew >>= 1; 262 263 DPU_DEBUG_VIDENC(phys_enc, 264 "split_role %d, halve horizontal %d %d %d %d %d\n", 265 phys_enc->split_role, 266 mode.hdisplay, mode.htotal, 267 mode.hsync_start, mode.hsync_end, 268 mode.hskew); 269 } 270 271 drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params); 272 273 fmt = dpu_get_dpu_format(fmt_fourcc); 274 DPU_DEBUG_VIDENC(phys_enc, "fmt_fourcc 0x%X\n", fmt_fourcc); 275 276 intf_cfg.intf = phys_enc->hw_intf->idx; 277 intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID; 278 intf_cfg.stream_sel = 0; /* Don't care value for video mode */ 279 intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); 280 intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); 281 if (phys_enc->hw_pp->merge_3d) 282 intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; 283 284 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 285 phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf, 286 &timing_params, fmt); 287 phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg); 288 289 /* setup which pp blk will connect to this intf */ 290 if (phys_enc->hw_intf->ops.bind_pingpong_blk) 291 phys_enc->hw_intf->ops.bind_pingpong_blk( 292 phys_enc->hw_intf, 293 phys_enc->hw_pp->idx); 294 295 if (phys_enc->hw_pp->merge_3d) 296 phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, intf_cfg.mode_3d); 297 298 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 299 300 programmable_fetch_config(phys_enc, &timing_params); 301 } 302 303 static void dpu_encoder_phys_vid_vblank_irq(void *arg) 304 { 305 struct dpu_encoder_phys *phys_enc = arg; 306 struct dpu_hw_ctl *hw_ctl; 307 unsigned long lock_flags; 308 u32 flush_register = 0; 309 310 hw_ctl = phys_enc->hw_ctl; 311 312 DPU_ATRACE_BEGIN("vblank_irq"); 313 314 dpu_encoder_vblank_callback(phys_enc->parent, phys_enc); 315 316 atomic_read(&phys_enc->pending_kickoff_cnt); 317 318 /* 319 * only decrement the pending flush count if we've actually flushed 320 * hardware. due to sw irq latency, vblank may have already happened 321 * so we need to double-check with hw that it accepted the flush bits 322 */ 323 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 324 if (hw_ctl->ops.get_flush_register) 325 flush_register = hw_ctl->ops.get_flush_register(hw_ctl); 326 327 if (!(flush_register & hw_ctl->ops.get_pending_flush(hw_ctl))) 328 atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); 329 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 330 331 /* Signal any waiting atomic commit thread */ 332 wake_up_all(&phys_enc->pending_kickoff_wq); 333 334 dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, 335 DPU_ENCODER_FRAME_EVENT_DONE); 336 337 DPU_ATRACE_END("vblank_irq"); 338 } 339 340 static void dpu_encoder_phys_vid_underrun_irq(void *arg) 341 { 342 struct dpu_encoder_phys *phys_enc = arg; 343 344 dpu_encoder_underrun_callback(phys_enc->parent, phys_enc); 345 } 346 347 static bool dpu_encoder_phys_vid_needs_single_flush( 348 struct dpu_encoder_phys *phys_enc) 349 { 350 return phys_enc->split_role != ENC_ROLE_SOLO; 351 } 352 353 static void dpu_encoder_phys_vid_atomic_mode_set( 354 struct dpu_encoder_phys *phys_enc, 355 struct drm_crtc_state *crtc_state, 356 struct drm_connector_state *conn_state) 357 { 358 phys_enc->irq[INTR_IDX_VSYNC] = phys_enc->hw_intf->cap->intr_vsync; 359 360 phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun; 361 } 362 363 static int dpu_encoder_phys_vid_control_vblank_irq( 364 struct dpu_encoder_phys *phys_enc, 365 bool enable) 366 { 367 int ret = 0; 368 int refcount; 369 370 refcount = atomic_read(&phys_enc->vblank_refcount); 371 372 /* Slave encoders don't report vblank */ 373 if (!dpu_encoder_phys_vid_is_master(phys_enc)) 374 goto end; 375 376 /* protect against negative */ 377 if (!enable && refcount == 0) { 378 ret = -EINVAL; 379 goto end; 380 } 381 382 DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable, 383 atomic_read(&phys_enc->vblank_refcount)); 384 385 if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) 386 ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, 387 phys_enc->irq[INTR_IDX_VSYNC], 388 dpu_encoder_phys_vid_vblank_irq, 389 phys_enc); 390 else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) 391 ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, 392 phys_enc->irq[INTR_IDX_VSYNC]); 393 394 end: 395 if (ret) { 396 DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n", 397 DRMID(phys_enc->parent), 398 phys_enc->hw_intf->idx - INTF_0, ret, enable, 399 refcount); 400 } 401 return ret; 402 } 403 404 static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) 405 { 406 struct dpu_hw_ctl *ctl; 407 408 ctl = phys_enc->hw_ctl; 409 410 DPU_DEBUG_VIDENC(phys_enc, "\n"); 411 412 if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing)) 413 return; 414 415 dpu_encoder_helper_split_config(phys_enc, phys_enc->hw_intf->idx); 416 417 dpu_encoder_phys_vid_setup_timing_engine(phys_enc); 418 419 /* 420 * For single flush cases (dual-ctl or pp-split), skip setting the 421 * flush bit for the slave intf, since both intfs use same ctl 422 * and HW will only flush the master. 423 */ 424 if (dpu_encoder_phys_vid_needs_single_flush(phys_enc) && 425 !dpu_encoder_phys_vid_is_master(phys_enc)) 426 goto skip_flush; 427 428 ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); 429 if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d) 430 ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); 431 432 skip_flush: 433 DPU_DEBUG_VIDENC(phys_enc, 434 "update pending flush ctl %d intf %d\n", 435 ctl->idx - CTL_0, phys_enc->hw_intf->idx); 436 437 atomic_set(&phys_enc->underrun_cnt, 0); 438 439 /* ctl_flush & timing engine enable will be triggered by framework */ 440 if (phys_enc->enable_state == DPU_ENC_DISABLED) 441 phys_enc->enable_state = DPU_ENC_ENABLING; 442 } 443 444 static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc) 445 { 446 DPU_DEBUG_VIDENC(phys_enc, "\n"); 447 kfree(phys_enc); 448 } 449 450 static int dpu_encoder_phys_vid_wait_for_vblank( 451 struct dpu_encoder_phys *phys_enc) 452 { 453 struct dpu_encoder_wait_info wait_info; 454 int ret; 455 456 wait_info.wq = &phys_enc->pending_kickoff_wq; 457 wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt; 458 wait_info.timeout_ms = KICKOFF_TIMEOUT_MS; 459 460 if (!dpu_encoder_phys_vid_is_master(phys_enc)) { 461 return 0; 462 } 463 464 /* Wait for kickoff to complete */ 465 ret = dpu_encoder_helper_wait_for_irq(phys_enc, 466 phys_enc->irq[INTR_IDX_VSYNC], 467 dpu_encoder_phys_vid_vblank_irq, 468 &wait_info); 469 470 if (ret == -ETIMEDOUT) { 471 dpu_encoder_helper_report_irq_timeout(phys_enc, INTR_IDX_VSYNC); 472 } 473 474 return ret; 475 } 476 477 static int dpu_encoder_phys_vid_wait_for_commit_done( 478 struct dpu_encoder_phys *phys_enc) 479 { 480 struct dpu_hw_ctl *hw_ctl = phys_enc->hw_ctl; 481 int ret; 482 483 if (!hw_ctl) 484 return 0; 485 486 ret = wait_event_timeout(phys_enc->pending_kickoff_wq, 487 (hw_ctl->ops.get_flush_register(hw_ctl) == 0), 488 msecs_to_jiffies(50)); 489 if (ret <= 0) { 490 DPU_ERROR("vblank timeout\n"); 491 return -ETIMEDOUT; 492 } 493 494 return 0; 495 } 496 497 static void dpu_encoder_phys_vid_prepare_for_kickoff( 498 struct dpu_encoder_phys *phys_enc) 499 { 500 struct dpu_hw_ctl *ctl; 501 int rc; 502 struct drm_encoder *drm_enc; 503 504 drm_enc = phys_enc->parent; 505 506 ctl = phys_enc->hw_ctl; 507 if (!ctl->ops.wait_reset_status) 508 return; 509 510 /* 511 * hw supports hardware initiated ctl reset, so before we kickoff a new 512 * frame, need to check and wait for hw initiated ctl reset completion 513 */ 514 rc = ctl->ops.wait_reset_status(ctl); 515 if (rc) { 516 DPU_ERROR_VIDENC(phys_enc, "ctl %d reset failure: %d\n", 517 ctl->idx, rc); 518 msm_disp_snapshot_state(drm_enc->dev); 519 dpu_core_irq_unregister_callback(phys_enc->dpu_kms, 520 phys_enc->irq[INTR_IDX_VSYNC]); 521 } 522 } 523 524 static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) 525 { 526 unsigned long lock_flags; 527 int ret; 528 struct dpu_hw_intf_status intf_status = {0}; 529 530 if (!phys_enc->parent || !phys_enc->parent->dev) { 531 DPU_ERROR("invalid encoder/device\n"); 532 return; 533 } 534 535 if (!phys_enc->hw_intf) { 536 DPU_ERROR("invalid hw_intf %d hw_ctl %d\n", 537 phys_enc->hw_intf != NULL, phys_enc->hw_ctl != NULL); 538 return; 539 } 540 541 if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing)) 542 return; 543 544 if (phys_enc->enable_state == DPU_ENC_DISABLED) { 545 DPU_ERROR("already disabled\n"); 546 return; 547 } 548 549 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 550 phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0); 551 if (dpu_encoder_phys_vid_is_master(phys_enc)) 552 dpu_encoder_phys_inc_pending(phys_enc); 553 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 554 555 /* 556 * Wait for a vsync so we know the ENABLE=0 latched before 557 * the (connector) source of the vsync's gets disabled, 558 * otherwise we end up in a funny state if we re-enable 559 * before the disable latches, which results that some of 560 * the settings changes for the new modeset (like new 561 * scanout buffer) don't latch properly.. 562 */ 563 if (dpu_encoder_phys_vid_is_master(phys_enc)) { 564 ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc); 565 if (ret) { 566 atomic_set(&phys_enc->pending_kickoff_cnt, 0); 567 DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", 568 DRMID(phys_enc->parent), 569 phys_enc->hw_intf->idx - INTF_0, ret); 570 } 571 } 572 573 if (phys_enc->hw_intf && phys_enc->hw_intf->ops.get_status) 574 phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &intf_status); 575 576 /* 577 * Wait for a vsync if timing en status is on after timing engine 578 * is disabled. 579 */ 580 if (intf_status.is_en && dpu_encoder_phys_vid_is_master(phys_enc)) { 581 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 582 dpu_encoder_phys_inc_pending(phys_enc); 583 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 584 ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc); 585 if (ret) { 586 atomic_set(&phys_enc->pending_kickoff_cnt, 0); 587 DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", 588 DRMID(phys_enc->parent), 589 phys_enc->hw_intf->idx - INTF_0, ret); 590 } 591 } 592 593 dpu_encoder_helper_phys_cleanup(phys_enc); 594 phys_enc->enable_state = DPU_ENC_DISABLED; 595 } 596 597 static void dpu_encoder_phys_vid_handle_post_kickoff( 598 struct dpu_encoder_phys *phys_enc) 599 { 600 unsigned long lock_flags; 601 602 /* 603 * Video mode must flush CTL before enabling timing engine 604 * Video encoders need to turn on their interfaces now 605 */ 606 if (phys_enc->enable_state == DPU_ENC_ENABLING) { 607 trace_dpu_enc_phys_vid_post_kickoff(DRMID(phys_enc->parent), 608 phys_enc->hw_intf->idx - INTF_0); 609 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); 610 phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1); 611 spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); 612 phys_enc->enable_state = DPU_ENC_ENABLED; 613 } 614 } 615 616 static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc, 617 bool enable) 618 { 619 int ret; 620 621 trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent), 622 phys_enc->hw_intf->idx - INTF_0, 623 enable, 624 atomic_read(&phys_enc->vblank_refcount)); 625 626 if (enable) { 627 ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true); 628 if (WARN_ON(ret)) 629 return; 630 631 dpu_core_irq_register_callback(phys_enc->dpu_kms, 632 phys_enc->irq[INTR_IDX_UNDERRUN], 633 dpu_encoder_phys_vid_underrun_irq, 634 phys_enc); 635 } else { 636 dpu_encoder_phys_vid_control_vblank_irq(phys_enc, false); 637 dpu_core_irq_unregister_callback(phys_enc->dpu_kms, 638 phys_enc->irq[INTR_IDX_UNDERRUN]); 639 } 640 } 641 642 static int dpu_encoder_phys_vid_get_line_count( 643 struct dpu_encoder_phys *phys_enc) 644 { 645 if (!dpu_encoder_phys_vid_is_master(phys_enc)) 646 return -EINVAL; 647 648 if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_line_count) 649 return -EINVAL; 650 651 return phys_enc->hw_intf->ops.get_line_count(phys_enc->hw_intf); 652 } 653 654 static int dpu_encoder_phys_vid_get_frame_count( 655 struct dpu_encoder_phys *phys_enc) 656 { 657 struct dpu_hw_intf_status s = {0}; 658 u32 fetch_start = 0; 659 struct drm_display_mode mode; 660 661 drm_mode_init(&mode, &phys_enc->cached_mode); 662 663 if (!dpu_encoder_phys_vid_is_master(phys_enc)) 664 return -EINVAL; 665 666 if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_status) 667 return -EINVAL; 668 669 phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &s); 670 671 if (s.is_prog_fetch_en && s.is_en) { 672 fetch_start = mode.vtotal - (mode.vsync_start - mode.vdisplay); 673 if ((s.line_count > fetch_start) && 674 (s.line_count <= mode.vtotal)) 675 return s.frame_count + 1; 676 } 677 678 return s.frame_count; 679 } 680 681 static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) 682 { 683 ops->is_master = dpu_encoder_phys_vid_is_master; 684 ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set; 685 ops->enable = dpu_encoder_phys_vid_enable; 686 ops->disable = dpu_encoder_phys_vid_disable; 687 ops->destroy = dpu_encoder_phys_vid_destroy; 688 ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq; 689 ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done; 690 ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank; 691 ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_vblank; 692 ops->irq_control = dpu_encoder_phys_vid_irq_control; 693 ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff; 694 ops->handle_post_kickoff = dpu_encoder_phys_vid_handle_post_kickoff; 695 ops->needs_single_flush = dpu_encoder_phys_vid_needs_single_flush; 696 ops->get_line_count = dpu_encoder_phys_vid_get_line_count; 697 ops->get_frame_count = dpu_encoder_phys_vid_get_frame_count; 698 } 699 700 struct dpu_encoder_phys *dpu_encoder_phys_vid_init( 701 struct dpu_enc_phys_init_params *p) 702 { 703 struct dpu_encoder_phys *phys_enc = NULL; 704 705 if (!p) { 706 DPU_ERROR("failed to create encoder due to invalid parameter\n"); 707 return ERR_PTR(-EINVAL); 708 } 709 710 phys_enc = kzalloc(sizeof(*phys_enc), GFP_KERNEL); 711 if (!phys_enc) { 712 DPU_ERROR("failed to create encoder due to memory allocation error\n"); 713 return ERR_PTR(-ENOMEM); 714 } 715 716 DPU_DEBUG_VIDENC(phys_enc, "\n"); 717 718 dpu_encoder_phys_init(phys_enc, p); 719 720 dpu_encoder_phys_vid_init_ops(&phys_enc->ops); 721 phys_enc->intf_mode = INTF_MODE_VIDEO; 722 723 DPU_DEBUG_VIDENC(phys_enc, "created intf idx:%d\n", p->hw_intf->idx); 724 725 return phys_enc; 726 } 727