disp: msm: add panel's param feature to display FW

Add the display's param feature such as HBM, ACL, or CABC feature to
display framework

Port from: f988eb8

Change-Id: I445ea7e58188d2354888e2202ed7119bf2e55fc9
Signed-off-by: Bang Nguyen <bangnguyen@motorola.com>
Reviewed-on: https://gerrit.mot.com/1444400
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1509802
Reviewed-by: Hua Tan <tanhua1@motorola.com>
This commit is contained in:
Bang Nguyen authored and Gilberto Gambugge committed 2023-06-01 00:43:20 -03:00
1 parent e0ac15bcc0
commit fa247f6d83
9 files changed
+328 -1

No files matched your search

+4
View File
@@ -281,6 +281,8 @@ enum dsi_dyn_clk_feature_type {
* @DSI_CMD_SET_POST_TIMING_SWITCH: Post timing switch
* @DSI_CMD_SET_QSYNC_ON Enable qsync mode
* @DSI_CMD_SET_QSYNC_OFF Disable qsync mode
* @DSI_CMD_SET_HBM_ON: Turning HBM on
* @DSI_CMD_SET_HBM_OFF: Turning HBM off
* @DSI_CMD_SET_MAX
*/
enum dsi_cmd_set_type {
@@ -307,6 +309,8 @@ enum dsi_cmd_set_type {
DSI_CMD_SET_POST_TIMING_SWITCH,
DSI_CMD_SET_QSYNC_ON,
DSI_CMD_SET_QSYNC_OFF,
DSI_CMD_SET_HBM_ON,
DSI_CMD_SET_HBM_OFF,
DSI_CMD_SET_MAX
};
+22
View File
@@ -246,6 +246,28 @@ error:
return rc;
}
int dsi_display_set_param(void *display, struct msm_param_info *param_info)
{
struct dsi_display *dsi_display = display;
struct dsi_panel *panel;
int rc = 0;
if (dsi_display == NULL || dsi_display->panel == NULL)
return -EINVAL;
panel = dsi_display->panel;
DSI_DEBUG("%s+\n", __func__);
if (!dsi_panel_initialized(panel))
return -EINVAL;
rc = dsi_panel_set_param(panel, param_info);
if (rc)
DSI_ERR("[%s] failed to panel to set param. rc=%d\n",
dsi_display->name, rc);
return rc;
}
static int dsi_display_cmd_engine_enable(struct dsi_display *display)
{
int rc = 0;
+2
View File
@@ -563,6 +563,8 @@ int dsi_post_clkoff_cb(void *priv, enum dsi_clk_type clk_type,
enum dsi_lclk_type l_type,
enum dsi_clk_state curr_state);
int dsi_display_set_param(void *display, struct msm_param_info *param_info);
/**
* dsi_post_clkon_cb() - Callback after clock is turned on
* @priv: private data pointer.
+175
View File
@@ -101,6 +101,15 @@ static char dsi_dsc_rc_range_max_qp_1_1_scr1[][15] = {
static char dsi_dsc_rc_range_bpg_offset[] = {2, 0, 0, -2, -4, -6, -8, -8,
-8, -10, -10, -12, -12, -12, -12};
static struct panel_param_val_map hbm_map[HBM_STATE_NUM] = {
{HBM_OFF_STATE, DSI_CMD_SET_HBM_OFF, NULL},
{HBM_ON_STATE, DSI_CMD_SET_HBM_ON, NULL},
};
static struct panel_param dsi_panel_param[PARAM_ID_NUM] = {
{"HBM", hbm_map, HBM_STATE_NUM, HBM_OFF_STATE, HBM_OFF_STATE, false},
};
int dsi_dsc_create_pps_buf_cmd(struct msm_display_dsc_info *dsc, char *buf,
int pps_id)
{
@@ -830,6 +839,100 @@ static int dsi_panel_pwm_register(struct dsi_panel *panel)
return 0;
}
static int dsi_panel_send_param_cmd (struct dsi_panel *panel,
struct msm_param_info *param_info)
{
int rc = 0;
struct panel_param_val_map *param_map;
struct panel_param_val_map *param_map_state;
struct panel_param *panel_param;
struct dsi_cmd_desc *cmds;
ssize_t len;
const struct mipi_dsi_host_ops *ops = panel->host->ops;
panel_param = &panel->param_cmds[param_info->param_idx];
if (!panel_param) {
DSI_ERR("%s: invalid panel_param.\n", __func__);
return -EINVAL;
}
param_map = panel_param->val_map;
DSI_DEBUG("%s: param_name=%s; val_max =%d, default_value=%d, value=%d\n",
__func__, panel_param->param_name, panel_param->val_max,
panel_param->default_value, panel_param->value);
mutex_lock(&panel->panel_lock);
if (panel_param->value == param_info->value)
{
DSI_INFO("%s(mode=%d): requested value=%d is same. Do nothing\n",
__func__, param_info->param_idx, param_info->value);
rc = 0;
} else {
DSI_DEBUG("%s: requested: old=%d new=%d.\n", __func__,
panel_param->value, param_info->value);
param_map = panel->param_cmds[param_info->param_idx].val_map;
param_map_state = &param_map[param_info->value];
cmds = param_map_state->cmds->cmds;
if (param_map_state->cmds->state == DSI_CMD_SET_STATE_LP)
cmds->msg.flags |= MIPI_DSI_MSG_USE_LPM |
MIPI_DSI_MSG_LASTCOMMAND;
len = ops->transfer(panel->host, &cmds->msg);
if (len < 0) {
rc = len;
DSI_ERR("%s:failed to send param cmd, rc=%d\n",
__func__, rc);
goto end;
}
panel_param->value = param_info->value;
DSI_INFO("%s(%d) is setting new value %d\n", __func__,
param_info->param_idx, param_info->value);
rc = len;
}
end:
mutex_unlock(&panel->panel_lock);
return rc;
};
static int dsi_panel_set_hbm(struct dsi_panel *panel,
struct msm_param_info *param_info)
{
int rc = 0;
pr_info("%s(%d)\n", __func__, param_info->value);
rc = dsi_panel_send_param_cmd(panel, param_info);
if (rc < 0)
DSI_ERR("%s: failed to send param cmds. ret=%d\n", __func__, rc);
return rc;
};
int dsi_panel_set_param(struct dsi_panel *panel,
struct msm_param_info *param_info)
{
int rc = 0;
if (!panel || !param_info) {
DSI_ERR("invalid params\n");
return -EINVAL;
}
DSI_DEBUG("%s+\n", __func__);
if (param_info->param_idx == PARAM_HBM_ID)
rc = dsi_panel_set_hbm(panel, param_info);
else {
DSI_ERR("%s: Invalid set_param type=%d\n",
__func__, param_info->param_idx);
rc = -EINVAL;
}
return rc;
}
static int dsi_panel_bl_register(struct dsi_panel *panel)
{
int rc = 0;
@@ -1888,6 +1991,9 @@ const char *cmd_set_prop_map[DSI_CMD_SET_MAX] = {
"qcom,mdss-dsi-post-mode-switch-on-command",
"qcom,mdss-dsi-qsync-on-commands",
"qcom,mdss-dsi-qsync-off-commands",
"qcom,mdss-dsi-hbm-on-command",
"qcom,mdss-dsi-hbm-off-command",
};
const char *cmd_set_state_map[DSI_CMD_SET_MAX] = {
@@ -1914,6 +2020,8 @@ const char *cmd_set_state_map[DSI_CMD_SET_MAX] = {
"qcom,mdss-dsi-post-mode-switch-on-command-state",
"qcom,mdss-dsi-qsync-on-commands-state",
"qcom,mdss-dsi-qsync-off-commands-state",
"qcom,mdss-dsi-hbm-on-command-state",
"qcom,mdss-dsi-hbm-off-command-state",
};
static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt)
@@ -3429,6 +3537,68 @@ end:
utils->node = panel->panel_of_node;
}
static int dsi_panel_parse_param_prop(struct dsi_panel *panel,
struct device_node *of_node)
{
int i, j, rc =0;
struct panel_param *param;
struct panel_param_val_map *param_map;
struct dsi_panel_cmd_set *cmds;
enum dsi_cmd_set_type type;
const char *prop;
struct dsi_parser_utils *utils = &panel->utils;
for (i = 0; i < PARAM_ID_NUM; i++) {
param = &dsi_panel_param[i];
for (j = 0; j < param->val_max; j++) {
param_map = &param->val_map[j];
param_map->cmds = NULL;
cmds = kcalloc(param->val_max,
sizeof(struct dsi_panel_cmd_set), GFP_KERNEL);
if (cmds == NULL) {
rc = -ENOMEM;
goto err;
}
param_map->cmds = cmds;
type = param_map->type;
prop = cmd_set_prop_map[type];
if (!prop)
continue;
rc = dsi_panel_parse_cmd_sets_sub(param_map->cmds,
type, utils);
if (rc) {
DSI_ERR("panel param cmd %s parsing failed\n",
param->param_name);
rc = -EINVAL;
goto parse_err;
}
}
param->is_supported = true;
DSI_INFO("%s: feature enabled.\n", param->param_name);
}
return rc;
parse_err:
for (i = 0; i < ARRAY_SIZE(dsi_panel_param); i++) {
param = &dsi_panel_param[i];
for (j = 0; j < param->val_max; j++) {
if (param->val_map[j].cmds) {
kfree(param->val_map[j].cmds);
param->val_map[j].cmds= NULL;
}
}
param->is_supported = false;
}
err:
return rc;
}
static int dsi_panel_parse_mot_panel_config(struct dsi_panel *panel,
struct device_node *of_node)
{
@@ -3555,6 +3725,11 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
if (rc)
DSI_DEBUG("failed to parse mot_panel_config, rc = %d\n", rc);
panel->param_cmds = &dsi_panel_param[0];
rc = dsi_panel_parse_param_prop(panel, of_node);
if (rc)
pr_debug("failed to parse panel param prop, rc =%d\n", rc);
rc = dsi_panel_parse_host_config(panel);
if (rc) {
DSI_ERR("failed to parse host configuration, rc=%d\n",
+29 -1
View File
@@ -28,7 +28,6 @@
#define DSI_MODE_MAX 32
#define DSI_PANEL_MAX_PANEL_LEN 256
/*
* Defining custom dsi msg flag,
@@ -37,6 +36,9 @@
*/
#define MIPI_DSI_MSG_ASYNC_OVERRIDE BIT(4)
#define DSI_PANEL_MAX_PANEL_LEN 256
#define MAX_PARAM_NAME 10
enum dsi_panel_rotation {
DSI_PANEL_ROTATE_NONE = 0,
DSI_PANEL_ROTATE_HV_FLIP,
@@ -176,6 +178,27 @@ struct drm_panel_esd_config {
u32 groups;
};
enum hbm_state {
HBM_OFF_STATE = 0,
HBM_ON_STATE,
HBM_STATE_NUM
};
struct panel_param_val_map {
int state;
enum dsi_cmd_set_type type;
struct dsi_panel_cmd_set *cmds;
};
struct panel_param {
const char *param_name;
struct panel_param_val_map *val_map;
const u16 val_max;
const u16 default_value;
u16 value;
bool is_supported;
};
struct dsi_panel {
const char *name;
const char *type;
@@ -236,6 +259,8 @@ struct dsi_panel {
u32 disp_on_chk_val;
bool no_panel_on_read_support;
struct panel_param *param_cmds;
};
static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel)
@@ -356,4 +381,7 @@ void dsi_panel_ext_bridge_put(struct dsi_panel *panel);
void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config,
struct dsi_display_mode *mode, u32 frame_threshold_us);
int dsi_panel_set_param(struct dsi_panel *panel,
struct msm_param_info *param_info);
#endif /* _DSI_PANEL_H_ */
+13
View File
@@ -202,6 +202,8 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_QSYNC_MODE,
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
/* MOT feature panel*/
CONNECTOR_PROP_HBM,
/* total # of properties */
CONNECTOR_PROP_COUNT
};
@@ -310,6 +312,17 @@ struct msm_roi_caps {
struct msm_roi_alignment align;
};
enum msm_param_id {
PARAM_HBM_ID = 0,
PARAM_ID_NUM
};
struct msm_param_info {
enum msm_param_id param_idx;
enum msm_mdp_conn_property param_conn_idx;
int value;
};
/**
* struct msm_display_dsc_info - defines dsc configuration
* @version: DSC version.
+73
View File
@@ -692,6 +692,24 @@ static int _sde_connector_update_hdr_metadata(struct sde_connector *c_conn,
return rc;
}
static int _sde_connector_update_param(struct sde_connector *c_conn,
struct msm_param_info *param_info)
{
struct dsi_display *dsi_display;
int rc = 0;
if (!c_conn) {
SDE_ERROR("Invalid params sde_connector null\n");
return -EINVAL;
}
dsi_display = c_conn->display;
if (dsi_display && c_conn->ops.set_param)
rc = c_conn->ops.set_param(dsi_display, param_info);
return rc;
}
static int _sde_connector_update_dirty_properties(
struct drm_connector *connector)
{
@@ -1362,6 +1380,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
int idx, rc;
uint64_t fence_user_fd;
uint64_t __user prev_user_fd;
struct msm_param_info param_info;
if (!connector || !state || !property) {
SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n",
@@ -1471,6 +1490,13 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
msm_property_set_dirty(&c_conn->property_info,
&c_state->property_state, idx);
break;
case CONNECTOR_PROP_HBM:
param_info.value = sde_connector_get_property(
connector->state, CONNECTOR_PROP_HBM);
param_info.param_idx = PARAM_HBM_ID;
param_info.param_conn_idx = CONNECTOR_PROP_HBM;
_sde_connector_update_param(c_conn, &param_info);
break;
default:
break;
}
@@ -2353,6 +2379,45 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
return rc;
}
static int sde_connector_install_panel_params(struct sde_connector *c_conn)
{
struct panel_param *param_cmds;
uint32_t prop_idx;
int i;
struct dsi_display *dsi_display;
if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI)
return 0;
dsi_display = (struct dsi_display *) (c_conn->display);
param_cmds = dsi_display->panel->param_cmds;
for (i = 0; i < PARAM_ID_NUM; i++) {
SDE_DEBUG("%s:i = %d param_name = %s is_support=%d\n",
__func__, i,
param_cmds->param_name, param_cmds->is_supported);
if (!strncmp(param_cmds->param_name, "HBM", 3))
prop_idx = CONNECTOR_PROP_HBM;
else {
SDE_ERROR("Invalid param_name =%s\n",
param_cmds->param_name);
return -EINVAL;
}
if (param_cmds->is_supported)
msm_property_install_volatile_range(
&c_conn->property_info,
param_cmds->param_name,
0x0, 0, param_cmds->val_max,
param_cmds->default_value, prop_idx);
param_cmds++;
}
return 0;
}
int sde_connector_set_blob_data(struct drm_connector *conn,
struct drm_connector_state *state,
enum msm_mdp_conn_property prop_id)
@@ -2683,6 +2748,14 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
}
}
rc = sde_connector_install_panel_params(c_conn);
if (rc) {
SDE_ERROR_CONN(c_conn,
"failed to install property for panel params. rc =%d\n",
rc);
goto error_cleanup_fence;
}
rc = sde_connector_get_info(&c_conn->base, &display_info);
if (!rc && (connector_type == DRM_MODE_CONNECTOR_DSI) &&
(display_info.capabilities & MSM_DISPLAY_CAP_VID_MODE))
+7
View File
@@ -284,6 +284,13 @@ struct sde_connector_ops {
*/
bool (*force_esd_disable)(void *display);
/**
* set_param - set display's feature param setting
* @display: Pointer to private display handle
* Returns: Zero for success, negative for failure
*/
int (*set_param)(void *display, struct msm_param_info *param_info);
/**
* config_hdr - configure HDR
* @connector: Pointer to drm connector structure
+3
View File
@@ -1438,6 +1438,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.motUtil_transfer = dsi_display_motUtil_transfer,
.cmd_transfer = dsi_display_cmd_transfer,
.force_esd_disable = dsi_display_force_esd_disable,
.set_param = dsi_display_set_param,
.cont_splash_config = dsi_display_cont_splash_config,
.get_panel_vfp = dsi_display_get_panel_vfp,
.get_default_lms = dsi_display_get_default_lms,
@@ -1456,6 +1457,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.check_status = NULL,
.cmd_transfer = NULL,
.force_esd_disable = NULL,
.set_param = NULL,
.cont_splash_config = NULL,
.get_panel_vfp = NULL,
};
@@ -1474,6 +1476,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.config_hdr = dp_connector_config_hdr,
.cmd_transfer = NULL,
.force_esd_disable = NULL,
.set_param = NULL,
.cont_splash_config = NULL,
.get_panel_vfp = NULL,
.update_pps = dp_connector_update_pps,