Skip to content

drm/msm/dpu: Prevent unnecessary hardware block migration#568

Open
chenchongbiao wants to merge 1 commit into
radxa:linux-7.0.11from
chenchongbiao:20260623-fix-msm-dpu
Open

drm/msm/dpu: Prevent unnecessary hardware block migration#568
chenchongbiao wants to merge 1 commit into
radxa:linux-7.0.11from
chenchongbiao:20260623-fix-msm-dpu

Conversation

@chenchongbiao

Copy link
Copy Markdown

When one CRTC is disabled during Type-C hot-unplug, the DPU Resource Manager would unnecessarily reassign hardware blocks (CTL, LM, DSPP) for the remaining active CRTC. The sequence:

  1. crtc-0's dpu_rm_release() frees ctl-0, LM-0/1
  2. crtc-1's dpu_crtc_assign_resources() releases ctl-1/LM-2/3 then calls dpu_rm_reserve()
  3. _dpu_rm_reserve_ctls() scans from j=0, finds ctl-0 free, assigns it to crtc-1 instead of keeping ctl-1
  4. _dpu_rm_reserve_lms() does the same for LM blocks
  5. The hardware pipeline migration triggers a modeset that disables/re-enables the encoder, but vblank IRQ callbacks are not properly re-registered (cb:0x0 in core_irq debugfs)
  6. INTF hardware continues generating vsync but interrupts go unhandled, causing the display to freeze

Fix by:

  • In dpu_crtc_assign_resources(): only release resources when the CRTC is being disabled, not on every modeset. For enabled CRTCs, let dpu_rm_reserve() retain the existing assignment.
  • In _dpu_rm_reserve_ctls() and _dpu_rm_reserve_lms(): use a two-pass approach that first prefers hardware blocks already assigned to this CRTC, then falls back to the free pool.

@chenchongbiao

chenchongbiao commented Jun 23, 2026

Copy link
Copy Markdown
Author

改动一:dpu_crtc_assign_resources
// 改前:
dpu_rm_release(global_state, crtc); // 无条件释放
if (!crtc_state->enable)
return 0;
dpu_rm_reserve(...); // 重新分配

// 改后:
if (!crtc_state->enable) {
dpu_rm_release(global_state, crtc); // 只在关闭时释放
return 0;
}
dpu_rm_reserve(...); // 开着就不释放,直接 reserve

原来无论 CRTC 开还是关,先扔干净再重新捡。释放 ctl-0 后 ctl-0 变成空闲,然后 crtc-1 的 reserve 从 j=0 扫描就会抢走。
改后:CRTC 还开着就不扔。reserve 时 ctl_to_crtc_id[1] 还指着 crtc-1,第一轮"已经是我自己的"直接命中,不动。
改动二:_dpu_rm_reserve_ctls — CTL 分配

// 改前:一轮循环
for (j = 0; j < N; j++) {
if (reserved_by_other(...)) continue; // 跳过被占的
ctl_idx[i] = j; // 第一个空闲就分
break;
}

// 改后:两轮循环
// 第一轮:只找"我已经占着的"
for (j = 0; j < N; j++) {
if (ctl_to_crtc_id[j] != crtc_id) continue; // 不是我占的跳过
ctl_idx[i] = j; // 保留
i++;
}
// 第二轮:不够再从空闲池找
for (j = 0; j < N; j++) {
if (reserved_by_other(...)) continue;
ctl_idx[i] = j;
i++;
}
第一轮只看 ctl_to_crtc_id[j] == crtc_id——"这个 CTL 登记在我名下",直接拿。第二轮才从真正空闲的池子里找。

改动三:_dpu_rm_reserve_lms — LM 分配,同理但加了一个关键点
// 第一轮找已有的 LM,但跳过 dpu_rm_check_lm_and_get_connected_blks
// 因为:
// - boot 时 topology 可能 num_dspp=0,检查放行
// - hotplug 后 topology 变了,num_dspp>0,检查拒绝 LM-4/5(DSPP
-1)
// - 既然之前能工作,就别重检,原样保留
// 直接从 LM 的硬件配置读 PP/DSPP 编号
pp_idx = lm_cfg->pingpong - PINGPONG_0;
if (topology->num_dspp) {
d = lm_cfg->dspp - DSPP_0;
dspp_idx = (d >= 0) ? d : 0; // -1 安全处理
}
不加的话 LM-4/5 被拒,退到第二轮抢走刚释放的 LM-2/3,HDMI 蓝屏。

…unplug

When one CRTC is disabled during Type-C hot-unplug, the DPU Resource
Manager would unnecessarily reassign hardware blocks (CTL, LM, DSPP)
for the remaining active CRTC.  The sequence:

  1. crtc-0's dpu_rm_release() frees ctl-0, LM-0/1
  2. crtc-1's dpu_crtc_assign_resources() releases ctl-1/LM-2/3
     then calls dpu_rm_reserve()
  3. _dpu_rm_reserve_ctls() scans from j=0, finds ctl-0 free,
     assigns it to crtc-1 instead of keeping ctl-1
  4. _dpu_rm_reserve_lms() does the same for LM blocks
  5. The hardware pipeline migration triggers a modeset that
     disables/re-enables the encoder, but vblank IRQ callbacks
     are not properly re-registered (cb:0x0 in core_irq debugfs)
  6. INTF hardware continues generating vsync but interrupts go
     unhandled, causing the display to freeze

Fix by:
  - In dpu_crtc_assign_resources(): only release resources when
    the CRTC is being disabled, not on every modeset.  For enabled
    CRTCs, let dpu_rm_reserve() retain the existing assignment.
  - In _dpu_rm_reserve_ctls() and _dpu_rm_reserve_lms(): use a
    two-pass approach that first prefers hardware blocks already
    assigned to this CRTC, then falls back to the free pool.

Signed-off-by: Chongbiao Chen <chenchongbiao@radxa.com>
@chenchongbiao chenchongbiao marked this pull request as draft June 23, 2026 02:40
@chenchongbiao chenchongbiao force-pushed the 20260623-fix-msm-dpu branch from 27af9d0 to 03915e9 Compare June 23, 2026 03:30
@chenchongbiao chenchongbiao marked this pull request as ready for review June 23, 2026 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant