disp: msm: sde: expose dnsc_blur connector properties
Add downscale blur connector properties to expose the hw block count, downscaling filters used and the ratios supported. Add a custom dnsc_blur property to allow usermode to send the required configuration to program the hardware. Expose only for the virtual connector as the dnsc_blur is only supported with writeback block. Change-Id: I35dd263d9d5aafdb59bacbb3a0528ffd2bcaf6a3 Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
This commit is contained in:
@@ -200,6 +200,7 @@ enum msm_mdp_conn_property {
|
||||
CONNECTOR_PROP_HDR_METADATA,
|
||||
CONNECTOR_PROP_DEMURA_PANEL_ID,
|
||||
CONNECTOR_PROP_DIMMING_BL_LUT,
|
||||
CONNECTOR_PROP_DNSC_BLUR,
|
||||
|
||||
/* # of blob properties */
|
||||
CONNECTOR_PROP_BLOBCOUNT,
|
||||
|
@@ -84,23 +84,6 @@ static const struct drm_prop_enum_list e_panel_mode[] = {
|
||||
{MSM_DISPLAY_MODE_MAX, "none"},
|
||||
};
|
||||
|
||||
static inline struct sde_kms *_sde_connector_get_kms(struct drm_connector *conn)
|
||||
{
|
||||
struct msm_drm_private *priv;
|
||||
|
||||
if (!conn || !conn->dev || !conn->dev->dev_private) {
|
||||
SDE_ERROR("invalid connector\n");
|
||||
return NULL;
|
||||
}
|
||||
priv = conn->dev->dev_private;
|
||||
if (!priv || !priv->kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return to_sde_kms(priv->kms);
|
||||
}
|
||||
|
||||
static void sde_dimming_bl_notify(struct sde_connector *conn, struct dsi_backlight_config *config)
|
||||
{
|
||||
struct drm_event event;
|
||||
@@ -140,7 +123,7 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
|
||||
int rc = 0;
|
||||
struct sde_kms *sde_kms;
|
||||
|
||||
sde_kms = _sde_connector_get_kms(&c_conn->base);
|
||||
sde_kms = sde_connector_get_kms(&c_conn->base);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return -EINVAL;
|
||||
@@ -234,7 +217,7 @@ static int sde_backlight_setup(struct sde_connector *c_conn,
|
||||
static int display_count;
|
||||
char bl_node_name[BL_NODE_NAME_SIZE];
|
||||
|
||||
sde_kms = _sde_connector_get_kms(&c_conn->base);
|
||||
sde_kms = sde_connector_get_kms(&c_conn->base);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return -EINVAL;
|
||||
@@ -445,7 +428,7 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn,
|
||||
struct drm_encoder *drm_enc = NULL;
|
||||
struct sde_connector *sde_conn;
|
||||
|
||||
sde_kms = _sde_connector_get_kms(conn);
|
||||
sde_kms = sde_connector_get_kms(conn);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return;
|
||||
@@ -1103,7 +1086,7 @@ void sde_connector_helper_bridge_disable(struct drm_connector *connector)
|
||||
bool poms_pending = false;
|
||||
struct sde_kms *sde_kms;
|
||||
|
||||
sde_kms = _sde_connector_get_kms(connector);
|
||||
sde_kms = sde_connector_get_kms(connector);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return;
|
||||
@@ -1149,7 +1132,7 @@ void sde_connector_helper_bridge_enable(struct drm_connector *connector)
|
||||
struct dsi_display *display;
|
||||
struct sde_kms *sde_kms;
|
||||
|
||||
sde_kms = _sde_connector_get_kms(connector);
|
||||
sde_kms = sde_connector_get_kms(connector);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return;
|
||||
@@ -2182,7 +2165,7 @@ static ssize_t _sde_debugfs_conn_cmd_tx_write(struct file *file,
|
||||
}
|
||||
c_conn = to_sde_connector(connector);
|
||||
|
||||
sde_kms = _sde_connector_get_kms(&c_conn->base);
|
||||
sde_kms = sde_connector_get_kms(&c_conn->base);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return -EINVAL;
|
||||
@@ -2704,7 +2687,7 @@ const char *sde_conn_get_topology_name(struct drm_connector *conn,
|
||||
struct sde_kms *sde_kms;
|
||||
int topology_idx = 0;
|
||||
|
||||
sde_kms = _sde_connector_get_kms(conn);
|
||||
sde_kms = sde_connector_get_kms(conn);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return NULL;
|
||||
@@ -2831,7 +2814,7 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
|
||||
const char *topo_name = NULL;
|
||||
int rc = 0;
|
||||
|
||||
sde_kms = _sde_connector_get_kms(conn);
|
||||
sde_kms = sde_connector_get_kms(conn);
|
||||
if (!sde_kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return -EINVAL;
|
||||
|
@@ -731,6 +731,29 @@ struct sde_connector_state {
|
||||
#define sde_connector_get_out_fb(S) \
|
||||
((S) ? to_sde_connector_state((S))->out_fb : 0)
|
||||
|
||||
/**
|
||||
* sde_connector_get_kms - helper to get sde_kms from connector
|
||||
* @conn: Pointer to drm connector
|
||||
* Returns: Pointer to sde_kms or NULL
|
||||
*/
|
||||
static inline struct sde_kms *sde_connector_get_kms(struct drm_connector *conn)
|
||||
{
|
||||
struct msm_drm_private *priv;
|
||||
|
||||
if (!conn || !conn->dev || !conn->dev->dev_private) {
|
||||
SDE_ERROR("invalid connector\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
priv = conn->dev->dev_private;
|
||||
if (!priv->kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return to_sde_kms(priv->kms);
|
||||
}
|
||||
|
||||
/**
|
||||
* sde_connector_get_topology_name - helper accessor to retrieve topology_name
|
||||
* @connector: pointer to drm connector
|
||||
|
@@ -584,6 +584,19 @@ void sde_kms_info_append_format(struct sde_kms_info *info,
|
||||
uint32_t pixel_format,
|
||||
uint64_t modifier);
|
||||
|
||||
/**
|
||||
* sde_kms_info_append_dnsc_blur_filter_info - append dnsc_blur filters code to 'sde_kms_info'
|
||||
* Usage:
|
||||
* sde_kms_info_start(key)
|
||||
* sde_kms_info_append_dnsc_blur_filter_info(info, ratio)
|
||||
* ...
|
||||
* sde_kms_info_stop
|
||||
* @info: Pointer to sde_kms_info structure
|
||||
* @filter: Pointer to dnsc_blur filter info
|
||||
*/
|
||||
void sde_kms_info_append_dnsc_blur_filter_info(struct sde_kms_info *info,
|
||||
struct sde_dnsc_blur_filter_info *filter);
|
||||
|
||||
/**
|
||||
* sde_kms_info_stop - finish adding key to 'sde_kms_info'
|
||||
* Usage:
|
||||
|
@@ -167,6 +167,40 @@ void sde_kms_info_stop(struct sde_kms_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
void sde_kms_info_append_dnsc_blur_filter_info(struct sde_kms_info *info,
|
||||
struct sde_dnsc_blur_filter_info *filter_info)
|
||||
{
|
||||
int i;
|
||||
uint32_t len, cur_len;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
len = snprintf(info->data + info->staged_len, SDE_KMS_INFO_MAX_SIZE - info->staged_len,
|
||||
info->start ?
|
||||
"%c/%c/%c/%c/%c/%c/%c/%c/%c/" : " %c/%c/%c/%c/%c/%c/%c/%c/%c/",
|
||||
filter_info->filter & 0xFF, filter_info->src_min & 0xFF,
|
||||
filter_info->src_max & 0xFF, filter_info->dst_min & 0xFF,
|
||||
filter_info->dst_max & 0xFF, filter_info->min_ratio & 0xFF,
|
||||
filter_info->max_ratio & 0xFF, filter_info->fraction_support & 0xFF,
|
||||
filter_info->ratio_count & 0xFF);
|
||||
|
||||
cur_len = len;
|
||||
for (i = 0; i < filter_info->ratio_count; i++) {
|
||||
len = snprintf(info->data + (info->staged_len + cur_len),
|
||||
SDE_KMS_INFO_MAX_SIZE - (info->staged_len + cur_len),
|
||||
(i == filter_info->ratio_count - 1) ? "%c" : "%c,",
|
||||
filter_info->ratio[i]);
|
||||
cur_len += len;
|
||||
}
|
||||
|
||||
/* check if snprintf truncated the string */
|
||||
if ((info->staged_len + cur_len) < SDE_KMS_INFO_MAX_SIZE) {
|
||||
info->staged_len += cur_len;
|
||||
info->start = false;
|
||||
}
|
||||
}
|
||||
|
||||
void sde_kms_rect_intersect(const struct sde_rect *r1,
|
||||
const struct sde_rect *r2,
|
||||
struct sde_rect *result)
|
||||
|
@@ -416,40 +416,36 @@ 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;
|
||||
struct sde_kms *sde_kms;
|
||||
struct sde_mdss_cfg *catalog;
|
||||
int i;
|
||||
|
||||
if (!connector || !info || !display || !wb_dev->wb_cfg) {
|
||||
SDE_ERROR("invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_kms = sde_connector_get_kms(connector);
|
||||
if (!sde_kms)
|
||||
return -EINVAL;
|
||||
catalog = sde_kms->catalog;
|
||||
|
||||
format_list = wb_dev->wb_cfg->format_list;
|
||||
|
||||
/*
|
||||
* Populate info buffer
|
||||
*/
|
||||
/* Populate info buffer */
|
||||
if (format_list) {
|
||||
sde_kms_info_start(info, "pixel_formats");
|
||||
while (format_list->fourcc_format) {
|
||||
sde_kms_info_append_format(info,
|
||||
format_list->fourcc_format,
|
||||
sde_kms_info_append_format(info, format_list->fourcc_format,
|
||||
format_list->modifier);
|
||||
++format_list;
|
||||
}
|
||||
sde_kms_info_stop(info);
|
||||
}
|
||||
|
||||
sde_kms_info_add_keyint(info,
|
||||
"wb_intf_index",
|
||||
wb_dev->wb_idx - WB_0);
|
||||
|
||||
sde_kms_info_add_keyint(info,
|
||||
"maxlinewidth",
|
||||
wb_dev->wb_cfg->sblk->maxlinewidth);
|
||||
|
||||
sde_kms_info_add_keyint(info,
|
||||
"maxlinewidth_linear",
|
||||
sde_kms_info_add_keyint(info, "wb_intf_index", wb_dev->wb_idx - WB_0);
|
||||
sde_kms_info_add_keyint(info, "maxlinewidth", wb_dev->wb_cfg->sblk->maxlinewidth);
|
||||
sde_kms_info_add_keyint(info, "maxlinewidth_linear",
|
||||
wb_dev->wb_cfg->sblk->maxlinewidth_linear);
|
||||
|
||||
sde_kms_info_start(info, "features");
|
||||
@@ -457,64 +453,39 @@ 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", test_bit(SDE_FEATURE_CWB_DITHER,
|
||||
sde_kms->catalog->features));
|
||||
} else {
|
||||
SDE_ERROR("invalid params %pK\n", wb_dev->drm_dev);
|
||||
return -EINVAL;
|
||||
catalog->features));
|
||||
|
||||
if (catalog->dnsc_blur_count && catalog->dnsc_blur_filters) {
|
||||
sde_kms_info_add_keyint(info, "dnsc_blur_count", catalog->dnsc_blur_count);
|
||||
|
||||
sde_kms_info_start(info, "dnsc_blur_info");
|
||||
for (i = 0; i < catalog->dnsc_blur_filter_count; i++)
|
||||
sde_kms_info_append_dnsc_blur_filter_info(info,
|
||||
&catalog->dnsc_blur_filters[i]);
|
||||
sde_kms_info_stop(info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sde_wb_connector_install_dither_property(struct sde_wb_device *wb_dev,
|
||||
struct sde_connector *c_conn)
|
||||
static void _sde_wb_connector_install_dither_property(struct sde_wb_device *wb_dev)
|
||||
{
|
||||
struct sde_connector *c_conn = to_sde_connector(wb_dev->connector);
|
||||
struct sde_kms *sde_kms = sde_connector_get_kms(wb_dev->connector);
|
||||
struct sde_mdss_cfg *catalog;
|
||||
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);
|
||||
if (!sde_kms || !sde_kms->catalog)
|
||||
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 (!test_bit(SDE_FEATURE_CWB_DITHER, catalog->features))
|
||||
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);
|
||||
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,
|
||||
@@ -591,7 +562,12 @@ int sde_wb_connector_post_init(struct drm_connector *connector, void *display)
|
||||
msm_property_install_range(&c_conn->property_info, "early_fence_line",
|
||||
0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_EARLY_FENCE_LINE);
|
||||
|
||||
sde_wb_connector_install_dither_property(wb_dev, c_conn);
|
||||
if (catalog->dnsc_blur_count && catalog->dnsc_blur_filters)
|
||||
msm_property_install_range(&c_conn->property_info, "dnsc_blur",
|
||||
0x0, 0, ~0, 0, CONNECTOR_PROP_DNSC_BLUR);
|
||||
|
||||
_sde_wb_connector_install_dither_property(wb_dev);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user