Skip to content

Commit 4cd33d9

Browse files
committed
Merge tag 'drm-msm-fixes-2024-10-16' of https://gitlab.freedesktop.org/drm/msm into drm-fixes
Fixes for v6.12 Display: - move CRTC resource assignment to atomic_check otherwise to make consecutive calls to atomic_check() consistent - fix rounding / sign-extension issues with pclk calculation in case of DSC - cleanups to drop incorrect null checks in dpu snapshots - fix to use kvzalloc in dpu snapshot to avoid allocation issues in heavily loaded system cases - Fix to not program merge_3d block if dual LM is not being used - Fix to not flush merge_3d block if its not enabled otherwise this leads to false timeouts GPU: - a7xx: add a fence wait before SMMU table update Signed-off-by: Dave Airlie <[email protected]> From: Rob Clark <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGsp3Zbd_H3FhHdRz9yCYA4wxX4SenpYRSk=Mx2d8GMSuQ@mail.gmail.com
2 parents 8e929cb + 77ad507 commit 4cd33d9

File tree

8 files changed

+89
-59
lines changed

8 files changed

+89
-59
lines changed

drivers/gpu/drm/msm/adreno/a6xx_gpu.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter,
101101
}
102102

103103
static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
104-
struct msm_ringbuffer *ring, struct msm_file_private *ctx)
104+
struct msm_ringbuffer *ring, struct msm_gem_submit *submit)
105105
{
106106
bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
107+
struct msm_file_private *ctx = submit->queue->ctx;
107108
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
108109
phys_addr_t ttbr;
109110
u32 asid;
@@ -115,6 +116,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
115116
if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
116117
return;
117118

119+
if (adreno_gpu->info->family >= ADRENO_7XX_GEN1) {
120+
/* Wait for previous submit to complete before continuing: */
121+
OUT_PKT7(ring, CP_WAIT_TIMESTAMP, 4);
122+
OUT_RING(ring, 0);
123+
OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
124+
OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
125+
OUT_RING(ring, submit->seqno - 1);
126+
}
127+
118128
if (!sysprof) {
119129
if (!adreno_is_a7xx(adreno_gpu)) {
120130
/* Turn off protected mode to write to special registers */
@@ -193,7 +203,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
193203
struct msm_ringbuffer *ring = submit->ring;
194204
unsigned int i, ibs = 0;
195205

196-
a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
206+
a6xx_set_pagetable(a6xx_gpu, ring, submit);
197207

198208
get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
199209
rbmemptr_stats(ring, index, cpcycles_start));
@@ -283,7 +293,7 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
283293
OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
284294
OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR);
285295

286-
a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
296+
a6xx_set_pagetable(a6xx_gpu, ring, submit);
287297

288298
get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0),
289299
rbmemptr_stats(ring, index, cpcycles_start));

drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -711,12 +711,13 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc)
711711
_dpu_crtc_complete_flip(crtc);
712712
}
713713

714-
static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
714+
static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc,
715715
struct drm_crtc_state *state)
716716
{
717717
struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
718718
struct drm_display_mode *adj_mode = &state->adjusted_mode;
719719
u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers;
720+
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
720721
int i;
721722

722723
for (i = 0; i < cstate->num_mixers; i++) {
@@ -727,7 +728,12 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
727728
r->y2 = adj_mode->vdisplay;
728729

729730
trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r);
731+
732+
if (drm_rect_width(r) > dpu_kms->catalog->caps->max_mixer_width)
733+
return -E2BIG;
730734
}
735+
736+
return 0;
731737
}
732738

733739
static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state,
@@ -803,7 +809,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
803809

804810
DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
805811

806-
_dpu_crtc_setup_lm_bounds(crtc, crtc->state);
812+
_dpu_crtc_check_and_setup_lm_bounds(crtc, crtc->state);
807813

808814
/* encoder will trigger pending mask now */
809815
drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
@@ -1091,9 +1097,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
10911097

10921098
dpu_core_perf_crtc_update(crtc, 0);
10931099

1094-
memset(cstate->mixers, 0, sizeof(cstate->mixers));
1095-
cstate->num_mixers = 0;
1096-
10971100
/* disable clk & bw control until clk & bw properties are set */
10981101
cstate->bw_control = false;
10991102
cstate->bw_split_vote = false;
@@ -1192,8 +1195,11 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
11921195
if (crtc_state->active_changed)
11931196
crtc_state->mode_changed = true;
11941197

1195-
if (cstate->num_mixers)
1196-
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
1198+
if (cstate->num_mixers) {
1199+
rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state);
1200+
if (rc)
1201+
return rc;
1202+
}
11971203

