Merge "disp: msm: sde: add support for spr hw block configuration"

This commit is contained in:
qctecmdr
2020-03-20 15:31:25 -07:00
committed by Gerrit - the friendly Code Review server
14 changed files with 498 additions and 1 deletions

View File

@@ -561,6 +561,38 @@ struct drm_msm_ltm_buffer {
__u32 status;
};
#define SPR_INIT_PARAM_SIZE_1 4
#define SPR_INIT_PARAM_SIZE_2 5
#define SPR_INIT_PARAM_SIZE_3 16
#define SPR_INIT_PARAM_SIZE_4 24
#define SPR_INIT_PARAM_SIZE_5 32
/**
* struct drm_msm_spr_init_cfg - SPR initial configuration structure
*
*/
struct drm_msm_spr_init_cfg {
__u64 flags;
__u16 cfg0;
__u16 cfg1;
__u16 cfg2;
__u16 cfg3;
__u16 cfg4;
__u16 cfg5;
__u16 cfg6;
__u16 cfg7;
__u16 cfg8;
__u16 cfg9;
__u32 cfg10;
__u16 cfg11[SPR_INIT_PARAM_SIZE_1];
__u16 cfg12[SPR_INIT_PARAM_SIZE_1];
__u16 cfg13[SPR_INIT_PARAM_SIZE_1];
__u16 cfg14[SPR_INIT_PARAM_SIZE_2];
__u16 cfg15[SPR_INIT_PARAM_SIZE_5];
int cfg16[SPR_INIT_PARAM_SIZE_3];
int cfg17[SPR_INIT_PARAM_SIZE_4];
};
/**
* struct drm_msm_ad4_manual_str_cfg - ad4 manual strength config set
* by user-space client.

View File

@@ -650,6 +650,10 @@ int dsi_conn_set_info_blob(struct drm_connector *connector,
break;
}
if (panel->spr_info.enable)
sde_kms_info_add_keystr(info, "spr_pack_type",
msm_spr_pack_type_str[panel->spr_info.pack_type]);
if (mode_info && mode_info->roi_caps.enabled) {
sde_kms_info_add_keyint(info, "partial_update_num_roi",
mode_info->roi_caps.num_roi);

View File

@@ -1860,6 +1860,8 @@ error:
static int dsi_panel_parse_misc_features(struct dsi_panel *panel)
{
struct dsi_parser_utils *utils = &panel->utils;
const char *string;
int i, rc = 0;
panel->ulps_feature_enabled =
utils->read_bool(utils->data, "qcom,ulps-enabled");
@@ -1881,6 +1883,29 @@ static int dsi_panel_parse_misc_features(struct dsi_panel *panel)
panel->lp11_init = utils->read_bool(utils->data,
"qcom,mdss-dsi-lp11-init");
panel->spr_info.enable = false;
panel->spr_info.pack_type = MSM_DISPLAY_SPR_TYPE_MAX;
rc = utils->read_string(utils->data, "qcom,spr-pack-type", &string);
if (!rc) {
// find match for pack-type string
for (i = 0; i < MSM_DISPLAY_SPR_TYPE_MAX; i++) {
if (msm_spr_pack_type_str[i] &&
(!strcmp(string, msm_spr_pack_type_str[i]))) {
panel->spr_info.enable = true;
panel->spr_info.pack_type = i;
break;
}
}
}
pr_debug("%s source side spr packing, pack-type %s\n",
panel->spr_info.enable ? "enable" : "disable",
panel->spr_info.enable ?
msm_spr_pack_type_str[panel->spr_info.pack_type] : "none");
return 0;
}

View File

@@ -155,6 +155,11 @@ struct drm_panel_esd_config {
u32 groups;
};
struct dsi_panel_spr_info {
bool enable;
enum msm_display_spr_pack_type pack_type;
};
struct dsi_panel {
const char *name;
const char *type;
@@ -203,6 +208,8 @@ struct dsi_panel {
char dce_pps_cmd[DSI_CMD_PPS_SIZE];
enum dsi_dms_mode dms_mode;
struct dsi_panel_spr_info spr_info;
bool sync_broadcast_en;
int panel_test_gpio;

View File

@@ -231,6 +231,32 @@ enum msm_display_compression_type {
#define MSM_DISPLAY_COMPRESSION_RATIO_NONE 1
#define MSM_DISPLAY_COMPRESSION_RATIO_MAX 5
/**
* enum msm_display_spr_pack_type - sub pixel rendering pack patterns supported
* @MSM_DISPLAY_SPR_TYPE_NONE: Bypass, no special packing
* @MSM_DISPLAY_SPR_TYPE_PENTILE: pentile pack pattern
* @MSM_DISPLAY_SPR_TYPE_RGBW: RGBW pack pattern
* @MSM_DISPLAY_SPR_TYPE_YYGM: YYGM pack pattern
* @MSM_DISPLAY_SPR_TYPE_YYGW: YYGW pack patterm
* @MSM_DISPLAY_SPR_TYPE_MAX: max and invalid
*/
enum msm_display_spr_pack_type {
MSM_DISPLAY_SPR_TYPE_NONE,
MSM_DISPLAY_SPR_TYPE_PENTILE,
MSM_DISPLAY_SPR_TYPE_RGBW,
MSM_DISPLAY_SPR_TYPE_YYGM,
MSM_DISPLAY_SPR_TYPE_YYGW,
MSM_DISPLAY_SPR_TYPE_MAX
};
static const char *msm_spr_pack_type_str[MSM_DISPLAY_SPR_TYPE_MAX] = {
[MSM_DISPLAY_SPR_TYPE_NONE] = "",
[MSM_DISPLAY_SPR_TYPE_PENTILE] = "pentile",
[MSM_DISPLAY_SPR_TYPE_RGBW] = "rgbw",
[MSM_DISPLAY_SPR_TYPE_YYGM] = "yygm",
[MSM_DISPLAY_SPR_TYPE_YYGW] = "yygw"
};
/**
* enum msm_display_caps - features/capabilities supported by displays
* @MSM_DISPLAY_CAP_VID_MODE: Video or "active" mode supported

View File

@@ -58,6 +58,8 @@ static void dspp_ltm_install_property(struct drm_crtc *crtc);
static void dspp_rc_install_property(struct drm_crtc *crtc);
static void dspp_spr_install_property(struct drm_crtc *crtc);
static void dspp_vlut_install_property(struct drm_crtc *crtc);
static void dspp_gamut_install_property(struct drm_crtc *crtc);
@@ -108,6 +110,7 @@ do { \
func[SDE_DSPP_SIXZONE] = dspp_sixzone_install_property; \
func[SDE_DSPP_AD] = dspp_ad_install_property; \
func[SDE_DSPP_LTM] = dspp_ltm_install_property; \
func[SDE_DSPP_SPR] = dspp_spr_install_property; \
func[SDE_DSPP_VLUT] = dspp_vlut_install_property; \
func[SDE_DSPP_GAMUT] = dspp_gamut_install_property; \
func[SDE_DSPP_GC] = dspp_gc_install_property; \
@@ -164,6 +167,7 @@ enum sde_cp_crtc_features {
SDE_CP_CRTC_DSPP_LTM_VLUT,
SDE_CP_CRTC_DSPP_SB,
SDE_CP_CRTC_DSPP_RC_MASK,
SDE_CP_CRTC_DSPP_SPR_INIT,
SDE_CP_CRTC_DSPP_MAX,
/* DSPP features end */
@@ -790,6 +794,22 @@ static int check_rc_pu_feature(struct sde_hw_dspp *hw_dspp,
return ret;
}
static int set_spr_init_feature(struct sde_hw_dspp *hw_dspp,
struct sde_hw_cp_cfg *hw_cfg,
struct sde_crtc *sde_crtc)
{
int ret = 0;
if (!sde_crtc || !hw_dspp || !hw_dspp->ops.setup_spr_init_config) {
DRM_ERROR("invalid arguments\n");
ret = -EINVAL;
} else {
hw_dspp->ops.setup_spr_init_config(hw_dspp, hw_cfg);
}
return ret;
}
feature_wrapper check_crtc_feature_wrappers[SDE_CP_CRTC_MAX_FEATURES];
#define setup_check_crtc_feature_wrappers(wrappers) \
do { \
@@ -839,6 +859,7 @@ do { \
wrappers[SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF3] = set_ltm_queue_buf_feature; \
wrappers[SDE_CP_CRTC_DSPP_LTM_HIST_CTL] = set_ltm_hist_crtl_feature; \
wrappers[SDE_CP_CRTC_DSPP_RC_MASK] = set_rc_mask_feature; \
wrappers[SDE_CP_CRTC_DSPP_SPR_INIT] = set_spr_init_feature; \
} while (0)
feature_wrapper set_crtc_pu_feature_wrappers[SDE_CP_CRTC_MAX_PU_FEATURES];
@@ -1499,6 +1520,7 @@ static const int dspp_feature_to_sub_blk_tbl[SDE_CP_CRTC_MAX_FEATURES] = {
[SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF3] = SDE_DSPP_LTM,
[SDE_CP_CRTC_DSPP_LTM_VLUT] = SDE_DSPP_LTM,
[SDE_CP_CRTC_DSPP_SB] = SDE_DSPP_SB,
[SDE_CP_CRTC_DSPP_SPR_INIT] = SDE_DSPP_SPR,
[SDE_CP_CRTC_DSPP_RC_MASK] = SDE_DSPP_RC,
[SDE_CP_CRTC_DSPP_MAX] = SDE_DSPP_MAX,
[SDE_CP_CRTC_LM_GC] = SDE_DSPP_MAX,
@@ -2550,6 +2572,30 @@ static void dspp_rc_install_property(struct drm_crtc *crtc)
}
}
static void dspp_spr_install_property(struct drm_crtc *crtc)
{
struct sde_kms *kms = NULL;
u32 version = 0;
kms = get_kms(crtc);
if (!kms) {
DRM_ERROR("!kms = %d\n ", !kms);
return;
}
version = kms->catalog->dspp[0].sblk->spr.version >> 16;
switch (version) {
case 1:
sde_cp_crtc_install_blob_property(crtc, "SDE_SPR_INIT_CFG_V1",
SDE_CP_CRTC_DSPP_SPR_INIT,
sizeof(struct drm_msm_spr_init_cfg));
break;
default:
DRM_ERROR("version %d not supported\n", version);
break;
}
}
static void lm_gc_install_property(struct drm_crtc *crtc)
{
char feature_name[256];

View File

@@ -397,6 +397,13 @@ enum {
RC_PROP_MAX,
};
enum {
SPR_OFF,
SPR_LEN,
SPR_VERSION,
SPR_PROP_MAX,
};
enum {
MIXER_OFF,
MIXER_LEN,
@@ -717,6 +724,12 @@ static struct sde_prop_type rc_prop[] = {
{RC_MEM_TOTAL_SIZE, "qcom,sde-dspp-rc-mem-size", false, PROP_TYPE_U32},
};
static struct sde_prop_type spr_prop[] = {
{SPR_OFF, "qcom,sde-dspp-spr-off", false, PROP_TYPE_U32_ARRAY},
{SPR_LEN, "qcom,sde-dspp-spr-size", false, PROP_TYPE_U32},
{SPR_VERSION, "qcom,sde-dspp-spr-version", false, PROP_TYPE_U32},
};
static struct sde_prop_type ds_top_prop[] = {
{DS_TOP_OFF, "qcom,sde-dest-scaler-top-off", false, PROP_TYPE_U32},
{DS_TOP_LEN, "qcom,sde-dest-scaler-top-size", false, PROP_TYPE_U32},
@@ -2489,6 +2502,46 @@ end:
return rc;
}
static int _sde_dspp_spr_parse_dt(struct device_node *np,
struct sde_mdss_cfg *sde_cfg)
{
int off_count, i;
struct sde_dt_props *props;
struct sde_dspp_cfg *dspp;
struct sde_dspp_sub_blks *sblk;
props = sde_get_dt_props(np, SPR_PROP_MAX, spr_prop,
ARRAY_SIZE(spr_prop), &off_count);
if (IS_ERR(props))
return PTR_ERR(props);
sde_cfg->spr_count = off_count;
if (off_count > sde_cfg->dspp_count) {
SDE_ERROR("limiting %d spr blocks to %d DSPP instances\n",
off_count, sde_cfg->dspp_count);
sde_cfg->spr_count = sde_cfg->dspp_count;
}
for (i = 0; i < sde_cfg->dspp_count; i++) {
dspp = &sde_cfg->dspp[i];
sblk = sde_cfg->dspp[i].sblk;
sblk->spr.id = SDE_DSPP_SPR;
if (props->exists[SPR_OFF] && i < off_count) {
sblk->spr.base = PROP_VALUE_ACCESS(props->values,
SPR_OFF, i);
sblk->spr.len = PROP_VALUE_ACCESS(props->values,
SPR_LEN, 0);
sblk->spr.version = PROP_VALUE_ACCESS(props->values,
SPR_VERSION, 0);
set_bit(SDE_DSPP_SPR, &dspp->features);
}
}
sde_put_dt_props(props);
return 0;
}
static int _sde_rc_parse_dt(struct device_node *np,
struct sde_mdss_cfg *sde_cfg)
{
@@ -2669,8 +2722,11 @@ static int sde_dspp_parse_dt(struct device_node *np,
if (rc)
goto end;
rc = _sde_rc_parse_dt(np, sde_cfg);
rc = _sde_dspp_spr_parse_dt(np, sde_cfg);
if (rc)
goto end;
rc = _sde_rc_parse_dt(np, sde_cfg);
end:
return rc;
}

View File

@@ -765,6 +765,7 @@ struct sde_dspp_sub_blks {
struct sde_pp_blk hist;
struct sde_pp_blk ad;
struct sde_pp_blk ltm;
struct sde_pp_blk spr;
struct sde_pp_blk vlut;
struct sde_dspp_rc rc;
};
@@ -1545,6 +1546,7 @@ struct sde_mdss_cfg {
u32 ad_count;
u32 ltm_count;
u32 rc_count;
u32 spr_count;
u32 merge_3d_count;
struct sde_merge_3d_cfg merge_3d[MAX_BLOCKS];

View File

@@ -274,6 +274,16 @@ static void dspp_rc(struct sde_hw_dspp *c)
}
}
static void dspp_spr(struct sde_hw_dspp *c)
{
if (c->cap->sblk->spr.version == SDE_COLOR_PROCESS_VER(0x1, 0x0)) {
reg_dmav1_init_dspp_op_v4(SDE_DSPP_SPR, c->idx);
c->ops.setup_spr_init_config = reg_dmav1_setup_spr_init_cfgv1;
} else {
c->ops.setup_spr_init_config = NULL;
}
}
static void (*dspp_blocks[SDE_DSPP_MAX])(struct sde_hw_dspp *c);
static void _init_dspp_ops(void)
@@ -291,6 +301,7 @@ static void _init_dspp_ops(void)
dspp_blocks[SDE_DSPP_AD] = dspp_ad;
dspp_blocks[SDE_DSPP_LTM] = dspp_ltm;
dspp_blocks[SDE_DSPP_RC] = dspp_rc;
dspp_blocks[SDE_DSPP_SPR] = dspp_spr;
}
static void _setup_dspp_ops(struct sde_hw_dspp *c, unsigned long features)
@@ -371,6 +382,14 @@ struct sde_hw_dspp *sde_hw_dspp_init(enum sde_dspp idx,
c->hw.blk_off + cfg->sblk->rc.base +
cfg->sblk->rc.len, c->hw.xin_id);
}
if ((cfg->sblk->spr.id == SDE_DSPP_SPR) && cfg->sblk->spr.base) {
snprintf(buf, ARRAY_SIZE(buf), "%s_%d", "spr", c->idx - DSPP_0);
sde_dbg_reg_register_dump_range(SDE_DBG_NAME, buf,
c->hw.blk_off + cfg->sblk->spr.base,
c->hw.blk_off + cfg->sblk->spr.base +
cfg->sblk->spr.len, c->hw.xin_id);
}
return c;
blk_init_error:

