Merge "disp: msm: dsi: update DSI PHY configuration to support splitlink"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
3090ffd63f
@@ -84,6 +84,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
|
|||||||
ctrl->ops.configure_cmddma_window = NULL;
|
ctrl->ops.configure_cmddma_window = NULL;
|
||||||
ctrl->ops.reset_trig_ctrl = NULL;
|
ctrl->ops.reset_trig_ctrl = NULL;
|
||||||
ctrl->ops.log_line_count = NULL;
|
ctrl->ops.log_line_count = NULL;
|
||||||
|
ctrl->ops.splitlink_cmd_setup = NULL;
|
||||||
break;
|
break;
|
||||||
case DSI_CTRL_VERSION_2_0:
|
case DSI_CTRL_VERSION_2_0:
|
||||||
ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map;
|
ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map;
|
||||||
@@ -102,6 +103,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
|
|||||||
ctrl->ops.configure_cmddma_window = NULL;
|
ctrl->ops.configure_cmddma_window = NULL;
|
||||||
ctrl->ops.reset_trig_ctrl = NULL;
|
ctrl->ops.reset_trig_ctrl = NULL;
|
||||||
ctrl->ops.log_line_count = NULL;
|
ctrl->ops.log_line_count = NULL;
|
||||||
|
ctrl->ops.splitlink_cmd_setup = NULL;
|
||||||
break;
|
break;
|
||||||
case DSI_CTRL_VERSION_2_2:
|
case DSI_CTRL_VERSION_2_2:
|
||||||
case DSI_CTRL_VERSION_2_3:
|
case DSI_CTRL_VERSION_2_3:
|
||||||
@@ -129,6 +131,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
|
|||||||
ctrl->ops.reset_trig_ctrl =
|
ctrl->ops.reset_trig_ctrl =
|
||||||
dsi_ctrl_hw_22_reset_trigger_controls;
|
dsi_ctrl_hw_22_reset_trigger_controls;
|
||||||
ctrl->ops.log_line_count = dsi_ctrl_hw_22_log_line_count;
|
ctrl->ops.log_line_count = dsi_ctrl_hw_22_log_line_count;
|
||||||
|
ctrl->ops.splitlink_cmd_setup = dsi_ctrl_hw_22_configure_splitlink;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@@ -290,4 +290,6 @@ int dsi_catalog_phy_pll_setup(struct dsi_phy_hw *phy, u32 pll_ver);
|
|||||||
int dsi_pll_5nm_configure(void *pll, bool commit);
|
int dsi_pll_5nm_configure(void *pll, bool commit);
|
||||||
int dsi_pll_5nm_toggle(void *pll, bool prepare);
|
int dsi_pll_5nm_toggle(void *pll, bool prepare);
|
||||||
|
|
||||||
|
void dsi_ctrl_hw_22_configure_splitlink(struct dsi_ctrl_hw *ctrl,
|
||||||
|
struct dsi_host_common_cfg *common_cfg, u32 sublink);
|
||||||
#endif /* _DSI_CATALOG_H_ */
|
#endif /* _DSI_CATALOG_H_ */
|
||||||
|
@@ -997,7 +997,7 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl,
|
|||||||
if (host_cfg->data_lanes & DSI_DATA_LANE_3)
|
if (host_cfg->data_lanes & DSI_DATA_LANE_3)
|
||||||
num_of_lanes++;
|
num_of_lanes++;
|
||||||
|
|
||||||
if (split_link->split_link_enabled)
|
if (split_link->enabled)
|
||||||
num_of_lanes = split_link->lanes_per_sublink;
|
num_of_lanes = split_link->lanes_per_sublink;
|
||||||
|
|
||||||
config->common_config.num_data_lanes = num_of_lanes;
|
config->common_config.num_data_lanes = num_of_lanes;
|
||||||
@@ -1360,6 +1360,9 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl,
|
|||||||
{
|
{
|
||||||
u32 hw_flags = 0;
|
u32 hw_flags = 0;
|
||||||
struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops;
|
struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops;
|
||||||
|
struct dsi_split_link_config *split_link;
|
||||||
|
|
||||||
|
split_link = &(dsi_ctrl->host_config.common_config.split_link);
|
||||||
|
|
||||||
SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY, flags,
|
SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY, flags,
|
||||||
msg->flags);
|
msg->flags);
|
||||||
@@ -1368,6 +1371,10 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl,
|
|||||||
dsi_hw_ops.reset_trig_ctrl(&dsi_ctrl->hw,
|
dsi_hw_ops.reset_trig_ctrl(&dsi_ctrl->hw,
|
||||||
&dsi_ctrl->host_config.common_config);
|
&dsi_ctrl->host_config.common_config);
|
||||||
|
|
||||||
|
if (dsi_hw_ops.splitlink_cmd_setup && split_link->enabled)
|
||||||
|
dsi_hw_ops.splitlink_cmd_setup(&dsi_ctrl->hw,
|
||||||
|
&dsi_ctrl->host_config.common_config, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always enable DMA scheduling for video mode panel.
|
* Always enable DMA scheduling for video mode panel.
|
||||||
*
|
*
|
||||||
|
@@ -33,6 +33,8 @@
|
|||||||
* display panel dtsi file instead of default.
|
* display panel dtsi file instead of default.
|
||||||
* @DSI_CTRL_CMD_ASYNC_WAIT: Command flag to indicate that the wait for done
|
* @DSI_CTRL_CMD_ASYNC_WAIT: Command flag to indicate that the wait for done
|
||||||
* for this command is asynchronous and must be queued.
|
* for this command is asynchronous and must be queued.
|
||||||
|
* @DSI_CTRL_CMD_SUBLINK0: Send the command in splitlink sublink0 only.
|
||||||
|
* @DSI_CTRL_CMD_SUBLINK1: Send the command in splitlink sublink1 only.
|
||||||
*/
|
*/
|
||||||
#define DSI_CTRL_CMD_READ 0x1
|
#define DSI_CTRL_CMD_READ 0x1
|
||||||
#define DSI_CTRL_CMD_BROADCAST 0x2
|
#define DSI_CTRL_CMD_BROADCAST 0x2
|
||||||
@@ -44,6 +46,8 @@
|
|||||||
#define DSI_CTRL_CMD_NON_EMBEDDED_MODE 0x80
|
#define DSI_CTRL_CMD_NON_EMBEDDED_MODE 0x80
|
||||||
#define DSI_CTRL_CMD_CUSTOM_DMA_SCHED 0x100
|
#define DSI_CTRL_CMD_CUSTOM_DMA_SCHED 0x100
|
||||||
#define DSI_CTRL_CMD_ASYNC_WAIT 0x200
|
#define DSI_CTRL_CMD_ASYNC_WAIT 0x200
|
||||||
|
#define DSI_CTRL_CMD_SUBLINK0 0x400
|
||||||
|
#define DSI_CTRL_CMD_SUBLINK1 0x800
|
||||||
|
|
||||||
/* DSI embedded mode fifo size
|
/* DSI embedded mode fifo size
|
||||||
* If the command is greater than 256 bytes it is sent in non-embedded mode.
|
* If the command is greater than 256 bytes it is sent in non-embedded mode.
|
||||||
|
@@ -869,6 +869,15 @@ struct dsi_ctrl_hw_ops {
|
|||||||
* @cmd_mode: Boolean to indicate command mode operation.
|
* @cmd_mode: Boolean to indicate command mode operation.
|
||||||
*/
|
*/
|
||||||
u32 (*log_line_count)(struct dsi_ctrl_hw *ctrl, bool cmd_mode);
|
u32 (*log_line_count)(struct dsi_ctrl_hw *ctrl, bool cmd_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hw.ops.splitlink_cmd_setup() - configure the sublink to transfer
|
||||||
|
* @ctrl: Pointer to the controller host hardware.
|
||||||
|
* @common_cfg: Common configuration parameters.
|
||||||
|
* @sublink: Which sublink to transfer the command.
|
||||||
|
*/
|
||||||
|
void (*splitlink_cmd_setup)(struct dsi_ctrl_hw *ctrl,
|
||||||
|
struct dsi_host_common_cfg *common_cfg, u32 sublink);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/iopoll.h>
|
#include <linux/iopoll.h>
|
||||||
#include "dsi_ctrl_hw.h"
|
#include "dsi_ctrl_hw.h"
|
||||||
#include "dsi_ctrl_reg.h"
|
#include "dsi_ctrl_reg.h"
|
||||||
#include "dsi_hw.h"
|
#include "dsi_hw.h"
|
||||||
|
#include "dsi_ctrl.h"
|
||||||
#include "dsi_catalog.h"
|
#include "dsi_catalog.h"
|
||||||
|
|
||||||
#define DISP_CC_MISC_CMD_REG_OFF 0x00
|
#define DISP_CC_MISC_CMD_REG_OFF 0x00
|
||||||
@@ -280,3 +281,27 @@ u32 dsi_ctrl_hw_22_log_line_count(struct dsi_ctrl_hw *ctrl, bool cmd_mode)
|
|||||||
+ MDP_INTF_LINE_COUNT_OFFSET);
|
+ MDP_INTF_LINE_COUNT_OFFSET);
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dsi_ctrl_hw_22_configure_splitlink(struct dsi_ctrl_hw *ctrl,
|
||||||
|
struct dsi_host_common_cfg *common_cfg, u32 flags)
|
||||||
|
{
|
||||||
|
u32 reg = 0;
|
||||||
|
|
||||||
|
reg = DSI_R32(ctrl, DSI_SPLIT_LINK);
|
||||||
|
|
||||||
|
/* DMA_LINK_SEL */
|
||||||
|
reg &= ~(0x7 << 12);
|
||||||
|
|
||||||
|
/* Send command to both sublinks unless specified */
|
||||||
|
if (flags & DSI_CTRL_CMD_SUBLINK0)
|
||||||
|
reg |= BIT(12);
|
||||||
|
else if (flags & DSI_CTRL_CMD_SUBLINK1)
|
||||||
|
reg |= BIT(13);
|
||||||
|
else
|
||||||
|
reg |= (BIT(12) | BIT(13));
|
||||||
|
|
||||||
|
DSI_W32(ctrl, DSI_SPLIT_LINK, reg);
|
||||||
|
|
||||||
|
/* Make sure the split link config is updated */
|
||||||
|
wmb();
|
||||||
|
}
|
||||||
|
@@ -56,7 +56,7 @@ static void dsi_split_link_setup(struct dsi_ctrl_hw *ctrl,
|
|||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
if (!cfg->split_link.split_link_enabled)
|
if (!cfg->split_link.enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
reg = DSI_R32(ctrl, DSI_SPLIT_LINK);
|
reg = DSI_R32(ctrl, DSI_SPLIT_LINK);
|
||||||
@@ -69,6 +69,14 @@ static void dsi_split_link_setup(struct dsi_ctrl_hw *ctrl,
|
|||||||
reg &= ~(0x7 << 20);
|
reg &= ~(0x7 << 20);
|
||||||
reg |= DSI_CTRL_MDP0_LINK_SEL;
|
reg |= DSI_CTRL_MDP0_LINK_SEL;
|
||||||
|
|
||||||
|
/* COMMAND_INPUT_SWAP|VIDEO_INPUT_SWAP */
|
||||||
|
if (cfg->split_link.sublink_swap) {
|
||||||
|
if (cfg->split_link.panel_mode == DSI_OP_CMD_MODE)
|
||||||
|
reg |= BIT(8);
|
||||||
|
else
|
||||||
|
reg |= BIT(4);
|
||||||
|
}
|
||||||
|
|
||||||
/* EN */
|
/* EN */
|
||||||
reg |= 0x1;
|
reg |= 0x1;
|
||||||
|
|
||||||
|
@@ -443,14 +443,20 @@ struct dsi_mode_info {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dsi_split_link_config - Split Link Configuration
|
* struct dsi_split_link_config - Split Link Configuration
|
||||||
* @split_link_enabled: Split Link Enabled.
|
* @enabled: Split Link Enabled.
|
||||||
|
* @sublink_swap: Split link left right sublinks swap.
|
||||||
* @num_sublinks: Number of sublinks.
|
* @num_sublinks: Number of sublinks.
|
||||||
* @lanes_per_sublink: Number of lanes per sublink.
|
* @lanes_per_sublink: Number of lanes per sublink.
|
||||||
|
* @panel_mode: Specifies cmd or video mode.
|
||||||
|
* @lanes_enabled: Specifies what all lanes are enabled.
|
||||||
*/
|
*/
|
||||||
struct dsi_split_link_config {
|
struct dsi_split_link_config {
|
||||||
bool split_link_enabled;
|
bool enabled;
|
||||||
|
bool sublink_swap;
|
||||||
u32 num_sublinks;
|
u32 num_sublinks;
|
||||||
u32 lanes_per_sublink;
|
u32 lanes_per_sublink;
|
||||||
|
u8 lanes_enabled;
|
||||||
|
enum dsi_op_mode panel_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2055,7 +2055,7 @@ static void adjust_timing_by_ctrl_count(const struct dsi_display *display,
|
|||||||
struct dsi_display_mode *mode)
|
struct dsi_display_mode *mode)
|
||||||
{
|
{
|
||||||
struct dsi_host_common_cfg *host = &display->panel->host_config;
|
struct dsi_host_common_cfg *host = &display->panel->host_config;
|
||||||
bool is_split_link = host->split_link.split_link_enabled;
|
bool is_split_link = host->split_link.enabled;
|
||||||
u32 sublinks_count = host->split_link.num_sublinks;
|
u32 sublinks_count = host->split_link.num_sublinks;
|
||||||
|
|
||||||
if (is_split_link && sublinks_count > 1) {
|
if (is_split_link && sublinks_count > 1) {
|
||||||
@@ -4104,6 +4104,7 @@ static int dsi_display_res_init(struct dsi_display *display)
|
|||||||
|
|
||||||
display_for_each_ctrl(i, display) {
|
display_for_each_ctrl(i, display) {
|
||||||
struct msm_dsi_phy *phy = display->ctrl[i].phy;
|
struct msm_dsi_phy *phy = display->ctrl[i].phy;
|
||||||
|
struct dsi_host_common_cfg *host = &display->panel->host_config;
|
||||||
|
|
||||||
phy->cfg.force_clk_lane_hs =
|
phy->cfg.force_clk_lane_hs =
|
||||||
display->panel->host_config.force_hs_clk_lane;
|
display->panel->host_config.force_hs_clk_lane;
|
||||||
@@ -4117,6 +4118,10 @@ static int dsi_display_res_init(struct dsi_display *display)
|
|||||||
if ((display->panel->dyn_clk_caps.dyn_clk_support) &&
|
if ((display->panel->dyn_clk_caps.dyn_clk_support) &&
|
||||||
(display->panel->panel_mode == DSI_OP_VIDEO_MODE))
|
(display->panel->panel_mode == DSI_OP_VIDEO_MODE))
|
||||||
dsi_phy_pll_parse_dfps_data(phy);
|
dsi_phy_pll_parse_dfps_data(phy);
|
||||||
|
|
||||||
|
phy->cfg.split_link.enabled = host->split_link.enabled;
|
||||||
|
phy->cfg.split_link.num_sublinks = host->split_link.num_sublinks;
|
||||||
|
phy->cfg.split_link.lanes_per_sublink = host->split_link.lanes_per_sublink;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = dsi_display_parse_lane_map(display);
|
rc = dsi_display_parse_lane_map(display);
|
||||||
@@ -5296,16 +5301,9 @@ static int dsi_display_validate_split_link(struct dsi_display *display)
|
|||||||
struct dsi_display_ctrl *ctrl;
|
struct dsi_display_ctrl *ctrl;
|
||||||
struct dsi_host_common_cfg *host = &display->panel->host_config;
|
struct dsi_host_common_cfg *host = &display->panel->host_config;
|
||||||
|
|
||||||
if (!host->split_link.split_link_enabled)
|
if (!host->split_link.enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (display->panel->panel_mode == DSI_OP_CMD_MODE) {
|
|
||||||
DSI_ERR("[%s] split link is not supported in command mode\n",
|
|
||||||
display->name);
|
|
||||||
rc = -ENOTSUPP;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
display_for_each_ctrl(i, display) {
|
display_for_each_ctrl(i, display) {
|
||||||
ctrl = &display->ctrl[i];
|
ctrl = &display->ctrl[i];
|
||||||
if (!ctrl->ctrl->split_link_supported) {
|
if (!ctrl->ctrl->split_link_supported) {
|
||||||
@@ -5316,13 +5314,14 @@ static int dsi_display_validate_split_link(struct dsi_display *display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_bit(DSI_PHY_SPLIT_LINK, ctrl->phy->hw.feature_map);
|
set_bit(DSI_PHY_SPLIT_LINK, ctrl->phy->hw.feature_map);
|
||||||
|
host->split_link.panel_mode = display->panel->panel_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSI_DEBUG("Split link is enabled\n");
|
DSI_DEBUG("Split link is enabled\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
host->split_link.split_link_enabled = false;
|
host->split_link.enabled = false;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6552,7 +6551,7 @@ int dsi_display_get_info(struct drm_connector *connector,
|
|||||||
info->te_source = display->te_source;
|
info->te_source = display->te_source;
|
||||||
|
|
||||||
host = &display->panel->host_config;
|
host = &display->panel->host_config;
|
||||||
if (host->split_link.split_link_enabled)
|
if (host->split_link.enabled)
|
||||||
info->capabilities |= MSM_DISPLAY_SPLIT_LINK;
|
info->capabilities |= MSM_DISPLAY_SPLIT_LINK;
|
||||||
|
|
||||||
info->dsc_count = display->panel->dsc_count;
|
info->dsc_count = display->panel->dsc_count;
|
||||||
@@ -6818,7 +6817,7 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|||||||
display_mode.timing.mdp_transfer_time_us;
|
display_mode.timing.mdp_transfer_time_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_split_link = host->split_link.split_link_enabled;
|
is_split_link = host->split_link.enabled;
|
||||||
sublinks_count = host->split_link.num_sublinks;
|
sublinks_count = host->split_link.num_sublinks;
|
||||||
if (is_split_link && sublinks_count > 1) {
|
if (is_split_link && sublinks_count > 1) {
|
||||||
display_mode.timing.h_active *= sublinks_count;
|
display_mode.timing.h_active *= sublinks_count;
|
||||||
@@ -6916,7 +6915,7 @@ int dsi_display_get_panel_vfp(void *dsi_display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
host = &display->panel->host_config;
|
host = &display->panel->host_config;
|
||||||
if (host->split_link.split_link_enabled)
|
if (host->split_link.enabled)
|
||||||
h_active *= host->split_link.num_sublinks;
|
h_active *= host->split_link.num_sublinks;
|
||||||
else
|
else
|
||||||
h_active *= display->ctrl_count;
|
h_active *= display->ctrl_count;
|
||||||
|
@@ -1157,7 +1157,7 @@ static void dsi_panel_parse_split_link_config(struct dsi_host_common_cfg *host,
|
|||||||
|
|
||||||
if (!supported) {
|
if (!supported) {
|
||||||
DSI_DEBUG("[%s] Split link is not supported\n", name);
|
DSI_DEBUG("[%s] Split link is not supported\n", name);
|
||||||
split_link->split_link_enabled = false;
|
split_link->enabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1177,9 +1177,14 @@ static void dsi_panel_parse_split_link_config(struct dsi_host_common_cfg *host,
|
|||||||
split_link->lanes_per_sublink = val;
|
split_link->lanes_per_sublink = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supported = utils->read_bool(utils->data, "qcom,split-link-sublink-swap");
|
||||||
|
|
||||||
|
if (!supported)
|
||||||
|
split_link->sublink_swap = false;
|
||||||
|
|
||||||
DSI_DEBUG("[%s] Split link is supported %d-%d\n", name,
|
DSI_DEBUG("[%s] Split link is supported %d-%d\n", name,
|
||||||
split_link->num_sublinks, split_link->lanes_per_sublink);
|
split_link->num_sublinks, split_link->lanes_per_sublink);
|
||||||
split_link->split_link_enabled = true;
|
split_link->enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsi_panel_parse_host_config(struct dsi_panel *panel)
|
static int dsi_panel_parse_host_config(struct dsi_panel *panel)
|
||||||
|
@@ -116,6 +116,7 @@ struct dsi_phy_per_lane_cfgs {
|
|||||||
* @force_clk_lane_hs:Boolean whether to force clock lane in HS mode.
|
* @force_clk_lane_hs:Boolean whether to force clock lane in HS mode.
|
||||||
* @phy_type: Phy-type (Dphy/Cphy).
|
* @phy_type: Phy-type (Dphy/Cphy).
|
||||||
* @bit_clk_rate_hz: DSI bit clk rate in HZ.
|
* @bit_clk_rate_hz: DSI bit clk rate in HZ.
|
||||||
|
* @split_link: DSI split link config data.
|
||||||
*/
|
*/
|
||||||
struct dsi_phy_cfg {
|
struct dsi_phy_cfg {
|
||||||
struct dsi_phy_per_lane_cfgs lanecfg;
|
struct dsi_phy_per_lane_cfgs lanecfg;
|
||||||
@@ -128,6 +129,7 @@ struct dsi_phy_cfg {
|
|||||||
bool force_clk_lane_hs;
|
bool force_clk_lane_hs;
|
||||||
enum dsi_phy_type phy_type;
|
enum dsi_phy_type phy_type;
|
||||||
unsigned long bit_clk_rate_hz;
|
unsigned long bit_clk_rate_hz;
|
||||||
|
struct dsi_split_link_config split_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dsi_phy_hw;
|
struct dsi_phy_hw;
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/iopoll.h>
|
#include <linux/iopoll.h>
|
||||||
#include "dsi_hw.h"
|
#include "dsi_hw.h"
|
||||||
|
#include "dsi_defs.h"
|
||||||
#include "dsi_phy_hw.h"
|
#include "dsi_phy_hw.h"
|
||||||
#include "dsi_catalog.h"
|
#include "dsi_catalog.h"
|
||||||
|
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
#define DSIPHY_CMN_LANE_STATUS0 0x148
|
#define DSIPHY_CMN_LANE_STATUS0 0x148
|
||||||
#define DSIPHY_CMN_LANE_STATUS1 0x14C
|
#define DSIPHY_CMN_LANE_STATUS1 0x14C
|
||||||
#define DSIPHY_CMN_GLBL_DIGTOP_SPARE10 0x1AC
|
#define DSIPHY_CMN_GLBL_DIGTOP_SPARE10 0x1AC
|
||||||
|
#define DSIPHY_CMN_CMN_SL_DSI_LANE_CTRL1 0x1B4
|
||||||
|
|
||||||
/* n = 0..3 for data lanes and n = 4 for clock lane */
|
/* n = 0..3 for data lanes and n = 4 for clock lane */
|
||||||
#define DSIPHY_LNX_CFG0(n) (0x200 + (0x80 * (n)))
|
#define DSIPHY_LNX_CFG0(n) (0x200 + (0x80 * (n)))
|
||||||
@@ -156,12 +158,17 @@ static void dsi_phy_hw_v4_0_lane_settings(struct dsi_phy_hw *phy,
|
|||||||
u8 tx_dctrl_v4[] = {0x00, 0x00, 0x00, 0x04, 0x01};
|
u8 tx_dctrl_v4[] = {0x00, 0x00, 0x00, 0x04, 0x01};
|
||||||
u8 tx_dctrl_v4_1[] = {0x40, 0x40, 0x40, 0x46, 0x41};
|
u8 tx_dctrl_v4_1[] = {0x40, 0x40, 0x40, 0x46, 0x41};
|
||||||
u8 *tx_dctrl;
|
u8 *tx_dctrl;
|
||||||
|
bool split_link_enabled;
|
||||||
|
u32 lanes_per_sublink;
|
||||||
|
|
||||||
if (phy->version >= DSI_PHY_VERSION_4_1)
|
if (phy->version >= DSI_PHY_VERSION_4_1)
|
||||||
tx_dctrl = &tx_dctrl_v4_1[0];
|
tx_dctrl = &tx_dctrl_v4_1[0];
|
||||||
else
|
else
|
||||||
tx_dctrl = &tx_dctrl_v4[0];
|
tx_dctrl = &tx_dctrl_v4[0];
|
||||||
|
|
||||||
|
split_link_enabled = cfg->split_link.enabled;
|
||||||
|
lanes_per_sublink = cfg->split_link.lanes_per_sublink;
|
||||||
|
|
||||||
/* Strength ctrl settings */
|
/* Strength ctrl settings */
|
||||||
for (i = DSI_LOGICAL_LANE_0; i < DSI_LANE_MAX; i++) {
|
for (i = DSI_LOGICAL_LANE_0; i < DSI_LANE_MAX; i++) {
|
||||||
/*
|
/*
|
||||||
@@ -182,6 +189,19 @@ static void dsi_phy_hw_v4_0_lane_settings(struct dsi_phy_hw *phy,
|
|||||||
DSI_W32(phy, DSIPHY_LNX_TX_DCTRL(i), tx_dctrl[i]);
|
DSI_W32(phy, DSIPHY_LNX_TX_DCTRL(i), tx_dctrl[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove below check if cphy splitlink is enabled */
|
||||||
|
if (split_link_enabled && (cfg->phy_type == DSI_PHY_TYPE_CPHY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Configure the splitlink clock lane with clk lane settings */
|
||||||
|
if (split_link_enabled) {
|
||||||
|
DSI_W32(phy, DSIPHY_LNX_LPRX_CTRL(5), 0x0);
|
||||||
|
DSI_W32(phy, DSIPHY_LNX_PIN_SWAP(5), 0x0);
|
||||||
|
DSI_W32(phy, DSIPHY_LNX_CFG0(5), cfg->lanecfg.lane[4][0]);
|
||||||
|
DSI_W32(phy, DSIPHY_LNX_CFG1(5), cfg->lanecfg.lane[4][1]);
|
||||||
|
DSI_W32(phy, DSIPHY_LNX_CFG2(5), cfg->lanecfg.lane[4][2]);
|
||||||
|
DSI_W32(phy, DSIPHY_LNX_TX_DCTRL(5), tx_dctrl[4]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dsi_phy_hw_v4_0_commit_phy_timing(struct dsi_phy_hw *phy,
|
void dsi_phy_hw_v4_0_commit_phy_timing(struct dsi_phy_hw *phy,
|
||||||
@@ -331,6 +351,8 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
|
|||||||
u32 glbl_hstx_str_ctrl_0 = 0;
|
u32 glbl_hstx_str_ctrl_0 = 0;
|
||||||
u32 glbl_rescode_top_ctrl = 0;
|
u32 glbl_rescode_top_ctrl = 0;
|
||||||
u32 glbl_rescode_bot_ctrl = 0;
|
u32 glbl_rescode_bot_ctrl = 0;
|
||||||
|
bool split_link_enabled;
|
||||||
|
u32 lanes_per_sublink;
|
||||||
|
|
||||||
/* Alter PHY configurations if data rate less than 1.5GHZ*/
|
/* Alter PHY configurations if data rate less than 1.5GHZ*/
|
||||||
if (cfg->bit_clk_rate_hz <= 1500000000)
|
if (cfg->bit_clk_rate_hz <= 1500000000)
|
||||||
@@ -356,10 +378,17 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
|
|||||||
glbl_rescode_bot_ctrl = 0x3c;
|
glbl_rescode_bot_ctrl = 0x3c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
split_link_enabled = cfg->split_link.enabled;
|
||||||
|
lanes_per_sublink = cfg->split_link.lanes_per_sublink;
|
||||||
/* de-assert digital and pll power down */
|
/* de-assert digital and pll power down */
|
||||||
data = BIT(6) | BIT(5);
|
data = BIT(6) | BIT(5);
|
||||||
DSI_W32(phy, DSIPHY_CMN_CTRL_0, data);
|
DSI_W32(phy, DSIPHY_CMN_CTRL_0, data);
|
||||||
|
|
||||||
|
if (split_link_enabled) {
|
||||||
|
data = DSI_R32(phy, DSIPHY_CMN_GLBL_CTRL);
|
||||||
|
/* set SPLIT_LINK_ENABLE in global control */
|
||||||
|
DSI_W32(phy, DSIPHY_CMN_GLBL_CTRL, (data | BIT(5)));
|
||||||
|
}
|
||||||
/* Assert PLL core reset */
|
/* Assert PLL core reset */
|
||||||
DSI_W32(phy, DSIPHY_CMN_PLL_CNTRL, 0x00);
|
DSI_W32(phy, DSIPHY_CMN_PLL_CNTRL, 0x00);
|
||||||
|
|
||||||
@@ -389,10 +418,23 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
|
|||||||
glbl_rescode_bot_ctrl);
|
glbl_rescode_bot_ctrl);
|
||||||
DSI_W32(phy, DSIPHY_CMN_GLBL_LPTX_STR_CTRL, 0x55);
|
DSI_W32(phy, DSIPHY_CMN_GLBL_LPTX_STR_CTRL, 0x55);
|
||||||
|
|
||||||
/* Remove power down from all blocks */
|
if (split_link_enabled) {
|
||||||
DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f);
|
if (lanes_per_sublink == 1) {
|
||||||
|
/* remove Lane1 and Lane3 configs */
|
||||||
|
DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0xed);
|
||||||
|
DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x35);
|
||||||
|
} else {
|
||||||
|
/* enable all together with sublink clock */
|
||||||
|
DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0xff);
|
||||||
|
DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x1F);
|
DSI_W32(phy, DSIPHY_CMN_CMN_SL_DSI_LANE_CTRL1, 0x03);
|
||||||
|
} else {
|
||||||
|
/* Remove power down from all blocks */
|
||||||
|
DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f);
|
||||||
|
DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x1F);
|
||||||
|
}
|
||||||
|
|
||||||
/* Select full-rate mode */
|
/* Select full-rate mode */
|
||||||
DSI_W32(phy, DSIPHY_CMN_CTRL_2, 0x40);
|
DSI_W32(phy, DSIPHY_CMN_CTRL_2, 0x40);
|
||||||
@@ -472,8 +514,8 @@ void dsi_phy_hw_v4_0_disable(struct dsi_phy_hw *phy,
|
|||||||
dsi_phy_hw_v4_0_config_lpcdrx(phy, cfg, false);
|
dsi_phy_hw_v4_0_config_lpcdrx(phy, cfg, false);
|
||||||
|
|
||||||
data = DSI_R32(phy, DSIPHY_CMN_CTRL_0);
|
data = DSI_R32(phy, DSIPHY_CMN_CTRL_0);
|
||||||
/* disable all lanes */
|
/* disable all lanes and splitlink clk lane*/
|
||||||
data &= ~0x1F;
|
data &= ~0x9F;
|
||||||
DSI_W32(phy, DSIPHY_CMN_CTRL_0, data);
|
DSI_W32(phy, DSIPHY_CMN_CTRL_0, data);
|
||||||
DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0);
|
DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user