Skip to content

Commit 57bf433

Browse files
Hai Lirobclark
Hai Li
authored andcommitted
drm/msm/dsi: Pass down use case to PHY
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 <[email protected]> Signed-off-by: Archit Taneja <[email protected]> Signed-off-by: Rob Clark <[email protected]>
1 parent dceac34 commit 57bf433

File tree

4 files changed

+51
-30
lines changed

4 files changed

+51
-30
lines changed

drivers/gpu/drm/msm/dsi/dsi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ enum msm_dsi_phy_type {
3737
MSM_DSI_PHY_MAX
3838
};
3939

40+
enum msm_dsi_phy_usecase {
41+
MSM_DSI_PHY_STANDALONE,
42+
MSM_DSI_PHY_MASTER,
43+
MSM_DSI_PHY_SLAVE,
44+
};
45+
4046
#define DSI_DEV_REGULATOR_MAX 8
4147
#define DSI_BUS_CLK_MAX 4
4248

@@ -180,6 +186,8 @@ void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
180186
void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
181187
struct msm_dsi_phy_shared_timings *shared_timing);
182188
struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy);
189+
void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
190+
enum msm_dsi_phy_usecase uc);
183191

184192
#endif /* __DSI_CONNECTOR_H__ */
185193

drivers/gpu/drm/msm/dsi/dsi_manager.c

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ static int dsi_mgr_parse_dual_dsi(struct device_node *np, int id)
7272
return 0;
7373
}
7474

75-
static int dsi_mgr_host_register(int id)
75+
static int dsi_mgr_setup_components(int id)
7676
{
7777
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
7878
struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
7979
struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
80+
struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
8081
struct msm_dsi_pll *src_pll;
8182
int ret;
8283

@@ -85,30 +86,35 @@ static int dsi_mgr_host_register(int id)
8586
if (ret)
8687
return ret;
8788

89+
msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
8890
src_pll = msm_dsi_phy_get_pll(msm_dsi->phy);
8991
ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll);
9092
} else if (!other_dsi) {
9193
ret = 0;
9294
} else {
93-
struct msm_dsi *mdsi = IS_MASTER_DSI_LINK(id) ?
94-
msm_dsi : other_dsi;
95-
struct msm_dsi *sdsi = IS_MASTER_DSI_LINK(id) ?
96-
other_dsi : msm_dsi;
95+
struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
96+
msm_dsi : other_dsi;
97+
struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
98+
other_dsi : msm_dsi;
9799
/* Register slave host first, so that slave DSI device
98100
* has a chance to probe, and do not block the master
99101
* DSI device's probe.
100102
* Also, do not check defer for the slave host,
101103
* because only master DSI device adds the panel to global
102104
* panel list. The panel's device is the master DSI device.
103105
*/
104-
ret = msm_dsi_host_register(sdsi->host, false);
106+
ret = msm_dsi_host_register(slave_link_dsi->host, false);
105107
if (ret)
106108
return ret;
107-
ret = msm_dsi_host_register(mdsi->host, true);
109+
ret = msm_dsi_host_register(master_link_dsi->host, true);
108110
if (ret)
109111
return ret;
110112

111113
/* PLL0 is to drive both 2 DSI link clocks in Dual DSI mode. */
114+
msm_dsi_phy_set_usecase(clk_master_dsi->phy,
115+
MSM_DSI_PHY_MASTER);
116+
msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
117+
MSM_DSI_PHY_SLAVE);
112118
src_pll = msm_dsi_phy_get_pll(clk_master_dsi->phy);
113119
ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll);
114120
if (ret)
@@ -665,28 +671,12 @@ int msm_dsi_manager_phy_enable(int id,
665671
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
666672
struct msm_dsi_phy *phy = msm_dsi->phy;
667673
int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id;
668-
struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy);
669674
int ret;
670675

671676
ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate);
672677
if (ret)
673678
return ret;
674679

675-
/*
676-
* Reset DSI PHY silently changes its PLL registers to reset status,
677-
* which will confuse clock driver and result in wrong output rate of
678-
* link clocks. Restore PLL status if its PLL is being used as clock
679-
* source.
680-
*/
681-
if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) {
682-
ret = msm_dsi_pll_restore_state(pll);
683-
if (ret) {
684-
pr_err("%s: failed to restore pll state\n", __func__);
685-
msm_dsi_phy_disable(phy);
686-
return ret;
687-
}
688-
}
689-
690680
msm_dsi->phy_enabled = true;
691681
msm_dsi_phy_get_shared_timings(phy, shared_timings);
692682

@@ -699,11 +689,6 @@ void msm_dsi_manager_phy_disable(int id)
699689
struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
700690
struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
701691
struct msm_dsi_phy *phy = msm_dsi->phy;
702-
struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy);
703-
704-
/* Save PLL status if it is a clock source */
705-
if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER))
706-
msm_dsi_pll_save_state(pll);
707692

708693
/* disable DSI phy
709694
* In dual-dsi configuration, the phy should be disabled for the
@@ -834,7 +819,7 @@ int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
834819
goto fail;
835820
}
836821

837-
ret = dsi_mgr_host_register(id);
822+
ret = dsi_mgr_setup_components(id);
838823
if (ret) {
839824
pr_err("%s: failed to register mipi dsi host for DSI %d\n",
840825
__func__, id);

drivers/gpu/drm/msm/dsi/phy/dsi_phy.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,14 +451,35 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
451451
return ret;
452452
}
453453

454-
return 0;
454+
/*
455+
* Resetting DSI PHY silently changes its PLL registers to reset status,
456+
* which will confuse clock driver and result in wrong output rate of
457+
* link clocks. Restore PLL status if its PLL is being used as clock
458+
* source.
459+
*/
460+
if (phy->usecase != MSM_DSI_PHY_SLAVE) {
461+
ret = msm_dsi_pll_restore_state(phy->pll);
462+
if (ret) {
463+
pr_err("%s: failed to restore pll state\n", __func__);
464+
if (phy->cfg->ops.disable)
465+
phy->cfg->ops.disable(phy);
466+
dsi_phy_regulator_disable(phy);
467+
return ret;
468+
}
469+
}
470+
471+
return ret;
455472
}
456473

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

479+
/* Save PLL status if it is a clock source */
480+
if (phy->usecase != MSM_DSI_PHY_SLAVE)
481+
msm_dsi_pll_save_state(phy->pll);
482+
462483
phy->cfg->ops.disable(phy);
463484

464485
dsi_phy_regulator_disable(phy);
@@ -479,3 +500,9 @@ struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy)
479500
return phy->pll;
480501
}
481502

503+
void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
504+
enum msm_dsi_phy_usecase uc)
505+
{
506+
if (phy)
507+
phy->usecase = uc;
508+
}

drivers/gpu/drm/msm/dsi/phy/dsi_phy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct msm_dsi_phy {
7878
struct msm_dsi_dphy_timing timing;
7979
const struct msm_dsi_phy_cfg *cfg;
8080

81+
enum msm_dsi_phy_usecase usecase;
8182
bool regulator_ldo_mode;
8283

8384
struct msm_dsi_pll *pll;

0 commit comments

Comments
 (0)