Skip to content

Commit 479e25d

Browse files
committed
Merge tag 'drm-msm-fixes-2025-12-26' of https://gitlab.freedesktop.org/drm/msm into drm-fixes
Fixes for v6.19: GPU: - Fix crash on a7xx GPUs not supporting IFPC - Fix perfcntr use with IFPC - Concurrent binning fix DPU: - Fixed DSC and SSPP fetching issues - Switched to scnprint instead of snprintf - Added missing NULL checks in pingpong code Also documentation fixes. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rob Clark <rob.clark@oss.qualcomm.com> Link: https://patch.msgid.link/CACSVV01jcLLChsFtmqc4VDNoQ2ic2q+d86n3wdoSUdmW6xaSdQ@mail.gmail.com
2 parents 9448598 + 66691e2 commit 479e25d

36 files changed

Lines changed: 347 additions & 372 deletions

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,6 @@ static const uint32_t a7xx_pwrup_reglist_regs[] = {
13761376
REG_A6XX_UCHE_MODE_CNTL,
13771377
REG_A6XX_RB_NC_MODE_CNTL,
13781378
REG_A6XX_RB_CMP_DBG_ECO_CNTL,
1379-
REG_A7XX_GRAS_NC_MODE_CNTL,
13801379
REG_A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE_ENABLE,
13811380
REG_A6XX_UCHE_GBIF_GX_CONFIG,
13821381
REG_A6XX_UCHE_CLIENT_PF,
@@ -1392,6 +1391,7 @@ static const u32 a750_ifpc_reglist_regs[] = {
13921391
REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE(2),
13931392
REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE(3),
13941393
REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE(4),
1394+
REG_A6XX_RBBM_PERFCTR_CNTL,
13951395
REG_A6XX_TPL1_NC_MODE_CNTL,
13961396
REG_A6XX_SP_NC_MODE_CNTL,
13971397
REG_A6XX_CP_DBG_ECO_CNTL,
@@ -1448,6 +1448,12 @@ static const u32 a750_ifpc_reglist_regs[] = {
14481448

14491449
DECLARE_ADRENO_REGLIST_LIST(a750_ifpc_reglist);
14501450

1451+
static const struct adreno_reglist_pipe a7xx_dyn_pwrup_reglist_regs[] = {
1452+
{ REG_A7XX_GRAS_NC_MODE_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
1453+
};
1454+
1455+
DECLARE_ADRENO_REGLIST_PIPE_LIST(a7xx_dyn_pwrup_reglist);
1456+
14511457
static const struct adreno_info a7xx_gpus[] = {
14521458
{
14531459
.chip_ids = ADRENO_CHIP_IDS(0x07000200),
@@ -1491,6 +1497,7 @@ static const struct adreno_info a7xx_gpus[] = {
14911497
.hwcg = a730_hwcg,
14921498
.protect = &a730_protect,
14931499
.pwrup_reglist = &a7xx_pwrup_reglist,
1500+
.dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
14941501
.gbif_cx = a640_gbif,
14951502
.gmu_cgc_mode = 0x00020000,
14961503
},
@@ -1513,6 +1520,7 @@ static const struct adreno_info a7xx_gpus[] = {
15131520
.hwcg = a740_hwcg,
15141521
.protect = &a730_protect,
15151522
.pwrup_reglist = &a7xx_pwrup_reglist,
1523+
.dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
15161524
.gbif_cx = a640_gbif,
15171525
.gmu_chipid = 0x7020100,
15181526
.gmu_cgc_mode = 0x00020202,
@@ -1547,6 +1555,7 @@ static const struct adreno_info a7xx_gpus[] = {
15471555
.hwcg = a740_hwcg,
15481556
.protect = &a730_protect,
15491557
.pwrup_reglist = &a7xx_pwrup_reglist,
1558+
.dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
15501559
.ifpc_reglist = &a750_ifpc_reglist,
15511560
.gbif_cx = a640_gbif,
15521561
.gmu_chipid = 0x7050001,
@@ -1589,6 +1598,7 @@ static const struct adreno_info a7xx_gpus[] = {
15891598
.a6xx = &(const struct a6xx_info) {
15901599
.protect = &a730_protect,
15911600
.pwrup_reglist = &a7xx_pwrup_reglist,
1601+
.dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
15921602
.ifpc_reglist = &a750_ifpc_reglist,
15931603
.gbif_cx = a640_gbif,
15941604
.gmu_chipid = 0x7090100,
@@ -1623,6 +1633,7 @@ static const struct adreno_info a7xx_gpus[] = {
16231633
.hwcg = a740_hwcg,
16241634
.protect = &a730_protect,
16251635
.pwrup_reglist = &a7xx_pwrup_reglist,
1636+
.dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
16261637
.gbif_cx = a640_gbif,
16271638
.gmu_chipid = 0x70f0000,
16281639
.gmu_cgc_mode = 0x00020222,

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

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -849,9 +849,16 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
849849
min_acc_len_64b << 3 |
850850
hbb_lo << 1 | ubwc_mode);
851851

852-
if (adreno_is_a7xx(adreno_gpu))
853-
gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
854-
FIELD_PREP(GENMASK(8, 5), hbb_lo));
852+
if (adreno_is_a7xx(adreno_gpu)) {
853+
for (u32 pipe_id = PIPE_BR; pipe_id <= PIPE_BV; pipe_id++) {
854+
gpu_write(gpu, REG_A7XX_CP_APERTURE_CNTL_HOST,
855+
A7XX_CP_APERTURE_CNTL_HOST_PIPE(pipe_id));
856+
gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
857+
FIELD_PREP(GENMASK(8, 5), hbb_lo));
858+
}
859+
gpu_write(gpu, REG_A7XX_CP_APERTURE_CNTL_HOST,
860+
A7XX_CP_APERTURE_CNTL_HOST_PIPE(PIPE_NONE));
861+
}
855862

856863
gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL,
857864
min_acc_len_64b << 23 | hbb_lo << 21);
@@ -865,23 +872,27 @@ static void a7xx_patch_pwrup_reglist(struct msm_gpu *gpu)
865872
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
866873
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
867874
const struct adreno_reglist_list *reglist;
875+
const struct adreno_reglist_pipe_list *dyn_pwrup_reglist;
868876
void *ptr = a6xx_gpu->pwrup_reglist_ptr;
869877
struct cpu_gpu_lock *lock = ptr;
870878
u32 *dest = (u32 *)&lock->regs[0];
879+
u32 dyn_pwrup_reglist_count = 0;
871880
int i;
872881

873882
lock->gpu_req = lock->cpu_req = lock->turn = 0;
874883

875884
reglist = adreno_gpu->info->a6xx->ifpc_reglist;
876-
lock->ifpc_list_len = reglist->count;
885+
if (reglist) {
886+
lock->ifpc_list_len = reglist->count;
877887

878-
/*
879-
* For each entry in each of the lists, write the offset and the current
880-
* register value into the GPU buffer
881-
*/
882-
for (i = 0; i < reglist->count; i++) {
883-
*dest++ = reglist->regs[i];
884-
*dest++ = gpu_read(gpu, reglist->regs[i]);
888+
/*
889+
* For each entry in each of the lists, write the offset and the current
890+
* register value into the GPU buffer
891+
*/
892+
for (i = 0; i < reglist->count; i++) {
893+
*dest++ = reglist->regs[i];
894+
*dest++ = gpu_read(gpu, reglist->regs[i]);
895+
}
885896
}
886897

887898
reglist = adreno_gpu->info->a6xx->pwrup_reglist;
@@ -907,7 +918,24 @@ static void a7xx_patch_pwrup_reglist(struct msm_gpu *gpu)
907918
* (<aperture, shifted 12 bits> <address> <data>), and the length is
908919
* stored as number for triplets in dynamic_list_len.
909920
*/
910-
lock->dynamic_list_len = 0;
921+
dyn_pwrup_reglist = adreno_gpu->info->a6xx->dyn_pwrup_reglist;
922+
if (dyn_pwrup_reglist) {
923+
for (u32 pipe_id = PIPE_BR; pipe_id <= PIPE_BV; pipe_id++) {
924+
gpu_write(gpu, REG_A7XX_CP_APERTURE_CNTL_HOST,
925+
A7XX_CP_APERTURE_CNTL_HOST_PIPE(pipe_id));
926+
for (i = 0; i < dyn_pwrup_reglist->count; i++) {
927+
if ((dyn_pwrup_reglist->regs[i].pipe & BIT(pipe_id)) == 0)
928+
continue;
929+
*dest++ = A7XX_CP_APERTURE_CNTL_HOST_PIPE(pipe_id);
930+
*dest++ = dyn_pwrup_reglist->regs[i].offset;
931+
*dest++ = gpu_read(gpu, dyn_pwrup_reglist->regs[i].offset);
932+
dyn_pwrup_reglist_count++;
933+
}
934+
}
935+
gpu_write(gpu, REG_A7XX_CP_APERTURE_CNTL_HOST,
936+
A7XX_CP_APERTURE_CNTL_HOST_PIPE(PIPE_NONE));
937+
}
938+
lock->dynamic_list_len = dyn_pwrup_reglist_count;
911939
}
912940

913941
static int a7xx_preempt_start(struct msm_gpu *gpu)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct a6xx_info {
4545
const struct adreno_reglist *hwcg;
4646
const struct adreno_protect *protect;
4747
const struct adreno_reglist_list *pwrup_reglist;
48+
const struct adreno_reglist_pipe_list *dyn_pwrup_reglist;
4849
const struct adreno_reglist_list *ifpc_reglist;
4950
const struct adreno_reglist *gbif_cx;
5051
const struct adreno_reglist_pipe *nonctxt_reglist;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,11 +454,11 @@ void a6xx_preempt_init(struct msm_gpu *gpu)
454454
gpu->vm, &a6xx_gpu->preempt_postamble_bo,
455455
&a6xx_gpu->preempt_postamble_iova);
456456

457-
preempt_prepare_postamble(a6xx_gpu);
458-
459457
if (IS_ERR(a6xx_gpu->preempt_postamble_ptr))
460458
goto fail;
461459

460+
preempt_prepare_postamble(a6xx_gpu);
461+
462462
timer_setup(&a6xx_gpu->preempt_timer, a6xx_preempt_timer, 0);
463463

464464
return;

drivers/gpu/drm/msm/adreno/adreno_gpu.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,19 @@ static const struct adreno_reglist_list name = { \
188188
.count = ARRAY_SIZE(name ## _regs), \
189189
};
190190

191+
struct adreno_reglist_pipe_list {
192+
/** @reg: List of register **/
193+
const struct adreno_reglist_pipe *regs;
194+
/** @count: Number of registers in the list **/
195+
u32 count;
196+
};
197+
198+
#define DECLARE_ADRENO_REGLIST_PIPE_LIST(name) \
199+
static const struct adreno_reglist_pipe_list name = { \
200+
.regs = name ## _regs, \
201+
.count = ARRAY_SIZE(name ## _regs), \
202+
};
203+
191204
struct adreno_gpu {
192205
struct msm_gpu base;
193206
const struct adreno_info *info;

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

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
200200
struct dpu_crtc_state *crtc_state)
201201
{
202202
struct dpu_crtc_mixer *m;
203-
u32 crcs[CRTC_QUAD_MIXERS];
203+
u32 crcs[CRTC_DUAL_MIXERS];
204204

205205
int rc = 0;
206206
int i;
@@ -1328,7 +1328,6 @@ static struct msm_display_topology dpu_crtc_get_topology(
13281328
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
13291329
struct msm_display_topology topology = {0};
13301330
struct drm_encoder *drm_enc;
1331-
u32 num_rt_intf;
13321331

13331332
drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask)
13341333
dpu_encoder_update_topology(drm_enc, &topology, crtc_state->state,
@@ -1342,14 +1341,11 @@ static struct msm_display_topology dpu_crtc_get_topology(
13421341
* Dual display
13431342
* 2 LM, 2 INTF ( Split display using 2 interfaces)
13441343
*
1345-
* If DSC is enabled, try to use 4:4:2 topology if there is enough
1346-
* resource. Otherwise, use 2:2:2 topology.
1347-
*
13481344
* Single display
13491345
* 1 LM, 1 INTF
13501346
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
13511347
*
1352-
* If DSC is enabled, use 2:2:1 topology
1348+
* If DSC is enabled, use 2 LMs for 2:2:1 topology
13531349
*
13541350
* Add dspps to the reservation requirements if ctm is requested
13551351
*
@@ -1361,23 +1357,14 @@ static struct msm_display_topology dpu_crtc_get_topology(
13611357
* (mode->hdisplay > MAX_HDISPLAY_SPLIT) check.
13621358
*/
13631359

1364-
num_rt_intf = topology.num_intf;
1365-
if (topology.cwb_enabled)
1366-
num_rt_intf--;
1367-
1368-
if (topology.num_dsc) {
1369-
if (dpu_kms->catalog->dsc_count >= num_rt_intf * 2)
1370-
topology.num_dsc = num_rt_intf * 2;
1371-
else
1372-
topology.num_dsc = num_rt_intf;
1373-
topology.num_lm = topology.num_dsc;
1374-
} else if (num_rt_intf == 2) {
1360+
if (topology.num_intf == 2 && !topology.cwb_enabled)
1361+
topology.num_lm = 2;
1362+
else if (topology.num_dsc == 2)
13751363
topology.num_lm = 2;
1376-
} else if (dpu_kms->catalog->caps->has_3d_merge) {
1364+
else if (dpu_kms->catalog->caps->has_3d_merge)
13771365
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
1378-
} else {
1366+
else
13791367
topology.num_lm = 1;
1380-
}
13811368

13821369
if (crtc_state->ctm)
13831370
topology.num_dspp = topology.num_lm;
@@ -1620,17 +1607,6 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
16201607
return 0;
16211608
}
16221609

1623-
/**
1624-
* dpu_crtc_get_num_lm - Get mixer number in this CRTC pipeline
1625-
* @state: Pointer to drm crtc state object
1626-
*/
1627-
unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state)
1628-
{
1629-
struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
1630-
1631-
return cstate->num_mixers;
1632-
}
1633-
16341610
#ifdef CONFIG_DEBUG_FS
16351611
static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
16361612
{

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,18 +210,18 @@ struct dpu_crtc_state {
210210

211211
bool bw_control;
212212
bool bw_split_vote;
213-
struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
213+
struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
214214

215215
uint64_t input_fence_timeout_ns;
216216

217217
struct dpu_core_perf_params new_perf;
218218

219219
/* HW Resources reserved for the crtc */
220220
u32 num_mixers;
221-
struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
221+
struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
222222

223223
u32 num_ctls;
224-
struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
224+
struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
225225

226226
enum dpu_crtc_crc_source crc_source;
227227
int crc_frame_skip_count;
@@ -267,6 +267,4 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type(
267267

268268
void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
269269

270-
unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state);
271-
272270
#endif /* _DPU_CRTC_H_ */

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
#define MAX_PHYS_ENCODERS_PER_VIRTUAL \
5656
(MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
5757

58-
#define MAX_CHANNELS_PER_ENC 4
58+
#define MAX_CHANNELS_PER_ENC 2
5959
#define MAX_CWB_PER_ENC 2
6060

6161
#define IDLE_SHORT_TIMEOUT 1
@@ -661,6 +661,7 @@ void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
661661
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
662662
struct msm_drm_private *priv = dpu_enc->base.dev->dev_private;
663663
struct msm_display_info *disp_info = &dpu_enc->disp_info;
664+
struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
664665
struct drm_connector *connector;
665666
struct drm_connector_state *conn_state;
666667
struct drm_framebuffer *fb;
@@ -674,12 +675,22 @@ void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
674675

675676
dsc = dpu_encoder_get_dsc_config(drm_enc);
676677

677-
/*
678-
* Set DSC number as 1 to mark the enabled status, will be adjusted
679-
* in dpu_crtc_get_topology()
680-
*/
681-
if (dsc)
682-
topology->num_dsc = 1;
678+
/* We only support 2 DSC mode (with 2 LM and 1 INTF) */
679+
if (dsc) {
680+
/*
681+
* Use 2 DSC encoders, 2 layer mixers and 1 or 2 interfaces
682+
* when Display Stream Compression (DSC) is enabled,
683+
* and when enough DSC blocks are available.
684+
* This is power-optimal and can drive up to (including) 4k
685+
* screens.
686+
*/
687+
WARN(topology->num_intf > 2,
688+
"DSC topology cannot support more than 2 interfaces\n");
689+
if (topology->num_intf >= 2 || dpu_kms->catalog->dsc_count >= 2)
690+
topology->num_dsc = 2;
691+
else
692+
topology->num_dsc = 1;
693+
}
683694

684695
connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
685696
if (!connector)
@@ -2169,8 +2180,8 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
21692180
{
21702181
int i, num_lm;
21712182
struct dpu_global_state *global_state;
2172-
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
2173-
struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
2183+
struct dpu_hw_blk *hw_lm[2];
2184+
struct dpu_hw_mixer *hw_mixer[2];
21742185
struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
21752186

21762187
/* reset all mixers for this encoder */

drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
302302

303303
/* Use merge_3d unless DSC MERGE topology is used */
304304
if (phys_enc->split_role == ENC_ROLE_SOLO &&
305-
(dpu_cstate->num_mixers != 1) &&
305+
dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
306306
!dpu_encoder_use_dsc_merge(phys_enc->parent))
307307
return BLEND_3D_H_ROW_INT;
308308

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,14 +247,12 @@ static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc)
247247
if (hw_cdm)
248248
intf_cfg.cdm = hw_cdm->idx;
249249

250-
if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode)
251-
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
252-
mode_3d);
250+
if (hw_pp && hw_pp->merge_3d && hw_pp->merge_3d->ops.setup_3d_mode)
251+
hw_pp->merge_3d->ops.setup_3d_mode(hw_pp->merge_3d, mode_3d);
253252

254253
/* setup which pp blk will connect to this wb */
255-
if (hw_pp && phys_enc->hw_wb->ops.bind_pingpong_blk)
256-
phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb,
257-
phys_enc->hw_pp->idx);
254+
if (hw_pp && hw_wb->ops.bind_pingpong_blk)
255+
hw_wb->ops.bind_pingpong_blk(hw_wb, hw_pp->idx);
258256

259257
phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
260258
} else if (phys_enc->hw_ctl && phys_enc->hw_ctl->ops.setup_intf_cfg) {

0 commit comments

Comments
 (0)