Skip to content

Commit

Permalink
drm/msm/dsi: Pass down use case to PHY
Browse files Browse the repository at this point in the history
For some new types of DSI PHY, more settings depend on
use cases controlled by DSI manager. This change allows
DSI manager to setup PHY with a use case.

Signed-off-by: Hai Li <hali@codeaurora.org>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
  • Loading branch information
Hai Li authored and Rob Clark committed Feb 6, 2017
1 parent dceac34 commit 57bf433
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 30 deletions.
8 changes: 8 additions & 0 deletions drivers/gpu/drm/msm/dsi/dsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ enum msm_dsi_phy_type {
MSM_DSI_PHY_MAX
};

enum msm_dsi_phy_usecase {
MSM_DSI_PHY_STANDALONE,
MSM_DSI_PHY_MASTER,
MSM_DSI_PHY_SLAVE,
};

#define DSI_DEV_REGULATOR_MAX 8
#define DSI_BUS_CLK_MAX 4

Expand Down Expand Up @@ -180,6 +186,8 @@ void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
struct msm_dsi_phy_shared_timings *shared_timing);
struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy);
void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
enum msm_dsi_phy_usecase uc);

#endif /* __DSI_CONNECTOR_H__ */

43 changes: 14 additions & 29 deletions drivers/gpu/drm/msm/dsi/dsi_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@ static int dsi_mgr_parse_dual_dsi(struct device_node *np, int id)
return 0;
}

static int dsi_mgr_host_register(int id)
static int dsi_mgr_setup_components(int id)
{
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
struct msm_dsi_pll *src_pll;
int ret;

Expand All @@ -85,30 +86,35 @@ static int dsi_mgr_host_register(int id)
if (ret)
return ret;

msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
src_pll = msm_dsi_phy_get_pll(msm_dsi->phy);
ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll);
} else if (!other_dsi) {
ret = 0;
} else {
struct msm_dsi *mdsi = IS_MASTER_DSI_LINK(id) ?
msm_dsi : other_dsi;
struct msm_dsi *sdsi = IS_MASTER_DSI_LINK(id) ?
other_dsi : msm_dsi;
struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
msm_dsi : other_dsi;
struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
other_dsi : msm_dsi;
/* Register slave host first, so that slave DSI device
* has a chance to probe, and do not block the master
* DSI device's probe.
* Also, do not check defer for the slave host,
* because only master DSI device adds the panel to global
* panel list. The panel's device is the master DSI device.
*/
ret = msm_dsi_host_register(sdsi->host, false);
ret = msm_dsi_host_register(slave_link_dsi->host, false);
if (ret)
return ret;
ret = msm_dsi_host_register(mdsi->host, true);
ret = msm_dsi_host_register(master_link_dsi->host, true);
if (ret)
return ret;

/* PLL0 is to drive both 2 DSI link clocks in Dual DSI mode. */
msm_dsi_phy_set_usecase(clk_master_dsi->phy,
MSM_DSI_PHY_MASTER);
msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
MSM_DSI_PHY_SLAVE);
src_pll = msm_dsi_phy_get_pll(clk_master_dsi->phy);
ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll);
if (ret)
Expand Down Expand Up @@ -665,28 +671,12 @@ int msm_dsi_manager_phy_enable(int id,
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
struct msm_dsi_phy *phy = msm_dsi->phy;
int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id;
struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy);
int ret;

ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate);
if (ret)
return ret;

/*
* Reset DSI PHY silently changes its PLL registers to reset status,
* which will confuse clock driver and result in wrong output rate of
* link clocks. Restore PLL status if its PLL is being used as clock
* source.
*/
if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) {
ret = msm_dsi_pll_restore_state(pll);
if (ret) {
pr_err("%s: failed to restore pll state\n", __func__);
msm_dsi_phy_disable(phy);
return ret;
}
}

msm_dsi->phy_enabled = true;
msm_dsi_phy_get_shared_timings(phy, shared_timings);

Expand All @@ -699,11 +689,6 @@ void msm_dsi_manager_phy_disable(int id)
struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
struct msm_dsi_phy *phy = msm_dsi->phy;
struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy);

/* Save PLL status if it is a clock source */
if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER))
msm_dsi_pll_save_state(pll);

/* disable DSI phy
* In dual-dsi configuration, the phy should be disabled for the
Expand Down Expand Up @@ -834,7 +819,7 @@ int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
goto fail;
}

ret = dsi_mgr_host_register(id);
ret = dsi_mgr_setup_components(id);
if (ret) {
pr_err("%s: failed to register mipi dsi host for DSI %d\n",
__func__, id);
Expand Down
29 changes: 28 additions & 1 deletion drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,14 +451,35 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
return ret;
}

return 0;
/*
* Resetting DSI PHY silently changes its PLL registers to reset status,
* which will confuse clock driver and result in wrong output rate of
* link clocks. Restore PLL status if its PLL is being used as clock
* source.
*/
if (phy->usecase != MSM_DSI_PHY_SLAVE) {
ret = msm_dsi_pll_restore_state(phy->pll);
if (ret) {
pr_err("%s: failed to restore pll state\n", __func__);
if (phy->cfg->ops.disable)
phy->cfg->ops.disable(phy);
dsi_phy_regulator_disable(phy);
return ret;
}
}

return ret;
}

void msm_dsi_phy_disable(struct msm_dsi_phy *phy)
{
if (!phy || !phy->cfg->ops.disable)
return;

/* Save PLL status if it is a clock source */
if (phy->usecase != MSM_DSI_PHY_SLAVE)
msm_dsi_pll_save_state(phy->pll);

phy->cfg->ops.disable(phy);

dsi_phy_regulator_disable(phy);
Expand All @@ -479,3 +500,9 @@ struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy)
return phy->pll;
}

void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
enum msm_dsi_phy_usecase uc)
{
if (phy)
phy->usecase = uc;
}
1 change: 1 addition & 0 deletions drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct msm_dsi_phy {
struct msm_dsi_dphy_timing timing;
const struct msm_dsi_phy_cfg *cfg;

enum msm_dsi_phy_usecase usecase;
bool regulator_ldo_mode;

struct msm_dsi_pll *pll;
Expand Down

0 comments on commit 57bf433

Please sign in to comment.