"Devon push for Android 13"

* tag 'MMI-T2SN33.73-22-3' of https://github.com/MotorolaMobilityLLC/kernel-msm-techpack-display:
  Revert "disp: msm: use vzalloc for large allocations"
  disp/msm/dsi:enabel ESD te check for video panel
  disp/msm/dsi:support to config glbl_hstx_str_ctrl_0 for mipi driver strength
  disp: msm: use vzalloc for large allocations
  disp: msm: sde: fix RM poll timeouts during PM suspend/resume usecase
  disp: msm: avoid BW down vote after splash memory release
  disp: msm: dsi: Only enable lanes required during phy enable
  disp: msm: sde: while timing engine enabling poll for active region
  [PATCH] disp: msm: sde: remove panic from autorefresh disable sequence
  drm/dsi_panel: send specific demura command when bl change
  drm/msm/dsi-staging: add default brightness property
  kernel/display:hawao+oled:change lcm timing
  HAWAO+OLED: solve mipi driver strength weak problem
  kernel/display:hawao+oled:change lcm timing
  Revert "HAWAO+OLED:solve mipi driver strength weak problem"
  HAWAO+OLED: solve mipi driver strength weak problem
  disp: msm: Fixing motUtil tool for ACL feature
  drm: Add the panel color feature for game mode
  drm: Add the DC panel param feature
  display: Modify the lcd reset gpio pin.
  Fix: display blinking issue
  propagation: panel: add ft8006s special reset timing control
  display: support ft8006s panel brightness level special align
  [Guam NA] Fix propagation error in dsi_display.c
  kernel:dsi: ESD te support for video mode panel
  kernel:dsi: backlight update for hbm gpio
  kernel:dsi: backlight update for hbm gpio
  kernel: dsi: rst pull down config update
  kernel: dsi: tp_rst seq update
  kernel: dsi: enable tp_rst & esd fail logs
  Capri beingup
  kernel: dsi: add new backlight device to avoid conflict
  kernel: dsi: download touch firmware after panel reset
  msm/dsi: add panel tp rst configs
  kernel: dsi: pull down reset pin when shutdown
  dsi: add new backlight control type I2C
  drm/msm/sde: limit the backlight min brightness as bl_min_level
  Kernel: read panel supplier from device tree
  disp: msm: Parsing and store panel's 0xDA register info
  dsi_panel: fix out-of-bounds  issue
  backlight: support device hbm use 51 cmd
  backlight: add hbm gpio control driver
  msm/dsi: add backlight and hbm debug log
  msm/dsi: set brightness at maximum if enabling LCD HBM
  dsi_panel: Check the return status of the touch screen
  drm/panel_param: optimize the code
  Display PanelMode: Add CABC control
  msm: dsi_panel: refresh rate config option
  msm: dsi_panel: refresh rate config option
  disp: msm: Correct DSC 1.1 Rate control for Max val
  dsi: pushing display notifications
  Revert"disp:msm:sde: update splash resource allocation for dual display"
  disp: msm: Restore old backlight setting after exitting HBM
  disp: msm:: reset the param value to the default value
  disp: msm: support for HBM_FOD mode
  disp: msm: add display frequency change notification
  Revert "Revert "disp: msm: sde: update splash resource allocation for dual display""
  Kernel/Display: mot extend code: get lcd para
  Kernel/display: mot extend - early power
  Kernel: Add Moto extern display code
  disp: msm: implement xxx-hbm-is-51cmd dts entry
  disp: msm: fix checking returned value of xx_cmd_transfer
  disp: msm: Register for reboot_notifier
  disp: msm: Support ACL when setting panel param
  disp: msm: Enable "val" to control HBM property
  disp: msm: dsi: Reducing logging in dsi_panel.c
  disp: msm: dsi: Add print info for DSI_CTRL
  disp: msm : Add the ACL panel param feature
  disp: msm: Populate the passing panel's info from BL.
  disp: msm: Set panel enable_status during probing
  disp: msm: Add panel name to enable status API
  disp: msm: Report panel's probe status
  disp: msm: provide API to query for panel enable state
  disp: msm: Correct the panel's LP11_INIT
  disp: msm: Adding KMS property testing for motUtil tool
  disp: msm: add panel's param feature to display FW
  disp: msm: Provide a dynamic method to disable the ESD.
  disp: msm: Add DispUtil tool to motUtil Debugfs
  disp: msm: sde: Add motUtil Debugfs framework
  disp: msm: dsi: Raise BUG for continous panel recovery failure
  disp: msm: dsi: Trigger ESD event if display isn't on
  disp: msm: dsi: Check panel's power_mode during resume
  disp: msm: dsi: parsing BL setting ESD and panel
  disp: msm: sde: Change display ESD checking interval to 8s
  disp: msm: dsi: add prints for DSI/panel turning off/on
  disp: msm: dsi: Add "bl_ctrl_dummy" to panel bl type
  disp: msm: dsi: Add support display 2bytes brightness.
  guam: input add drm support
  input add touch support
  disp: msm: sde: synx: Add quic copyright
  disp: msm: sde: handle partial update transitions in rounded corner.
  Revert "disp: msm: sde: handle partial update transitions in rounded corner".
  disp: msm: sde: handle partial update transitions in rounded corner
  disp: msm: sde: clear partial update mask during last close

 Conflicts:
	techpack/display/msm/msm_drv.c
	techpack/display/msm/msm_drv.h

Change-Id: I40dab2ee196d87f2d24439d5b4e7c4cd14b7051d
This commit is contained in:
Michael Bestas committed 2024-01-03 01:34:07 +02:00
commit cdfcefda47
27 files changed
+4149 -67

No files matched your search

