Merge "disp: msm: sde: add support for spr hw block configuration"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
56d95ba3e2
@@ -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.
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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];
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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];
|
||||
|
@@ -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:
|
||||
|
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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, ®,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user