Skip to content

Commit ec31abf

Browse files
Hai Lirobclark
authored andcommitted
drm/msm/dsi: Separate PHY to another platform device
There are different types of PHY from one chipset to another, while the DSI host controller is relatively consistent across platforms. Also, the PLL inside PHY is providing the source of DSI byte and pixel clocks, which are used by DSI host controller. Separated devices for clock provider and clock consumer make DSI driver better fit into common clock framework. Signed-off-by: Hai Li <[email protected]> Signed-off-by: Rob Clark <[email protected]>
1 parent 9d32c49 commit ec31abf

File tree

5 files changed

+326
-94
lines changed

5 files changed

+326
-94
lines changed

Documentation/devicetree/bindings/drm/msm/dsi.txt

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
Qualcomm Technologies Inc. adreno/snapdragon DSI output
22

3+
DSI Controller:
34
Required properties:
45
- compatible:
56
* "qcom,mdss-dsi-ctrl"
6-
- reg: Physical base address and length of the registers of controller, PLL,
7-
PHY and PHY regulator
7+
- reg: Physical base address and length of the registers of controller
88
- reg-names: The names of register regions. The following regions are required:
99
* "dsi_ctrl"
10-
* "dsi_pll"
11-
* "dsi_phy"
12-
* "dsi_phy_regulator"
1310
- qcom,dsi-host-index: The ID of DSI controller hardware instance. This should
1411
be 0 or 1, since we have 2 DSI controllers at most for now.
1512
- interrupts: The interrupt signal from the DSI block.
@@ -24,10 +21,10 @@ Required properties:
2421
* "iface_clk"
2522
* "mdp_core_clk"
2623
* "pixel_clk"
27-
- #clock-cells: The value should be 1.
2824
- vdd-supply: phandle to vdd regulator device node
2925
- vddio-supply: phandle to vdd-io regulator device node
3026
- vdda-supply: phandle to vdda regulator device node
27+
- qcom,dsi-phy: phandle to DSI PHY device node
3128

3229
Optional properties:
3330
- panel@0: Node of panel connected to this DSI controller.
@@ -42,22 +39,34 @@ Optional properties:
4239
- interrupt-parent: phandle to the MDP block if the interrupt signal is routed
4340
through MDP block
4441

42+
DSI PHY:
43+
Required properties:
44+
- compatible: Could be the following
45+
* "qcom,dsi-phy-28nm-hpm"
46+
* "qcom,dsi-phy-28nm-lp"
47+
- reg: Physical base address and length of the registers of PLL, PHY and PHY
48+
regulator
49+
- reg-names: The names of register regions. The following regions are required:
50+
* "dsi_pll"
51+
* "dsi_phy"
52+
* "dsi_phy_regulator"
53+
- qcom,dsi-phy-index: The ID of DSI PHY hardware instance. This should
54+
be 0 or 1, since we have 2 DSI PHYs at most for now.
55+
- power-domains: Should be <&mmcc MDSS_GDSC>.
56+
- clocks: device clocks
57+
See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
58+
- clock-names: the following clocks are required:
59+
* "iface_clk"
60+
- vddio-supply: phandle to vdd-io regulator device node
61+
4562
Example:
4663
mdss_dsi0: qcom,mdss_dsi@fd922800 {
4764
compatible = "qcom,mdss-dsi-ctrl";
4865
qcom,dsi-host-index = <0>;
4966
interrupt-parent = <&mdss_mdp>;
5067
interrupts = <4 0>;
51-
reg-names =
52-
"dsi_ctrl",
53-
"dsi_pll",
54-
"dsi_phy",
55-
"dsi_phy_regulator",
56-
reg = <0xfd922800 0x200>,
57-
<0xfd922a00 0xd4>,
58-
<0xfd922b00 0x2b0>,
59-
<0xfd922d80 0x7b>,
60-
<0xfd828000 0x108>;
68+
reg-names = "dsi_ctrl";
69+
reg = <0xfd922800 0x200>;
6170
power-domains = <&mmcc MDSS_GDSC>;
6271
clock-names =
6372
"bus_clk",
@@ -75,11 +84,12 @@ Example:
7584
<&mmcc MDSS_AHB_CLK>,
7685
<&mmcc MDSS_MDP_CLK>,
7786
<&mmcc MDSS_PCLK0_CLK>;
78-
#clock-cells = <1>;
7987
vdda-supply = <&pma8084_l2>;
8088
vdd-supply = <&pma8084_l22>;
8189
vddio-supply = <&pma8084_l12>;
8290

91+
qcom,dsi-phy = <&mdss_dsi_phy0>;
92+
8393
qcom,dual-panel-mode;
8494
qcom,master-panel;
8595
qcom,sync-dual-panel;
@@ -93,3 +103,18 @@ Example:
93103
backlight = <...>;
94104
};
95105
};
106+
107+
mdss_dsi_phy0: qcom,mdss_dsi_phy@fd922a00 {
108+
compatible = "qcom,dsi-phy-28nm-hpm";
109+
qcom,dsi-phy-index = <0>;
110+
reg-names =
111+
"dsi_pll",
112+
"dsi_phy",
113+
"dsi_phy_regulator";
114+
reg = <0xfd922a00 0xd4>,
115+
<0xfd922b00 0x2b0>,
116+
<0xfd922d80 0x7b>;
117+
clock-names = "iface_clk";
118+
clocks = <&mmcc MDSS_AHB_CLK>;
119+
vddio-supply = <&pma8084_l12>;
120+
};

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

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,45 @@ struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi)
2323
msm_dsi->encoders[MSM_DSI_CMD_ENCODER_ID];
2424
}
2525