+1
View File
@@ -11,3 +11,4 @@ export CONFIG_QCOM_MDSS_PLL=y
export CONFIG_MSM_SDE_ROTATOR=y
export CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
export CONFIG_DRM_SDE_RSC=y
export CONFIG_DRM_DYNAMIC_REFRESH_RATE=y
+1
View File
@@ -17,3 +17,4 @@
#define CONFIG_MSM_SDE_ROTATOR 1
#define CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG 1
#define CONFIG_DRM_SDE_RSC 1
#define CONFIG_DRM_DYNAMIC_REFRESH_RATE 1
+2
View File
@@ -32,6 +32,7 @@ msm_drm-$(CONFIG_DRM_MSM_SDE) += sde/sde_crtc.o \
sde/sde_core_perf.o \
sde/sde_rm.o \
sde/sde_kms_utils.o \
sde/sde_motUtil.o \
sde/sde_kms.o \
sde/sde_plane.o \
sde/sde_connector.o \
@@ -100,6 +101,7 @@ msm_drm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi_phy.o \
dsi/dsi_panel.o \
dsi/dsi_clk_manager.o \
dsi/dsi_display_test.o \
dsi/dsi_display_mot_ext.o \
msm_drm-$(CONFIG_DSI_PARSER) += dsi/dsi_parser.o \
+42
View File
@@ -281,6 +281,27 @@ 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_FOD_ON: Turning HBM_FOD on
* @DSI_CMD_SET_HBM_ON: Turning HBM on
* @DSI_CMD_SET_HBM_OFF: Turning HBM off
* @DSI_CMD_SET_ACL_ON: Turning ACL on
* @DSI_CMD_SET_ACL_OFF: Turning ACL off
* @DSI_CMD_SET_CABC_UI: CABC UI mode
* @DSI_CMD_SET_CABC_MV: CABC MV mode
* @DSI_CMD_SET_CABC_DIS: CABC DIS mode
* @DSI_CMD_SET_DC_ON: DC mode on
* @DSI_CMD_SET_DC_OFF: DC mode off
* @DSI_CMD_SET_COLOR_VBT : COLOR VBT mode
* @DSI_CMD_SET_COLOR_STD: COLOR STD mode
* @DSI_CMD_SET_COLOR_GAME : COLOR GAME mode
* @DSI_CMD_SET_COLOR_NONE: COLOR NONE mode
* @DSI_CMD_SET_BRIGHTNESS_1E: Send demura codes when brightness changes to 0-1E
* @DSI_CMD_SET_BRIGHTNESS_1FD: Send demura codes when brightness changes to 1F-1FD
* @DSI_CMD_SET_BRIGHTNESS_2FF: Send demura codes when brightness changes to 1FE-2FF
* @DSI_CMD_SET_BRIGHTNESS_3FF: Send demura codes when brightness changes to 300-3FF
* @DSI_CMD_SET_BRIGHTNESS_4FF: Send demura codes when brightness changes to 400-4FF
* @DSI_CMD_SET_BRIGHTNESS_5FF: Send demura codes when brightness changes to 500-5FF
* @DSI_CMD_SET_BRIGHTNESS_FFF: Send demura codes when brightness changes to 600-FFF
* @DSI_CMD_SET_MAX
*/
enum dsi_cmd_set_type {
@@ -307,6 +328,27 @@ 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_FOD_ON,
DSI_CMD_SET_HBM_ON,
DSI_CMD_SET_HBM_OFF,
DSI_CMD_SET_ACL_ON,
DSI_CMD_SET_ACL_OFF,
DSI_CMD_SET_CABC_UI,
DSI_CMD_SET_CABC_MV,
DSI_CMD_SET_CABC_DIS,
DSI_CMD_SET_DC_ON,
DSI_CMD_SET_DC_OFF,
DSI_CMD_SET_COLOR_VBT,
DSI_CMD_SET_COLOR_STD,
DSI_CMD_SET_COLOR_GAME,
DSI_CMD_SET_COLOR_NONE,
DSI_CMD_SET_BRIGHTNESS_1E,
DSI_CMD_SET_BRIGHTNESS_1FD,
DSI_CMD_SET_BRIGHTNESS_2FF,
DSI_CMD_SET_BRIGHTNESS_3FF,
DSI_CMD_SET_BRIGHTNESS_4FF,
DSI_CMD_SET_BRIGHTNESS_5FF,
DSI_CMD_SET_BRIGHTNESS_FFF,
DSI_CMD_SET_MAX
};
+600 -5
View File
@@ -45,6 +45,10 @@ static const struct of_device_id dsi_display_dt_match[] = {
{}
};
static int dsi_display_enable_status (struct dsi_display *display, bool enable);
static void dsi_display_is_probed(struct dsi_display *display,
int probe_status);
static void dsi_display_mask_ctrl_error_interrupts(struct dsi_display *display,
u32 mask, bool enable)
{
@@ -246,6 +250,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;
@@ -697,6 +723,40 @@ exit:
return rc;
}
int dsi_display_cmd_mipi_transfer(struct dsi_display *display,
struct mipi_dsi_msg *msg,
u32 flags)
{
int rc = 0;
struct dsi_display_ctrl *m_ctrl;
m_ctrl = &display->ctrl[display->cmd_master_idx];
if (display->tx_cmd_buf == NULL) {
rc = dsi_host_alloc_cmd_tx_buffer(display);
if (rc) {
DSI_ERR("failed to allocate cmd tx buffer memory\n");
goto done;
}
}
rc = dsi_display_cmd_engine_enable(display);
if (rc) {
DSI_ERR("cmd engine enable failed\n");
return -EPERM;
}
flags |= DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, msg, &flags);
if (((flags & DSI_CTRL_CMD_READ) && rc <= 0) ||
(!(flags & DSI_CTRL_CMD_READ) && rc))
DSI_ERR("failed to transfer cmd. rc = %d\n", rc);
dsi_display_cmd_engine_disable(display);
done:
return rc;
}
static int dsi_display_status_reg_read(struct dsi_display *display)
{
int rc = 0, i;
@@ -777,6 +837,21 @@ static int dsi_display_status_check_te(struct dsi_display *display)
return rc;
}
static int dsi_display_status_check_te_video(struct dsi_display *display)
{
int rc = 1;
struct dsi_panel *panel = display->panel;
if((panel->video_te_count - panel->video_te_count_priv) > 1) {
panel->video_te_count_priv = panel->video_te_count;
} else {
DSI_ERR("%s: video TE check ERROR te_count %d, priv =%d\n", __func__, panel->video_te_count, panel->video_te_count_priv);
rc = 0;
}
return rc;
}
int dsi_display_check_status(struct drm_connector *connector, void *display,
bool te_check_override)
{
@@ -835,6 +910,8 @@ int dsi_display_check_status(struct drm_connector *connector, void *display,
rc = dsi_display_status_reg_read(dsi_display);
} else if (status_mode == ESD_MODE_SW_BTA) {
rc = dsi_display_status_bta_request(dsi_display);
} else if (status_mode == ESD_MODE_PANEL_TE_VIDEO) {
rc = dsi_display_status_check_te_video(dsi_display);
} else if (status_mode == ESD_MODE_PANEL_TE) {
rc = dsi_display_status_check_te(dsi_display);
} else {
@@ -864,6 +941,19 @@ release_panel_lock:
return rc;
}
bool dsi_display_force_esd_disable(void *display)
{
struct dsi_display *dsi_display = display;
struct dsi_panel *panel;
if (dsi_display == NULL)
return false;
panel = dsi_display->panel;
return (panel->esd_utag_enable? false: true);
}
static int dsi_display_cmd_prepare(const char *cmd_buf, u32 cmd_buf_len,
struct dsi_cmd_desc *cmd, u8 *payload, u32 payload_len)
{
@@ -894,6 +984,166 @@ static int dsi_display_cmd_prepare(const char *cmd_buf, u32 cmd_buf_len,
return 0;
}
static int dsi_display_dispUtil_get_datatype (char dsi_cmd, u8 cmd_type,
size_t tx_len, u8 *tx_data_type)
{
int rc = 0;
*tx_data_type = 0;
/* cmd_type = 0 : DSI DCS cmd;
* cmd_type = 1 : DSI Generic cmd */
if (cmd_type > DISPUTIL_DSI_GENERIC) {
DSI_ERR("%s: Invalid DSI package type[%d] = 0x%x\n",
__func__, DISPUTIL_MIPI_CMD_TYPE,
cmd_type);
return -EINVAL;
}
DSI_DEBUG("dsi_cmd =0x%x cmd_type=0x%x tx_len=0x%x\n",
dsi_cmd, cmd_type, (u32)tx_len);
if (dsi_cmd == DISPUTIL_DSI_WRITE) {
/* This is a DSI write command */
switch(tx_len) {
case 1:
if (cmd_type == DISPUTIL_DSI_GENERIC)
/* write, generic, no param */
*tx_data_type = 0x3;
else if (cmd_type == DISPUTIL_DSI_DCS)
/* write, DCS, no param */
*tx_data_type = 0x5;
break;
case 2:
if (cmd_type == DISPUTIL_DSI_GENERIC)
/* Write, generic, 1 param */
*tx_data_type = 0x13;
else if (cmd_type == DISPUTIL_DSI_DCS)
/* write, DCS, 1 param */
*tx_data_type = 0x15;
break;
default:
if (cmd_type == DISPUTIL_DSI_GENERIC)
/* Write, generic, long*/
*tx_data_type = 0x29;
else if (cmd_type == DISPUTIL_DSI_DCS)
/* write, DCS, long*/
*tx_data_type = 0x39;
break;
}
} else if (dsi_cmd == DISPUTIL_DSI_READ) {
if ((cmd_type == DISPUTIL_DSI_DCS) && (tx_len > 1)) {
/* Note: tx_len will include read command and payload */
/* DCS read */
DSI_ERR("DCS read supports no parameter. tx_len=%d\n",
(u32)tx_len);
rc = -EINVAL;
} else {
switch(tx_len) {
case 1:
if (cmd_type == DISPUTIL_DSI_GENERIC)
/* Read, generic, no param */
*tx_data_type = 0x4;
else if (cmd_type == DISPUTIL_DSI_DCS)
/* Read, DCS, no param */
*tx_data_type = 0x6;
break;
case 2:
if (cmd_type == DISPUTIL_DSI_GENERIC)
/* Read, Generic, 1 param */
*tx_data_type = 0x14;
break;
case 3:
if (cmd_type == DISPUTIL_DSI_GENERIC)
/* read, generic, 2 params */
*tx_data_type = 0x24;
break;
default:
DSI_ERR("Invalid for tx_len= %d\n", (u32)tx_len);
break;
}
}
} else
rc = -EINVAL;
if (rc)
DSI_ERR("Invalid input data: dsi_cmd=0x%x tx_data_type =0x%x for tx_len=0x%x\n",
dsi_cmd, *tx_data_type, (u32)tx_len);
return rc;
}
static int dsi_display_dispUtil_prepare(const char *cmd_buf, u32 cmd_buf_len,
struct dsi_cmd_desc *cmd, u8 *payload, u32 payload_len_max,
struct motUtil *motUtil_data)
{
int rc, i;
u8 tx_data_type;
memset(cmd, 0x00, sizeof(*cmd));
/*
* DISPUTIL_PAYLOAD_LEN_U and SDE_MOT_UTIL_PAYLOAD_LEN_L to
* indicate number of payload in bytes
*/
cmd->msg.tx_len = ((cmd_buf[DISPUTIL_PAYLOAD_LEN_U] << 8) |
(cmd_buf[DISPUTIL_PAYLOAD_LEN_L]));
rc = dsi_display_dispUtil_get_datatype(cmd_buf[DISPUTIL_CMD_TYPE],
cmd_buf[DISPUTIL_MIPI_CMD_TYPE],
cmd->msg.tx_len, &tx_data_type);
if (rc)
return rc;
cmd->msg.type = tx_data_type;
cmd->msg.channel = 0;
cmd->last_command = 1;
cmd->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
/* DISPUTIL_CMD_TYPE = 1 for DSI write cmd
* DISPUTIL_CMD_TYPE = 0 for DSI read cmd */
if (cmd_buf[DISPUTIL_CMD_TYPE] == DISPUTIL_DSI_READ) {
cmd->msg.flags |= MIPI_DSI_MSG_READ; /* This is a read DSI */
cmd->msg.rx_buf = motUtil_data->rd_buf;
/* cmd_buf[3] = number bytes host wants to read */
cmd->msg.rx_len = cmd_buf[DISPUTIL_NUM_BYTE_RD];
motUtil_data->read_cmd = true;
} else
motUtil_data->read_cmd = false;
/*
* DISPUTIL_CMD_XFER_MODE = 0: DSI cmd transfers at HS mode
* DISPUTIL_CMD_XFER_MODE = 1: DSI cmd transfers at LP mode
*/
if (cmd_buf[DISPUTIL_CMD_XFER_MODE] == DISPUTIL_DSI_LP_MODE)
cmd->msg.flags |= MIPI_DSI_MSG_USE_LPM;
cmd->msg.ctrl = 0;
cmd->post_wait_ms = 0;
/*
* msg.tx_len is number of bytes of the payload.
* Checking msg.tx_len with the payload, DISPUTIL_PAYLOAD,
* to make sure they are matched
*/
if ((cmd->msg.tx_len > (cmd_buf_len - DISPUTIL_PAYLOAD)) ||
(cmd->msg.tx_len > payload_len_max)) {
DSI_ERR("Incorrect payload length tx_len:%ld, payload_len_max=%d cmd_buf_len=%d\n",
cmd->msg.tx_len, payload_len_max, cmd_buf_len);
return -EINVAL;
}
for (i = 0; i < cmd->msg.tx_len; i++)
payload[i] = cmd_buf[DISPUTIL_PAYLOAD + i];
cmd->msg.tx_buf = payload;
return 0;
}
static int dsi_display_ctrl_get_host_init_state(struct dsi_display *dsi_display,
bool *state)
{
@@ -987,6 +1237,51 @@ static void _dsi_display_continuous_clk_ctrl(struct dsi_display *display,
}
}
int dsi_display_motUtil_transfer(void *display, const char *cmd_buf,
u32 cmd_buf_len, struct motUtil *motUtil_data)
{
struct dsi_display *dsi_display = display;
struct dsi_cmd_desc cmd;
u8 cmd_payload[MAX_CMD_PAYLOAD_SIZE];
int rc = 0;
bool state = false;
if (!dsi_display || !cmd_buf) {
DSI_ERR("[DSI] invalid params\n");
return -EINVAL;
}
DSI_INFO("[DSI] Display dispUtil transfer\n");
rc = dsi_display_dispUtil_prepare(cmd_buf, cmd_buf_len,
&cmd, cmd_payload, MAX_CMD_PAYLOAD_SIZE,
motUtil_data);
if (rc) {
DSI_ERR("[DSI] command prepare failed. rc %d\n", rc);
return rc;
}
mutex_lock(&dsi_display->display_lock);
rc = dsi_display_ctrl_get_host_init_state(dsi_display, &state);
if (rc || !state) {
DSI_ERR("[DSI] Invalid host state %d rc %d\n",
state, rc);
rc = -EPERM;
goto end;
}
/*
* rc will be returned from ops->transfer, which will be 0 or 1 for
* DSI write command. rc will be returned for number of read bytes
* for DSI read commad
*/
rc = dsi_display->host.ops->transfer(&dsi_display->host,
&cmd.msg);
end:
mutex_unlock(&dsi_display->display_lock);
return rc;
}
int dsi_display_soft_reset(void *display)
{
struct dsi_display *dsi_display;
@@ -2940,9 +3235,12 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE)
cmd_flags |= DSI_CTRL_CMD_ASYNC_WAIT;
if (msg->rx_buf)
cmd_flags |= DSI_CTRL_CMD_READ;
rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
&cmd_flags);
if (rc) {
if (((cmd_flags & DSI_CTRL_CMD_READ) && rc <= 0) ||
(!(cmd_flags & DSI_CTRL_CMD_READ) && rc)) {
DSI_ERR("[%s] cmd transfer failed, rc=%d\n",
display->name, rc);
goto error_disable_cmd_engine;
@@ -3762,11 +4060,88 @@ static int dsi_display_parse_dt(struct dsi_display *display)
break;
}
/* Parse mot extend feature supporting */
display->is_dsi_mot_ext_enabled = of_property_read_bool(of_node,
"qcom,platform-mot-ext-feature-enable");
if ( display->is_dsi_mot_ext_enabled )
display->is_dsi_mot_early_power_enabled = of_property_read_bool(of_node, "qcom,platform-mot-early-power-enable");
pr_info("is_dsi_mot_ext_enabled %d, is_dsi_mot_early_power_enabled %d\n", display->is_dsi_mot_ext_enabled, display->is_dsi_mot_early_power_enabled);
DSI_DEBUG("success\n");
error:
return rc;
}
static void dsi_video_te_irq_work(struct work_struct *work)
{
struct dsi_panel *panel = NULL;
struct delayed_work *dw = to_delayed_work(work);
panel = container_of(dw, struct dsi_panel, te_event_work);
if (!panel) {
DSI_ERR("%s: invalid panel data\n", __func__);
return;
}
if(panel->video_te_count%60 == 0)
DSI_INFO("%s video te count = %d\n", __func__, panel->video_te_count);
enable_irq(panel->video_te_irq);
}
extern u32 interval_video_te;
static irqreturn_t dsi_video_te_interrupt(int irq, void *data)
{
struct dsi_panel *panel = data;
disable_irq_nosync(irq);
if(panel->video_te_count++ < 3000) {
enable_irq(irq);
} else {
queue_delayed_work(panel->workq, &panel->te_event_work, msecs_to_jiffies(interval_video_te/3));
//DSI_DEBUG("%s video_te_count=%d\n", __func__, panel->video_te_count);
}
return IRQ_HANDLED;
}
static int dsi_init_video_te_irq(struct dsi_panel *panel)
{
int rc = -1;
if (gpio_is_valid(panel->video_te_gpio)) {
rc = gpio_request(panel->video_te_gpio, "video-te-gpio");
if (rc < 0) {
DSI_ERR("%s: video te gpio_request fail rc=%d\n", __func__,rc);
return rc ;
}
rc = gpio_direction_input(panel->video_te_gpio);
if (rc < 0) {
DSI_ERR("%s: video te gpio_direction_input fail rc=%d\n", __func__ ,rc);
return rc ;
}
panel->video_te_count_priv = 0;
panel->video_te_count = 3;
panel->video_te_irq = gpio_to_irq(panel->video_te_gpio);
DSI_INFO("%s: irq = %d, gpio=%d\n", __func__, panel->video_te_irq, panel->video_te_gpio);
rc = request_threaded_irq(panel->video_te_irq, dsi_video_te_interrupt, NULL,
IRQF_TRIGGER_RISING|IRQF_ONESHOT, "video-te-irq", panel);
if (rc < 0) {
DSI_ERR("%s: video te request_irq fail rc=%d\n",__func__, rc);
return rc ;
}
} else {
DSI_ERR("%s: video te irq gpio not provided\n", __func__);
return rc ;
}
return 0;
}
static int dsi_display_res_init(struct dsi_display *display)
{
int rc = 0;
@@ -3814,6 +4189,9 @@ static int dsi_display_res_init(struct dsi_display *display)
display->panel->host_config.phy_type;
}
dsi_panel_parse_panel_cfg(display->panel,
!strcmp(display->display_type, "primary"));
rc = dsi_display_parse_lane_map(display);
if (rc) {
DSI_ERR("Lane map not found, rc=%d\n", rc);
@@ -3826,6 +4204,17 @@ static int dsi_display_res_init(struct dsi_display *display)
goto error_ctrl_put;
}
if(display->panel->esd_config.status_mode == ESD_MODE_PANEL_TE_VIDEO) {
display->panel->workq = create_workqueue("mdss_dsi_video_te");
if (!(display->panel->workq)) {
DSI_ERR("%s: Error creating video te workqueue\n", __func__);
goto error_ctrl_put;
}
INIT_DELAYED_WORK(&(display->panel->te_event_work), dsi_video_te_irq_work);
dsi_init_video_te_irq(display->panel);
}
return 0;
error_ctrl_put:
for (i = i - 1; i >= 0; i--) {
@@ -4642,6 +5031,20 @@ static void dsi_display_validate_dms_fps(struct dsi_display_mode *cur_mode,
}
}
static int dsi_phy_update_mipi_driver_strength(struct dsi_panel *panel, struct msm_dsi_phy *phy)
{
if((panel == NULL) || (phy == NULL))
{
return 1;
}
phy->cfg.dsi_phy_rescode_top = panel->glbl_rescode_top_ctrl;
phy->cfg.dsi_phy_rescode_bot = panel->glbl_rescode_bot_ctrl;
phy->cfg.dsi_phy_hstx_str_ctrl_0 = panel->glbl_hstx_str_ctrl_0;
return 0;
}
static int dsi_display_set_mode_sub(struct dsi_display *display,
struct dsi_display_mode *mode,
@@ -4768,6 +5171,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display,
DSI_ERR("failed to add DSI PHY timing params\n");
}
}
dsi_phy_update_mipi_driver_strength(display->panel, ctrl->phy);
error:
return rc;
}
@@ -5188,6 +5592,7 @@ static int dsi_display_bind(struct device *dev,
}
DSI_INFO("Successfully bind display panel '%s'\n", display->name);
dsi_display_is_probed(display, 0);
display->drm_dev = drm;
display_for_each_ctrl(i, display) {
@@ -5289,6 +5694,20 @@ static void dsi_display_unbind(struct device *dev,
mutex_unlock(&display->display_lock);
}
static void dsi_display_dev_shutdown(struct platform_device *pdev)
{
struct dsi_display *display = NULL;
if (!pdev) {
DSI_ERR("Invalid device\n");
} else {
display = platform_get_drvdata(pdev);
display->panel->reset_config.reset_force_pull_low =
display->panel->utils.read_bool(display->panel->utils.data,
"qcom,mdss-dsi-reset-force-pull-low");
}
}
static const struct component_ops dsi_display_comp_ops = {
.bind = dsi_display_bind,
.unbind = dsi_display_unbind,
@@ -5297,6 +5716,7 @@ static const struct component_ops dsi_display_comp_ops = {
static struct platform_driver dsi_display_driver = {
.probe = dsi_display_dev_probe,
.remove = dsi_display_dev_remove,
.shutdown = dsi_display_dev_shutdown,
.driver = {
.name = "msm-dsi-display",
.of_match_table = dsi_display_dt_match,
@@ -5383,11 +5803,15 @@ int dsi_display_dev_probe(struct platform_device *pdev)
display->display_type = of_get_property(pdev->dev.of_node,
"label", NULL);
if (!display->display_type)
if (!display->display_type) {
display->display_type = "primary";
display->display_idx = 0;
}
if (!strcmp(display->display_type, "secondary"))
if (!strcmp(display->display_type, "secondary")) {
index = DSI_SECONDARY;
display->display_idx = 1;
}
boot_disp = &boot_displays[index];
node = pdev->dev.of_node;
@@ -5442,6 +5866,13 @@ int dsi_display_dev_probe(struct platform_device *pdev)
goto end;
}
// Initialize mot extend code for early powern and debug tool feature
if ( display->is_dsi_mot_ext_enabled && index == DSI_PRIMARY ) {
dsi_display_ext_init(display);
}
pr_info("dsi_display_dev_probe: display(%p), name: %s, is_dsi_mot_early_power_enabled=%d, is_dsi_mot_ext_enabled=%d\n",
display, (display->name==NULL)?"Null":display->name, display->is_dsi_mot_early_power_enabled, display->is_dsi_mot_ext_enabled);
return 0;
end:
if (display)
@@ -6054,8 +6485,12 @@ int dsi_display_get_info(struct drm_connector *connector,
info->is_connected = true;
if (!strcmp(display->display_type, "primary"))
if (!strcmp(display->display_type, "primary")) {
info->display_type = SDE_CONNECTOR_PRIMARY;
//Update panel info for Mot early power
if ( display->is_dsi_mot_early_power_enabled )
display->is_dsi_mot_primary = true;
}
else if (!strcmp(display->display_type, "secondary"))
info->display_type = SDE_CONNECTOR_SECONDARY;
@@ -6069,6 +6504,14 @@ int dsi_display_get_info(struct drm_connector *connector,
(display->panel->qsync_caps.qsync_min_fps_list_len > 0) ?
true : false;
info->panel_id = display->panel->panel_id;
info->panel_ver = display->panel->panel_ver;
info->panel_regDA = display->panel->panel_regDA;
strncpy(info->panel_name, display->panel->panel_name,
sizeof(display->panel->panel_name));
strncpy(info->panel_supplier, display->panel->panel_supplier,
sizeof(display->panel->panel_supplier));
switch (display->panel->panel_mode) {
case DSI_OP_VIDEO_MODE:
info->curr_panel_mode = MSM_DISPLAY_VIDEO_MODE;
@@ -6783,6 +7226,14 @@ int dsi_display_set_mode(struct dsi_display *display,
timing.refresh_rate);
memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode));
//Update early power state
//This interface is called from dsi bridge, not moto early-power.
//It means it is system who want powr on display
//From now on early power on is forbidden
if ( display->is_dsi_mot_early_power_enabled )
display->dsi_mot_ext.early_power_state = DSI_EARLY_POWER_FORBIDDEN;
error:
mutex_unlock(&display->display_lock);
return rc;
@@ -7144,6 +7595,7 @@ int dsi_display_prepare(struct dsi_display *display)
{
int rc = 0;
struct dsi_display_mode *mode;
struct dsi_display_ctrl *ctrl = &display->ctrl[0];
if (!display) {
DSI_ERR("Invalid params\n");
@@ -7155,9 +7607,18 @@ int dsi_display_prepare(struct dsi_display *display)
return -EINVAL;
}
DSI_INFO("panel_name=%s ctrl-index=%d\n",
display->panel->name, ctrl->ctrl->cell_index);
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY);
mutex_lock(&display->display_lock);
//Check if Mot early power is on going...
if ( display->is_dsi_mot_early_power_enabled && display->is_dsi_display_prepared ) {
pr_info("already prepared\n");
goto error;
}
mode = display->panel->cur_mode;
dsi_display_set_ctrl_esd_check_flag(display, false);
@@ -7282,6 +7743,11 @@ int dsi_display_prepare(struct dsi_display *display)
}
}
}
//Update prepare statue for Mot early power
if ( display->is_dsi_mot_early_power_enabled )
display->is_dsi_display_prepared = true;
goto error;
error_ctrl_link_off:
@@ -7297,7 +7763,8 @@ error_ctrl_clk_off:
(void)dsi_display_clk_ctrl(display->dsi_clk_handle,
DSI_CORE_CLK, DSI_CLK_OFF);
error_panel_post_unprep:
(void)dsi_panel_post_unprepare(display->panel);
if (!display->is_cont_splash_enabled)
(void)dsi_panel_post_unprepare(display->panel);
error:
mutex_unlock(&display->display_lock);
SDE_EVT32(SDE_EVTLOG_FUNC_EXIT);
@@ -7566,6 +8033,94 @@ int dsi_display_pre_commit(void *display,
return rc;
}
struct dsi_enable_status {
struct dsi_display *display;
int probed;
bool enable;
char pname[DSI_PANEL_MAX_PANEL_LEN];
};
static struct dsi_enable_status enable_status[2] = {
{
.probed = -ENODEV,
},
{
.probed = -ENODEV,
},
};
static void dsi_display_is_probed (struct dsi_display *display,
int probe_status)
{
int enable_idx;
if (!display->display_type)
enable_idx = 0;
if (!strcmp(display->display_type, "secondary"))
enable_idx = 1;
enable_status[enable_idx].probed = probe_status;
strncpy(enable_status[enable_idx].pname, display->name,
sizeof(enable_status[enable_idx].pname));
DSI_DEBUG("display->drm_conn[%d] set: probe =%d, name =%s\n",
enable_idx, probe_status, display->name);
}
static int dsi_display_enable_status (struct dsi_display *display, bool enable)
{
int ret = 0;
if (!strncmp("DSI-1", display->drm_conn->name, 5)) {
DSI_DEBUG("display->drm_conn->name=%s enable = %d MAIN_DISPLAY\n",
display->drm_conn->name, enable);
enable_status[0].display = display;
enable_status[0].enable = enable;
} else if (!strncmp("DSI-2", display->drm_conn->name, 5)) {
DSI_DEBUG("display->drm_conn->name=%s enable = %d CLI_DISPLAY\n",
display->drm_conn->name, enable);
enable_status[1].display = display;
enable_status[1].enable = enable;
} else {
DSI_ERR("display->drm_conn: invalid name =%s\n",
display->drm_conn->name);
ret = -EINVAL;
}
return ret;
}
bool dsi_display_is_panel_enable (int panel_index, int *probe_status,
char **pname)
{
struct dsi_display *display;
bool enable = false;
if (panel_index > 1) {
pr_err("display->drm_conn: invalid panel index =%d\n",
panel_index);
if (probe_status)
*probe_status = -ENODEV;
return false;
}
if (probe_status)
*probe_status = enable_status[panel_index].probed;
if (pname)
*pname = &enable_status[panel_index].pname[0];
display = enable_status[panel_index].display;
if (display) {
mutex_lock(&display->display_lock);
enable = enable_status[panel_index].enable;
mutex_unlock(&display->display_lock);
}
return enable;
}
EXPORT_SYMBOL(dsi_display_is_panel_enable);
int dsi_display_enable(struct dsi_display *display)
{
int rc = 0;
@@ -7596,6 +8151,7 @@ int dsi_display_enable(struct dsi_display *display)
return -EINVAL;
}
dsi_display_enable_status(display, 1);
display->panel->panel_initialized = true;
DSI_DEBUG("cont splash enabled, display enable not required\n");
return 0;
@@ -7603,6 +8159,12 @@ int dsi_display_enable(struct dsi_display *display)
mutex_lock(&display->display_lock);
//Check if Mot early power is on going
if ( display->is_dsi_mot_early_power_enabled && dsi_panel_initialized(display->panel)) {
pr_info("panel already enabled\n");
goto error;
}
mode = display->panel->cur_mode;
if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
@@ -7620,6 +8182,8 @@ int dsi_display_enable(struct dsi_display *display)
display->name, rc);
goto error;
}
dsi_display_enable_status(display, true);
}
/* Block sending pps command if modeset is due to fps difference */
@@ -7632,6 +8196,7 @@ int dsi_display_enable(struct dsi_display *display)
display->name, rc);
goto error;
}
dsi_panel_reset_param(display->panel);
}
if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
@@ -7755,6 +8320,14 @@ int dsi_display_pre_disable(struct dsi_display *display)
DSI_ERR("[%s] panel pre-disable failed, rc=%d\n",
display->name, rc);
}
//Update early power state
//Here is called from dsi bridge, not moto early-power.
//It means it is system who want powr off display
//From now on early power on is permitted
if ( display->is_dsi_mot_ext_enabled )
display->dsi_mot_ext.early_power_state = DSI_EARLY_POWER_IDLE;
goto exit;
error_disable_clks:
@@ -7778,13 +8351,24 @@ int dsi_display_disable(struct dsi_display *display)
return -EINVAL;
}
DSI_INFO("%s(%s)+\n", __func__, display->drm_conn->name);
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY);
mutex_lock(&display->display_lock);
//Check is Mot early power is on going
pr_info("display %p, name %s is_dsi_mot_primary(%d)\n", display, display->name, display->is_dsi_mot_primary);
if ( display->is_dsi_mot_early_power_enabled && !dsi_panel_initialized(display->panel)) {
mutex_unlock(&display->display_lock);
pr_info("panel already unprepared\n");
return rc;
}
rc = dsi_display_wake_up(display);
if (rc)
DSI_ERR("[%s] display wake up failed, rc=%d\n",
display->name, rc);
else
dsi_display_enable_status(display, false);
if (display->config.panel_mode == DSI_OP_VIDEO_MODE) {
rc = dsi_display_vid_engine_disable(display);
@@ -7842,6 +8426,13 @@ int dsi_display_unprepare(struct dsi_display *display)
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY);
mutex_lock(&display->display_lock);
//Check if Mot early power is on going
if ( display->is_dsi_mot_early_power_enabled && !display->is_dsi_display_prepared) {
mutex_unlock(&display->display_lock);
pr_info("panel already disabled\n");
return rc;
}
rc = dsi_display_wake_up(display);
if (rc)
DSI_ERR("[%s] display wake up failed, rc=%d\n",
@@ -7909,6 +8500,10 @@ int dsi_display_unprepare(struct dsi_display *display)
display->name, rc);
}
//Update prepare state for Mot early power
if ( display->is_dsi_mot_early_power_enabled )
display->is_dsi_display_prepared = false;
mutex_unlock(&display->display_lock);
/* Free up DSI ERROR event callback */
+46
View File
@@ -19,6 +19,9 @@
#include "dsi_ctrl.h"
#include "dsi_phy.h"
#include "dsi_panel.h"
#include "sde_connector.h"
#include "sde_motUtil.h"
#include "dsi_display_mot_ext.h"
#define MAX_DSI_CTRLS_PER_DISPLAY 2
#define DSI_CLIENT_NAME_SIZE 20
@@ -141,6 +144,7 @@ struct dsi_display_ext_bridge {
* @ext_conn: Pointer to external connector attached to DSI connector
* @name: Name of the display.
* @display_type: Display type as defined in device tree.
* @display_idx: Display index (0-primary, 1-secondary)
* @list: List pointer.
* @is_active: Is display active.
* @is_cont_splash_enabled: Is continuous splash enabled
@@ -197,6 +201,7 @@ struct dsi_display {
const char *name;
const char *display_type;
int display_idx;
struct list_head list;
bool is_cont_splash_enabled;
bool sw_te_using_wd;
@@ -263,6 +268,12 @@ struct dsi_display {
struct work_struct fifo_underflow_work;
struct work_struct fifo_overflow_work;
struct work_struct lp_rx_timeout_work;
/* used for moto feature early-pane- power to speed up the power on sequence */
bool is_dsi_mot_ext_enabled;
bool is_dsi_mot_early_power_enabled;
bool is_dsi_display_prepared;
bool is_dsi_mot_primary;
struct dsi_mot_ext_feature dsi_mot_ext;
/* firmware panel data */
const struct firmware *fw;
@@ -561,6 +572,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.
@@ -656,6 +669,25 @@ int dsi_display_cmd_transfer(struct drm_connector *connector,
void *display, const char *cmd_buffer,
u32 cmd_buf_len);
/**
* dsi_display_motUtil_transfer() - Convert motUtil data and transfer command
* to the panel
* @display: Handle to display.
* @cmd_buf: Command buffer
* @cmd_buf_len: Command buffer length in bytes
* @motUtil_data: motUtil data information
*/
int dsi_display_motUtil_transfer(void *display, const char *cmd_buf,
u32 cmd_buf_len, struct motUtil *motUtil_data);
/**
* dsi_display_force_esd_disable() - check if ESD UTAG is forced to disable ESD
* @display: Handle to display.
*/
bool dsi_display_force_esd_disable(void *display);
/**
* dsi_display_soft_reset() - perform a soft reset on DSI controller
* @display: Handle to display
@@ -718,6 +750,20 @@ enum dsi_pixel_format dsi_display_get_dst_format(
struct drm_connector *connector,
void *display);
/*
* dsi_display_cmd_mipi_transfer() - Sending the MIPI DSI command
* @display: Handle to display
* @msg: MIPI DSI command information
* @flags: Modifier flags
* Return: if this is a MIPI DSI read then it will return number read byte
* in success case. Otherwise will be "<=0"
* if this is a MIPI DSI write then it will return "0" for success
*
*/
int dsi_display_cmd_mipi_transfer(struct dsi_display *display,
struct mipi_dsi_msg *msg,
u32 flags);
/**
* dsi_display_cont_splash_config() - initialize splash resources
* @display: Handle to display
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2015-2019, The Linux Foundation.All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _DSI_DISPLAY_MOT_EXT_H_
#define _DSI_DISPLAY_MOT_EXT_H_
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/of_device.h>
#include <linux/firmware.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include "msm_drv.h"
#include "dsi_defs.h"
#include "dsi_ctrl.h"
#include "dsi_phy.h"
#include "dsi_panel.h"
#include "sde_connector.h"
#include "sde_motUtil.h"
#include "dsi_display.h"
#include <linux/alarmtimer.h>
#define LCD_PARA_LINE_LEN 2*1024
enum dsi_display_early_power_state {
DSI_EARLY_POWER_IDLE = 0,
DSI_EARLY_POWER_BEGIN,
DSI_EARLY_POWER_PREPARED,
DSI_EARLY_POWER_INITIALIZED,
DSI_EARLY_POWER_FORBIDDEN,
DSI_EARLY_POWER_STATE_NUM
};
struct dsi_mot_ext_feature {
struct dsi_display *display;
struct workqueue_struct *early_power_workq;
struct work_struct early_on_work;
struct delayed_work early_off_work;
enum dsi_display_early_power_state early_power_state;
struct wakeup_source* early_wake_src;
};
/**
* dsi_display_ext_init() - Moto early power init
* @display: Handle to display.
*
* Prepare for early power up sequences for the primary panel.
*
* Return: error code.
*/
int dsi_display_ext_init(struct dsi_display *display);
#endif /* _DSI_DISPLAY_MOT_EXT_H_ */
+1080 -39
View File
File diff suppressed because it is too large. Load diff
+156
View File
@@ -35,6 +35,38 @@
*/
#define MIPI_DSI_MSG_ASYNC_OVERRIDE BIT(4)
#define DSI_PANEL_MAX_PANEL_LEN 128
#define MAX_PARAM_NAME 10
#define BRIGHTNESS_HBM_ON 0xFFFFFFFE
#define BRIGHTNESS_HBM_OFF (BRIGHTNESS_HBM_ON - 1)
#define HBM_BRIGHTNESS(value) ((value) == HBM_ON_STATE ?\
BRIGHTNESS_HBM_ON : BRIGHTNESS_HBM_OFF)
/* HBM implementation is different, depending on display and backlight hardware
* design, which is classified into the following types:
* HBM_TYPE_OLED: OLED panel, HBM is controlled by DSI register only, which
* is independent on brightness.
* HBM_TYPE_LCD_DCS_WLED: LCD panel, HBM is controlled by DSI register, and
* brightness is decided by WLED IC on I2C/SPI bus.
* HBM_TYPE_LCD_DCS_ONLY: LCD panel, brightness/HBM is controlled by DSI
* register only.
* HBM_TYPE_LCD_WLED_ONLY: LCD panel, brightness/HBM is controlled by WLED
* IC only.
* HBM_TYPE_LCD_DCS_GPIO: LCD panel, HBM is controlled by GPIO, and brightness
* is controlled by DSI register.
*
* Note: brightness must be at maximum while enabling HBM for all LCD panels
*/
enum panel_hbm_type {
HBM_TYPE_OLED = 0,
HBM_TYPE_LCD_DCS_WLED,
HBM_TYPE_LCD_DCS_ONLY,
HBM_TYPE_LCD_WLED_ONLY,
HBM_TYPE_LCD_DCS_GPIO
};
enum dsi_panel_rotation {
DSI_PANEL_ROTATE_NONE = 0,
DSI_PANEL_ROTATE_HV_FLIP,
@@ -46,11 +78,19 @@ enum dsi_backlight_type {
DSI_BACKLIGHT_PWM = 0,
DSI_BACKLIGHT_WLED,
DSI_BACKLIGHT_DCS,
DSI_BACKLIGHT_DUMMY,
DSI_BACKLIGHT_EXTERNAL,
DSI_BACKLIGHT_I2C,
DSI_BACKLIGHT_UNKNOWN,
DSI_BACKLIGHT_MAX,
};
enum dsi_backlight_level_align_type {
DSI_BACKLIGHT_LEVEL_ALIGN_NORMAL = 0,
DSI_BACKLIGHT_LEVEL_ALIGN_BIT15_8_BIT3_0 = 1,
};
enum bl_update_flag {
BL_UPDATE_DELAY_UNTIL_FIRST_FRAME,
BL_UPDATE_NONE,
@@ -115,13 +155,18 @@ struct dsi_backlight_config {
enum dsi_backlight_type type;
enum bl_update_flag bl_update;
bool bl_2bytes_enable;
u32 bl_min_level;
u32 bl_max_level;
u32 brightness_max_level;
u32 brightness_default_level;
u32 bl_level;
u32 bl_scale;
u32 bl_scale_sv;
u32 bl_level_align;
bool bl_inverted_dbv;
bool bl_demura_cmd;
u32 demura_type;
u32 bl_dcs_subtype;
int en_gpio;
@@ -133,6 +178,7 @@ struct dsi_backlight_config {
/* WLED params */
struct led_trigger *wled;
struct backlight_device *raw_bd;
struct backlight_device *i2c_bd;
};
struct dsi_reset_seq {
@@ -147,13 +193,22 @@ struct dsi_panel_reset_config {
int reset_gpio;
int disp_en_gpio;
int lcd_mode_sel_gpio;
int tp_rst_gpio;
u32 tp_rst_post_sleep;
u32 panel_rst_due_tp_rst_sleep;
u32 mode_sel_state;
bool panel_on_rst_pull_down;
bool panel_on_tp_rst_enable;
bool reset_force_pull_low;
bool panel_rst_due_tp_rst;
};
enum esd_check_status_mode {
ESD_MODE_REG_READ,
ESD_MODE_SW_BTA,
ESD_MODE_PANEL_TE,
ESD_MODE_PANEL_TE_VIDEO,
ESD_MODE_SW_SIM_SUCCESS,
ESD_MODE_SW_SIM_FAILURE,
ESD_MODE_MAX
@@ -172,6 +227,65 @@ struct drm_panel_esd_config {
u32 groups;
};
enum panel_idx {
MAIN_IDX = 0,
PANEL_IDX_MAX,
};
enum acl_state {
ACL_OFF_STATE = 0,
ACL_ON_STATE,
ACL_STATE_NUM,
};
enum hbm_state {
HBM_OFF_STATE = 0,
HBM_ON_STATE,
HBM_FOD_ON_STATE,
HBM_STATE_NUM
};
enum cabc_state {
CABC_UI_STATE,
CABC_MV_STATE,
CABC_DIS_STATE,
CABC_STATE_NUM,
};
enum dc_state {
DC_OFF_STATE = 0,
DC_ON_STATE,
DC_STATE_NUM,
};
enum color_state {
COLOR_VBT_STATE = 0,
COLOR_STD_STATE,
COLOR_GAME_STATE,
COLOR_NONE_STATE,
COLOR_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;
u16 val_max;
const u16 default_value;
u16 value;
bool is_supported;
};
enum touch_state {
TOUCH_DEEP_SLEEP_STATE = 0,
TOUCH_LOW_POWER_STATE,
};
struct dsi_panel {
const char *name;
const char *type;
@@ -204,6 +318,13 @@ struct dsi_panel {
struct drm_panel_hdr_properties hdr_props;
struct drm_panel_esd_config esd_config;
struct workqueue_struct *workq;
struct delayed_work te_event_work;
int video_te_gpio;
u32 video_te_count;
u32 video_te_count_priv;
int video_te_irq;
struct dsi_parser_utils utils;
bool lp11_init;
@@ -211,6 +332,7 @@ struct dsi_panel {
bool ulps_suspend_enabled;
bool allow_phy_power_off;
bool reset_gpio_always_on;
bool disp_pre_reset;
atomic_t esd_recovery_pending;
bool panel_initialized;
@@ -225,6 +347,31 @@ struct dsi_panel {
int panel_test_gpio;
int power_mode;
enum dsi_panel_physical_type panel_type;
bool esd_utag_enable;
u64 panel_id;
u64 panel_ver;
u32 panel_regDA;
char panel_name[DSI_PANEL_MAX_PANEL_LEN];
char panel_supplier[DSI_PANEL_MAX_PANEL_LEN];
u32 disp_on_chk_val;
bool no_panel_on_read_support;
enum panel_hbm_type hbm_type;
u32 bl_lvl_during_hbm;
bool panel_hbm_fod;
int hbm_en_gpio;
bool is_hbm_using_51_cmd;
struct panel_param *param_cmds;
enum touch_state tp_state;
bool tp_state_check_enable;
int glbl_rescode_top_ctrl;
int glbl_rescode_bot_ctrl;
int glbl_hstx_str_ctrl_0;
int reset_avdd_time_interval;
};
static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel)
@@ -297,6 +444,8 @@ int dsi_panel_set_nolp(struct dsi_panel *panel);
int dsi_panel_prepare(struct dsi_panel *panel);
int dsi_panel_reset(struct dsi_panel *panel);
int dsi_panel_enable(struct dsi_panel *panel);
int dsi_panel_post_enable(struct dsi_panel *panel);
@@ -340,9 +489,16 @@ struct dsi_panel *dsi_panel_ext_bridge_get(struct device *parent,
int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel);
int dsi_panel_parse_panel_cfg(struct dsi_panel *panel, bool is_primary);
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);
void dsi_panel_reset_param(struct dsi_panel *panel);
#endif /* _DSI_PANEL_H_ */
+3
View File
@@ -115,6 +115,9 @@ struct dsi_phy_cfg {
enum dsi_phy_type phy_type;
unsigned long bit_clk_rate_hz;
u32 data_lanes;
int dsi_phy_rescode_top;
int dsi_phy_rescode_bot;
int dsi_phy_hstx_str_ctrl_0;
};
struct dsi_phy_hw;
@@ -355,8 +355,21 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00;
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c;
if(cfg->dsi_phy_rescode_top >= 0)
{
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : cfg->dsi_phy_rescode_top;
}
if(cfg->dsi_phy_rescode_bot >= 0)
{
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : cfg->dsi_phy_rescode_bot;
}
glbl_str_swi_cal_sel_ctrl = 0x00;
glbl_hstx_str_ctrl_0 = 0x88;
if(cfg->dsi_phy_hstx_str_ctrl_0 > 0)
{
glbl_hstx_str_ctrl_0 = cfg->dsi_phy_hstx_str_ctrl_0;
DSI_PHY_INFO(phy, "glbl_hstx_str_ctrl_0=0x%2x\n", glbl_hstx_str_ctrl_0);
}
} else {
vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
+33
View File
@@ -45,6 +45,7 @@
#include <linux/workqueue.h>
#include <uapi/linux/sched/types.h>
#include <drm/drm_of.h>
#include <linux/reboot.h>
#include "msm_drv.h"
#include "msm_kms.h"
@@ -386,6 +387,11 @@ static int msm_drm_uninit(struct device *dev)
priv->registered = false;
}
if (priv->msm_drv_notifier.notifier_call) {
unregister_reboot_notifier(&priv->msm_drv_notifier);
priv->msm_drv_notifier.notifier_call = NULL;
}
#ifdef CONFIG_DRM_FBDEV_EMULATION
if (fbdev && priv->fbdev)
msm_fbdev_free(ddev);
@@ -858,6 +864,23 @@ static void msm_idle_init(struct drm_device *ddev)
spin_lock_init(&idle->lock);
}
static void msm_pdev_shutdown(struct platform_device *pdev);
static int msm_drv_shutdown_notifier_cb(struct notifier_block *nb,
unsigned long event, void *unused)
{
struct device *dev;
struct platform_device *pdev;
struct msm_drm_private *priv = container_of(nb, struct msm_drm_private,
msm_drv_notifier);
dev = priv->dev->dev;
pdev = to_platform_device(dev);
dev_warn(dev, "prepare to shutdown\n");
msm_pdev_shutdown(pdev);
return NOTIFY_DONE;
}
static int msm_drm_init(struct device *dev, struct drm_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -990,6 +1013,16 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
drm_kms_helper_poll_init(ddev);
priv->msm_drv_notifier.notifier_call = msm_drv_shutdown_notifier_cb;
priv->msm_drv_notifier.next = NULL;
priv->msm_drv_notifier.priority = 1;
ret = register_reboot_notifier(&priv->msm_drv_notifier);
if (ret) {
dev_err(dev, "Failed to register for reboot_notifier. ret = %d\n",
ret);
goto fail;
}
return 0;
fail:
+42
View File
@@ -36,6 +36,7 @@
#include <linux/sde_io_util.h>
#include <asm/sizes.h>
#include <linux/kthread.h>
#include <linux/notifier.h>
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
@@ -202,12 +203,19 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_QSYNC_MODE,
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
/* MOT feature panel*/
CONNECTOR_PROP_HBM,
CONNECTOR_PROP_CABC,
CONNECTOR_PROP_ACL,
CONNECTOR_PROP_DC,
CONNECTOR_PROP_COLOR,
/* total # of properties */
CONNECTOR_PROP_COUNT
};
#define MSM_GPU_MAX_RINGS 4
#define MAX_H_TILES_PER_DISPLAY 2
#define MSM_DISP_NAME_LEN_MAX 128
/**
* enum msm_display_compression_type - compression method used for pixel stream
@@ -310,6 +318,28 @@ 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_CABC_ID,
PARAM_ACL_ID,
PARAM_DC_ID,
PARAM_COLOR_ID,
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.
@@ -501,6 +531,10 @@ struct msm_resource_caps_info {
* @h_tile_instance: Controller instance used per tile. Number of elements is
* based on num_of_h_tiles
* @is_connected: Set to true if display is connected
* @panel_id
* @panel_ver
* @panel_regDA
* @panel_name[MSM_DISP_NAME_LEN_MAX];
* @width_mm: Physical width
* @height_mm: Physical height
* @max_width: Max width of display. In case of hot pluggable display
@@ -525,6 +559,12 @@ struct msm_display_info {
bool is_connected;
uint64_t panel_id;
uint64_t panel_ver;
uint32_t panel_regDA;
char panel_name[MSM_DISP_NAME_LEN_MAX];
char panel_supplier[MSM_DISP_NAME_LEN_MAX];
unsigned int width_mm;
unsigned int height_mm;
@@ -712,6 +752,8 @@ struct msm_drm_private {
bool shutdown_in_progress;
struct msm_idle idle;
struct notifier_block msm_drv_notifier;
};
/* get struct msm_kms * from drm_device * */
+166 -3
View File
@@ -88,6 +88,9 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
if (brightness > display->panel->bl_config.bl_max_level)
brightness = display->panel->bl_config.bl_max_level;
if(brightness && brightness < display->panel->bl_config.bl_min_level)
brightness = display->panel->bl_config.bl_min_level;
/* map UI brightness into driver backlight level with rounding */
bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level,
display->panel->bl_config.brightness_max_level);
@@ -149,7 +152,7 @@ static int sde_backlight_setup(struct sde_connector *c_conn,
display = (struct dsi_display *) c_conn->display;
bl_config = &display->panel->bl_config;
props.max_brightness = bl_config->brightness_max_level;
props.brightness = bl_config->brightness_max_level;
props.brightness = bl_config->brightness_default_level;
snprintf(bl_node_name, BL_NODE_NAME_SIZE, "panel%u-backlight",
display_count);
c_conn->bl_device = backlight_device_register(bl_node_name, dev->dev,
@@ -488,8 +491,10 @@ void sde_connector_schedule_status_work(struct drm_connector *connector,
return;
sde_connector_get_info(connector, &info);
if (c_conn->ops.check_status &&
(info.capabilities & MSM_DISPLAY_ESD_ENABLED)) {
if ((c_conn->ops.force_esd_disable &&
(c_conn->ops.force_esd_disable(c_conn->display) == false)) &&
(c_conn->ops.check_status &&
(info.capabilities & MSM_DISPLAY_ESD_ENABLED))) {
if (en) {
u32 interval;
@@ -690,6 +695,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)
{
@@ -1360,6 +1383,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",
@@ -1469,6 +1493,46 @@ 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 = val;
param_info.param_idx = PARAM_HBM_ID;
param_info.param_conn_idx = CONNECTOR_PROP_HBM;
rc = _sde_connector_update_param(c_conn, &param_info);
if (rc)
goto end;
break;
case CONNECTOR_PROP_ACL:
param_info.value = val;
param_info.param_idx = PARAM_ACL_ID;
param_info.param_conn_idx = CONNECTOR_PROP_ACL;
rc = _sde_connector_update_param(c_conn, &param_info);
if (rc)
goto end;
break;
case CONNECTOR_PROP_CABC:
param_info.value = val;
param_info.param_idx = PARAM_CABC_ID;
param_info.param_conn_idx = CONNECTOR_PROP_CABC;
rc = _sde_connector_update_param(c_conn, &param_info);
if (rc)
goto end;
break;
case CONNECTOR_PROP_DC:
param_info.value = val;
param_info.param_idx = PARAM_DC_ID;
param_info.param_conn_idx = CONNECTOR_PROP_DC;
rc = _sde_connector_update_param(c_conn, &param_info);
if (rc)
goto end;
break;
case CONNECTOR_PROP_COLOR:
param_info.value = val;
param_info.param_idx = PARAM_COLOR_ID;
param_info.param_conn_idx = CONNECTOR_PROP_COLOR;
rc = _sde_connector_update_param(c_conn, &param_info);
if (rc)
goto end;
break;
default:
break;
}
@@ -1969,8 +2033,40 @@ static int sde_connector_init_debugfs(struct drm_connector *connector)
}
#endif
static int sde_connector_get_panel_vendor_info(struct drm_connector *connector)
{
struct sde_connector *sde_connector;
struct msm_display_info info;
if (!connector) {
SDE_ERROR("invalid connector\n");
return -EINVAL;
}
sde_connector = to_sde_connector(connector);
sde_connector_get_info(connector, &info);
connector->display_info.panel_id = info.panel_id;
connector->display_info.panel_ver = info.panel_ver;
connector->display_info.panel_regDA = info.panel_regDA;
strncpy(connector->display_info.panel_name, info.panel_name,
sizeof(info.panel_name));
strncpy(connector->display_info.panel_supplier, info.panel_supplier,
sizeof(info.panel_supplier));
return 0;
}
static int sde_connector_late_register(struct drm_connector *connector)
{
int ret = 0;
ret = sde_connector_get_panel_vendor_info(connector);
if (ret) {
SDE_ERROR("failed to retrieve panel vendor info\n");
return ret;
}
return sde_connector_init_debugfs(connector);
}
@@ -2213,6 +2309,7 @@ int sde_connector_esd_status(struct drm_connector *conn)
return ret;
}
u32 interval_video_te = STATUS_CHECK_INTERVAL_MS;
static void sde_connector_check_status_work(struct work_struct *work)
{
struct sde_connector *conn;
@@ -2248,6 +2345,9 @@ static void sde_connector_check_status_work(struct work_struct *work)
/* If debugfs property is not set then take default value */
interval = conn->esd_status_interval ?
conn->esd_status_interval : STATUS_CHECK_INTERVAL_MS;
interval_video_te = interval;
schedule_delayed_work(&conn->status_work,
msecs_to_jiffies(interval));
return;
@@ -2351,6 +2451,61 @@ 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;
u16 prop_max, prop_min, prop_init;
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 if (!strncmp(param_cmds->param_name, "CABC", 4))
prop_idx = CONNECTOR_PROP_CABC;
else if (!strncmp(param_cmds->param_name, "ACL", 3))
prop_idx = CONNECTOR_PROP_ACL;
else if (!strncmp(param_cmds->param_name, "DC", 2))
prop_idx = CONNECTOR_PROP_DC;
else if (!strncmp(param_cmds->param_name, "COLOR", 5))
prop_idx = CONNECTOR_PROP_COLOR;
else {
SDE_ERROR("Invalid param_name =%s\n",
param_cmds->param_name);
return -EINVAL;
}
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++;
}
return 0;
}
int sde_connector_set_blob_data(struct drm_connector *conn,
struct drm_connector_state *state,
enum msm_mdp_conn_property prop_id)
@@ -2681,6 +2836,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))
+27
View File
@@ -15,6 +15,7 @@
#include "msm_prop.h"
#include "sde_kms.h"
#include "sde_fence.h"
#include "sde_motUtil.h"
#define SDE_CONNECTOR_NAME_SIZE 16
#define SDE_CONNECTOR_DHDR_MEMPOOL_MAX_SIZE SZ_32
@@ -264,6 +265,32 @@ struct sde_connector_ops {
void *display, const char *cmd_buf,
u32 cmd_buf_len);
/**
* motUtil_transfer - Convert motUtil data and Transfer command
* to the connected display panel
* @display: Pointer to private display handle
* @cmd_buf: Command buffer
* @cmd_buf_len: Command buffer length in bytes
* @motUtil_data: motUtil data information
* Returns: Zero for success, negetive for failure
*/
int (*motUtil_transfer)(void *display, const char *cmd_buf,
u32 cmd_buf_len, struct motUtil *motUtil_data);
/**
* force_esd_disable - force to disable check_status
* @display: Pointer to private display handle
* Returns: true for forcing ESD disable
*/
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
+6 -2
View File
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (C) 2013 Red Hat
@@ -3377,6 +3378,7 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc,
struct sde_crtc_state *cstate;
struct drm_encoder *enc;
struct sde_kms *sde_kms;
u32 encoder_mask;
if (!crtc || !state) {
SDE_ERROR("invalid argument(s)\n");
@@ -3392,9 +3394,11 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc,
return;
}
SDE_DEBUG("crtc%d\n", crtc->base.id);
encoder_mask = state->encoder_mask ? state->encoder_mask :
crtc->state->encoder_mask;
SDE_DEBUG("crtc%d\n, encoder_mask=%d", crtc->base.id, encoder_mask);
drm_for_each_encoder_mask(enc, crtc->dev, state->encoder_mask)
drm_for_each_encoder_mask(enc, crtc->dev, encoder_mask)
sde_rm_release(&sde_kms->rm, enc, true);
__drm_atomic_helper_crtc_destroy_state(state);
@@ -675,8 +675,18 @@ static bool _sde_encoder_phys_cmd_is_ongoing_pptx(
phys_enc->hw_intf->idx - INTF_0,
atomic_read(&phys_enc->pending_kickoff_cnt),
info.wr_ptr_line_count,
info.intf_frame_count,
info.wr_ptr_line_count,
info.intf_frame_count,
info.intf_line_count,
phys_enc->cached_mode.vdisplay);
pr_err("%s enc:%d pp:%d intf:%d kickoff:%d wr_ptr:%d intf frame:%d int line:%d vdisp:%d\n",
__func__, DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
phys_enc->hw_intf->idx - INTF_0, atomic_read(&phys_enc->pending_kickoff_cnt),
info.wr_ptr_line_count, info.intf_frame_count,
info.intf_line_count, phys_enc->cached_mode.vdisplay);
if (info.wr_ptr_line_count > 0 && info.wr_ptr_line_count <
phys_enc->cached_mode.vdisplay)
return true;
@@ -1498,6 +1508,8 @@ static int _sde_encoder_phys_cmd_wait_for_wr_ptr(
ret = frame_pending ? ret : 0;
SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
/*
* There can be few cases of ESD where CTL_START is cleared but
* wr_ptr irq doesn't come. Signaling retire fence in these
@@ -1826,7 +1838,6 @@ static void _sde_encoder_autorefresh_disable_seq2(
> AUTOREFRESH_SEQ2_POLL_TIMEOUT) {
SDE_ERROR_CMDENC(cmd_enc,
"disable autorefresh failed\n");
SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
break;
}
+3
View File
@@ -633,6 +633,9 @@ static int sde_hw_intf_get_vsync_info(struct sde_hw_intf *intf,
val = SDE_REG_READ(c, INTF_FRAME_COUNT);
info->intf_frame_count = val;
val = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
info->intf_line_count = val;
return 0;
}
+1
View File
@@ -697,6 +697,7 @@ struct sde_hw_pp_vsync_info {
u32 rd_ptr_line_count;
u32 wr_ptr_line_count;
u32 intf_frame_count;
u32 intf_line_count;
};
#endif /* _SDE_HW_MDSS_H */
@@ -490,7 +490,7 @@ void reg_dmav1_setup_dspp_vlutv18(struct sde_hw_dspp *ctx, void *cfg)
return;
}
data = kzalloc(VLUT_LEN, GFP_KERNEL);
data = vzalloc(VLUT_LEN);
if (!data)
return;
@@ -537,7 +537,7 @@ void reg_dmav1_setup_dspp_vlutv18(struct sde_hw_dspp *ctx, void *cfg)
}
exit:
kfree(data);
vfree(data);
/* update flush bit */
if (!rc && ctl && ctl->ops.update_bitmask_dspp_pavlut) {
int dspp_idx;
@@ -1152,7 +1152,7 @@ int reg_dmav1_setup_rc_datav1(struct sde_hw_dspp *ctx, void *cfg)
}
DRM_DEBUG_DRIVER("allocating %u bytes of memory for dma\n", buf_sz);
data = kzalloc(buf_sz, GFP_KERNEL);
data = vzalloc(buf_sz);
if (!data) {
DRM_ERROR("memory allocation failed ret %d\n", rc);
return -ENOMEM;
@@ -1188,7 +1188,7 @@ int reg_dmav1_setup_rc_datav1(struct sde_hw_dspp *ctx, void *cfg)
}
exit:
kfree(data);
vfree(data);
return rc;
}
@@ -1291,7 +1291,7 @@ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg)
return;
}
data = kzalloc(PCC_LEN, GFP_KERNEL);
data = vzalloc(PCC_LEN);
if (!data)
return;
@@ -1357,7 +1357,7 @@ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg)
DRM_ERROR("failed to kick off ret %d\n", rc);
exit:
kfree(data);
vfree(data);
}
void reg_dmav1_setup_dspp_pa_hsicv17(struct sde_hw_dspp *ctx, void *cfg)
@@ -2333,7 +2333,7 @@ static int reg_dmav1_setup_vig_igc_common(struct sde_hw_reg_dma_ops *dma_ops,
hw_cfg->len, sizeof(struct drm_msm_igc_lut));
}
data = kzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
data = vzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32));
if (!data)
return -ENOMEM;
@@ -2395,7 +2395,7 @@ static int reg_dmav1_setup_vig_igc_common(struct sde_hw_reg_dma_ops *dma_ops,
if (rc)
DRM_ERROR("setting opcode failed ret %d\n", rc);
exit:
kfree(data);
vfree(data);
return rc;
}
@@ -2597,7 +2597,7 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
return;
}
data = kzalloc(DMA_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
data = vzalloc(DMA_1D_LUT_IGC_LEN * sizeof(u32));
if (!data) {
DRM_ERROR("failed to allocate memory for igc\n");
return;
@@ -2658,7 +2658,7 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
if (rc)
DRM_ERROR("failed to kick off ret %d\n", rc);
igc_exit:
kfree(data);
vfree(data);
}
static void dma_gcv5_off(struct sde_hw_pipe *ctx, void *cfg,
+12
View File
@@ -27,6 +27,8 @@
#include <linux/of_irq.h>
#include <linux/dma-buf.h>
#include <linux/memblock.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/bootmem.h>
#include <soc/qcom/scm.h>
@@ -55,6 +57,8 @@
#include "soc/qcom/secure_buffer.h"
#include "soc/qcom/qtee_shmbridge.h"
#include "sde_motUtil.h"
#define CREATE_TRACE_POINTS
#include "sde_trace.h"
@@ -147,6 +151,7 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms)
(void) sde_debugfs_vbif_init(sde_kms, debugfs_root);
(void) sde_debugfs_core_irq_init(sde_kms, debugfs_root);
(void) sde_debugfs_mot_util_init(sde_kms, debugfs_root);
rc = sde_core_perf_debugfs_init(&sde_kms->perf, debugfs_root);
if (rc) {
@@ -1430,7 +1435,10 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.post_kickoff = dsi_conn_post_kickoff,
.check_status = dsi_display_check_status,
.enable_event = dsi_conn_enable_event,
.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,
@@ -1448,6 +1456,8 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.get_dst_format = NULL,
.check_status = NULL,
.cmd_transfer = NULL,
.force_esd_disable = NULL,
.set_param = NULL,
.cont_splash_config = NULL,
.get_panel_vfp = NULL,
};
@@ -1465,6 +1475,8 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.set_colorspace = dp_connector_set_colorspace,
.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,
+1 -1
View File
@@ -124,7 +124,7 @@
#define SDE_KMS_OPS_PREPARE_PLANE_FB BIT(3)
/* ESD status check interval in miliseconds */
#define STATUS_CHECK_INTERVAL_MS 5000
#define STATUS_CHECK_INTERVAL_MS 8000
/**
* enum sde_kms_smmu_state: smmu state
+423
View File
@@ -0,0 +1,423 @@
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define pr_fmt(fmt) "motUtil:[%s]" fmt, __func__
#include <linux/debugfs.h>
#include <linux/string.h>
#include <linux/slab.h>
#include "sde_connector.h"
#include "sde_encoder.h"
#include "sde_motUtil.h"
#include "dsi_display.h"
#define MAIN_DSI_CONN_NAME "DSI-1"
#define CLI_DSI_CONN_NAME "DSI-2"
struct motUtil motUtil_data;
static ssize_t _sde_debugfs_motUtil_string2num(const char __user *buf,
size_t count, char buffer[])
{
char *input, *input_copy, *token, *input_dup = NULL;
const char *delim =" ";
u32 buf_size = 0;
int rc=0, strtoint;
/*copy the data from user space*/
input = kmalloc(count + 1, GFP_KERNEL);
if (!input)
return -ENOMEM;
if (copy_from_user(input, buf, count)) {
SDE_ERROR("copy from user failed\n");
rc = -EFAULT;
goto end;
}
input[count]='\0';
SDE_INFO("input_cmd = %s\n", input);
input_copy = kstrdup(input, GFP_KERNEL);
if (!input_copy) {
rc = -ENOMEM;
goto end;
}
input_dup = input_copy,
token = strsep(&input_copy, delim);
while (token) {
rc = kstrtoint(token, 0, &strtoint);
if (rc) {
rc = -EIO;
SDE_ERROR("input buffer conversion failed\n");
goto end;
}
if (buf_size >= MAX_CMD_PAYLOAD_SIZE) {
SDE_ERROR("buffer size exceeding the limit %d\n",
MAX_CMD_PAYLOAD_SIZE);
goto end;
}
buffer[buf_size++] = (strtoint & 0xff);
token = strsep(&input_copy, delim);
}
SDE_DEBUG("command packet size in bytes: %u\n", buf_size);
rc = buf_size;
end:
kfree(input_dup);
kfree(input);
return rc;
}
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;
int found_conn = 0;
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
struct drm_connector_list_iter conn_iter;
mutex_lock(&dev->mode_config.mutex);
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(conn, &conn_iter) {
if (panel_type == MOTUTIL_MAIN_DISP) {
if (!strncmp(conn->name, MAIN_DSI_CONN_NAME, 5)) {
SDE_DEBUG("found MAIN disp conn\n");
found_conn = 1;
break;
}
} else if (panel_type == MOTUTIL_CLI_DISP) {
if (!strncmp(conn->name, CLI_DSI_CONN_NAME, 5)) {
SDE_DEBUG("found CLI disp conn\n");
found_conn = 1;
break;
}
}
}
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;
}
static int _sde_debugfs_motUtil_transfer(struct sde_kms *kms,
size_t count, char input[])
{
struct sde_connector *sde_conn = NULL;
int ret = 0;
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
if (panel_type > MOTUTIL_CLI_DISP) {
SDE_ERROR("Invalid panel number = %d\n", panel_type);
return -EINVAL;
}
sde_conn = _sde_debugfs_motUtil_get_sde_conn(kms, count, input);
if (!sde_conn) {
ret = -EINVAL;
goto end;
}
if (sde_conn && !sde_conn->ops.motUtil_transfer) {
SDE_ERROR("no motUtil_transfer support for connector name %s\n",
sde_conn->name);
ret = -ENOENT;
goto end;
}
if (motUtil_data.rd_buf) {
mutex_lock(&sde_conn->lock);
ret = sde_conn->ops.motUtil_transfer(sde_conn->display,
input, count, &motUtil_data);
motUtil_data.cmd_status = ret;
motUtil_data.read_len = ret;
mutex_unlock(&sde_conn->lock);
ret = count;
} else
ret = -ENOMEM;
end:
return ret;
}
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;
case KMSPROPTEST_TYPE_CABC:
conn_prop_idx = CONNECTOR_PROP_CABC;
break;
case KMSPROPTEST_TYPE_DC:
conn_prop_idx = CONNECTOR_PROP_DC;
break;
case KMSPROPTEST_TYPE_COLOR:
conn_prop_idx = CONNECTOR_PROP_COLOR;
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[])
{
int ret = 0;
enum sde_motUtil_type motUtil_type = input[0];
motUtil_data.motUtil_type = motUtil_type;
switch (motUtil_type) {
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;
}
return ret;
}
static int _sde_debugfs_motUtil_open(struct inode *inode,
struct file *file)
{
if (!inode || !file)
return -EINVAL;
/* non-seekable */
file->private_data = inode->i_private;
return nonseekable_open(inode, file);
}
static ssize_t _sde_debugfs_motUtil_write(struct file *file,
const char __user *buf, size_t count, loff_t *ppos)
{
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");
ret = -EINVAL;
goto end;
}
buf_size = _sde_debugfs_motUtil_string2num(buf, count, buffer);
if (buf_size <= 0){
SDE_ERROR("invalid input\n");
ret = -EINVAL;
goto end;
}
mutex_lock(&motUtil_data.lock);
ret = _sde_debugfs_motUtil_exe_command(kms, count, buffer);
mutex_unlock(&motUtil_data.lock);
end:
motUtil_data.cmd_status = ret;
return count;
}
static ssize_t _sde_debugfs_motUtil_dispUtil_read(char *buffer)
{
int blen = 0, i;
if (motUtil_data.read_len) {
blen = snprintf(buffer, 16, "motUtil_read: ");
for (i = 0; i < motUtil_data.read_len; i ++)
blen += snprintf((buffer + blen) , 6, "0x%02x ",
*motUtil_data.rd_buf++);
blen += snprintf((buffer + blen), 2, "\n");
} else
SDE_ERROR("motUtil failed to read from panel\n");
return blen;
}
static ssize_t _sde_debugfs_motUtil_read(struct file *file,
char __user *buf, size_t count, loff_t *ppos)
{
int blen = 0;
char buffer[MAX_CMD_PAYLOAD_SIZE];
if (*ppos)
return 0;
mutex_lock(&motUtil_data.lock);
if (motUtil_data.cmd_status < 0 || !motUtil_data.read_cmd) {
blen = snprintf(buffer, MAX_CMD_PAYLOAD_SIZE,
"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) {
SDE_ERROR("snprintf failed, blen %d\n", blen);
return 0;
}
if (copy_to_user(buf, buffer, min(count, (size_t)blen+1))) {
SDE_ERROR("copy to user buffer failed\n");
return -EFAULT;
}
*ppos += blen;
mutex_unlock(&motUtil_data.lock);
return blen;
}
static const struct file_operations sde_debugfs_motUtil_fops = {
.open = _sde_debugfs_motUtil_open,
.read = _sde_debugfs_motUtil_read,
.write = _sde_debugfs_motUtil_write,
};
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
struct dentry *parent)
{
debugfs_create_file("motUtil", 0606, parent,
sde_kms, &sde_debugfs_motUtil_fops);
motUtil_data.rd_buf = kzalloc(SZ_4K, GFP_KERNEL);
if (!motUtil_data.rd_buf)
return -ENOMEM;
motUtil_data.te_enable = true;
mutex_init(&motUtil_data.lock);
return 0;
}
+152
View File
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __MOTUTIL_H__
#define __MOTUTIL_H__
#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 {
DISPUTIL_TYPE = 0,
DISPUTIL_PANEL_TYPE,
DISPUTIL_CMD_TYPE,
DISPUTIL_CMD_XFER_MODE,
DISPUTIL_MIPI_CMD_TYPE,
DISPUTIL_NUM_BYTE_RD,
DISPUTIL_PAYLOAD_LEN_U,
DISPUTIL_PAYLOAD_LEN_L,
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,
KMSPROPTEST_TYPE_DC,
KMSPROPTEST_TYPE_COLOR,
};
struct motUtil {
struct mutex lock;
enum sde_motUtil_type motUtil_type;
bool read_cmd;
int cmd_status;
u16 read_len;
u8 *rd_buf;
int val;
bool te_enable;
};
#define DISPUTIL_DSI_WRITE 0
#define DISPUTIL_DSI_READ 1
#define DISPUTIL_DSI_DCS 0
#define DISPUTIL_DSI_GENERIC 1
#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
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
struct dentry *parent);
#endif /* __MOTUTIL_H__ */
+9 -4
View File
@@ -3254,6 +3254,7 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
u32 *dump_addr = NULL;
u32 status = 0;
struct sde_debug_bus_entry *head;
phys_addr_t phys = 0;
int list_size;
int i;
u32 offset;
@@ -3291,7 +3292,8 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
if (in_mem) {
if (!(*dump_mem))
*dump_mem = vzalloc(list_size);
*dump_mem = dma_alloc_coherent(sde_dbg_base.dev,
list_size, &phys, GFP_KERNEL);
if (*dump_mem) {
dump_addr = *dump_mem;
@@ -3401,6 +3403,7 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
u32 value, d0, d1;
unsigned long reg, reg1, reg2;
struct vbif_debug_bus_entry *head;
phys_addr_t phys = 0;
int i, list_size = 0;
void __iomem *mem_base = NULL;
struct vbif_debug_bus_entry *dbg_bus;
@@ -3450,7 +3453,8 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
if (in_mem) {
if (!(*dump_mem))
*dump_mem = vzalloc(list_size);
*dump_mem = dma_alloc_coherent(sde_dbg_base.dev,
list_size, &phys, GFP_KERNEL);
if (*dump_mem) {
dump_addr = *dump_mem;
@@ -3541,12 +3545,14 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
int i;
u32 reg_dump_size;
struct sde_dbg_base *dbg_base = &sde_dbg_base;
phys_addr_t phys = 0;
mutex_lock(&sde_dbg_base.mutex);
reg_dump_size = _sde_dbg_get_reg_dump_size();
if (!dbg_base->reg_dump_base)
dbg_base->reg_dump_base = vzalloc(reg_dump_size);
dbg_base->reg_dump_base = dma_alloc_coherent(sde_dbg_base.dev,
reg_dump_size, &phys, GFP_KERNEL);
dbg_base->reg_dump_addr = dbg_base->reg_dump_base;
@@ -4785,7 +4791,6 @@ static void sde_dbg_reg_base_destroy(void)
list_del(&blk_base->reg_base_head);
kfree(blk_base);
}
vfree(dbg_base->reg_dump_base);
}
static void sde_dbg_buses_destroy(void)
+2 -2
View File
@@ -86,7 +86,7 @@ enum sde_dbg_dump_context {
* sysfs node or panic. This prevents kernel log from evtlog message
* flood.
*/
#define SDE_EVTLOG_PRINT_ENTRY 256
#define SDE_EVTLOG_PRINT_ENTRY 512
/*
* evtlog keeps this number of entries in memory for debug purpose. This
@@ -137,7 +137,7 @@ extern struct sde_dbg_evtlog *sde_dbg_base_evtlog;
* number must be greater than number of possible writes in at least one
* single commit.
*/
#define SDE_REGLOG_ENTRY 1024
#define SDE_REGLOG_ENTRY 2048
struct sde_dbg_reglog_log {
s64 time;