Skip to content

Commit

Permalink
drm/msm/dpu: add support for color processing blocks in dpu driver
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kalyan Thota authored and Rob Clark committed May 18, 2020
1 parent e433787 commit e47616d
Show file tree
Hide file tree
Showing 14 changed files with 322 additions and 15 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/msm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ msm-y := \
disp/dpu1/dpu_hw_lm.o \
disp/dpu1/dpu_hw_pingpong.o \
disp/dpu1/dpu_hw_sspp.o \
disp/dpu1/dpu_hw_dspp.o \
disp/dpu1/dpu_hw_top.o \
disp/dpu1/dpu_hw_util.o \
disp/dpu1/dpu_hw_vbif.o \
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ struct dpu_crtc_smmu_state_data {
* struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC
* @hw_lm: LM HW Driver context
* @lm_ctl: CTL Path HW driver context
* @lm_dspp: DSPP HW driver context
* @mixer_op_mode: mixer blending operation mode
* @flush_mask: mixer flush mask for ctl, mixer and pipe
*/
struct dpu_crtc_mixer {
struct dpu_hw_mixer *hw_lm;
struct dpu_hw_ctl *lm_ctl;
struct dpu_hw_dspp *hw_dspp;
u32 mixer_op_mode;
u32 flush_mask;
};
Expand Down
12 changes: 11 additions & 1 deletion drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "dpu_hw_catalog.h"
#include "dpu_hw_intf.h"
#include "dpu_hw_ctl.h"
#include "dpu_hw_dspp.h"
#include "dpu_formats.h"
#include "dpu_encoder_phys.h"
#include "dpu_crtc.h"
Expand Down Expand Up @@ -536,6 +537,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
* 1 LM, 1 INTF
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
*
* Adding color blocks only to primary interface
*/
if (intf_count == 2)
topology.num_lm = 2;
Expand All @@ -544,6 +546,9 @@ static struct msm_display_topology dpu_encoder_get_topology(
else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;

if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI)
topology.num_dspp = topology.num_lm;

topology.num_enc = 0;
topology.num_intf = intf_count;

Expand Down Expand Up @@ -959,7 +964,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
int num_lm, num_ctl, num_pp;
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
int num_lm, num_ctl, num_pp, num_dspp;
int i, j;

if (!drm_enc) {
Expand Down Expand Up @@ -1008,6 +1014,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));

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

cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
}

cstate->num_mixers = num_lm;
Expand Down
39 changes: 29 additions & 10 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#define PINGPONG_SDM845_SPLIT_MASK \
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))

#define DSPP_SC7180_MASK 0

#define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
#define DEFAULT_DPU_LINE_WIDTH 2048
#define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
Expand Down Expand Up @@ -291,29 +293,30 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
},
};

#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair) \
#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
{ \
.name = _name, .id = _id, \
.base = _base, .len = 0x320, \
.features = _fmask, \
.sblk = _sblk, \
.pingpong = _pp, \
.lm_pair_mask = (1 << _lmpair) \
.lm_pair_mask = (1 << _lmpair), \
.dspp = _dspp \
}

static const struct dpu_lm_cfg sdm845_lm[] = {
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
&sdm845_lm_sblk, PINGPONG_0, LM_1),
&sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
&sdm845_lm_sblk, PINGPONG_1, LM_0),
&sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
&sdm845_lm_sblk, PINGPONG_2, LM_5),
&sdm845_lm_sblk, PINGPONG_2, LM_5, 0),
LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK,
&sdm845_lm_sblk, PINGPONG_MAX, 0),
&sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK,
&sdm845_lm_sblk, PINGPONG_MAX, 0),
&sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
&sdm845_lm_sblk, PINGPONG_3, LM_2),
&sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
};

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

static const struct dpu_lm_cfg sc7180_lm[] = {
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
&sc7180_lm_sblk, PINGPONG_0, LM_1),
&sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SC7180_MASK,
&sc7180_lm_sblk, PINGPONG_1, LM_0),
&sc7180_lm_sblk, PINGPONG_1, LM_0, 0),
};

/*************************************************************
* DSPP sub blocks config
*************************************************************/
#define DSPP_BLK(_name, _id, _base) \
{\
.name = _name, .id = _id, \
.base = _base, .len = 0x1800, \
.features = DSPP_SC7180_MASK, \
.sblk = NULL, \
}

static const struct dpu_dspp_cfg sc7180_dspp[] = {
DSPP_BLK("dspp_0", DSPP_0, 0x54000),
};
/*************************************************************
* PINGPONG sub blocks config
*************************************************************/
Expand Down Expand Up @@ -587,6 +604,8 @@ static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
.sspp = sc7180_sspp,
.mixer_count = ARRAY_SIZE(sc7180_lm),
.mixer = sc7180_lm,
.dspp_count = ARRAY_SIZE(sc7180_dspp),
.dspp = sc7180_dspp,
.pingpong_count = ARRAY_SIZE(sc7180_pp),
.pingpong = sc7180_pp,
.intf_count = ARRAY_SIZE(sc7180_intf),
Expand Down
39 changes: 39 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ enum {
DPU_MIXER_MAX
};

/**
* DSPP sub-blocks
* @DPU_DSPP_PCC Panel color correction block
* @DPU_DSPP_GC Gamma correction block
*/
enum {
DPU_DSPP_PCC = 0x1,
DPU_DSPP_GC,
DPU_DSPP_MAX
};

