Skip to content

Commit e47616d

Browse files
Kalyan Thotarobclark
authored andcommitted
drm/msm/dpu: add support for color processing blocks in dpu driver
This change adds support to configure dspp blocks in the dpu driver. Macro description of the changes coming in this patch. 1) Add dspp definitions in the hw catalog. 2) Add capability to reserve dspp blocks in the display data path. 3) Attach the reserved block to the encoder. Signed-off-by: Kalyan Thota <kalyan_t@codeaurora.org> Tested-by: Fritz Koenig <frkoenig@google.com> Signed-off-by: Rob Clark <robdclark@chromium.org>
1 parent e433787 commit e47616d

File tree

14 files changed

+322
-15
lines changed

14 files changed

+322
-15
lines changed

drivers/gpu/drm/msm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ msm-y := \
6565
disp/dpu1/dpu_hw_lm.o \
6666
disp/dpu1/dpu_hw_pingpong.o \
6767
disp/dpu1/dpu_hw_sspp.o \
68+
disp/dpu1/dpu_hw_dspp.o \
6869
disp/dpu1/dpu_hw_top.o \
6970
disp/dpu1/dpu_hw_util.o \
7071
disp/dpu1/dpu_hw_vbif.o \

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,14 @@ struct dpu_crtc_smmu_state_data {
7373
* struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC
7474
* @hw_lm: LM HW Driver context
7575
* @lm_ctl: CTL Path HW driver context
76+
* @lm_dspp: DSPP HW driver context
7677
* @mixer_op_mode: mixer blending operation mode
7778
* @flush_mask: mixer flush mask for ctl, mixer and pipe
7879
*/
7980
struct dpu_crtc_mixer {
8081
struct dpu_hw_mixer *hw_lm;
8182
struct dpu_hw_ctl *lm_ctl;
83+
struct dpu_hw_dspp *hw_dspp;
8284
u32 mixer_op_mode;
8385
u32 flush_mask;
8486
};

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "dpu_hw_catalog.h"
2121
#include "dpu_hw_intf.h"
2222
#include "dpu_hw_ctl.h"
23+
#include "dpu_hw_dspp.h"
2324
#include "dpu_formats.h"
2425
#include "dpu_encoder_phys.h"
2526
#include "dpu_crtc.h"
@@ -536,6 +537,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
536537
* 1 LM, 1 INTF
537538
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
538539
*
540+
* Adding color blocks only to primary interface
539541
*/
540542
if (intf_count == 2)
541543
topology.num_lm = 2;
@@ -544,6 +546,9 @@ static struct msm_display_topology dpu_encoder_get_topology(
544546
else
545547
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
546548

549+
if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI)
550+
topology.num_dspp = topology.num_lm;
551+
547552
topology.num_enc = 0;
548553
topology.num_intf = intf_count;
549554

@@ -959,7 +964,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
959964
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
960965
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
961966
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
962-
int num_lm, num_ctl, num_pp;
967+
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
968+
int num_lm, num_ctl, num_pp, num_dspp;
963969
int i, j;
964970

965971
if (!drm_enc) {
@@ -1008,6 +1014,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
10081014
drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
10091015
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
10101016
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
1017+
num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
1018+
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
1019+
ARRAY_SIZE(hw_dspp));
10111020

10121021
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
10131022
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -1020,6 +1029,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
10201029

10211030
cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
10221031
cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
1032+
cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
10231033
}
10241034

10251035
cstate->num_mixers = num_lm;

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

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
#define PINGPONG_SDM845_SPLIT_MASK \
4242
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
4343

44+
#define DSPP_SC7180_MASK 0
45+
4446
#define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
4547
#define DEFAULT_DPU_LINE_WIDTH 2048
4648
#define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
@@ -291,29 +293,30 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
291293
},
292294
};
293295

294-
#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair) \
296+
#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
295297
{ \
296298
.name = _name, .id = _id, \
297299
.base = _base, .len = 0x320, \
298300
.features = _fmask, \
299301
.sblk = _sblk, \
300302
.pingpong = _pp, \
301-
.lm_pair_mask = (1 << _lmpair) \
303+
.lm_pair_mask = (1 << _lmpair), \
304+
.dspp = _dspp \
302305
}
303306

