@@ -171,6 +171,11 @@ static void rzg2l_mipi_dsi_link_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 d
171
171
iowrite32 (data , dsi -> mmio + LINK_REG_OFFSET + reg );
172
172
}
173
173
174
+ static u32 rzg2l_mipi_dsi_phy_read (struct rzg2l_mipi_dsi * dsi , u32 reg )
175
+ {
176
+ return ioread32 (dsi -> mmio + reg );
177
+ }
178
+
174
179
static u32 rzg2l_mipi_dsi_link_read (struct rzg2l_mipi_dsi * dsi , u32 reg )
175
180
{
176
181
return ioread32 (dsi -> mmio + LINK_REG_OFFSET + reg );
@@ -180,52 +185,25 @@ static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
180
185
* Hardware Setup
181
186
*/
182
187
183
- static int rzg2l_mipi_dsi_startup (struct rzg2l_mipi_dsi * dsi ,
184
- const struct drm_display_mode * mode )
188
+ static int rzg2l_mipi_dsi_dphy_init (struct rzg2l_mipi_dsi * dsi ,
189
+ unsigned long hsfreq )
185
190
{
186
191
const struct rzg2l_mipi_dsi_timings * dphy_timings ;
187
- unsigned long hsfreq ;
188
- unsigned int i , bpp ;
189
- u32 txsetr ;
190
- u32 clstptsetr ;
191
- u32 lptrnstsetr ;
192
- u32 clkkpt ;
193
- u32 clkbfht ;
194
- u32 clkstpt ;
195
- u32 golpbkt ;
192
+ unsigned int i ;
196
193
u32 dphyctrl0 ;
197
194
u32 dphytim0 ;
198
195
u32 dphytim1 ;
199
196
u32 dphytim2 ;
200
197
u32 dphytim3 ;
201
198
int ret ;
202
199
203
- /*
204
- * Relationship between hsclk and vclk must follow
205
- * vclk * bpp = hsclk * 8 * lanes
206
- * where vclk: video clock (Hz)
207
- * bpp: video pixel bit depth
208
- * hsclk: DSI HS Byte clock frequency (Hz)
209
- * lanes: number of data lanes
210
- *
211
- * hsclk(bit) = hsclk(byte) * 8
212
- */
213
- bpp = mipi_dsi_pixel_format_to_bpp (dsi -> format );
214
- hsfreq = (mode -> clock * bpp * 8 ) / (8 * dsi -> lanes );
215
-
216
200
/* All DSI global operation timings are set with recommended setting */
217
201
for (i = 0 ; i < ARRAY_SIZE (rzg2l_mipi_dsi_global_timings ); ++ i ) {
218
202
dphy_timings = & rzg2l_mipi_dsi_global_timings [i ];
219
203
if (hsfreq <= dphy_timings -> hsfreq_max )
220
204
break ;
221
205
}
222
206
223
- ret = pm_runtime_resume_and_get (dsi -> dev );
224
- if (ret < 0 )
225
- return ret ;
226
-
227
- clk_set_rate (dsi -> vclk , mode -> clock * 1000 );
228
-
229
207
/* Initializing DPHY before accessing LINK */
230
208
dphyctrl0 = DSIDPHYCTRL0_CAL_EN_HSRX_OFS | DSIDPHYCTRL0_CMN_MASTER_EN |
231
209
DSIDPHYCTRL0_RE_VDD_DETVCCQLV18 | DSIDPHYCTRL0_EN_BGR ;
@@ -259,10 +237,62 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
259
237
260
238
ret = reset_control_deassert (dsi -> rstc );
261
239
if (ret < 0 )
262
- goto err_pm_put ;
240
+ return ret ;
263
241
264
242
udelay (1 );
265
243
244
+ return 0 ;
245
+ }
246
+
247
+ static void rzg2l_mipi_dsi_dphy_exit (struct rzg2l_mipi_dsi * dsi )
248
+ {
249
+ u32 dphyctrl0 ;
250
+
251
+ dphyctrl0 = rzg2l_mipi_dsi_phy_read (dsi , DSIDPHYCTRL0 );
252
+
253
+ dphyctrl0 &= ~(DSIDPHYCTRL0_EN_LDO1200 | DSIDPHYCTRL0_EN_BGR );
254
+ rzg2l_mipi_dsi_phy_write (dsi , DSIDPHYCTRL0 , dphyctrl0 );
255
+
256
+ reset_control_assert (dsi -> rstc );
257
+ }
258
+
259
+ static int rzg2l_mipi_dsi_startup (struct rzg2l_mipi_dsi * dsi ,
260
+ const struct drm_display_mode * mode )
261
+ {
262
+ unsigned long hsfreq ;
263
+ unsigned int bpp ;
264
+ u32 txsetr ;
265
+ u32 clstptsetr ;
266
+ u32 lptrnstsetr ;
267
+ u32 clkkpt ;
268
+ u32 clkbfht ;
269
+ u32 clkstpt ;
270
+ u32 golpbkt ;
271
+ int ret ;
272
+
273
+ /*
274
+ * Relationship between hsclk and vclk must follow
275
+ * vclk * bpp = hsclk * 8 * lanes
276
+ * where vclk: video clock (Hz)
277
+ * bpp: video pixel bit depth
278
+ * hsclk: DSI HS Byte clock frequency (Hz)
279
+ * lanes: number of data lanes
280
+ *
281
+ * hsclk(bit) = hsclk(byte) * 8
282
+ */
283
+ bpp = mipi_dsi_pixel_format_to_bpp (dsi -> format );
284
+ hsfreq = (mode -> clock * bpp * 8 ) / (8 * dsi -> lanes );
285
+
286
+ ret = pm_runtime_resume_and_get (dsi -> dev );
287
+ if (ret < 0 )
288
+ return ret ;
289
+
290
+ clk_set_rate (dsi -> vclk , mode -> clock * 1000 );
291
+
292
+ ret = rzg2l_mipi_dsi_dphy_init (dsi , hsfreq );
293
+ if (ret < 0 )
294
+ goto err_phy ;
295
+
266
296
/* Enable Data lanes and Clock lanes */
267
297
txsetr = TXSETR_DLEN | TXSETR_NUMLANEUSE (dsi -> lanes - 1 ) | TXSETR_CLEN ;
268
298
rzg2l_mipi_dsi_link_write (dsi , TXSETR , txsetr );
@@ -301,15 +331,16 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
301
331
302
332
return 0 ;
303
333
304
- err_pm_put :
334
+ err_phy :
335
+ rzg2l_mipi_dsi_dphy_exit (dsi );
305
336
pm_runtime_put (dsi -> dev );
306
337
307
338
return ret ;
308
339
}
309
340
310
341
static void rzg2l_mipi_dsi_stop (struct rzg2l_mipi_dsi * dsi )
311
342
{
312
- reset_control_assert (dsi -> rstc );
343
+ rzg2l_mipi_dsi_dphy_exit (dsi );
313
344
pm_runtime_put (dsi -> dev );
314
345
}
315
346
@@ -666,7 +697,9 @@ static const struct dev_pm_ops rzg2l_mipi_pm_ops = {
666
697
667
698
static int rzg2l_mipi_dsi_probe (struct platform_device * pdev )
668
699
{
700
+ unsigned int num_data_lanes ;
669
701
struct rzg2l_mipi_dsi * dsi ;
702
+ u32 txsetr ;
670
703
int ret ;
671
704
672
705
dsi = devm_kzalloc (& pdev -> dev , sizeof (* dsi ), GFP_KERNEL );
@@ -681,7 +714,7 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
681
714
return dev_err_probe (dsi -> dev , ret ,
682
715
"missing or invalid data-lanes property\n" );
683
716
684
- dsi -> num_data_lanes = ret ;
717
+ num_data_lanes = ret ;
685
718
686
719
dsi -> mmio = devm_platform_ioremap_resource (pdev , 0 );
687
720
if (IS_ERR (dsi -> mmio ))
@@ -710,6 +743,24 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
710
743
711
744
pm_runtime_enable (dsi -> dev );
712
745
746
+ ret = pm_runtime_resume_and_get (dsi -> dev );
747
+ if (ret < 0 )
748
+ goto err_pm_disable ;
749
+
750
+ /*
751
+ * TXSETR register can be read only after DPHY init. But during probe
752
+ * mode->clock and format are not available. So initialize DPHY with
753
+ * timing parameters for 80Mbps.
754
+ */
755
+ ret = rzg2l_mipi_dsi_dphy_init (dsi , 80000 );
756
+ if (ret < 0 )
757
+ goto err_phy ;
758
+
759
+ txsetr = rzg2l_mipi_dsi_link_read (dsi , TXSETR );
760
+ dsi -> num_data_lanes = min (((txsetr >> 16 ) & 3 ) + 1 , num_data_lanes );
761
+ rzg2l_mipi_dsi_dphy_exit (dsi );
762
+ pm_runtime_put (dsi -> dev );
763
+
713
764
/* Initialize the DRM bridge. */
714
765
dsi -> bridge .funcs = & rzg2l_mipi_dsi_bridge_ops ;
715
766
dsi -> bridge .of_node = dsi -> dev -> of_node ;
@@ -723,6 +774,9 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
723
774
724
775
return 0 ;
725
776
777
+ err_phy :
778
+ rzg2l_mipi_dsi_dphy_exit (dsi );
779
+ pm_runtime_put (dsi -> dev );
726
780
err_pm_disable :
727
781
pm_runtime_disable (dsi -> dev );
728
782
return ret ;
0 commit comments