14
14
#include <linux/module.h>
15
15
#include <linux/of.h>
16
16
#include <linux/phy/phy.h>
17
+ #include <linux/phy/phy-dp.h>
17
18
#include <linux/platform_device.h>
18
19
#include <linux/regulator/consumer.h>
19
20
#include <linux/reset.h>
69
70
70
71
#define TXn_TRAN_DRVR_EMP_EN 0x0078
71
72
72
- struct qcom_edp_cfg {
73
- bool is_dp ;
74
-
75
- /* DP PHY swing and pre_emphasis tables */
73
+ struct qcom_edp_swing_pre_emph_cfg {
76
74
const u8 (* swing_hbr_rbr )[4 ][4 ];
77
75
const u8 (* swing_hbr3_hbr2 )[4 ][4 ];
78
76
const u8 (* pre_emphasis_hbr_rbr )[4 ][4 ];
79
77
const u8 (* pre_emphasis_hbr3_hbr2 )[4 ][4 ];
80
78
};
81
79
80
+ struct qcom_edp_phy_cfg {
81
+ bool is_edp ;
82
+ const struct qcom_edp_swing_pre_emph_cfg * swing_pre_emph_cfg ;
83
+ };
84
+
82
85
struct qcom_edp {
83
86
struct device * dev ;
84
- const struct qcom_edp_cfg * cfg ;
87
+ const struct qcom_edp_phy_cfg * cfg ;
85
88
86
89
struct phy * phy ;
87
90
@@ -97,6 +100,8 @@ struct qcom_edp {
97
100
98
101
struct clk_bulk_data clks [2 ];
99
102
struct regulator_bulk_data supplies [2 ];
103
+
104
+ bool is_edp ;
100
105
};
101
106
102
107
static const u8 dp_swing_hbr_rbr [4 ][4 ] = {
@@ -127,8 +132,7 @@ static const u8 dp_pre_emp_hbr2_hbr3[4][4] = {
127
132
{ 0x04 , 0xff , 0xff , 0xff }
128
133
};
129
134
130
- static const struct qcom_edp_cfg dp_phy_cfg = {
131
- .is_dp = true,
135
+ static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg = {
132
136
.swing_hbr_rbr = & dp_swing_hbr_rbr ,
133
137
.swing_hbr3_hbr2 = & dp_swing_hbr2_hbr3 ,
134
138
.pre_emphasis_hbr_rbr = & dp_pre_emp_hbr_rbr ,
@@ -163,18 +167,28 @@ static const u8 edp_pre_emp_hbr2_hbr3[4][4] = {
163
167
{ 0x00 , 0xff , 0xff , 0xff }
164
168
};
165
169
166
- static const struct qcom_edp_cfg edp_phy_cfg = {
167
- .is_dp = false,
170
+ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
168
171
.swing_hbr_rbr = & edp_swing_hbr_rbr ,
169
172
.swing_hbr3_hbr2 = & edp_swing_hbr2_hbr3 ,
170
173
.pre_emphasis_hbr_rbr = & edp_pre_emp_hbr_rbr ,
171
174
.pre_emphasis_hbr3_hbr2 = & edp_pre_emp_hbr2_hbr3 ,
172
175
};
173
176
177
+ static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
178
+ };
179
+
180
+ static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
181
+ .swing_pre_emph_cfg = & dp_phy_swing_pre_emph_cfg ,
182
+ };
183
+
184
+ static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
185
+ .is_edp = true,
186
+ .swing_pre_emph_cfg = & edp_phy_swing_pre_emph_cfg ,
187
+ };
188
+
174
189
static int qcom_edp_phy_init (struct phy * phy )
175
190
{
176
191
struct qcom_edp * edp = phy_get_drvdata (phy );
177
- const struct qcom_edp_cfg * cfg = edp -> cfg ;
178
192
int ret ;
179
193
u8 cfg8 ;
180
194
@@ -201,7 +215,12 @@ static int qcom_edp_phy_init(struct phy *phy)
201
215
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN ,
202
216
edp -> edp + DP_PHY_PD_CTL );
203
217
204
- if (cfg && cfg -> is_dp )
218
+ /*
219
+ * TODO: Re-work the conditions around setting the cfg8 value
220
+ * when more information becomes available about why this is
221
+ * even needed.
222
+ */
223
+ if (edp -> cfg -> swing_pre_emph_cfg && !edp -> is_edp )
205
224
cfg8 = 0xb7 ;
206
225
else
207
226
cfg8 = 0x37 ;
@@ -235,7 +254,7 @@ static int qcom_edp_phy_init(struct phy *phy)
235
254
236
255
static int qcom_edp_set_voltages (struct qcom_edp * edp , const struct phy_configure_opts_dp * dp_opts )
237
256
{
238
- const struct qcom_edp_cfg * cfg = edp -> cfg ;
257
+ const struct qcom_edp_swing_pre_emph_cfg * cfg = edp -> cfg -> swing_pre_emph_cfg ;
239
258
unsigned int v_level = 0 ;
240
259
unsigned int p_level = 0 ;
241
260
u8 ldo_config ;
@@ -246,6 +265,9 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
246
265
if (!cfg )
247
266
return 0 ;
248
267
268
+ if (edp -> is_edp )
269
+ cfg = & edp_phy_swing_pre_emph_cfg ;
270
+
249
271
for (i = 0 ; i < dp_opts -> lanes ; i ++ ) {
250
272
v_level = max (v_level , dp_opts -> voltage [i ]);
251
273
p_level = max (p_level , dp_opts -> pre [i ]);
@@ -262,7 +284,7 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
262
284
if (swing == 0xff || emph == 0xff )
263
285
return - EINVAL ;
264
286
265
- ldo_config = ( cfg && cfg -> is_dp ) ? 0x1 : 0x0 ;
287
+ ldo_config = edp -> is_edp ? 0x0 : 0x1 ;
266
288
267
289
writel (ldo_config , edp -> tx0 + TXn_LDO_CONFIG );
268
290
writel (swing , edp -> tx0 + TXn_TX_DRV_LVL );
@@ -448,10 +470,9 @@ static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel
448
470
static int qcom_edp_phy_power_on (struct phy * phy )
449
471
{
450
472
const struct qcom_edp * edp = phy_get_drvdata (phy );
451
- const struct qcom_edp_cfg * cfg = edp -> cfg ;
452
473
u32 bias0_en , drvr0_en , bias1_en , drvr1_en ;
453
474
unsigned long pixel_freq ;
454
- u8 ldo_config ;
475
+ u8 ldo_config = 0x0 ;
455
476
int timeout ;
456
477
int ret ;
457
478
u32 val ;
@@ -469,7 +490,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
469
490
return timeout ;
470
491
471
492
472
- ldo_config = (cfg && cfg -> is_dp ) ? 0x1 : 0x0 ;
493
+ if (edp -> cfg -> swing_pre_emph_cfg && !edp -> is_edp )
494
+ ldo_config = 0x1 ;
473
495
474
496
writel (ldo_config , edp -> tx0 + TXn_LDO_CONFIG );
475
497
writel (ldo_config , edp -> tx1 + TXn_LDO_CONFIG );
@@ -590,6 +612,18 @@ static int qcom_edp_phy_power_off(struct phy *phy)
590
612
return 0 ;
591
613
}
592
614
615
+ static int qcom_edp_phy_set_mode (struct phy * phy , enum phy_mode mode , int submode )
616
+ {
617
+ struct qcom_edp * edp = phy_get_drvdata (phy );
618
+
619
+ if (mode != PHY_MODE_DP )
620
+ return - EINVAL ;
621
+
622
+ edp -> is_edp = submode == PHY_SUBMODE_EDP ;
623
+
624
+ return 0 ;
625
+ }
626
+
593
627
static int qcom_edp_phy_exit (struct phy * phy )
594
628
{
595
629
struct qcom_edp * edp = phy_get_drvdata (phy );
@@ -605,6 +639,7 @@ static const struct phy_ops qcom_edp_ops = {
605
639
.configure = qcom_edp_phy_configure ,
606
640
.power_on = qcom_edp_phy_power_on ,
607
641
.power_off = qcom_edp_phy_power_off ,
642
+ .set_mode = qcom_edp_phy_set_mode ,
608
643
.exit = qcom_edp_phy_exit ,
609
644
.owner = THIS_MODULE ,
610
645
};
@@ -782,6 +817,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
782
817
783
818
edp -> dev = dev ;
784
819
edp -> cfg = of_device_get_match_data (& pdev -> dev );
820
+ edp -> is_edp = edp -> cfg -> is_edp ;
785
821
786
822
edp -> edp = devm_platform_ioremap_resource (pdev , 0 );
787
823
if (IS_ERR (edp -> edp ))
@@ -840,10 +876,10 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
840
876
}
841
877
842
878
static const struct of_device_id qcom_edp_phy_match_table [] = {
843
- { .compatible = "qcom,sc7280-edp-phy" },
844
- { .compatible = "qcom,sc8180x-edp-phy" },
845
- { .compatible = "qcom,sc8280xp-dp-phy" , .data = & dp_phy_cfg },
846
- { .compatible = "qcom,sc8280xp-edp-phy" , .data = & edp_phy_cfg },
879
+ { .compatible = "qcom,sc7280-edp-phy" , . data = & sc7280_dp_phy_cfg , },
880
+ { .compatible = "qcom,sc8180x-edp-phy" , . data = & sc7280_dp_phy_cfg , },
881
+ { .compatible = "qcom,sc8280xp-dp-phy" , .data = & sc8280xp_dp_phy_cfg , },
882
+ { .compatible = "qcom,sc8280xp-edp-phy" , .data = & sc8280xp_edp_phy_cfg , },
847
883
{ }
848
884
};
849
885
MODULE_DEVICE_TABLE (of , qcom_edp_phy_match_table );
0 commit comments