disp: msm: add cwb dither support
Add cwb dither support. Catalog: Read dtsi value of cwb dither in pp parse part. Wb: Install blob property for cwb dither. Wb hw: Adds a new wb ops function to program cwb dither hardware. CRTC: To ensure that userspace can check whether cwb dither is supported, added "has_cwb_dither" to sde kms info. PingPong: In order to reuse dither's map array, move dither_depth_map array to pp header file. Change-Id: I77e6a052a00b7c649452103145e5d7b4c8deb3a2 Signed-off-by: Yuchao Ma <yuchaom@codeaurora.org>
This commit is contained in:
@@ -193,6 +193,7 @@ enum msm_mdp_conn_property {
|
||||
CONNECTOR_PROP_HDR_INFO,
|
||||
CONNECTOR_PROP_EXT_HDR_INFO,
|
||||
CONNECTOR_PROP_PP_DITHER,
|
||||
CONNECTOR_PROP_PP_CWB_DITHER,
|
||||
CONNECTOR_PROP_HDR_METADATA,
|
||||
CONNECTOR_PROP_DEMURA_PANEL_ID,
|
||||
|
||||
|
@@ -919,6 +919,10 @@ static void _sde_encoder_phys_wb_update_cwb_flush(
|
||||
enum sde_cwb src_pp_idx = 0;
|
||||
bool dspp_out = false;
|
||||
bool need_merge = false;
|
||||
struct sde_connector *c_conn = NULL;
|
||||
struct sde_connector_state *c_state = NULL;
|
||||
void *dither_cfg = NULL;
|
||||
size_t dither_sz = 0;
|
||||
|
||||
if (!phys_enc->in_clone_mode) {
|
||||
SDE_DEBUG("not in CWB mode. early return\n");
|
||||
@@ -973,11 +977,30 @@ static void _sde_encoder_phys_wb_update_cwb_flush(
|
||||
|
||||
if (test_bit(SDE_WB_CWB_CTRL, &hw_wb->caps->features) ||
|
||||
test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features)) {
|
||||
if (test_bit(SDE_WB_CWB_DITHER_CTRL, &hw_wb->caps->features)) {
|
||||
if (cwb_capture_mode) {
|
||||
c_conn = to_sde_connector(phys_enc->connector);
|
||||
c_state = to_sde_connector_state(phys_enc->connector->state);
|
||||
dither_cfg = msm_property_get_blob(&c_conn->property_info,
|
||||
&c_state->property_state, &dither_sz,
|
||||
CONNECTOR_PROP_PP_CWB_DITHER);
|
||||
SDE_DEBUG("Read cwb dither setting from blob %pK\n", dither_cfg);
|
||||
} else {
|
||||
/* disable case: tap is lm */
|
||||
dither_cfg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < crtc->num_mixers; i++) {
|
||||
src_pp_idx = (enum sde_cwb) (src_pp_idx + i);
|
||||
|
||||
if (test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features)) {
|
||||
dcwb_idx = (enum sde_dcwb) ((hw_pp->idx % 2) + i);
|
||||
if (test_bit(SDE_WB_CWB_DITHER_CTRL, &hw_wb->caps->features)) {
|
||||
if (hw_wb->ops.program_cwb_dither_ctrl)
|
||||
hw_wb->ops.program_cwb_dither_ctrl(hw_wb,
|
||||
dcwb_idx, dither_cfg, dither_sz, enable);
|
||||
}
|
||||
if (hw_wb->ops.program_dcwb_ctrl)
|
||||
hw_wb->ops.program_dcwb_ctrl(hw_wb, dcwb_idx,
|
||||
src_pp_idx, cwb_capture_mode,
|
||||
|
@@ -329,6 +329,7 @@ enum {
|
||||
DITHER_OFF,
|
||||
DITHER_LEN,
|
||||
DITHER_VER,
|
||||
CWB_DITHER,
|
||||
PP_MERGE_3D_ID,
|
||||
PP_PROP_MAX,
|
||||
};
|
||||
@@ -850,6 +851,7 @@ static struct sde_prop_type pp_prop[] = {
|
||||
{DITHER_OFF, "qcom,sde-dither-off", false, PROP_TYPE_U32_ARRAY},
|
||||
{DITHER_LEN, "qcom,sde-dither-size", false, PROP_TYPE_U32},
|
||||
{DITHER_VER, "qcom,sde-dither-version", false, PROP_TYPE_U32},
|
||||
{CWB_DITHER, "qcom,sde-cwb-dither", false, PROP_TYPE_U32_ARRAY},
|
||||
{PP_MERGE_3D_ID, "qcom,sde-pp-merge-3d-id", false, PROP_TYPE_U32_ARRAY},
|
||||
};
|
||||
|
||||
@@ -2564,6 +2566,10 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
|
||||
sde_cfg->cwb_blk_off = 0x83000;
|
||||
sde_cfg->cwb_blk_stride = 0x100;
|
||||
}
|
||||
|
||||
if (sde_cfg->has_cwb_dither)
|
||||
set_bit(SDE_WB_CWB_DITHER_CTRL, &wb->features);
|
||||
|
||||
} else if (sde_cfg->has_cwb_support) {
|
||||
set_bit(SDE_WB_HAS_CWB, &wb->features);
|
||||
if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
|
||||
@@ -3910,6 +3916,11 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
|
||||
sblk->dither.version = PROP_VALUE_ACCESS(prop_value, DITHER_VER,
|
||||
0);
|
||||
|
||||
if (sde_cfg->has_cwb_dither &&
|
||||
PROP_VALUE_ACCESS(prop_value, CWB_DITHER, i)) {
|
||||
set_bit(SDE_PINGPONG_CWB_DITHER, &pp->features);
|
||||
}
|
||||
|
||||
if (sde_cfg->dither_luma_mode_support)
|
||||
set_bit(SDE_PINGPONG_DITHER_LUMA, &pp->features);
|
||||
|
||||
@@ -5094,6 +5105,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
|
||||
sde_cfg->syscache_supported = true;
|
||||
} else if (IS_WAIPIO_TARGET(hw_rev)) {
|
||||
sde_cfg->has_dedicated_cwb_support = true;
|
||||
sde_cfg->has_cwb_dither = true;
|
||||
sde_cfg->has_wb_ubwc = true;
|
||||
sde_cfg->has_cwb_crop = true;
|
||||
sde_cfg->has_qsync = true;
|
||||
|
@@ -421,6 +421,7 @@ enum {
|
||||
* @SDE_PINGPONG_DITHER_LUMA, Dither sub-blocks and features
|
||||
* @SDE_PINGPONG_MERGE_3D, Separate MERGE_3D block exists
|
||||
* @SDE_PINGPONG_CWB, PP block supports CWB
|
||||
* @SDE_PINGPONG_CWB_DITHER, PP block supports CWB dither
|
||||
* @SDE_PINGPONG_MAX
|
||||
*/
|
||||
enum {
|
||||
@@ -433,6 +434,7 @@ enum {
|
||||
SDE_PINGPONG_DITHER_LUMA,
|
||||
SDE_PINGPONG_MERGE_3D,
|
||||
SDE_PINGPONG_CWB,
|
||||
SDE_PINGPONG_CWB_DITHER,
|
||||
SDE_PINGPONG_MAX
|
||||
};
|
||||
|
||||
@@ -535,6 +537,7 @@ enum {
|
||||
* @SDE_WB_CROP CWB supports cropping
|
||||
* @SDE_WB_CWB_CTRL Separate CWB control is available for configuring
|
||||
* @SDE_WB_DCWB_CTRL Separate DCWB control is available for configuring
|
||||
* @SDE_WB_CWB_DITHER_CTRL CWB dither is available for configuring
|
||||
* @SDE_WB_MAX maximum value
|
||||
*/
|
||||
enum {
|
||||
@@ -559,6 +562,7 @@ enum {
|
||||
SDE_WB_CROP,
|
||||
SDE_WB_CWB_CTRL,
|
||||
SDE_WB_DCWB_CTRL,
|
||||
SDE_WB_CWB_DITHER_CTRL,
|
||||
SDE_WB_MAX
|
||||
};
|
||||
|
||||
@@ -1458,6 +1462,7 @@ struct sde_perf_cfg {
|
||||
* @has_cwb_crop CWB cropping is supported
|
||||
* @has_cwb_support indicates if device supports primary capture through CWB
|
||||
* @has_dedicated_cwb_support indicates if device supports dedicated path for CWB capture
|
||||
* @has_cwb_dither indicates if device supports cwb dither feature
|
||||
* @cwb_blk_off CWB offset address
|
||||
* @cwb_blk_stride offset between each CWB blk
|
||||
* @ubwc_version UBWC feature version (0x0 for not supported)
|
||||
@@ -1543,6 +1548,7 @@ struct sde_mdss_cfg {
|
||||
bool has_cwb_crop;
|
||||
bool has_cwb_support;
|
||||
bool has_dedicated_cwb_support;
|
||||
bool has_cwb_dither;
|
||||
u32 cwb_blk_off;
|
||||
u32 cwb_blk_stride;
|
||||
u32 ubwc_version;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
@@ -33,11 +33,6 @@
|
||||
#define PP_DCE_DATA_IN_SWAP 0x0ac
|
||||
#define PP_DCE_DATA_OUT_SWAP 0x0c8
|
||||
|
||||
#define DITHER_DEPTH_MAP_INDEX 9
|
||||
static u32 dither_depth_map[DITHER_DEPTH_MAP_INDEX] = {
|
||||
0, 0, 0, 0, 0, 1, 2, 3, 3
|
||||
};
|
||||
|
||||
#define DITHER_VER_MAJOR_1 1
|
||||
/* supports LUMA Dither */
|
||||
#define DITHER_VER_MAJOR_2 2
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SDE_HW_PINGPONG_H
|
||||
@@ -15,6 +15,11 @@
|
||||
struct sde_hw_pingpong;
|
||||
struct sde_hw_merge_3d;
|
||||
|
||||
#define DITHER_DEPTH_MAP_INDEX 9
|
||||
static u32 dither_depth_map[DITHER_DEPTH_MAP_INDEX] = {
|
||||
0, 0, 0, 0, 0, 1, 2, 3, 3
|
||||
};
|
||||
|
||||
struct sde_hw_dsc_cfg {
|
||||
u8 enable;
|
||||
};
|
||||
|
@@ -126,6 +126,38 @@ static void _sde_hw_dcwb_ctrl_init(struct sde_mdss_cfg *m,
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_hw_dcwb_pp_ctrl_init(struct sde_mdss_cfg *m,
|
||||
void __iomem *addr, struct sde_hw_wb *hw_wb)
|
||||
{
|
||||
int i = 0, dcwb_pp_count = 0;
|
||||
struct sde_pingpong_cfg *pp_blk = NULL;
|
||||
|
||||
if (!hw_wb) {
|
||||
DRM_ERROR("hw_wb is null\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < m->pingpong_count; i++) {
|
||||
pp_blk = &m->pingpong[i];
|
||||
if (test_bit(SDE_PINGPONG_CWB_DITHER, &pp_blk->features)) {
|
||||
if (dcwb_pp_count < DCWB_MAX - DCWB_0) {
|
||||
hw_wb->dcwb_pp_hw[dcwb_pp_count].caps = pp_blk;
|
||||
hw_wb->dcwb_pp_hw[dcwb_pp_count].idx = pp_blk->id;
|
||||
hw_wb->dcwb_pp_hw[dcwb_pp_count].hw.base_off = addr;
|
||||
hw_wb->dcwb_pp_hw[dcwb_pp_count].hw.blk_off = pp_blk->base;
|
||||
hw_wb->dcwb_pp_hw[dcwb_pp_count].hw.length = pp_blk->len;
|
||||
hw_wb->dcwb_pp_hw[dcwb_pp_count].hw.hwversion = m->hwversion;
|
||||
hw_wb->dcwb_pp_hw[dcwb_pp_count].hw.log_mask = SDE_DBG_MASK_WB;
|
||||
} else {
|
||||
DRM_ERROR("Invalid dcwb pp count %d more than %d",
|
||||
dcwb_pp_count, DCWB_MAX - DCWB_0);
|
||||
return;
|
||||
}
|
||||
++dcwb_pp_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sde_hw_wb_setup_outaddress(struct sde_hw_wb *ctx,
|
||||
struct sde_hw_wb_cfg *data)
|
||||
{
|
||||
@@ -374,6 +406,102 @@ static void sde_hw_wb_program_cwb_ctrl(struct sde_hw_wb *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static void sde_hw_wb_program_cwb_dither_ctrl(struct sde_hw_wb *ctx,
|
||||
const enum sde_dcwb dcwb_idx, void *cfg, size_t len, bool enable)
|
||||
{
|
||||
struct sde_hw_pingpong *pp = NULL;
|
||||
struct sde_hw_blk_reg_map *c = NULL;
|
||||
struct drm_msm_dither *dither_data = NULL;
|
||||
enum sde_pingpong pp_id = PINGPONG_MAX;
|
||||
u32 dither_base = 0, offset = 0, data = 0, idx = 0;
|
||||
bool found = false;
|
||||
|
||||
if (!ctx) {
|
||||
DRM_ERROR("Invalid pointer ctx is null\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* map to pp_id from dcwb id */
|
||||
if (dcwb_idx == DCWB_0) {
|
||||
pp_id = PINGPONG_CWB_0;
|
||||
} else if (dcwb_idx == DCWB_1) {
|
||||
pp_id = PINGPONG_CWB_1;
|
||||
} else {
|
||||
DRM_ERROR("Invalid dcwb_idx %d\n", dcwb_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* find pp blk with pp_id */
|
||||
for (idx = 0; idx < DCWB_MAX - DCWB_0; ++idx) {
|
||||
pp = &ctx->dcwb_pp_hw[idx];
|
||||
if (pp && pp->idx == pp_id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
DRM_ERROR("Not found pp id %d\n", pp_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!test_bit(SDE_PINGPONG_CWB_DITHER, &pp->caps->features)) {
|
||||
DRM_ERROR("Invalid ping-pong cwb config dcwb idx %d pp id %d\n",
|
||||
dcwb_idx, pp_id);
|
||||
return;
|
||||
}
|
||||
|
||||
c = &pp->hw;
|
||||
dither_base = pp->caps->sblk->dither.base;
|
||||
dither_data = (struct drm_msm_dither *)cfg;
|
||||
if (!dither_data || !enable) {
|
||||
SDE_REG_WRITE(c, dither_base, 0);
|
||||
SDE_DEBUG("cwb dither disabled, dcwb_idx %u pp_id %u\n", dcwb_idx, pp_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (len != sizeof(struct drm_msm_dither)) {
|
||||
SDE_ERROR("input len %zu, expected len %zu\n", len,
|
||||
sizeof(struct drm_msm_dither));
|
||||
return;
|
||||
}
|
||||
|
||||
if (dither_data->c0_bitdepth >= DITHER_DEPTH_MAP_INDEX ||
|
||||
dither_data->c1_bitdepth >= DITHER_DEPTH_MAP_INDEX ||
|
||||
dither_data->c2_bitdepth >= DITHER_DEPTH_MAP_INDEX ||
|
||||
dither_data->c3_bitdepth >= DITHER_DEPTH_MAP_INDEX) {
|
||||
SDE_ERROR("Invalid bitdepth [c0, c1, c2, c3] = [%u, %u, %u, %u]\n",
|
||||
dither_data->c0_bitdepth, dither_data->c1_bitdepth,
|
||||
dither_data->c2_bitdepth, dither_data->c3_bitdepth);
|
||||
return;
|
||||
}
|
||||
|
||||
offset += 4;
|
||||
data = dither_depth_map[dither_data->c0_bitdepth] & REG_MASK(2);
|
||||
data |= (dither_depth_map[dither_data->c1_bitdepth] & REG_MASK(2)) << 2;
|
||||
data |= (dither_depth_map[dither_data->c2_bitdepth] & REG_MASK(2)) << 4;
|
||||
data |= (dither_depth_map[dither_data->c3_bitdepth] & REG_MASK(2)) << 6;
|
||||
data |= (dither_data->temporal_en) ? (1 << 8) : 0;
|
||||
SDE_REG_WRITE(c, dither_base + offset, data);
|
||||
|
||||
for (idx = 0; idx < DITHER_MATRIX_SZ - 3; idx += 4) {
|
||||
offset += 4;
|
||||
data = (dither_data->matrix[idx] & REG_MASK(4)) |
|
||||
((dither_data->matrix[idx + 1] & REG_MASK(4)) << 4) |
|
||||
((dither_data->matrix[idx + 2] & REG_MASK(4)) << 8) |
|
||||
((dither_data->matrix[idx + 3] & REG_MASK(4)) << 12);
|
||||
SDE_REG_WRITE(c, dither_base + offset, data);
|
||||
}
|
||||
|
||||
/* Enable dither */
|
||||
if (test_bit(SDE_PINGPONG_DITHER_LUMA, &pp->caps->features)
|
||||
&& (dither_data->flags & DITHER_LUMA_MODE))
|
||||
SDE_REG_WRITE(c, dither_base, 0x11);
|
||||
else
|
||||
SDE_REG_WRITE(c, dither_base, 1);
|
||||
SDE_DEBUG("cwb dither enabled, dcwb_idx %u pp_id %u\n", dcwb_idx, pp_id);
|
||||
}
|
||||
|
||||
static void _setup_wb_ops(struct sde_hw_wb_ops *ops,
|
||||
unsigned long features)
|
||||
{
|
||||
@@ -402,6 +530,9 @@ static void _setup_wb_ops(struct sde_hw_wb_ops *ops,
|
||||
ops->program_dcwb_ctrl = sde_hw_wb_program_dcwb_ctrl;
|
||||
ops->bind_dcwb_pp_blk = sde_hw_wb_bind_dcwb_pp_blk;
|
||||
}
|
||||
|
||||
if (test_bit(SDE_WB_CWB_DITHER_CTRL, &features))
|
||||
ops->program_cwb_dither_ctrl = sde_hw_wb_program_cwb_dither_ctrl;
|
||||
}
|
||||
|
||||
static struct sde_hw_blk_ops sde_hw_ops = {
|
||||
@@ -452,8 +583,10 @@ struct sde_hw_wb *sde_hw_wb_init(enum sde_wb idx,
|
||||
if (test_bit(SDE_WB_CWB_CTRL, &cfg->features))
|
||||
_sde_hw_cwb_ctrl_init(m, addr, &c->cwb_hw);
|
||||
|
||||
if (test_bit(SDE_WB_DCWB_CTRL, &cfg->features))
|
||||
if (test_bit(SDE_WB_DCWB_CTRL, &cfg->features)) {
|
||||
_sde_hw_dcwb_ctrl_init(m, addr, &c->dcwb_hw);
|
||||
_sde_hw_dcwb_pp_ctrl_init(m, addr, c);
|
||||
}
|
||||
|
||||
return c;
|
||||
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include "sde_hw_mdss.h"
|
||||
#include "sde_hw_top.h"
|
||||
#include "sde_hw_util.h"
|
||||
#include "sde_hw_pingpong.h"
|
||||
|
||||
struct sde_hw_wb;
|
||||
|
||||
@@ -149,6 +150,17 @@ struct sde_hw_wb_ops {
|
||||
*/
|
||||
void (*program_dcwb_ctrl)(struct sde_hw_wb *ctx, const enum sde_dcwb cwb,
|
||||
const enum sde_cwb data_src, int tap_location, bool enable);
|
||||
|
||||
/**
|
||||
* program_cwb_dither_ctrl - program cwb dither block config
|
||||
* @ctx: Pointer to wb context
|
||||
* @dcwb_idx: Current Ping-Pong CWB block index to program
|
||||
* @cfg: cwb dither data
|
||||
* @len: the size of cwb dither data
|
||||
* @enable: enable or disable the cwb dither
|
||||
*/
|
||||
void (*program_cwb_dither_ctrl)(struct sde_hw_wb *ctx,
|
||||
const enum sde_dcwb dcwb_idx, void *cfg, size_t len, bool enable);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -163,6 +175,7 @@ struct sde_hw_wb_ops {
|
||||
* @hw_mdp: MDP top level hardware block
|
||||
* @cwb_hw: CWB control hwio details
|
||||
* @dcwb_hw: DCWB control hwio details
|
||||
* @dcwb_pp_hw: DCWB PingPong control hwio details
|
||||
*/
|
||||
struct sde_hw_wb {
|
||||
struct sde_hw_blk base;
|
||||
@@ -180,6 +193,7 @@ struct sde_hw_wb {
|
||||
struct sde_hw_mdp *hw_mdp;
|
||||
struct sde_hw_blk_reg_map cwb_hw;
|
||||
struct sde_hw_blk_reg_map dcwb_hw;
|
||||
struct sde_hw_pingpong dcwb_pp_hw[DCWB_MAX - DCWB_0];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
|
||||
@@ -366,6 +366,8 @@ int sde_wb_connector_set_info_blob(struct drm_connector *connector,
|
||||
{
|
||||
struct sde_wb_device *wb_dev = display;
|
||||
const struct sde_format_extended *format_list;
|
||||
struct msm_drm_private *priv = NULL;
|
||||
struct sde_kms *sde_kms = NULL;
|
||||
|
||||
if (!connector || !info || !display || !wb_dev->wb_cfg) {
|
||||
SDE_ERROR("invalid params\n");
|
||||
@@ -405,9 +407,74 @@ int sde_wb_connector_set_info_blob(struct drm_connector *connector,
|
||||
sde_kms_info_append(info, "wb_ubwc");
|
||||
sde_kms_info_stop(info);
|
||||
|
||||
if (wb_dev->drm_dev && wb_dev->drm_dev->dev_private) {
|
||||
priv = wb_dev->drm_dev->dev_private;
|
||||
if (!priv->kms) {
|
||||
SDE_ERROR("invalid kms reference\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_kms = to_sde_kms(priv->kms);
|
||||
sde_kms_info_add_keyint(info, "has_cwb_dither", sde_kms->catalog->has_cwb_dither);
|
||||
} else {
|
||||
SDE_ERROR("invalid params %pK\n", wb_dev->drm_dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sde_wb_connector_install_dither_property(struct sde_wb_device *wb_dev,
|
||||
struct sde_connector *c_conn)
|
||||
{
|
||||
char prop_name[DRM_PROP_NAME_LEN];
|
||||
struct sde_kms *sde_kms = NULL;
|
||||
struct msm_drm_private *priv = NULL;
|
||||
struct sde_mdss_cfg *catalog = NULL;
|
||||
u32 version = 0;
|
||||
|
||||
if (!wb_dev || !c_conn) {
|
||||
SDE_ERROR("invalid args (s), wb_dev %pK, c_conn %pK\n", wb_dev, c_conn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wb_dev->drm_dev) {
|
||||
SDE_ERROR("invalid drm_dev is null\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wb_dev->drm_dev->dev_private) {
|
||||
SDE_ERROR("invalid dev_private is null\n");
|
||||
return;
|
||||
}
|
||||
|
||||
priv = wb_dev->drm_dev->dev_private;
|
||||
if (!priv->kms) {
|
||||
SDE_ERROR("invalid kms reference is null\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sde_kms = to_sde_kms(priv->kms);
|
||||
catalog = sde_kms->catalog;
|
||||
|
||||
if (!catalog->has_cwb_dither)
|
||||
return;
|
||||
|
||||
version = SDE_COLOR_PROCESS_MAJOR(
|
||||
catalog->pingpong[0].sblk->dither.version);
|
||||
snprintf(prop_name, ARRAY_SIZE(prop_name), "%s%d",
|
||||
"SDE_PP_CWB_DITHER_V", version);
|
||||
switch (version) {
|
||||
case 2:
|
||||
msm_property_install_blob(&c_conn->property_info, prop_name,
|
||||
DRM_MODE_PROP_BLOB, CONNECTOR_PROP_PP_CWB_DITHER);
|
||||
break;
|
||||
default:
|
||||
SDE_ERROR("unsupported cwb dither version %d\n", version);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int sde_wb_connector_post_init(struct drm_connector *connector, void *display)
|
||||
{
|
||||
struct sde_connector *c_conn;
|
||||
@@ -446,6 +513,8 @@ int sde_wb_connector_post_init(struct drm_connector *connector, void *display)
|
||||
ARRAY_SIZE(e_fb_translation_mode), 0,
|
||||
CONNECTOR_PROP_FB_TRANSLATION_MODE);
|
||||
|
||||
sde_wb_connector_install_dither_property(wb_dev, c_conn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user