11981204
/* FIXME: move this to dpu_plane_atomic_check? */
11991205
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {

drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,40 @@ static struct msm_display_topology dpu_encoder_get_topology(
624624
return topology;
625625
}
626626

627+
static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms,
628+
struct drm_encoder *drm_enc,
629+
struct dpu_global_state *global_state,
630+
struct drm_crtc_state *crtc_state)
631+
{
632+
struct dpu_crtc_state *cstate;
633+
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
634+
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
635+
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC];
636+
int num_lm, num_ctl, num_dspp, i;
637+
638+
cstate = to_dpu_crtc_state(crtc_state);
639+
640+
memset(cstate->mixers, 0, sizeof(cstate->mixers));
641+
642+
num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
643+
drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
644+
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
645+
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
646+
num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
647+
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
648+
ARRAY_SIZE(hw_dspp));
649+
650+
for (i = 0; i < num_lm; i++) {
651+
int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
652+
653+
cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
654+
cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
655+
cstate->mixers[i].hw_dspp = i < num_dspp ? to_dpu_hw_dspp(hw_dspp[i]) : NULL;
656+
}
657+
658+
cstate->num_mixers = num_lm;
659+
}
660+
627661
static int dpu_encoder_virt_atomic_check(
628662
struct drm_encoder *drm_enc,
629663
struct drm_crtc_state *crtc_state,
@@ -692,6 +726,9 @@ static int dpu_encoder_virt_atomic_check(
692726
if (!crtc_state->active_changed || crtc_state->enable)
693727
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
694728
drm_enc, crtc_state, topology);
729+
if (!ret)
730+
dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc,
731+
global_state, crtc_state);
695732
}
696733

697734
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
@@ -1093,14 +1130,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
10931130
struct dpu_encoder_virt *dpu_enc;
10941131
struct msm_drm_private *priv;
10951132
struct dpu_kms *dpu_kms;
1096-
struct dpu_crtc_state *cstate;
10971133
struct dpu_global_state *global_state;
10981134
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
10991135
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
1100-
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
1101-
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
11021136
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
1103-
int num_lm, num_ctl, num_pp, num_dsc;
1137+
int num_ctl, num_pp, num_dsc;
11041138
unsigned int dsc_mask = 0;
11051139
int i;
11061140

@@ -1129,11 +1163,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
11291163
ARRAY_SIZE(hw_pp));
11301164
num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
11311165
drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
1132-
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
1133-
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
1134-
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
1135-
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
1136-
ARRAY_SIZE(hw_dspp));
11371166

11381167
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
11391168
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -1159,36 +1188,23 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
11591188
dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
11601189
}
11611190

1162-
cstate = to_dpu_crtc_state(crtc_state);
1163-
1164-
for (i = 0; i < num_lm; i++) {
1165-
int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
1166-
1167-
cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
1168-
cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
1169-
cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
1170-
}
1171-
1172-
cstate->num_mixers = num_lm;
1173-
11741191
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
11751192
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
11761193

1177-
if (!dpu_enc->hw_pp[i]) {
1194+
phys->hw_pp = dpu_enc->hw_pp[i];
1195+
if (!phys->hw_pp) {
11781196
DPU_ERROR_ENC(dpu_enc,
11791197
"no pp block assigned at idx: %d\n", i);
11801198
return;
11811199
}
11821200

1183-
if (!hw_ctl[i]) {
1201+
phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL;
1202+
if (!phys->hw_ctl) {
11841203
DPU_ERROR_ENC(dpu_enc,
11851204
"no ctl block assigned at idx: %d\n", i);
11861205
return;
11871206
}
11881207

1189-
phys->hw_pp = dpu_enc->hw_pp[i];
1190-
phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
1191-
11921208
phys->cached_mode = crtc_state->adjusted_mode;
11931209
if (phys->ops.atomic_mode_set)
11941210
phys->ops.atomic_mode_set(phys, crtc_state, conn_state);

drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
302302
intf_cfg.stream_sel = 0; /* Don't care value for video mode */
303303
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
304304
intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
305-
if (phys_enc->hw_pp->merge_3d)
305+
if (intf_cfg.mode_3d && phys_enc->hw_pp->merge_3d)
306306
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
307307

308308
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
@@ -440,10 +440,12 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
440440
struct dpu_hw_ctl *ctl;
441441
const struct msm_format *fmt;
442442
u32 fmt_fourcc;
443+
u32 mode_3d;
443444

444445
ctl = phys_enc->hw_ctl;
445446
fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc);
446447
fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0);
448+
mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
447449

448450
DPU_DEBUG_VIDENC(phys_enc, "\n");
449451

