disp: msm: Adding KMS property testing for motUtil tool

Adding the KMS property (HBM/ACL) testing functionality to
motUtil tool so these KMS property can be tested and verified as
standalone without supporting of the Android FW apk.

Port from: b345943

Change-Id: I825a1450f5b151025cc005fe45748bbae40c30bc
Signed-off-by: Bang Nguyen <bangnguyen@motorola.com>
Reviewed-on: https://gerrit.mot.com/1444401
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1509803
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 fa247f6d83
commit a07dfdc7ca
6 files changed
+282 -40

No files matched your search

+27 -9
View File
@@ -106,8 +106,11 @@ static struct panel_param_val_map hbm_map[HBM_STATE_NUM] = {
{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},
static struct panel_param dsi_panel_param[PANEL_IDX_MAX][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,
@@ -839,7 +842,7 @@ static int dsi_panel_pwm_register(struct dsi_panel *panel)
return 0;
}
static int dsi_panel_send_param_cmd (struct dsi_panel *panel,
static int dsi_panel_send_param_cmd(struct dsi_panel *panel,
struct msm_param_info *param_info)
{
int rc = 0;
@@ -874,6 +877,12 @@ static int dsi_panel_send_param_cmd (struct dsi_panel *panel,
param_map = panel->param_cmds[param_info->param_idx].val_map;
param_map_state = &param_map[param_info->value];
if (!param_map_state->cmds || !param_map_state->cmds->cmds) {
DSI_ERR("Invalid cmds or cmds->cmds\n");
rc = -EINVAL;
goto end;
}
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 |
@@ -3538,7 +3547,7 @@ end:
}
static int dsi_panel_parse_param_prop(struct dsi_panel *panel,
struct device_node *of_node)
struct device_node *of_node, u32 param_idx)
{
int i, j, rc =0;
struct panel_param *param;
@@ -3549,9 +3558,15 @@ static int dsi_panel_parse_param_prop(struct dsi_panel *panel,
struct dsi_parser_utils *utils = &panel->utils;
for (i = 0; i < PARAM_ID_NUM; i++) {
param = &dsi_panel_param[i];
param = &dsi_panel_param[param_idx][i];
for (j = 0; j < param->val_max; j++) {
if (!param) {
pr_err("Invalid param\n");
goto err;
}
rc = -EINVAL;
for (j = 0; j < param->val_max && param->val_max > 0 ; j++) {
param_map = &param->val_map[j];
param_map->cmds = NULL;
cmds = kcalloc(param->val_max,
@@ -3577,15 +3592,17 @@ static int dsi_panel_parse_param_prop(struct dsi_panel *panel,
}
}
if (!rc) {
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];
param = &dsi_panel_param[param_idx][i];
for (j = 0; j < param->val_max; j++) {
if (param->val_map[j].cmds) {
kfree(param->val_map[j].cmds);
@@ -3695,6 +3712,7 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
struct dsi_parser_utils *utils;
const char *panel_physical_type;
int rc = 0;
u32 param_idx = 0; /* Since only panel support for now */
panel = kzalloc(sizeof(*panel), GFP_KERNEL);
if (!panel)
@@ -3725,8 +3743,8 @@ 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);
panel->param_cmds = dsi_panel_param[param_idx];
rc = dsi_panel_parse_param_prop(panel, of_node, param_idx );
if (rc)
pr_debug("failed to parse panel param prop, rc =%d\n", rc);
+5
View File
@@ -178,6 +178,11 @@ struct drm_panel_esd_config {
u32 groups;
};
enum panel_idx {
MAIN_IDX = 0,
PANEL_IDX_MAX,
};
enum hbm_state {
HBM_OFF_STATE = 0,
HBM_ON_STATE,
+7
View File
@@ -312,6 +312,13 @@ struct msm_roi_caps {
struct msm_roi_alignment align;
};
enum msm_param_state {
PARAM_STATE_OFF = 0,
PARAM_STATE_ON,
PARAM_STATE_NUM,
PARAM_STATE_DISABLE = 0xFFFF,
};
enum msm_param_id {
PARAM_HBM_ID = 0,
PARAM_ID_NUM
+18 -8
View File
@@ -1495,7 +1495,9 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
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);
rc = _sde_connector_update_param(c_conn, &param_info);
if (rc)
goto end;
break;
default:
break;
@@ -2385,7 +2387,7 @@ static int sde_connector_install_panel_params(struct sde_connector *c_conn)
uint32_t prop_idx;
int i;
struct dsi_display *dsi_display;
u16 prop_max, prop_min, prop_init;
if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI)
return 0;
@@ -2405,12 +2407,20 @@ static int sde_connector_install_panel_params(struct sde_connector *c_conn)
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);
if (param_cmds->is_supported) {
prop_max = param_cmds->val_max;
prop_min = PARAM_STATE_OFF;
prop_init = param_cmds->default_value;
} else {
prop_max = PARAM_STATE_OFF;
prop_min = PARAM_STATE_OFF;
prop_init = PARAM_STATE_DISABLE;
}
msm_property_install_volatile_range( &c_conn->property_info,
param_cmds->param_name, 0x0,
prop_min, prop_max,
prop_init, prop_idx);
param_cmds++;
}
+137 -22
View File
@@ -61,6 +61,7 @@ static ssize_t _sde_debugfs_motUtil_string2num(const char __user *buf,
while (token) {
rc = kstrtoint(token, 0, &strtoint);
if (rc) {
rc = -EIO;
SDE_ERROR("input buffer conversion failed\n");
goto end;
}
@@ -84,13 +85,12 @@ end:
return rc;
}
static struct sde_connector *_sde_debugfs_motUtil_get_sde_conn(
static struct drm_connector *_sde_debugfs_motUtil_get_drm_conn(
struct sde_kms *kms,
size_t count, char input[])
{
struct drm_device *dev = kms->dev;
struct drm_connector *conn = NULL;
struct sde_connector *sde_conn = NULL;
int found_conn = 0;
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
struct drm_connector_list_iter conn_iter;
@@ -113,20 +113,30 @@ static struct sde_connector *_sde_debugfs_motUtil_get_sde_conn(
}
}
if (found_conn) {
SDE_DEBUG("found SDE Connector for %s\n",
(panel_type == MOTUTIL_MAIN_DISP) ?
"Main Display" : "CLI Display");
sde_conn = to_sde_connector(conn);
} else {
SDE_ERROR("Can not find SDE Connector for %s\n",
(panel_type == MOTUTIL_MAIN_DISP) ?
"Main Display" : "CLI Display");
}
drm_connector_list_iter_end(&conn_iter);
mutex_unlock(&dev->mode_config.mutex);
if (found_conn)
return conn;
else
return NULL;
}
static struct sde_connector *_sde_debugfs_motUtil_get_sde_conn(
struct sde_kms *kms,
size_t count, char input[])
{
struct drm_connector *conn = NULL;
struct sde_connector *sde_conn = NULL;
conn = _sde_debugfs_motUtil_get_drm_conn(kms, count, input);
if (conn)
sde_conn = to_sde_connector(conn);
else
DRM_ERROR("Can not find SDE Connector for %s\n",
(input[DISPUTIL_PANEL_TYPE] == MOTUTIL_MAIN_DISP) ?
"Main Display" : "CLI Display");
return sde_conn;
}
@@ -159,7 +169,7 @@ static int _sde_debugfs_motUtil_transfer(struct sde_kms *kms,
mutex_lock(&sde_conn->lock);
ret = sde_conn->ops.motUtil_transfer(sde_conn->display,
input, count, &motUtil_data);
motUtil_data.last_cmd_tx_status = !ret ? true : false;
motUtil_data.cmd_status = ret;
motUtil_data.read_len = ret;
mutex_unlock(&sde_conn->lock);
@@ -171,6 +181,98 @@ end:
}
static int _sde_debugfs_motUtil_kms_prop_test(struct sde_kms *kms,
size_t count, char input[])
{
struct drm_connector *conn = NULL;
struct sde_connector *sde_conn = NULL;
struct drm_property *property;
int ret = 0;
enum msm_mdp_conn_property conn_prop_idx;
uint64_t prop_val;
conn = _sde_debugfs_motUtil_get_drm_conn(kms, count, input);
if (!conn) {
ret = -EINVAL;
goto end;
}
sde_conn = to_sde_connector(conn);
if (!sde_conn) {
ret = -EINVAL;
goto end;
}
if (count < KMSPROPTEST_NEW_VAL) {
DRM_ERROR(" Number of Input data is invalid (%zu).\n", count);
ret = -EINVAL;
goto end;
}
switch (input[KMSPROPTEST_PROP_INDEX]) {
case KMSPROPTEST_TYPE_HBM:
conn_prop_idx = CONNECTOR_PROP_HBM;
break;
/* case KMSPROPTEST_TYPE_ACL:
conn_prop_idx = CONNECTOR_PROP_ACL;
break;
*/
default:
DRM_ERROR(" Invalid KMSPROPTEST_PROP_INDEX = %d\n",
input[KMSPROPTEST_PROP_INDEX]);
ret = -EINVAL;
break;
}
if (ret)
goto end;
property = msm_property_index_to_drm_property(&sde_conn->property_info,
conn_prop_idx);
if (!property) {
SDE_ERROR("invalid property index %d for sde_conn_name=%s\n",
conn_prop_idx, sde_conn->name);
ret = -EINVAL;
goto end;
}
prop_val = sde_connector_get_property(conn->state, conn_prop_idx);
if (prop_val == PARAM_STATE_DISABLE) {
DRM_ERROR("This KMS Property=%d is disabled\n", conn_prop_idx);
ret = -EPERM;
goto end;
}
switch(input[KMSPROPTEST_PROP_TYPE]) {
case KMSPROPTEST_GETPROP:
motUtil_data.read_cmd = true;
motUtil_data.val = (int)prop_val;
break;
case KMSPROPTEST_SETPROP:
motUtil_data.read_cmd = false;
if (conn->funcs && conn->funcs->atomic_set_property) {
ret = conn->funcs->atomic_set_property(conn,
conn->state, property,
input[KMSPROPTEST_NEW_VAL]);
} else {
ret = -EINVAL;
DRM_ERROR("Unsupport KMS set property\n");
}
break;
default:
DRM_ERROR("Invalid KMSPROPTEST_PROP_TYPE = %d\n",
input[KMSPROPTEST_PROP_TYPE]);
ret = -EINVAL;
break;
}
end:
motUtil_data.cmd_status = ret;
return ret;
}
static ssize_t _sde_debugfs_motUtil_exe_command(struct sde_kms *kms,
size_t count, char input[])
{
@@ -182,6 +284,9 @@ static ssize_t _sde_debugfs_motUtil_exe_command(struct sde_kms *kms,
case MOTUTIL_DISP_UTIL:
ret = _sde_debugfs_motUtil_transfer(kms, count, input);
break;
case MOTUTIL_KMS_PROP_TEST:
ret = _sde_debugfs_motUtil_kms_prop_test(kms, count, input);
break;
default:
SDE_ERROR("Un-support motUtil type = %d\n", motUtil_type);
ret = -EINVAL;
@@ -207,22 +312,26 @@ static ssize_t _sde_debugfs_motUtil_write(struct file *file,
u32 buf_size = 0;
char buffer[MAX_CMD_PAYLOAD_SIZE];
struct sde_kms *kms = (struct sde_kms *)file->private_data;
int ret = 0;
if (*ppos || !kms) {
SDE_ERROR("invalid argument(s)\n");
return 0;
ret = -EINVAL;
goto end;
}
buf_size = _sde_debugfs_motUtil_string2num(buf, count, buffer);
if (!buf_size){
if (buf_size <= 0){
SDE_ERROR("invalid input\n");
return count;
ret = -EINVAL;
goto end;
}
mutex_lock(&motUtil_data.lock);
_sde_debugfs_motUtil_exe_command(kms, count, buffer);
ret = _sde_debugfs_motUtil_exe_command(kms, count, buffer);
mutex_unlock(&motUtil_data.lock);
end:
motUtil_data.cmd_status = ret;
return count;
}
@@ -253,14 +362,20 @@ static ssize_t _sde_debugfs_motUtil_read(struct file *file,
return 0;
mutex_lock(&motUtil_data.lock);
if (!motUtil_data.read_cmd) {
if (motUtil_data.cmd_status < 0 || !motUtil_data.read_cmd) {
blen = snprintf(buffer, MAX_CMD_PAYLOAD_SIZE,
"motUtil_status: 0x%x\n",
motUtil_data.last_cmd_tx_status);
"motUtil_status: %d\n",
motUtil_data.cmd_status);
} else if (motUtil_data.motUtil_type == MOTUTIL_DISP_UTIL) {
blen = _sde_debugfs_motUtil_dispUtil_read(buffer);
} else if (motUtil_data.motUtil_type == MOTUTIL_KMS_PROP_TEST) {
blen = snprintf(buffer, 16, "motUtil_read: ");
blen += snprintf((buffer + blen), 12, "0x%08x ",
motUtil_data.val);
blen += snprintf((buffer + blen), 2, "\n");
}
SDE_INFO("%s\n", buffer);
if (blen <= 0) {
+88 -1
View File
@@ -18,8 +18,78 @@
#include <linux/debugfs.h>
#include <linux/types.h>
/*****************************************************************************
* /d/dri/0/debug/motUtil sysfs *
* - This is Mot debug sysfs to provide some tools to test panel and panel *
* features. This tool only exist with the userdebug and Engineering build *
* - Currently, this motUtil will provide 3 kind of tests and it can enhance *
* to test more if needed *
* - Test#1: DispUtil: This test is able to send any MIPI DSI command and *
* it can read any data back from the panel *
* - Test#2: TeTest: This test will be used to test the TE trace between *
* the panels and MDSS to make sure it works *
* - Test#3: kmsPropTest: This test will test the panel features such as *
* HBM, ACL, CABC, etc. It can read these features configurations*
* in the KMS property and it can change these setting from KMS *
* property. *
* - Usage: *
* - 1st byte will indicate which motUtil test will be run. *
* 0x00 = dispUtil, 0x01 = TeTest, 0x02 = kmsPropTest *
* --------------------------------------------------------------------------*
* - dispUtil: *
* 1st byte: 0x00: dispUtil *
* 2nd byte: 0x00: primary panel and 0x01: Secondary panel *
* 3rd byte: 0x00: MIPI write cmd to panel and 0x01: MIPI read *
* 4th byte: 0x00: MIPI HS mode and 0x01: MIPI LP mode *
* 5th byte: 0x00: MIPI DCS cmd and 0x01: MIPI generaic cmd *
* 6th byte: Indicate number of bytes to read from panel *
* 7th and 8th: Indicate number of bytes for the payload cmd *
* 9th and .. :the payload cmd *
* - Example: *
* echo "0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x28" > motUtil *
* - This will send a mipi DSC command "0x28" to panel and *
* which will request the panel to turn off the panel *
* cat motUtil *
* - This will report a sending previous cmd status *
* 0: send success or errno if it fails *
* echo "0x00 0x01 0x01 0x00 0x00 0x01 0x00 0x01 0x0a" > motUtil *
* - This will send MIPI read cmd "0xa" to the panel. *
* cat motUtil *
* - number of reading bytes from previous command or errno if it fails*
*---------------------------------------------------------------------------*
* - TeTest: This test has been removed *
*---------------------------------------------------------------------------*
* - kmsPropTest *
* 1st byte: kmsPropTest *
* 2nd byte: 0x00: primary panel and 0x01: Secondary panel *
* 3rd byte: 0x00: get KMS property and 0x01: set KMS property *
* 4th byte: 0x00: HBM 0x01: ACL for the KMS property/panel feature *
* 5th byte: new data for a "set KMS property" operation *
* - Example *
* echo "0x02 0x00 0x010 0x00 0x00" > motUtil *
* - This will read the HBM setting of the primary panel in the KMS *
* property. *
* cat motUtil *
* - This will return the status of previous cmd. *
* 0 if success or errno if it fails *
* echo "0x02 0x00 0x01 0x00 0x01" > motUtil *
* - This will turn on the HBM feature of the primary panel in the KMS *
* property. The panel's backlight will be brighter when HBM is on *
* cat motUtil *
* - This will return the status of previous cmd. *
* 0 if success or errno if it fails *
* echo "0x02 0x00 0x010 0x00 0x00" > motUtil *
* - This will read back the HBM setting in KMS property *
* echo "0x02 0x00 0x01 0x00 0x00" > motUtil *
* - This will turn off the HBM feature of the primary panel in the KMS *
* property. The panel's backlight will be dimmer when HBM is off *
* *
****************************************************************************/
enum sde_motUtil_type {
MOTUTIL_DISP_UTIL = 0,
MOTUTIL_TE_TEST,
MOTUTIL_KMS_PROP_TEST,
};
enum sde_motUtil_disp_cmd {
@@ -34,11 +104,25 @@ enum sde_motUtil_disp_cmd {
DISPUTIL_PAYLOAD,
};
enum sde_motUtil_kmsPropTest_cmd {
KMSPROPTEST_TYPE,
KMSPROPTEST_PANEL_TYPE,
KMSPROPTEST_PROP_TYPE,
KMSPROPTEST_PROP_INDEX,
KMSPROPTEST_NEW_VAL,
};
enum sde_motUtil_kmsPropTest_ConnPropType {
KMSPROPTEST_TYPE_HBM,
KMSPROPTEST_TYPE_ACL,
KMSPROPTEST_TYPE_CABC,
};
struct motUtil {
struct mutex lock;
enum sde_motUtil_type motUtil_type;
bool read_cmd;
bool last_cmd_tx_status;
int cmd_status;
u16 read_len;
u8 *rd_buf;
int val;
@@ -54,6 +138,9 @@ struct motUtil {
#define DISPUTIL_DSI_HS_MODE 0
#define DISPUTIL_DSI_LP_MODE 1
#define KMSPROPTEST_GETPROP 0
#define KMSPROPTEST_SETPROP 1
#define MOTUTIL_MAIN_DISP 0
#define MOTUTIL_CLI_DISP 1