View File

@@ -249,6 +249,13 @@ struct sde_hw_dspp_ops {
* Return: 0 on success, non-zero otherwise.
*/
int (*setup_rc_data)(struct sde_hw_dspp *ctx, void *cfg);
/**
* setup_spr_init_config - function to configure spr hw block
* @ctx: Pointer to dspp context
* @cfg: Pointer to configuration
*/
void (*setup_spr_init_config)(struct sde_hw_dspp *ctx, void *cfg);
};
/**

View File

@@ -808,6 +808,8 @@ int init_v12(struct sde_hw_reg_dma *cfg)
v1_supported[LTM_VLUT] = GRP_LTM_HW_BLK_SELECT;
v1_supported[RC_DATA] = (GRP_DSPP_HW_BLK_SELECT |
GRP_MDSS_HW_BLK_SELECT);
v1_supported[SPR_INIT] = (GRP_DSPP_HW_BLK_SELECT |
GRP_MDSS_HW_BLK_SELECT);
return 0;
}

View File

@@ -78,9 +78,12 @@
REG_DMA_HEADERS_BUFFER_SZ)
#define LTM_VLUT_MEM_SIZE ((sizeof(struct drm_msm_ltm_data)) + \
REG_DMA_HEADERS_BUFFER_SZ)
#define SPR_INIT_MEM_SIZE ((sizeof(struct drm_msm_spr_init_cfg)) + \
REG_DMA_HEADERS_BUFFER_SZ)
#define REG_MASK(n) ((BIT(n)) - 1)
#define REG_MASK_SHIFT(n, shift) ((REG_MASK(n)) << (shift))
#define APPLY_MASK_AND_SHIFT(x, n, shift) ((x & (REG_MASK(n))) << (shift))
#define REG_DMA_VIG_GAMUT_OP_MASK 0x300
#define REG_DMA_VIG_IGC_OP_MASK 0x1001F
#define DMA_DGM_0_OP_MODE_OFF 0x604
@@ -134,6 +137,7 @@ static u32 feature_map[SDE_DSPP_MAX] = {
/* MEMCOLOR can be mapped to any MEMC_SKIN/SKY/FOLIAGE/PROT*/
[SDE_DSPP_MEMCOLOR] = MEMC_SKIN,
[SDE_DSPP_SIXZONE] = SIX_ZONE,
[SDE_DSPP_SPR] = SPR_INIT,
[SDE_DSPP_DITHER] = REG_DMA_FEATURES_MAX,
[SDE_DSPP_HIST] = REG_DMA_FEATURES_MAX,
[SDE_DSPP_AD] = REG_DMA_FEATURES_MAX,
@@ -165,6 +169,7 @@ static u32 feature_reg_dma_sz[SDE_DSPP_MAX] = {
[SDE_DSPP_SIXZONE] = SIXZONE_MEM_SIZE,
[SDE_DSPP_MEMCOLOR] = MEMCOLOR_MEM_SIZE,
[SDE_DSPP_RC] = RC_MEM_SIZE,
[SDE_DSPP_SPR] = SPR_INIT_MEM_SIZE,
};
static u32 sspp_feature_reg_dma_sz[SDE_SSPP_MAX] = {
@@ -4430,3 +4435,261 @@ void reg_dmav2_setup_vig_gamutv61(struct sde_hw_pipe *ctx, void *cfg)
exit:
kfree(data);
}
int reg_dmav1_setup_spr_cfg3_params(struct sde_hw_dspp *ctx,
struct drm_msm_spr_init_cfg *payload,
struct sde_reg_dma_setup_ops_cfg *dma_write_cfg,
struct sde_hw_reg_dma_ops *dma_ops)
{
uint32_t reg_off, reg_cnt, base_off;
uint32_t reg[16];
int i, index, rc = 0;
if (!payload->cfg3)
return rc;
base_off = ctx->hw.blk_off + ctx->cap->sblk->spr.base;
reg_cnt = 2;
reg_off = base_off + 0x70;
reg[0] = APPLY_MASK_AND_SHIFT(payload->cfg13[0], 10, 0) |
APPLY_MASK_AND_SHIFT(payload->cfg13[1], 10, 10) |
APPLY_MASK_AND_SHIFT(payload->cfg13[2], 10, 20);
reg[1] = payload->cfg10 & REG_MASK(30);
REG_DMA_SETUP_OPS(*dma_write_cfg, reg_off, reg,
reg_cnt * sizeof(u32), REG_BLK_WRITE_SINGLE, 0, 0, 0);
rc = dma_ops->setup_payload(dma_write_cfg);
if (rc) {
DRM_ERROR("write spr cfg13 failed ret %d\n", rc);
return rc;
}
reg_cnt = ARRAY_SIZE(payload->cfg15) / 2;
reg_off = base_off + 0xA0;
for (i = 0; i < reg_cnt; i++) {
index = 2 * i;
reg[i] = APPLY_MASK_AND_SHIFT(payload->cfg15[index], 12, 0) |
APPLY_MASK_AND_SHIFT(payload->cfg15[index + 1], 12, 16);
}
REG_DMA_SETUP_OPS(*dma_write_cfg, reg_off, reg,
reg_cnt * sizeof(u32), REG_BLK_WRITE_SINGLE, 0, 0, 0);
rc = dma_ops->setup_payload(dma_write_cfg);
if (rc) {
DRM_ERROR("write spr cfg15 failed ret %d\n", rc);
return rc;
}
return rc;
}
int reg_dmav1_setup_spr_cfg4_params(struct sde_hw_dspp *ctx,
struct drm_msm_spr_init_cfg *payload,
struct sde_reg_dma_setup_ops_cfg *dma_write_cfg,
struct sde_hw_reg_dma_ops *dma_ops)
{
uint32_t reg_off, reg_cnt, base_off;
uint32_t reg[16];
int rc = 0;
if (!payload->cfg4)
return rc;
reg_cnt = 3;
base_off = ctx->hw.blk_off + ctx->cap->sblk->spr.base;
reg_off = base_off + 0x60;
reg[0] = payload->cfg9 & 0x0F;
reg[1] = APPLY_MASK_AND_SHIFT(payload->cfg12[3], 10, 0) |
APPLY_MASK_AND_SHIFT(payload->cfg12[0], 11, 16);
reg[2] = APPLY_MASK_AND_SHIFT(payload->cfg12[1], 11, 0) |
APPLY_MASK_AND_SHIFT(payload->cfg12[2], 11, 16);
REG_DMA_SETUP_OPS(*dma_write_cfg, reg_off, reg,
reg_cnt * sizeof(u32), REG_BLK_WRITE_SINGLE, 0, 0, 0);
rc = dma_ops->setup_payload(dma_write_cfg);
if (rc) {
DRM_ERROR("write spr cfg12 failed ret %d\n", rc);
return rc;
}
return rc;
}
void reg_dmav1_disable_spr(struct sde_hw_dspp *ctx, void *cfg)
{
struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
struct sde_hw_cp_cfg *hw_cfg = cfg;
struct sde_reg_dma_kickoff_cfg kick_off;
struct sde_hw_reg_dma_ops *dma_ops;
uint32_t reg_off, reg = 0;
int rc = 0;
dma_ops = sde_reg_dma_get_ops();
dma_ops->reset_reg_dma_buf(dspp_buf[SPR_INIT][ctx->idx]);
REG_DMA_INIT_OPS(dma_write_cfg, MDSS, SPR_INIT,
dspp_buf[SPR_INIT][ctx->idx]);
REG_DMA_SETUP_OPS(dma_write_cfg, 0, NULL, 0, HW_BLK_SELECT, 0, 0, 0);
rc = dma_ops->setup_payload(&dma_write_cfg);
if (rc) {
DRM_ERROR("spr write decode select failed ret %d\n", rc);
return;
}
reg_off = ctx->hw.blk_off + ctx->cap->sblk->spr.base + 0x04;
REG_DMA_SETUP_OPS(dma_write_cfg, reg_off, &reg,
sizeof(u32), REG_BLK_WRITE_SINGLE, 0, 0, 0);
rc = dma_ops->setup_payload(&dma_write_cfg);
if (rc) {
DRM_ERROR("write spr disable failed ret %d\n", rc);
return;
}
REG_DMA_SETUP_KICKOFF(kick_off, hw_cfg->ctl,
dspp_buf[SPR_INIT][ctx->idx],
REG_DMA_WRITE, DMA_CTL_QUEUE0, WRITE_IMMEDIATE);
rc = dma_ops->kick_off(&kick_off);
if (rc) {
DRM_ERROR("failed to kick off ret %d\n", rc);
return;
}
}
void reg_dmav1_setup_spr_init_cfgv1(struct sde_hw_dspp *ctx, void *cfg)
{
struct drm_msm_spr_init_cfg *payload = NULL;
struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
struct sde_hw_cp_cfg *hw_cfg = cfg;
struct sde_reg_dma_kickoff_cfg kick_off;
struct sde_hw_reg_dma_ops *dma_ops;
uint32_t reg_off, reg_cnt, base_off;
uint32_t reg[16];
int i, index, rc = 0;
rc = reg_dma_dspp_check(ctx, cfg, SPR_INIT);
if (rc)
return;
if (!hw_cfg->payload)
return reg_dmav1_disable_spr(ctx, cfg);
if (hw_cfg->len != sizeof(struct drm_msm_spr_init_cfg)) {
DRM_ERROR("invalid payload size len %d exp %zd\n", hw_cfg->len,
sizeof(struct drm_msm_spr_init_cfg));
return;
}
payload = hw_cfg->payload;
base_off = ctx->hw.blk_off + ctx->cap->sblk->spr.base;
dma_ops = sde_reg_dma_get_ops();
dma_ops->reset_reg_dma_buf(dspp_buf[SPR_INIT][ctx->idx]);
REG_DMA_INIT_OPS(dma_write_cfg, MDSS, SPR_INIT,
dspp_buf[SPR_INIT][ctx->idx]);
REG_DMA_SETUP_OPS(dma_write_cfg, 0, NULL, 0, HW_BLK_SELECT, 0, 0, 0);
rc = dma_ops->setup_payload(&dma_write_cfg);
if (rc) {
DRM_ERROR("spr write decode select failed ret %d\n", rc);
return;
}
reg_cnt = 2;
reg_off = base_off + 0x04;
reg[0] = APPLY_MASK_AND_SHIFT(payload->cfg0, 1, 0) |
APPLY_MASK_AND_SHIFT(payload->cfg1, 1, 1) |
APPLY_MASK_AND_SHIFT(payload->cfg2, 1, 2) |
APPLY_MASK_AND_SHIFT(payload->cfg4, 1, 3) |
APPLY_MASK_AND_SHIFT(payload->cfg3, 1, 24);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg5, 4, 16);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg6, 3, 20);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg7, 2, 4);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg8, 2, 6);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg11[0], 2, 8);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg11[1], 2, 10);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg11[2], 2, 12);
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg11[3], 1, 14);
reg[1] = 0;
if (hw_cfg->num_of_mixers == 2)
reg[1] = 1;
else if (hw_cfg->num_of_mixers == 4)
reg[1] = 3;
REG_DMA_SETUP_OPS(dma_write_cfg, reg_off, reg,
reg_cnt * sizeof(u32), REG_BLK_WRITE_SINGLE, 0, 0, 0);
rc = dma_ops->setup_payload(&dma_write_cfg);
if (rc) {
DRM_ERROR("write spr config failed ret %d\n", rc);
return;
}
reg_cnt = 1;
reg_off = base_off + 0x54;
reg[0] = 0;
for (i = 0; i < ARRAY_SIZE(payload->cfg14); i++)
reg[0] |= APPLY_MASK_AND_SHIFT(payload->cfg14[i], 5, 5 * i);
REG_DMA_SETUP_OPS(dma_write_cfg, reg_off, reg,
reg_cnt * sizeof(u32), REG_SINGLE_WRITE, 0, 0, 0);
rc = dma_ops->setup_payload(&dma_write_cfg);
if (rc) {
DRM_ERROR("write spr cfg14 failed ret %d\n", rc);
return;
}
reg_cnt = ARRAY_SIZE(payload->cfg17) / 6;
reg_off = base_off + 0x24;
for (i = 0; i < reg_cnt; i++) {
index = 6 * i;
reg[i] = APPLY_MASK_AND_SHIFT(payload->cfg17[index], 5, 0) |
APPLY_MASK_AND_SHIFT(payload->cfg17[index + 1], 5, 5) |
APPLY_MASK_AND_SHIFT(payload->cfg17[index + 2], 5, 10) |
APPLY_MASK_AND_SHIFT(payload->cfg17[index + 3], 5, 15) |
APPLY_MASK_AND_SHIFT(payload->cfg17[index + 4], 5, 20) |
APPLY_MASK_AND_SHIFT(payload->cfg17[index + 5], 5, 25);
}
reg[reg_cnt - 1] &= 0x3FF;
REG_DMA_SETUP_OPS(dma_write_cfg, reg_off, reg,
reg_cnt * sizeof(u32), REG_BLK_WRITE_SINGLE, 0, 0, 0);
rc = dma_ops->setup_payload(&dma_write_cfg);
if (rc) {
DRM_ERROR("write spr cfg17 failed ret %d\n", rc);
return;
}
reg_cnt = ARRAY_SIZE(payload->cfg16) / 2;
reg_off = base_off + 0x34;
for (i = 0; i < reg_cnt; i++) {
index = 2 * i;
reg[i] = APPLY_MASK_AND_SHIFT(payload->cfg16[index], 11, 0) |
APPLY_MASK_AND_SHIFT(payload->cfg16[index + 1], 11, 16);
}
REG_DMA_SETUP_OPS(dma_write_cfg, reg_off, reg, reg_cnt * sizeof(u32),
REG_BLK_WRITE_SINGLE, 0, 0, 0);
rc = dma_ops->setup_payload(&dma_write_cfg);
if (rc) {
DRM_ERROR("write spr cfg16 failed ret %d\n", rc);
return;
}
rc = reg_dmav1_setup_spr_cfg3_params(ctx, payload,
&dma_write_cfg, dma_ops);
if (rc)
return;
rc = reg_dmav1_setup_spr_cfg4_params(ctx, payload,
&dma_write_cfg, dma_ops);
if (rc)
return;
REG_DMA_SETUP_KICKOFF(kick_off, hw_cfg->ctl,
dspp_buf[SPR_INIT][ctx->idx],
REG_DMA_WRITE, DMA_CTL_QUEUE0, WRITE_IMMEDIATE);
rc = dma_ops->kick_off(&kick_off);
if (rc) {
DRM_ERROR("failed to kick off ret %d\n", rc);
return;
}
}

