Merge tag 'LA.UM.9.14.r1-19600.01-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers into android12-5.4-lahaina

"LA.UM.9.14.r1-19600.01-LAHAINA.QSSI12.0"

* tag 'LA.UM.9.14.r1-19600.01-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers:
  disp: msm: avoid minidump region addition for mdss register dumps
  disp: msm: dsi: avoid setting ulp load to disable load
  disp: msm: dsi: handle read cmd tx failure from dsi host transfer
  disp: msm: sde: unset and set clk parents during pm_suspend
  disp: msm: dsi: handle panel detection after a pp done timeout
  disp: msm: dsi: Fix DMA window scheduling programming

Change-Id: Iebd52dc842fa23e119b15d3d4f1df73f311c48b3
This commit is contained in:
Michael Bestas 2022-05-24 09:17:17 +03:00
commit df22692bb1
No known key found for this signature in database
GPG key ID: CC95044519BE6669
12 changed files with 136 additions and 22 deletions

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/errno.h>
@ -66,6 +66,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
dsi_ctrl_hw_cmn_wait4dynamic_refresh_done;
ctrl->ops.hs_req_sel = dsi_ctrl_hw_cmn_hs_req_sel;
ctrl->ops.vid_engine_busy = dsi_ctrl_hw_cmn_vid_engine_busy;
ctrl->ops.init_cmddma_trig_ctrl = dsi_ctrl_hw_cmn_init_cmddma_trig_ctrl;
switch (version) {
case DSI_CTRL_VERSION_1_4:

View file

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _DSI_CATALOG_H_
@ -214,6 +214,8 @@ void dsi_ctrl_hw_cmn_error_intr_ctrl(struct dsi_ctrl_hw *ctrl, bool en);
u32 dsi_ctrl_hw_cmn_get_error_mask(struct dsi_ctrl_hw *ctrl);
u32 dsi_ctrl_hw_cmn_get_hw_version(struct dsi_ctrl_hw *ctrl);
int dsi_ctrl_hw_cmn_wait_for_cmd_mode_mdp_idle(struct dsi_ctrl_hw *ctrl);
void dsi_ctrl_hw_cmn_init_cmddma_trig_ctrl(struct dsi_ctrl_hw *ctrl,
struct dsi_host_common_cfg *cfg);
/* Definitions specific to 1.4 DSI controller hardware */
int dsi_ctrl_hw_14_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of_device.h>
@ -1356,6 +1357,10 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl,
dsi_hw_ops.reset_trig_ctrl(&dsi_ctrl->hw,
&dsi_ctrl->host_config.common_config);
if (dsi_hw_ops.init_cmddma_trig_ctrl)
dsi_hw_ops.init_cmddma_trig_ctrl(&dsi_ctrl->hw,
&dsi_ctrl->host_config.common_config);
/*
* Always enable DMA scheduling for video mode panel.
*

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _DSI_CTRL_HW_H_
@ -866,6 +867,15 @@ struct dsi_ctrl_hw_ops {
void (*reset_trig_ctrl)(struct dsi_ctrl_hw *ctrl,
struct dsi_host_common_cfg *cfg);
/**
* hw.ops.init_cmddma_trig_ctrl() - Initialize the default trigger used
* for command mode DMA path.
* @ctrl: Pointer to the controller host hardware.
* @cfg: Common configuration parameters.
*/
void (*init_cmddma_trig_ctrl)(struct dsi_ctrl_hw *ctrl,
struct dsi_host_common_cfg *cfg);
/**
* hw.ops.log_line_count() - reads the MDP interface line count
* registers.

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/iopoll.h>
#include "dsi_ctrl_hw.h"
@ -243,14 +244,16 @@ void dsi_ctrl_hw_22_configure_cmddma_window(struct dsi_ctrl_hw *ctrl,
void dsi_ctrl_hw_22_reset_trigger_controls(struct dsi_ctrl_hw *ctrl,
struct dsi_host_common_cfg *cfg)
{
u32 reg = 0;
u32 reg;
const u8 trigger_map[DSI_TRIGGER_MAX] = {
0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
reg |= (cfg->te_mode == DSI_TE_ON_EXT_PIN) ? BIT(31) : 0;
reg |= (trigger_map[cfg->dma_cmd_trigger] & 0x7);
reg |= (trigger_map[cfg->mdp_cmd_trigger] & 0x7) << 4;
reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
reg &= ~BIT(16); /* Reset DMA_TRG_MUX */
reg &= ~(0xF); /* Reset DMA_TRIGGER_SEL */
reg |= (trigger_map[cfg->dma_cmd_trigger] & 0xF);
DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL2, 0x0);
DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL, 0x0);
ctrl->reset_trig_ctrl = false;

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/delay.h>
@ -86,13 +87,20 @@ static void dsi_split_link_setup(struct dsi_ctrl_hw *ctrl,
static void dsi_setup_trigger_controls(struct dsi_ctrl_hw *ctrl,
struct dsi_host_common_cfg *cfg)
{
u32 reg = 0;
u32 reg;
const u8 trigger_map[DSI_TRIGGER_MAX] = {
0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
reg |= (cfg->te_mode == DSI_TE_ON_EXT_PIN) ? BIT(31) : 0;
reg |= (trigger_map[cfg->dma_cmd_trigger] & 0x7);
reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
if (cfg->te_mode == DSI_TE_ON_EXT_PIN)
reg |= BIT(31);
else
reg &= ~BIT(31);
reg &= ~(0x7 << 4);
reg |= (trigger_map[cfg->mdp_cmd_trigger] & 0x7) << 4;
DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
}
@ -1741,3 +1749,18 @@ bool dsi_ctrl_hw_cmn_vid_engine_busy(struct dsi_ctrl_hw *ctrl)
return false;
}
void dsi_ctrl_hw_cmn_init_cmddma_trig_ctrl(struct dsi_ctrl_hw *ctrl,
struct dsi_host_common_cfg *cfg)
{
u32 reg;
const u8 trigger_map[DSI_TRIGGER_MAX] = {
0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
/* Initialize the default trigger used for Command Mode DMA path. */
reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
reg &= ~BIT(16); /* Reset DMA_TRG_MUX */
reg &= ~(0xF); /* Reset DMA_TRIGGER_SEL */
reg |= (trigger_map[cfg->dma_cmd_trigger] & 0xF);
DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
}

View file

@ -885,16 +885,17 @@ int dsi_display_check_status(struct drm_connector *connector, void *display,
panel->esd_config.esd_enabled = false;
}
if (rc <= 0 && te_check_override)
/*
* TE check may fail even if status read is passing. In case of
* te_check_override, check the status both from reg read and TE.
*/
if (rc > 0 && te_check_override)
rc = dsi_display_status_check_te(dsi_display, te_rechecks);
/* Unmask error interrupts if check passed*/
if (rc > 0) {
dsi_display_set_ctrl_esd_check_flag(dsi_display, false);
dsi_display_mask_ctrl_error_interrupts(dsi_display, mask,
false);
if (te_check_override && panel->esd_config.esd_enabled == false)
rc = dsi_display_status_check_te(dsi_display,
te_rechecks);
}
dsi_display_clk_ctrl(dsi_display->dsi_clk_handle,
@ -2659,7 +2660,7 @@ error:
}
#ifdef CONFIG_DEEPSLEEP
static int dsi_display_unset_clk_src(struct dsi_display *display)
int dsi_display_unset_clk_src(struct dsi_display *display)
{
int rc = 0;
int i;
@ -2684,13 +2685,13 @@ static int dsi_display_unset_clk_src(struct dsi_display *display)
return 0;
}
#else
static inline int dsi_display_unset_clk_src(struct dsi_display *display)
inline int dsi_display_unset_clk_src(struct dsi_display *display)
{
return 0;
}
#endif
static int dsi_display_set_clk_src(struct dsi_display *display)
int dsi_display_set_clk_src(struct dsi_display *display)
{
int rc = 0;
int i;
@ -3340,7 +3341,7 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
&cmd_flags);
if (rc) {
if (rc < 0) {
DSI_ERR("[%s] cmd transfer failed, rc=%d\n",
display->name, rc);
goto error_disable_cmd_engine;
@ -4200,6 +4201,9 @@ static int dsi_display_parse_dt(struct dsi_display *display)
/* Parse TE data */
dsi_display_parse_te_data(display);
display->needs_clk_src_reset = of_property_read_bool(of_node,
"qcom,needs-clk-src-reset");
/* Parse all external bridges from port 0 */
display_for_each_ctrl(i, display) {
display->ext_bridge[i].node_of =

View file

@ -214,6 +214,7 @@ struct dsi_display {
int disp_te_gpio;
bool is_te_irq_enabled;
struct completion esd_te_gate;
bool needs_clk_src_reset;
u32 ctrl_count;
struct dsi_display_ctrl ctrl[MAX_DSI_CTRLS_PER_DISPLAY];
@ -801,4 +802,19 @@ int dsi_display_dump_clks_state(struct dsi_display *display);
*/
void dsi_display_dfps_update_parent(struct dsi_display *display);
/**
* dsi_display_unset_clk_src() - reset the clocks source to default
* @display: Handle to display
*
* Return: Zero on Success
*/
int dsi_display_unset_clk_src(struct dsi_display *display);
/**
* dsi_display_set_clk_src() - set the clocks source
* @display: Handle to display
*
* Return: Zero on Success
*/
int dsi_display_set_clk_src(struct dsi_display *display);
#endif /* _DSI_DISPLAY_H_ */

View file

@ -68,7 +68,6 @@ static int dsi_pwr_parse_supply_node(struct dsi_parser_utils *utils,
rc = utils->read_u32(node, "qcom,supply-ulp-load", &tmp);
if (rc) {
DSI_DEBUG("ulp-load not specified\n");
rc = 0;
}
regs->vregs[i].ulp_load = (!rc ? tmp :
regs->vregs[i].enable_load);

View file

@ -27,6 +27,7 @@
#include <linux/of_irq.h>
#include <linux/dma-buf.h>
#include <linux/memblock.h>
#include <linux/suspend.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_probe_helper.h>
@ -3713,6 +3714,44 @@ void sde_kms_display_early_wakeup(struct drm_device *dev,
drm_connector_list_iter_end(&conn_iter);
}
#ifdef CONFIG_DEEPSLEEP
static int _sde_kms_pm_set_clk_src(struct sde_kms *sde_kms, bool enable)
{
int i, rc = 0;
void *display;
struct dsi_display *dsi_display;
if (mem_sleep_current == PM_SUSPEND_MEM) {
SDE_INFO("Deepsleep\n");
for (i = 0; i < sde_kms->dsi_display_count; i++) {
display = sde_kms->dsi_displays[i];
dsi_display = (struct dsi_display *)display;
if (!dsi_display->needs_clk_src_reset)
continue;
if (enable)
rc = dsi_display_set_clk_src(dsi_display);
else
rc = dsi_display_unset_clk_src(dsi_display);
if (rc) {
SDE_ERROR("failed to set clks rc:%d\n", rc);
return rc;
}
}
}
return rc;
}
#else
static inline int _sde_kms_pm_set_clk_src(struct sde_kms *sde_kms, bool enable)
{
return 0;
}
#endif
static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
struct device *dev)
{
@ -3904,6 +3943,9 @@ unlock:
pm_runtime_put_sync(dev);
pm_runtime_get_noresume(dev);
/* reset clock source based on PM suspend state */
_sde_kms_pm_set_clk_src(sde_kms, false);
/* dump clock state before entering suspend */
if (sde_kms->pm_suspend_clk_dump)
_sde_kms_dump_clks_state(sde_kms);
@ -3941,6 +3983,9 @@ retry:
goto end;
}
/* reset clock source based on PM suspend state */
_sde_kms_pm_set_clk_src(sde_kms, true);
sde_kms->suspend_block = false;
if (sde_kms->suspend_state) {

View file

@ -999,8 +999,10 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
bus->cmn.content_size = list_size / sizeof(u32);
}
#ifdef CONFIG_QCOM_VA_MINIDUMP
if (sde_mini_dump_add_region(bus->cmn.name, list_size, *dump_mem) < 0)
pr_err("minidump add %s failed\n", bus->cmn.name);
#endif
dump_addr = *dump_mem;
SDE_DBG_LOG_DUMP_ADDR(bus->cmn.name, dump_addr, list_size, 0);
@ -1047,8 +1049,10 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
bus->cmn.content_size = list_size / sizeof(u32);
}
#ifdef CONFIG_QCOM_VA_MINIDUMP
if (sde_mini_dump_add_region(bus->cmn.name, list_size, *dump_mem) < 0)
pr_err("minidump add %s failed\n", bus->cmn.name);
#endif
dump_addr = *dump_mem;
@ -1098,10 +1102,12 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
pr_err("Failed to allocate memory for reg_dump_addr size:%d\n",
reg_dump_size);
#ifdef CONFIG_QCOM_VA_MINIDUMP
if (dbg_base->reg_dump_addr &&
sde_mini_dump_add_region("reg_dump",
reg_dump_size, dbg_base->reg_dump_addr) < 0)
pr_err("minidump add regdump failed\n");
#endif
if (dump_all)
sde_evtlog_dump_all(sde_dbg_base.evtlog);

View file

@ -220,7 +220,7 @@ struct sde_dbg_evtlog *sde_evtlog_init(void)
{
struct sde_dbg_evtlog *evtlog;
evtlog = vzalloc(sizeof(*evtlog));
evtlog = kzalloc(sizeof(*evtlog), GFP_KERNEL);
if (!evtlog)
return ERR_PTR(-ENOMEM);
@ -240,7 +240,7 @@ struct sde_dbg_reglog *sde_reglog_init(void)
{
struct sde_dbg_reglog *reglog;
reglog = vzalloc(sizeof(*reglog));
reglog = kzalloc(sizeof(*reglog), GFP_KERNEL);
if (!reglog)
return ERR_PTR(-ENOMEM);
@ -351,7 +351,7 @@ void sde_evtlog_destroy(struct sde_dbg_evtlog *evtlog)
list_del(&filter_node->list);
kfree(filter_node);
}
vfree(evtlog);
kfree(evtlog);
}
void sde_reglog_destroy(struct sde_dbg_reglog *reglog)
@ -359,5 +359,5 @@ void sde_reglog_destroy(struct sde_dbg_reglog *reglog)
if (!reglog)
return;
vfree(reglog);
kfree(reglog);
}