disp: msm: dsi: add support for dual display with shared dsi
In dual display configuration, where only one display is active at a time, dsi0 and dsi1 can be used to drive primary large display and, one of the dsi (dsi0 or dsi1) can be used to drive secondary display. This helps to time division multiplex shared DSI for primary and secondary panel which solves the bandwidth limitation problem. This change adds support to allow sharing of dsi ctrl and phy between dual displays. Change-Id: Ib4ed1bf51f587b544ec24b1b558ff83225b36e4b Signed-off-by: Ritesh Kumar <quic_riteshk@quicinc.com>
This commit is contained in:
@@ -2080,6 +2080,8 @@ static int dsi_ctrl_dts_parse(struct dsi_ctrl *dsi_ctrl,
|
|||||||
|
|
||||||
dsi_ctrl->frame_threshold_time_us = frame_threshold_time_us;
|
dsi_ctrl->frame_threshold_time_us = frame_threshold_time_us;
|
||||||
|
|
||||||
|
dsi_ctrl->dsi_ctrl_shared = of_property_read_bool(of_node, "qcom,dsi-ctrl-shared");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2316,7 +2318,8 @@ struct dsi_ctrl *dsi_ctrl_get(struct device_node *of_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
mutex_lock(&ctrl->ctrl_lock);
|
||||||
if (ctrl->refcount == 1) {
|
if ((ctrl->dsi_ctrl_shared && ctrl->refcount == 2) ||
|
||||||
|
(!ctrl->dsi_ctrl_shared && ctrl->refcount == 1)) {
|
||||||
DSI_CTRL_ERR(ctrl, "Device in use\n");
|
DSI_CTRL_ERR(ctrl, "Device in use\n");
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
mutex_unlock(&ctrl->ctrl_lock);
|
||||||
ctrl = ERR_PTR(-EBUSY);
|
ctrl = ERR_PTR(-EBUSY);
|
||||||
|
@@ -243,6 +243,8 @@ struct dsi_ctrl_interrupts {
|
|||||||
* count.
|
* count.
|
||||||
* @cmd_mode: Boolean to indicate if panel is running in
|
* @cmd_mode: Boolean to indicate if panel is running in
|
||||||
* command mode.
|
* command mode.
|
||||||
|
* @dsi_ctrl_shared: Boolean to indicate if ctrl is shared between
|
||||||
|
* dual displays.
|
||||||
* @cmd_trigger_line: unsigned integer that indicates the line at
|
* @cmd_trigger_line: unsigned integer that indicates the line at
|
||||||
* which command gets triggered.
|
* which command gets triggered.
|
||||||
* @cmd_trigger_frame: unsigned integer that indicates the frame at
|
* @cmd_trigger_frame: unsigned integer that indicates the frame at
|
||||||
@@ -316,6 +318,7 @@ struct dsi_ctrl {
|
|||||||
bool split_link_supported;
|
bool split_link_supported;
|
||||||
bool enable_cmd_dma_stats;
|
bool enable_cmd_dma_stats;
|
||||||
bool cmd_mode;
|
bool cmd_mode;
|
||||||
|
bool dsi_ctrl_shared;
|
||||||
u32 cmd_trigger_line;
|
u32 cmd_trigger_line;
|
||||||
u32 cmd_trigger_frame;
|
u32 cmd_trigger_frame;
|
||||||
u32 cmd_success_line;
|
u32 cmd_success_line;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
@@ -344,6 +344,9 @@ static int dsi_phy_settings_init(struct platform_device *pdev,
|
|||||||
"qcom,dsi-phy-regulator-min-datarate-bps",
|
"qcom,dsi-phy-regulator-min-datarate-bps",
|
||||||
&phy->regulator_min_datarate_bps);
|
&phy->regulator_min_datarate_bps);
|
||||||
|
|
||||||
|
phy->dsi_phy_shared = of_property_read_bool(pdev->dev.of_node,
|
||||||
|
"qcom,dsi-phy-shared");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
lane->count_per_lane = 0;
|
lane->count_per_lane = 0;
|
||||||
@@ -622,7 +625,8 @@ struct msm_dsi_phy *dsi_phy_get(struct device_node *of_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&phy->phy_lock);
|
mutex_lock(&phy->phy_lock);
|
||||||
if (phy->refcount > 0) {
|
if ((phy->dsi_phy_shared && phy->refcount == 2) ||
|
||||||
|
(!phy->dsi_phy_shared && phy->refcount == 1)) {
|
||||||
DSI_PHY_ERR(phy, "Device under use\n");
|
DSI_PHY_ERR(phy, "Device under use\n");
|
||||||
phy = ERR_PTR(-EINVAL);
|
phy = ERR_PTR(-EINVAL);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DSI_PHY_H_
|
#ifndef _DSI_PHY_H_
|
||||||
@@ -76,6 +77,7 @@ enum phy_ulps_return_type {
|
|||||||
* @regulator_min_datarate_bps: Minimum per lane data rate to turn on regulator
|
* @regulator_min_datarate_bps: Minimum per lane data rate to turn on regulator
|
||||||
* @regulator_required: True if phy regulator is required
|
* @regulator_required: True if phy regulator is required
|
||||||
* @dfps_trigger_mdpintf_flush: mdp intf flush controls dfps trigger.
|
* @dfps_trigger_mdpintf_flush: mdp intf flush controls dfps trigger.
|
||||||
|
* @dsi_phy_shared: True if phy is shared between dual displays.
|
||||||
*/
|
*/
|
||||||
struct msm_dsi_phy {
|
struct msm_dsi_phy {
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
@@ -104,6 +106,7 @@ struct msm_dsi_phy {
|
|||||||
u32 regulator_min_datarate_bps;
|
u32 regulator_min_datarate_bps;
|
||||||
bool regulator_required;
|
bool regulator_required;
|
||||||
bool dfps_trigger_mdpintf_flush;
|
bool dfps_trigger_mdpintf_flush;
|
||||||
|
bool dsi_phy_shared;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user