View File

@@ -288,5 +288,11 @@ void reg_dmav2_setup_dspp_3d_gamutv43(struct sde_hw_dspp *ctx, void *cfg);
*/
void reg_dmav2_setup_vig_gamutv61(struct sde_hw_pipe *ctx, void *cfg);
/**
* reg_dmav1_setup_spr_init_cfgv1 - function to configure spr through LUTDMA
* @ctx: Pointer to dspp context
* @cfg: Pointer to configuration
*/
void reg_dmav1_setup_spr_init_cfgv1(struct sde_hw_dspp *ctx, void *cfg);
#endif /* _SDE_HW_REG_DMA_V1_COLOR_PROC_H */

View File

@@ -54,6 +54,7 @@ enum sde_reg_dma_read_sel {
* @SIX_ZONE: six zone
* @HSIC: Hue, saturation and contrast
* @GC: gamma correction
* @SPR_INIT: Sub pixel rendering init feature
* @LTM_INIT: LTM INIT
* @LTM_ROI: LTM ROI
* @LTM_VLUT: LTM VLUT
@@ -73,6 +74,7 @@ enum sde_reg_dma_features {
SIX_ZONE,
HSIC,
GC,
SPR_INIT,
LTM_INIT,
LTM_ROI,
LTM_VLUT,