304307
static const struct dpu_lm_cfg sdm845_lm[] = {
305308
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
306-
&sdm845_lm_sblk, PINGPONG_0, LM_1),
309+
&sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
307310
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
308-
&sdm845_lm_sblk, PINGPONG_1, LM_0),
311+
&sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
309312
LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
310-
&sdm845_lm_sblk, PINGPONG_2, LM_5),
313+
&sdm845_lm_sblk, PINGPONG_2, LM_5, 0),
311314
LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK,
312-
&sdm845_lm_sblk, PINGPONG_MAX, 0),
315+
&sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
313316
LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK,
314-
&sdm845_lm_sblk, PINGPONG_MAX, 0),
317+
&sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
315318
LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
316-
&sdm845_lm_sblk, PINGPONG_3, LM_2),
319+
&sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
317320
};
318321

319322
/* SC7180 */
@@ -328,11 +331,25 @@ static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
328331

329332
static const struct dpu_lm_cfg sc7180_lm[] = {
330333
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
331-
&sc7180_lm_sblk, PINGPONG_0, LM_1),
334+
&sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
332335
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SC7180_MASK,
333-
&sc7180_lm_sblk, PINGPONG_1, LM_0),
336+
&sc7180_lm_sblk, PINGPONG_1, LM_0, 0),
334337
};
335338

339+
/*************************************************************
340+
* DSPP sub blocks config
341+
*************************************************************/
342+
#define DSPP_BLK(_name, _id, _base) \
343+
{\
344+
.name = _name, .id = _id, \
345+
.base = _base, .len = 0x1800, \
346+
.features = DSPP_SC7180_MASK, \
347+
.sblk = NULL, \
348+
}
349+
350+
static const struct dpu_dspp_cfg sc7180_dspp[] = {
351+
DSPP_BLK("dspp_0", DSPP_0, 0x54000),
352+
};
336353
/*************************************************************
337354
* PINGPONG sub blocks config
338355
*************************************************************/
@@ -587,6 +604,8 @@ static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
587604
.sspp = sc7180_sspp,
588605
.mixer_count = ARRAY_SIZE(sc7180_lm),
589606
.mixer = sc7180_lm,
607+
.dspp_count = ARRAY_SIZE(sc7180_dspp),
608+
.dspp = sc7180_dspp,
590609
.pingpong_count = ARRAY_SIZE(sc7180_pp),
591610
.pingpong = sc7180_pp,
592611
.intf_count = ARRAY_SIZE(sc7180_intf),

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ enum {
145145
DPU_MIXER_MAX
146146
};
147147

