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:
1 parent
e0ac15bcc0
commit
fa247f6d83
9 files changed
+328
-1
No files matched your search
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 = ¶m_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 = ¶m->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
@@ -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_ */
|
||||
@@ -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.
|
||||
|
||||
@@ -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, ¶m_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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user