9
9
10
10
#include <linux/clk.h>
11
11
#include <linux/media-bus-format.h>
12
+ #include <linux/of.h>
13
+ #include <linux/of_graph.h>
12
14
#include <linux/pm_runtime.h>
13
15
14
16
#include <drm/drm_atomic.h>
15
17
#include <drm/drm_atomic_helper.h>
16
18
#include <drm/drm_atomic_state_helper.h>
17
19
#include <drm/drm_atomic_uapi.h>
20
+ #include <drm/drm_bridge.h>
21
+ #include <drm/drm_bridge_connector.h>
18
22
#include <drm/drm_crtc.h>
19
23
#include <drm/drm_crtc_helper.h>
20
24
#include <drm/drm_fb_dma_helper.h>
23
27
#include <drm/drm_gem_dma_helper.h>
24
28
#include <drm/drm_modeset_helper.h>
25
29
#include <drm/drm_modeset_helper_vtables.h>
30
+ #include <drm/drm_panel.h>
26
31
#include <drm/drm_probe_helper.h>
27
32
#include <drm/drm_simple_kms_helper.h>
28
33
#include <drm/drm_vblank.h>
35
40
#include "shmob_drm_plane.h"
36
41
#include "shmob_drm_regs.h"
37
42
38
- /*
39
- * TODO: panel support
40
- */
41
-
42
43
/* -----------------------------------------------------------------------------
43
44
* Page Flip
44
45
*/
@@ -201,7 +202,7 @@ static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc,
201
202
{
202
203
struct shmob_drm_crtc * scrtc = to_shmob_crtc (crtc );
203
204
struct shmob_drm_device * sdev = to_shmob_device (crtc -> dev );
204
- const struct shmob_drm_interface_data * idata = & sdev -> pdata -> iface ;
205
+ unsigned int clk_div = sdev -> config . clk_div ;
205
206
struct device * dev = sdev -> dev ;
206
207
u32 value ;
207
208
int ret ;
@@ -223,17 +224,17 @@ static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc,
223
224
lcdc_write (sdev , LDPMR , 0 );
224
225
225
226
value = sdev -> lddckr ;
226
- if (idata -> clk_div ) {
227
+ if (clk_div ) {
227
228
/* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
228
229
* denominator.
229
230
*/
230
231
lcdc_write (sdev , LDDCKPAT1R , 0 );
231
- lcdc_write (sdev , LDDCKPAT2R , (1 << (idata -> clk_div / 2 )) - 1 );
232
+ lcdc_write (sdev , LDDCKPAT2R , (1 << (clk_div / 2 )) - 1 );
232
233
233
- if (idata -> clk_div == 1 )
234
+ if (clk_div == 1 )
234
235
value |= LDDCKR_MOSEL ;
235
236
else
236
- value |= idata -> clk_div ;
237
+ value |= clk_div ;
237
238
}
238
239
239
240
lcdc_write (sdev , LDDCKR , value );
@@ -406,7 +407,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
406
407
}
407
408
408
409
/* -----------------------------------------------------------------------------
409
- * Encoder
410
+ * Legacy Encoder
410
411
*/
411
412
412
413
static bool shmob_drm_encoder_mode_fixup (struct drm_encoder * encoder ,
@@ -435,9 +436,14 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
435
436
.mode_fixup = shmob_drm_encoder_mode_fixup ,
436
437
};
437
438
439
+ /* -----------------------------------------------------------------------------
440
+ * Encoder
441
+ */
442
+
438
443
int shmob_drm_encoder_create (struct shmob_drm_device * sdev )
439
444
{
440
445
struct drm_encoder * encoder = & sdev -> encoder ;
446
+ struct drm_bridge * bridge ;
441
447
int ret ;
442
448
443
449
encoder -> possible_crtcs = 1 ;
@@ -447,13 +453,30 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
447
453
if (ret < 0 )
448
454
return ret ;
449
455
450
- drm_encoder_helper_add (encoder , & encoder_helper_funcs );
456
+ if (sdev -> pdata ) {
457
+ drm_encoder_helper_add (encoder , & encoder_helper_funcs );
458
+ return 0 ;
459
+ }
460
+
461
+ /* Create a panel bridge */
462
+ bridge = devm_drm_of_get_bridge (sdev -> dev , sdev -> dev -> of_node , 0 , 0 );
463
+ if (IS_ERR (bridge ))
464
+ return PTR_ERR (bridge );
465
+
466
+ /* Attach the bridge to the encoder */
467
+ ret = drm_bridge_attach (encoder , bridge , NULL ,
468
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR );
469
+ if (ret ) {
470
+ dev_err (sdev -> dev , "failed to attach bridge: %pe\n" ,
471
+ ERR_PTR (ret ));
472
+ return ret ;
473
+ }
451
474
452
475
return 0 ;
453
476
}
454
477
455
478
/* -----------------------------------------------------------------------------
456
- * Connector
479
+ * Legacy Connector
457
480
*/
458
481
459
482
static inline struct shmob_drm_connector * to_shmob_connector (struct drm_connector * connector )
@@ -563,13 +586,20 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev,
563
586
return connector ;
564
587
}
565
588
589
+ /* -----------------------------------------------------------------------------
590
+ * Connector
591
+ */
592
+
566
593
int shmob_drm_connector_create (struct shmob_drm_device * sdev ,
567
594
struct drm_encoder * encoder )
568
595
{
569
596
struct drm_connector * connector ;
570
597
int ret ;
571
598
572
- connector = shmob_drm_connector_init (sdev , encoder );
599
+ if (sdev -> pdata )
600
+ connector = shmob_drm_connector_init (sdev , encoder );
601
+ else
602
+ connector = drm_bridge_connector_init (& sdev -> ddev , encoder );
573
603
if (IS_ERR (connector )) {
574
604
dev_err (sdev -> dev , "failed to created connector: %pe\n" ,
575
605
connector );
0 commit comments