148+
/**
149+
* DSPP sub-blocks
150+
* @DPU_DSPP_PCC Panel color correction block
151+
* @DPU_DSPP_GC Gamma correction block
152+
*/
153+
enum {
154+
DPU_DSPP_PCC = 0x1,
155+
DPU_DSPP_GC,
156+
DPU_DSPP_MAX
157+
};
158+
148159
/**
149160
* PINGPONG sub-blocks
150161
* @DPU_PINGPONG_TE Tear check block
@@ -377,6 +388,16 @@ struct dpu_lm_sub_blks {
377388
struct dpu_pp_blk gc;
378389
};
379390

391+
/**
392+
* struct dpu_dspp_sub_blks: Information of DSPP block
393+
* @gc : gamma correction block
394+
* @pcc: pixel color correction block
395+
*/
396+
struct dpu_dspp_sub_blks {
397+
struct dpu_pp_blk gc;
398+
struct dpu_pp_blk pcc;
399+
};
400+
380401
struct dpu_pingpong_sub_blks {
381402
struct dpu_pp_blk te;
382403
struct dpu_pp_blk te2;
@@ -471,9 +492,23 @@ struct dpu_lm_cfg {
471492
DPU_HW_BLK_INFO;
472493
const struct dpu_lm_sub_blks *sblk;
473494
u32 pingpong;
495+
u32 dspp;
474496
unsigned long lm_pair_mask;
475497
};
476498

499+
/**
500+
* struct dpu_dspp_cfg - information of DSPP blocks
501+
* @id enum identifying this block
502+
* @base register offset of this block
503+
* @features bit mask identifying sub-blocks/features
504+
* supported by this block
505+
* @sblk sub-blocks information
506+
*/
507+
struct dpu_dspp_cfg {
508+
DPU_HW_BLK_INFO;
509+
const struct dpu_dspp_sub_blks *sblk;
510+
};
511+
477512
/**
478513
* struct dpu_pingpong_cfg - information of PING-PONG blocks
479514
* @id enum identifying this block
@@ -688,6 +723,9 @@ struct dpu_mdss_cfg {
688723

689724
u32 ad_count;
690725

726+
u32 dspp_count;
727+
const struct dpu_dspp_cfg *dspp;
728+
691729
/* Add additional block data structures here */
692730

693731
struct dpu_perf_cfg perf;
@@ -716,6 +754,7 @@ struct dpu_mdss_hw_cfg_handler {
716754
#define BLK_PINGPONG(s) ((s)->pingpong)
717755
#define BLK_INTF(s) ((s)->intf)
718756
#define BLK_AD(s) ((s)->ad)
757+
#define BLK_DSPP(s) ((s)->dspp)
719758

720759
/**
721760
* dpu_hw_catalog_init - dpu hardware catalog init API retrieves

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,31 @@ static int dpu_hw_ctl_active_get_bitmask_intf(struct dpu_hw_ctl *ctx,
272272
return 0;
273273
}
274274

275+
static uint32_t dpu_hw_ctl_get_bitmask_dspp(struct dpu_hw_ctl *ctx,
276+
enum dpu_dspp dspp)
277+
{
278+
uint32_t flushbits = 0;
279+
280+
switch (dspp) {
281+
case DSPP_0:
282+
flushbits = BIT(13);
283+
break;
284+
case DSPP_1:
285+
flushbits = BIT(14);
286+
break;
287+
case DSPP_2:
288+
flushbits = BIT(15);
289+
break;
290+
case DSPP_3:
291+
flushbits = BIT(21);
292+
break;
293+
default:
294+
return 0;
295+
}
296+
297+
return flushbits;
298+
}
299+
275300
static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
276301
{
277302
struct dpu_hw_blk_reg_map *c = &ctx->hw;
@@ -548,6 +573,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
548573
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
549574
ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
550575
ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer;
576+
ops->get_bitmask_dspp = dpu_hw_ctl_get_bitmask_dspp;
551577
};
552578

553579
static struct dpu_hw_blk_ops dpu_hw_ops;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ struct dpu_hw_ctl_ops {
139139
uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx,
140140
enum dpu_lm blk);
141141

142+
uint32_t (*get_bitmask_dspp)(struct dpu_hw_ctl *ctx,
143+
enum dpu_dspp blk);
144+
142145
/**
143146
* Query the value of the intf flush mask
144147
* No effect on hardware
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3+
*/
4+
5+
#include "dpu_hwio.h"
6+
#include "dpu_hw_catalog.h"
7+
#include "dpu_hw_lm.h"
8+
#include "dpu_hw_dspp.h"
9+
#include "dpu_kms.h"
10+
11+
12+
static void _setup_dspp_ops(struct dpu_hw_dspp *c,
13+
unsigned long features)
14+
{
15+
return;
16+
}
17+
18+
static const struct dpu_dspp_cfg *_dspp_offset(enum dpu_dspp dspp,
19+
const struct dpu_mdss_cfg *m,
20+
void __iomem *addr,
21+
struct dpu_hw_blk_reg_map *b)
22+
{
23+
int i;
24+
25+
if (!m || !addr || !b)
26+
return ERR_PTR(-EINVAL);
27+
28+
for (i = 0; i < m->dspp_count; i++) {
29+
if (dspp == m->dspp[i].id) {
30+
b->base_off = addr;
31+
b->blk_off = m->dspp[i].base;
32+
b->length = m->dspp[i].len;
33+
b->hwversion = m->hwversion;
34+
b->log_mask = DPU_DBG_MASK_DSPP;
35+
return &m->dspp[i];
36+
}
37+
}
38+
39+
return ERR_PTR(-EINVAL);
40+
}
41+
42+
static struct dpu_hw_blk_ops dpu_hw_ops;
43+
44+
struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx,
45+
void __iomem *addr,
46+
const struct dpu_mdss_cfg *m)
47+
{
48+
struct dpu_hw_dspp *c;
49+
const struct dpu_dspp_cfg *cfg;
50+
51+
if (!addr || !m)
52+
return ERR_PTR(-EINVAL);
53+
54+
c = kzalloc(sizeof(*c), GFP_KERNEL);
55+
if (!c)
56+
return ERR_PTR(-ENOMEM);
57+
58+
cfg = _dspp_offset(idx, m, addr, &c->hw);
59+
if (IS_ERR_OR_NULL(cfg)) {
60+
kfree(c);
61+
return ERR_PTR(-EINVAL);
62+
}
63+
64+
/* Assign ops */
65+
c->idx = idx;
66+
c->cap = cfg;
67+
_setup_dspp_ops(c, c->cap->features);
68+
69+
dpu_hw_blk_init(&c->base, DPU_HW_BLK_DSPP, idx, &dpu_hw_ops);
70+
71+
return c;
72+
}
73+
74+
void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp)
75+
{
76+
if (dspp)
77+
dpu_hw_blk_destroy(&dspp->base);
78+
79+
kfree(dspp);
80+
}
81+
82+

0 commit comments

Comments
 (0)