/**
* PINGPONG sub-blocks
* @DPU_PINGPONG_TE Tear check block
Expand Down Expand Up @@ -377,6 +388,16 @@ struct dpu_lm_sub_blks {
struct dpu_pp_blk gc;
};

/**
* struct dpu_dspp_sub_blks: Information of DSPP block
* @gc : gamma correction block
* @pcc: pixel color correction block
*/
struct dpu_dspp_sub_blks {
struct dpu_pp_blk gc;
struct dpu_pp_blk pcc;
};

struct dpu_pingpong_sub_blks {
struct dpu_pp_blk te;
struct dpu_pp_blk te2;
Expand Down Expand Up @@ -471,9 +492,23 @@ struct dpu_lm_cfg {
DPU_HW_BLK_INFO;
const struct dpu_lm_sub_blks *sblk;
u32 pingpong;
u32 dspp;
unsigned long lm_pair_mask;
};

/**
* struct dpu_dspp_cfg - information of DSPP blocks
* @id enum identifying this block
* @base register offset of this block
* @features bit mask identifying sub-blocks/features
* supported by this block
* @sblk sub-blocks information
*/
struct dpu_dspp_cfg {
DPU_HW_BLK_INFO;
const struct dpu_dspp_sub_blks *sblk;
};

/**
* struct dpu_pingpong_cfg - information of PING-PONG blocks
* @id enum identifying this block
Expand Down Expand Up @@ -688,6 +723,9 @@ struct dpu_mdss_cfg {

u32 ad_count;

u32 dspp_count;
const struct dpu_dspp_cfg *dspp;

/* Add additional block data structures here */

struct dpu_perf_cfg perf;
Expand Down Expand Up @@ -716,6 +754,7 @@ struct dpu_mdss_hw_cfg_handler {
#define BLK_PINGPONG(s) ((s)->pingpong)
#define BLK_INTF(s) ((s)->intf)
#define BLK_AD(s) ((s)->ad)
#define BLK_DSPP(s) ((s)->dspp)

/**
* dpu_hw_catalog_init - dpu hardware catalog init API retrieves
Expand Down
26 changes: 26 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,31 @@ static int dpu_hw_ctl_active_get_bitmask_intf(struct dpu_hw_ctl *ctx,
return 0;
}

static uint32_t dpu_hw_ctl_get_bitmask_dspp(struct dpu_hw_ctl *ctx,
enum dpu_dspp dspp)
{
uint32_t flushbits = 0;

switch (dspp) {
case DSPP_0:
flushbits = BIT(13);
break;
case DSPP_1:
flushbits = BIT(14);
break;
case DSPP_2:
flushbits = BIT(15);
break;
case DSPP_3:
flushbits = BIT(21);
break;
default:
return 0;
}

return flushbits;
}

static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
Expand Down Expand Up @@ -548,6 +573,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer;
ops->get_bitmask_dspp = dpu_hw_ctl_get_bitmask_dspp;
};

static struct dpu_hw_blk_ops dpu_hw_ops;
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ struct dpu_hw_ctl_ops {
uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx,
enum dpu_lm blk);

uint32_t (*get_bitmask_dspp)(struct dpu_hw_ctl *ctx,
enum dpu_dspp blk);

/**
* Query the value of the intf flush mask
* No effect on hardware
Expand Down
82 changes: 82 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/

#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
#include "dpu_hw_lm.h"
#include "dpu_hw_dspp.h"
#include "dpu_kms.h"


static void _setup_dspp_ops(struct dpu_hw_dspp *c,
unsigned long features)
{
return;
}

static const struct dpu_dspp_cfg *_dspp_offset(enum dpu_dspp dspp,
const struct dpu_mdss_cfg *m,
void __iomem *addr,
struct dpu_hw_blk_reg_map *b)
{
int i;

if (!m || !addr || !b)
return ERR_PTR(-EINVAL);

for (i = 0; i < m->dspp_count; i++) {
if (dspp == m->dspp[i].id) {
b->base_off = addr;
b->blk_off = m->dspp[i].base;
b->length = m->dspp[i].len;
b->hwversion = m->hwversion;
b->log_mask = DPU_DBG_MASK_DSPP;
return &m->dspp[i];
}
}

return ERR_PTR(-EINVAL);
}

static struct dpu_hw_blk_ops dpu_hw_ops;

struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx,
void __iomem *addr,
const struct dpu_mdss_cfg *m)
{
struct dpu_hw_dspp *c;
const struct dpu_dspp_cfg *cfg;

if (!addr || !m)
return ERR_PTR(-EINVAL);

c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);

cfg = _dspp_offset(idx, m, addr, &c->hw);
if (IS_ERR_OR_NULL(cfg)) {
kfree(c);
return ERR_PTR(-EINVAL);
}

/* Assign ops */
c->idx = idx;
c->cap = cfg;
_setup_dspp_ops(c, c->cap->features);

dpu_hw_blk_init(&c->base, DPU_HW_BLK_DSPP, idx, &dpu_hw_ops);

return c;
}

void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp)
{
if (dspp)
dpu_hw_blk_destroy(&dspp->base);

kfree(dspp);
}


Loading

0 comments on commit e47616d

Please sign in to comment.