26+
static int dsi_get_phy(struct msm_dsi *msm_dsi)
27+
{
28+
struct platform_device *pdev = msm_dsi->pdev;
29+
struct platform_device *phy_pdev;
30+
struct device_node *phy_node;
31+
32+
phy_node = of_parse_phandle(pdev->dev.of_node, "qcom,dsi-phy", 0);
33+
if (!phy_node) {
34+
dev_err(&pdev->dev, "cannot find phy device\n");
35+
return -ENXIO;
36+
}
37+
38+
phy_pdev = of_find_device_by_node(phy_node);
39+
if (phy_pdev)
40+
msm_dsi->phy = platform_get_drvdata(phy_pdev);
41+
42+
of_node_put(phy_node);
43+
44+
if (!phy_pdev || !msm_dsi->phy) {
45+
dev_err(&pdev->dev, "%s: phy driver is not ready\n", __func__);
46+
return -EPROBE_DEFER;
47+
}
48+
49+
msm_dsi->phy_dev = get_device(&phy_pdev->dev);
50+
51+
return 0;
52+
}
53+
2654
static void dsi_destroy(struct msm_dsi *msm_dsi)
2755
{
2856
if (!msm_dsi)
2957
return;
3058

3159
msm_dsi_manager_unregister(msm_dsi);
3260

33-
if (msm_dsi->phy) {
34-
msm_dsi_phy_destroy(msm_dsi->phy);
61+
if (msm_dsi->phy_dev) {
62+
put_device(msm_dsi->phy_dev);
3563
msm_dsi->phy = NULL;
64+
msm_dsi->phy_dev = NULL;
3665
}
3766

3867
if (msm_dsi->host) {
@@ -49,7 +78,6 @@ static struct msm_dsi *dsi_init(struct platform_device *pdev)
4978
int ret;
5079

5180
if (!pdev) {
52-
dev_err(&pdev->dev, "no dsi device\n");
5381
ret = -ENXIO;
5482
goto fail;
5583
}
@@ -69,13 +97,10 @@ static struct msm_dsi *dsi_init(struct platform_device *pdev)
6997
if (ret)
7098
goto fail;
7199

72-
/* Init dsi PHY */
73-
msm_dsi->phy = msm_dsi_phy_init(pdev, msm_dsi->phy_type, msm_dsi->id);
74-
if (!msm_dsi->phy) {
75-
ret = -ENXIO;
76-
pr_err("%s: phy init failed\n", __func__);
100+
/* GET dsi PHY */
101+
ret = dsi_get_phy(msm_dsi);
102+
if (ret)
77103
goto fail;
78-
}
79104

80105
/* Register to dsi manager */
81106
ret = msm_dsi_manager_register(msm_dsi);
@@ -156,12 +181,14 @@ static struct platform_driver dsi_driver = {
156181
void __init msm_dsi_register(void)
157182
{
158183
DBG("");
184+
msm_dsi_phy_driver_register();
159185
platform_driver_register(&dsi_driver);
160186
}
161187

162188
void __exit msm_dsi_unregister(void)
163189
{
164190
DBG("");
191+
msm_dsi_phy_driver_unregister();
165192
platform_driver_unregister(&dsi_driver);
166193
}
167194

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

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef __DSI_CONNECTOR_H__
1515
#define __DSI_CONNECTOR_H__
1616

17+
#include <linux/of_platform.h>
1718
#include <linux/platform_device.h>
1819

1920
#include "drm_crtc.h"
@@ -39,12 +40,27 @@
3940
#define DSI_ENCODER_SLAVE DSI_0
4041

4142
enum msm_dsi_phy_type {
42-
MSM_DSI_PHY_UNKNOWN,
4343
MSM_DSI_PHY_28NM_HPM,
4444
MSM_DSI_PHY_28NM_LP,
4545
MSM_DSI_PHY_MAX
4646
};
4747

48+
#define DSI_DEV_REGULATOR_MAX 8
49+
50+
/* Regulators for DSI devices */
51+
struct dsi_reg_entry {
52+
char name[32];
53+
int min_voltage;
54+
int max_voltage;
55+
int enable_load;
56+
int disable_load;
57+
};
58+
59+
struct dsi_reg_config {
60+
int num;
61+
struct dsi_reg_entry regs[DSI_DEV_REGULATOR_MAX];
62+
};
63+
4864
struct msm_dsi {
4965
struct drm_device *dev;
5066
struct platform_device *pdev;
@@ -57,7 +73,7 @@ struct msm_dsi {
5773
struct drm_panel *panel;
5874
unsigned long panel_flags;
5975

60-
enum msm_dsi_phy_type phy_type;
76+
struct device *phy_dev;
6177
bool phy_enabled;
6278

6379
/* the encoders we are hooked to (outside of dsi block) */
@@ -135,9 +151,8 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi);
135151

136152
/* dsi phy */
137153
struct msm_dsi_phy;
138-
struct msm_dsi_phy *msm_dsi_phy_init(struct platform_device *pdev,
139-
enum msm_dsi_phy_type type, int id);
140-
void msm_dsi_phy_destroy(struct msm_dsi_phy *phy);
154+
void msm_dsi_phy_driver_register(void);
155+
void msm_dsi_phy_driver_unregister(void);
141156
int msm_dsi_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel,
142157
const unsigned long bit_rate, const unsigned long esc_rate);
143158
int msm_dsi_phy_disable(struct msm_dsi_phy *phy);

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

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,19 @@
3636

3737
#define DSI_6G_REG_SHIFT 4
3838

39-
#define DSI_REGULATOR_MAX 8
40-
struct dsi_reg_entry {
41-
char name[32];
42-
int min_voltage;
43-
int max_voltage;
44-
int enable_load;
45-
int disable_load;
46-
};
47-
48-
struct dsi_reg_config {
49-
int num;
50-
struct dsi_reg_entry regs[DSI_REGULATOR_MAX];
51-
};
52-
5339
struct dsi_config {
5440
u32 major;
5541
u32 minor;
5642
u32 io_offset;
57-
enum msm_dsi_phy_type phy_type;
5843
struct dsi_reg_config reg_cfg;
5944
};
6045

6146
static const struct dsi_config dsi_cfgs[] = {
62-
{MSM_DSI_VER_MAJOR_V2, 0, 0, MSM_DSI_PHY_UNKNOWN},
47+
{MSM_DSI_VER_MAJOR_V2, 0, 0, {0,} },
6348
{ /* 8974 v1 */
6449
.major = MSM_DSI_VER_MAJOR_6G,
6550
.minor = MSM_DSI_6G_VER_MINOR_V1_0,
6651
.io_offset = DSI_6G_REG_SHIFT,
67-
.phy_type = MSM_DSI_PHY_28NM_HPM,
6852
.reg_cfg = {
6953
.num = 4,
7054
.regs = {
@@ -79,7 +63,6 @@ static const struct dsi_config dsi_cfgs[] = {
7963
.major = MSM_DSI_VER_MAJOR_6G,
8064
.minor = MSM_DSI_6G_VER_MINOR_V1_1,
8165
.io_offset = DSI_6G_REG_SHIFT,
82-
.phy_type = MSM_DSI_PHY_28NM_HPM,
8366
.reg_cfg = {
8467
.num = 4,
8568
.regs = {
@@ -94,7 +77,6 @@ static const struct dsi_config dsi_cfgs[] = {
9477
.major = MSM_DSI_VER_MAJOR_6G,
9578
.minor = MSM_DSI_6G_VER_MINOR_V1_1_1,
9679
.io_offset = DSI_6G_REG_SHIFT,
97-
.phy_type = MSM_DSI_PHY_28NM_HPM,
9880
.reg_cfg = {
9981
.num = 4,
10082
.regs = {
@@ -109,7 +91,6 @@ static const struct dsi_config dsi_cfgs[] = {
10991
.major = MSM_DSI_VER_MAJOR_6G,
11092
.minor = MSM_DSI_6G_VER_MINOR_V1_2,
11193
.io_offset = DSI_6G_REG_SHIFT,
112-
.phy_type = MSM_DSI_PHY_28NM_HPM,
11394
.reg_cfg = {
11495
.num = 4,
11596
.regs = {
@@ -124,7 +105,6 @@ static const struct dsi_config dsi_cfgs[] = {
124105
.major = MSM_DSI_VER_MAJOR_6G,
125106
.minor = MSM_DSI_6G_VER_MINOR_V1_3_1,
126107
.io_offset = DSI_6G_REG_SHIFT,
127-
.phy_type = MSM_DSI_PHY_28NM_LP,
128108
.reg_cfg = {
129109
.num = 4,
130110
.regs = {
@@ -197,7 +177,7 @@ struct msm_dsi_host {
197177
int id;
198178

199179
void __iomem *ctrl_base;
200-
struct regulator_bulk_data supplies[DSI_REGULATOR_MAX];
180+
struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX];
201181
struct clk *mdp_core_clk;
202182
struct clk *ahb_clk;
203183
struct clk *axi_clk;
@@ -1534,7 +1514,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
15341514

15351515
msm_dsi->host = &msm_host->base;
15361516
msm_dsi->id = msm_host->id;
1537-
msm_dsi->phy_type = msm_host->cfg->phy_type;
15381517

15391518
DBG("Dsi Host %d initialized", msm_host->id);
15401519
return 0;

0 commit comments

Comments
 (0)