@@ -466,7 +468,8 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
466468
goto skip_flush;
467469

468470
ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
469-
if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d)
471+
if (mode_3d && ctl->ops.update_pending_flush_merge_3d &&
472+
phys_enc->hw_pp->merge_3d)
470473
ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx);
471474

472475
if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm)

drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
275275
struct dpu_hw_pingpong *hw_pp;
276276
struct dpu_hw_cdm *hw_cdm;
277277
u32 pending_flush = 0;
278+
u32 mode_3d;
278279

279280
if (!phys_enc)
280281
return;
@@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
283284
hw_pp = phys_enc->hw_pp;
284285
hw_ctl = phys_enc->hw_ctl;
285286
hw_cdm = phys_enc->hw_cdm;
287+
mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
286288

287289
DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
288290

@@ -294,7 +296,8 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
294296
if (hw_ctl->ops.update_pending_flush_wb)
295297
hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx);
296298

297-
if (hw_ctl->ops.update_pending_flush_merge_3d && hw_pp && hw_pp->merge_3d)
299+
if (mode_3d && hw_ctl->ops.update_pending_flush_merge_3d &&
300+
hw_pp && hw_pp->merge_3d)
298301
hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
299302
hw_pp->merge_3d->idx);
300303

drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b
2626
end_addr = base_addr + aligned_len;
2727

2828
if (!(*reg))
29-
*reg = kzalloc(len_padded, GFP_KERNEL);
29+
*reg = kvzalloc(len_padded, GFP_KERNEL);
3030

3131
if (*reg)
3232
dump_addr = *reg;
@@ -48,20 +48,21 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b
4848
}
4949
}
5050

51-
static void msm_disp_state_print_regs(u32 **reg, u32 len, void __iomem *base_addr,
52-
struct drm_printer *p)
51+
static void msm_disp_state_print_regs(const u32 *dump_addr, u32 len,
52+
void __iomem *base_addr, struct drm_printer *p)
5353
{
5454
int i;
55-
u32 *dump_addr = NULL;
5655
void __iomem *addr;
5756
u32 num_rows;
5857

58+
if (!dump_addr) {
59+
drm_printf(p, "Registers not stored\n");
60+
return;
61+
}
62+
5963
addr = base_addr;
6064
num_rows = len / REG_DUMP_ALIGN;
6165

62-
if (*reg)
63-
dump_addr = *reg;
64-
6566
for (i = 0; i < num_rows; i++) {
6667
drm_printf(p, "0x%lx : %08x %08x %08x %08x\n",
6768
(unsigned long)(addr - base_addr),
@@ -89,7 +90,7 @@ void msm_disp_state_print(struct msm_disp_state *state, struct drm_printer *p)
8990

9091
list_for_each_entry_safe(block, tmp, &state->blocks, node) {
9192
drm_printf(p, "====================%s================\n", block->name);
92-
msm_disp_state_print_regs(&block->state, block->size, block->base_addr, p);
93+
msm_disp_state_print_regs(block->state, block->size, block->base_addr, p);
9394
}
9495

9596
drm_printf(p, "===================dpu drm state================\n");
@@ -161,7 +162,7 @@ void msm_disp_state_free(void *data)
161162

162163
list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) {
163164
list_del(&block->node);
164-
kfree(block->state);
165+
kvfree(block->state);
165166
kfree(block);
166167
}
167168

drivers/gpu/drm/msm/dsi/dsi_host.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,15 +542,15 @@ static unsigned long dsi_adjust_pclk_for_compression(const struct drm_display_mo
542542

543543
int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay;
544544

545-
return new_htotal * mode->vtotal * drm_mode_vrefresh(mode);
545+
return mult_frac(mode->clock * 1000u, new_htotal, mode->htotal);
546546
}
547547

548548
static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode,
549549
const struct drm_dsc_config *dsc, bool is_bonded_dsi)
550550
{
551551
unsigned long pclk_rate;
552552

553-
pclk_rate = mode->clock * 1000;
553+
pclk_rate = mode->clock * 1000u;
554554

555555
if (dsc)
556556
pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc);

drivers/gpu/drm/msm/hdmi/hdmi_phy_8998.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,6 @@ static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
153153
return dividend - 1;
154154
}
155155

156-
static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk)
157-
{
158-
u64 fdata = ((u64)pll_cmp) * ref_clk * 10;
159-
160-
do_div(fdata, HDMI_PLL_CMP_CNT);
161-
162-
return fdata;
163-
}
164-
165156
#define HDMI_REF_CLOCK_HZ ((u64)19200000)
166157
#define HDMI_MHZ_TO_HZ ((u64)1000000)
167158
static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk)

0 commit comments

Comments
 (0)