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:
Veera Sundaram Sankaran
2021-09-13 21:34:32 -07:00
parent c24dd3d172
commit 93ec98a33e
6 changed files with 115 additions and 85 deletions

View File

@@ -200,6 +200,7 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_HDR_METADATA, CONNECTOR_PROP_HDR_METADATA,
CONNECTOR_PROP_DEMURA_PANEL_ID, CONNECTOR_PROP_DEMURA_PANEL_ID,
CONNECTOR_PROP_DIMMING_BL_LUT, CONNECTOR_PROP_DIMMING_BL_LUT,
CONNECTOR_PROP_DNSC_BLUR,
/* # of blob properties */ /* # of blob properties */
CONNECTOR_PROP_BLOBCOUNT, CONNECTOR_PROP_BLOBCOUNT,

View File

@@ -84,23 +84,6 @@ static const struct drm_prop_enum_list e_panel_mode[] = {
{MSM_DISPLAY_MODE_MAX, "none"}, {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) static void sde_dimming_bl_notify(struct sde_connector *conn, struct dsi_backlight_config *config)
{ {
struct drm_event event; struct drm_event event;
@@ -140,7 +123,7 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
int rc = 0; int rc = 0;
struct sde_kms *sde_kms; 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) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return -EINVAL; return -EINVAL;
@@ -234,7 +217,7 @@ static int sde_backlight_setup(struct sde_connector *c_conn,
static int display_count; static int display_count;
char bl_node_name[BL_NODE_NAME_SIZE]; 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) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return -EINVAL; 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 drm_encoder *drm_enc = NULL;
struct sde_connector *sde_conn; struct sde_connector *sde_conn;
sde_kms = _sde_connector_get_kms(conn); sde_kms = sde_connector_get_kms(conn);
if (!sde_kms) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return; return;
@@ -1103,7 +1086,7 @@ void sde_connector_helper_bridge_disable(struct drm_connector *connector)
bool poms_pending = false; bool poms_pending = false;
struct sde_kms *sde_kms; struct sde_kms *sde_kms;
sde_kms = _sde_connector_get_kms(connector); sde_kms = sde_connector_get_kms(connector);
if (!sde_kms) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return; return;
@@ -1149,7 +1132,7 @@ void sde_connector_helper_bridge_enable(struct drm_connector *connector)
struct dsi_display *display; struct dsi_display *display;
struct sde_kms *sde_kms; struct sde_kms *sde_kms;
sde_kms = _sde_connector_get_kms(connector); sde_kms = sde_connector_get_kms(connector);
if (!sde_kms) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return; return;
@@ -2182,7 +2165,7 @@ static ssize_t _sde_debugfs_conn_cmd_tx_write(struct file *file,
} }
c_conn = to_sde_connector(connector); 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) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return -EINVAL; return -EINVAL;
@@ -2704,7 +2687,7 @@ const char *sde_conn_get_topology_name(struct drm_connector *conn,
struct sde_kms *sde_kms; struct sde_kms *sde_kms;
int topology_idx = 0; int topology_idx = 0;
sde_kms = _sde_connector_get_kms(conn); sde_kms = sde_connector_get_kms(conn);
if (!sde_kms) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return NULL; return NULL;
@@ -2831,7 +2814,7 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
const char *topo_name = NULL; const char *topo_name = NULL;
int rc = 0; int rc = 0;
sde_kms = _sde_connector_get_kms(conn); sde_kms = sde_connector_get_kms(conn);
if (!sde_kms) { if (!sde_kms) {
SDE_ERROR("invalid kms\n"); SDE_ERROR("invalid kms\n");
return -EINVAL; return -EINVAL;

View File

@@ -731,6 +731,29 @@ struct sde_connector_state {
#define sde_connector_get_out_fb(S) \ #define sde_connector_get_out_fb(S) \
((S) ? to_sde_connector_state((S))->out_fb : 0) ((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 * sde_connector_get_topology_name - helper accessor to retrieve topology_name
* @connector: pointer to drm connector * @connector: pointer to drm connector

View File

@@ -584,6 +584,19 @@ void sde_kms_info_append_format(struct sde_kms_info *info,
uint32_t pixel_format, uint32_t pixel_format,
uint64_t modifier); 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' * sde_kms_info_stop - finish adding key to 'sde_kms_info'
* Usage: * Usage:

View File

@@ -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, void sde_kms_rect_intersect(const struct sde_rect *r1,
const struct sde_rect *r2, const struct sde_rect *r2,
struct sde_rect *result) struct sde_rect *result)

View File

@@ -416,40 +416,36 @@ int sde_wb_connector_set_info_blob(struct drm_connector *connector,
{ {
struct sde_wb_device *wb_dev = display; struct sde_wb_device *wb_dev = display;
const struct sde_format_extended *format_list; const struct sde_format_extended *format_list;
struct msm_drm_private *priv = NULL; struct sde_kms *sde_kms;
struct sde_kms *sde_kms = NULL; struct sde_mdss_cfg *catalog;
int i;
if (!connector || !info || !display || !wb_dev->wb_cfg) { if (!connector || !info || !display || !wb_dev->wb_cfg) {
SDE_ERROR("invalid params\n"); SDE_ERROR("invalid params\n");
return -EINVAL; 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; format_list = wb_dev->wb_cfg->format_list;
/* /* Populate info buffer */
* Populate info buffer
*/
if (format_list) { if (format_list) {
sde_kms_info_start(info, "pixel_formats"); sde_kms_info_start(info, "pixel_formats");
while (format_list->fourcc_format) { while (format_list->fourcc_format) {
sde_kms_info_append_format(info, sde_kms_info_append_format(info, format_list->fourcc_format,
format_list->fourcc_format,
format_list->modifier); format_list->modifier);
++format_list; ++format_list;
} }
sde_kms_info_stop(info); sde_kms_info_stop(info);
} }
sde_kms_info_add_keyint(info, sde_kms_info_add_keyint(info, "wb_intf_index", wb_dev->wb_idx - WB_0);
"wb_intf_index", sde_kms_info_add_keyint(info, "maxlinewidth", wb_dev->wb_cfg->sblk->maxlinewidth);
wb_dev->wb_idx - WB_0); sde_kms_info_add_keyint(info, "maxlinewidth_linear",
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); wb_dev->wb_cfg->sblk->maxlinewidth_linear);
sde_kms_info_start(info, "features"); 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_append(info, "wb_ubwc");
sde_kms_info_stop(info); sde_kms_info_stop(info);
if (wb_dev->drm_dev && wb_dev->drm_dev->dev_private) { sde_kms_info_add_keyint(info, "has_cwb_dither", test_bit(SDE_FEATURE_CWB_DITHER,
priv = wb_dev->drm_dev->dev_private; catalog->features));
if (!priv->kms) {
SDE_ERROR("invalid kms reference\n");
return -EINVAL;
}
sde_kms = to_sde_kms(priv->kms); if (catalog->dnsc_blur_count && catalog->dnsc_blur_filters) {
sde_kms_info_add_keyint(info, "has_cwb_dither", test_bit(SDE_FEATURE_CWB_DITHER, sde_kms_info_add_keyint(info, "dnsc_blur_count", catalog->dnsc_blur_count);
sde_kms->catalog->features));
} else { sde_kms_info_start(info, "dnsc_blur_info");
SDE_ERROR("invalid params %pK\n", wb_dev->drm_dev); for (i = 0; i < catalog->dnsc_blur_filter_count; i++)
return -EINVAL; sde_kms_info_append_dnsc_blur_filter_info(info,
&catalog->dnsc_blur_filters[i]);
sde_kms_info_stop(info);
} }
return 0; return 0;
} }
static void sde_wb_connector_install_dither_property(struct sde_wb_device *wb_dev, static void _sde_wb_connector_install_dither_property(struct sde_wb_device *wb_dev)
struct sde_connector *c_conn)
{ {
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]; 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; u32 version = 0;
if (!wb_dev || !c_conn) { if (!sde_kms || !sde_kms->catalog)
SDE_ERROR("invalid args (s), wb_dev %pK, c_conn %pK\n", wb_dev, c_conn);
return; 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; catalog = sde_kms->catalog;
if (!test_bit(SDE_FEATURE_CWB_DITHER, catalog->features)) if (!test_bit(SDE_FEATURE_CWB_DITHER, catalog->features))
return; return;
version = SDE_COLOR_PROCESS_MAJOR( version = SDE_COLOR_PROCESS_MAJOR(catalog->pingpong[0].sblk->dither.version);
catalog->pingpong[0].sblk->dither.version); snprintf(prop_name, ARRAY_SIZE(prop_name), "%s%d", "SDE_PP_CWB_DITHER_V", version);
snprintf(prop_name, ARRAY_SIZE(prop_name), "%s%d",
"SDE_PP_CWB_DITHER_V", version);
switch (version) { switch (version) {
case 2: case 2:
msm_property_install_blob(&c_conn->property_info, prop_name, 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", msm_property_install_range(&c_conn->property_info, "early_fence_line",
0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_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; return 0;
} }