23
23
*/
24
24
25
25
#include <drm/drm_atomic_helper.h>
26
+ #include <drm/drm_bridge.h>
26
27
#include <drm/drm_crtc_helper.h>
27
28
#include <drm/drm_edid.h>
29
+ #include <drm/drm_of.h>
28
30
#include <drm/drm_panel.h>
29
31
#include <linux/clk.h>
30
32
#include <linux/component.h>
@@ -95,7 +97,8 @@ struct vc4_dpi {
95
97
96
98
struct drm_encoder * encoder ;
97
99
struct drm_connector * connector ;
98
- struct drm_panel * panel ;
100
+ struct drm_bridge * bridge ;
101
+ bool is_panel_bridge ;
99
102
100
103
void __iomem * regs ;
101
104
@@ -118,24 +121,6 @@ to_vc4_dpi_encoder(struct drm_encoder *encoder)
118
121
return container_of (encoder , struct vc4_dpi_encoder , base .base );
119
122
}
120
123
121
- /* VC4 DPI connector KMS struct */
122
- struct vc4_dpi_connector {
123
- struct drm_connector base ;
124
- struct vc4_dpi * dpi ;
125
-
126
- /* Since the connector is attached to just the one encoder,
127
- * this is the reference to it so we can do the best_encoder()
128
- * hook.
129
- */
130
- struct drm_encoder * encoder ;
131
- };
132
-
133
- static inline struct vc4_dpi_connector *
134
- to_vc4_dpi_connector (struct drm_connector * connector )
135
- {
136
- return container_of (connector , struct vc4_dpi_connector , base );
137
- }
138
-
139
124
#define DPI_REG (reg ) { reg, #reg }
140
125
static const struct {
141
126
u32 reg ;
@@ -167,80 +152,6 @@ int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused)
167
152
}
168
153
#endif
169
154
170
- static enum drm_connector_status
171
- vc4_dpi_connector_detect (struct drm_connector * connector , bool force )
172
- {
173
- struct vc4_dpi_connector * vc4_connector =
174
- to_vc4_dpi_connector (connector );
175
- struct vc4_dpi * dpi = vc4_connector -> dpi ;
176
-
177
- if (dpi -> panel )
178
- return connector_status_connected ;
179
- else
180
- return connector_status_disconnected ;
181
- }
182
-
183
- static void vc4_dpi_connector_destroy (struct drm_connector * connector )
184
- {
185
- drm_connector_unregister (connector );
186
- drm_connector_cleanup (connector );
187
- }
188
-
189
- static int vc4_dpi_connector_get_modes (struct drm_connector * connector )
190
- {
191
- struct vc4_dpi_connector * vc4_connector =
192
- to_vc4_dpi_connector (connector );
193
- struct vc4_dpi * dpi = vc4_connector -> dpi ;
194
-
195
- if (dpi -> panel )
196
- return drm_panel_get_modes (dpi -> panel );
197
-
198
- return 0 ;
199
- }
200
-
201
- static const struct drm_connector_funcs vc4_dpi_connector_funcs = {
202
- .dpms = drm_atomic_helper_connector_dpms ,
203
- .detect = vc4_dpi_connector_detect ,
204
- .fill_modes = drm_helper_probe_single_connector_modes ,
205
- .destroy = vc4_dpi_connector_destroy ,
206
- .reset = drm_atomic_helper_connector_reset ,
207
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state ,
208
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state ,
209
- };
210
-
211
- static const struct drm_connector_helper_funcs vc4_dpi_connector_helper_funcs = {
212
- .get_modes = vc4_dpi_connector_get_modes ,
213
- };
214
-
215
- static struct drm_connector * vc4_dpi_connector_init (struct drm_device * dev ,
216
- struct vc4_dpi * dpi )
217
- {
218
- struct drm_connector * connector = NULL ;
219
- struct vc4_dpi_connector * dpi_connector ;
220
-
221
- dpi_connector = devm_kzalloc (dev -> dev , sizeof (* dpi_connector ),
222
- GFP_KERNEL );
223
- if (!dpi_connector )
224
- return ERR_PTR (- ENOMEM );
225
-
226
- connector = & dpi_connector -> base ;
227
-
228
- dpi_connector -> encoder = dpi -> encoder ;
229
- dpi_connector -> dpi = dpi ;
230
-
231
- drm_connector_init (dev , connector , & vc4_dpi_connector_funcs ,
232
- DRM_MODE_CONNECTOR_DPI );
233
- drm_connector_helper_add (connector , & vc4_dpi_connector_helper_funcs );
234
-
235
- connector -> polled = 0 ;
236
- connector -> interlace_allowed = 0 ;
237
- connector -> doublescan_allowed = 0 ;
238
-
239
- drm_mode_connector_attach_encoder (connector , dpi -> encoder );
240
-
241
- return connector ;
242
- }
243
-
244
155
static const struct drm_encoder_funcs vc4_dpi_encoder_funcs = {
245
156
.destroy = drm_encoder_cleanup ,
246
157
};
@@ -250,11 +161,7 @@ static void vc4_dpi_encoder_disable(struct drm_encoder *encoder)
250
161
struct vc4_dpi_encoder * vc4_encoder = to_vc4_dpi_encoder (encoder );
251
162
struct vc4_dpi * dpi = vc4_encoder -> dpi ;
252
163
253
- drm_panel_disable (dpi -> panel );
254
-
255
164
clk_disable_unprepare (dpi -> pixel_clock );
256
-
257
- drm_panel_unprepare (dpi -> panel );
258
165
}
259
166
260
167
static void vc4_dpi_encoder_enable (struct drm_encoder * encoder )
@@ -265,12 +172,6 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
265
172
u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE ;
266
173
int ret ;
267
174
268
- ret = drm_panel_prepare (dpi -> panel );
269
- if (ret ) {
270
- DRM_ERROR ("Panel failed to prepare\n" );
271
- return ;
272
- }
273
-
274
175
if (dpi -> connector -> display_info .num_bus_formats ) {
275
176
u32 bus_format = dpi -> connector -> display_info .bus_formats [0 ];
276
177
@@ -321,13 +222,6 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
321
222
ret = clk_prepare_enable (dpi -> pixel_clock );
322
223
if (ret )
323
224
DRM_ERROR ("Failed to set clock rate: %d\n" , ret );
324
-
325
- ret = drm_panel_enable (dpi -> panel );
326
- if (ret ) {
327
- DRM_ERROR ("Panel failed to enable\n" );
328
- drm_panel_unprepare (dpi -> panel );
329
- return ;
330
- }
331
225
}
332
226
333
227
static bool vc4_dpi_encoder_mode_fixup (struct drm_encoder * encoder ,
@@ -351,24 +245,34 @@ static const struct of_device_id vc4_dpi_dt_match[] = {
351
245
{}
352
246
};
353
247
354
- /* Walks the OF graph to find the panel node and then asks DRM to look
355
- * up the panel .
248
+ /* Sets up the next link in the display chain, whether it's a panel or
249
+ * a bridge .
356
250
*/
357
- static struct drm_panel * vc4_dpi_get_panel (struct device * dev )
251
+ static int vc4_dpi_init_bridge (struct vc4_dpi * dpi )
358
252
{
359
- struct device_node * panel_node ;
360
- struct device_node * np = dev -> of_node ;
253
+ struct device * dev = & dpi -> pdev -> dev ;
361
254
struct drm_panel * panel ;
255
+ int ret ;
362
256
363
- /* don't proceed if we have an endpoint but no panel_node tied to it */
364
- panel_node = of_graph_get_remote_node (np , 0 , 0 );
365
- if (!panel_node )
366
- return NULL ;
257
+ ret = drm_of_find_panel_or_bridge (dev -> of_node , 0 , 0 ,
258
+ & panel , & dpi -> bridge );
259
+ if (ret ) {
260
+ /* If nothing was connected in the DT, that's not an
261
+ * error.
262
+ */
263
+ if (ret == - ENODEV )
264
+ return 0 ;
265
+ else
266
+ return ret ;
267
+ }
367
268
368
- panel = of_drm_find_panel (panel_node );
369
- of_node_put (panel_node );
269
+ if (panel ) {
270
+ dpi -> bridge = drm_panel_bridge_add (panel ,
271
+ DRM_MODE_CONNECTOR_DPI );
272
+ dpi -> is_panel_bridge = true;
273
+ }
370
274
371
- return panel ;
275
+ return drm_bridge_attach ( dpi -> encoder , dpi -> bridge , NULL ) ;
372
276
}
373
277
374
278
static int vc4_dpi_bind (struct device * dev , struct device * master , void * data )
@@ -422,20 +326,13 @@ static int vc4_dpi_bind(struct device *dev, struct device *master, void *data)
422
326
if (ret )
423
327
DRM_ERROR ("Failed to turn on core clock: %d\n" , ret );
424
328
425
- dpi -> panel = vc4_dpi_get_panel (dev );
426
-
427
329
drm_encoder_init (drm , dpi -> encoder , & vc4_dpi_encoder_funcs ,
428
330
DRM_MODE_ENCODER_DPI , NULL );
429
331
drm_encoder_helper_add (dpi -> encoder , & vc4_dpi_encoder_helper_funcs );
430
332
431
- dpi -> connector = vc4_dpi_connector_init (drm , dpi );
432
- if (IS_ERR (dpi -> connector )) {
433
- ret = PTR_ERR (dpi -> connector );
333
+ ret = vc4_dpi_init_bridge (dpi );
334
+ if (ret )
434
335
goto err_destroy_encoder ;
435
- }
436
-
437
- if (dpi -> panel )
438
- drm_panel_attach (dpi -> panel , dpi -> connector );
439
336
440
337
dev_set_drvdata (dev , dpi );
441
338
@@ -456,10 +353,9 @@ static void vc4_dpi_unbind(struct device *dev, struct device *master,
456
353
struct vc4_dev * vc4 = to_vc4_dev (drm );
457
354
struct vc4_dpi * dpi = dev_get_drvdata (dev );
458
355
459
- if (dpi -> panel )
460
- drm_panel_detach (dpi -> panel );
356
+ if (dpi -> is_panel_bridge )
357
+ drm_panel_bridge_remove (dpi -> bridge );
461
358
462
- vc4_dpi_connector_destroy (dpi -> connector );
463
359
drm_encoder_cleanup (dpi -> encoder );
464
360
465
361
clk_disable_unprepare (dpi -> core_clock );
0 commit comments