1616
1717#include <drm/bridge/dw_hdmi.h>
1818#include <drm/drm_atomic_helper.h>
19+ #include <drm/drm_bridge.h>
1920#include <drm/drm_device.h>
2021#include <drm/drm_edid.h>
2122#include <drm/drm_probe_helper.h>
@@ -135,6 +136,7 @@ struct meson_dw_hdmi_data {
135136
136137struct meson_dw_hdmi {
137138 struct drm_encoder encoder ;
139+ struct drm_bridge bridge ;
138140 struct dw_hdmi_plat_data dw_plat_data ;
139141 struct meson_drm * priv ;
140142 struct device * dev ;
@@ -151,6 +153,8 @@ struct meson_dw_hdmi {
151153};
152154#define encoder_to_meson_dw_hdmi (x ) \
153155 container_of(x, struct meson_dw_hdmi, encoder)
156+ #define bridge_to_meson_dw_hdmi (x ) \
157+ container_of(x, struct meson_dw_hdmi, bridge)
154158
155159static inline int dw_hdmi_is_compatible (struct meson_dw_hdmi * dw_hdmi ,
156160 const char * compat )
@@ -368,7 +372,7 @@ static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi)
368372}
369373
370374static void dw_hdmi_set_vclk (struct meson_dw_hdmi * dw_hdmi ,
371- struct drm_display_mode * mode )
375+ const struct drm_display_mode * mode )
372376{
373377 struct meson_drm * priv = dw_hdmi -> priv ;
374378 int vic = drm_match_cea_mode (mode );
@@ -663,6 +667,10 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
663667
664668/* Encoder */
665669
670+ static const u32 meson_dw_hdmi_out_bus_fmts [] = {
671+ MEDIA_BUS_FMT_YUV8_1X24 ,
672+ };
673+
666674static void meson_venc_hdmi_encoder_destroy (struct drm_encoder * encoder )
667675{
668676 drm_encoder_cleanup (encoder );
@@ -672,16 +680,43 @@ static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = {
672680 .destroy = meson_venc_hdmi_encoder_destroy ,
673681};
674682
675- static int meson_venc_hdmi_encoder_atomic_check (struct drm_encoder * encoder ,
683+ static u32 *
684+ meson_venc_hdmi_encoder_get_inp_bus_fmts (struct drm_bridge * bridge ,
685+ struct drm_bridge_state * bridge_state ,
686+ struct drm_crtc_state * crtc_state ,
687+ struct drm_connector_state * conn_state ,
688+ u32 output_fmt ,
689+ unsigned int * num_input_fmts )
690+ {
691+ u32 * input_fmts = NULL ;
692+
693+ if (output_fmt == meson_dw_hdmi_out_bus_fmts [0 ]) {
694+ * num_input_fmts = 1 ;
695+ input_fmts = kcalloc (* num_input_fmts ,
696+ sizeof (* input_fmts ),
697+ GFP_KERNEL );
698+ if (!input_fmts )
699+ return NULL ;
700+
701+ input_fmts [0 ] = output_fmt ;
702+ } else {
703+ * num_input_fmts = 0 ;
704+ }
705+
706+ return input_fmts ;
707+ }
708+
709+ static int meson_venc_hdmi_encoder_atomic_check (struct drm_bridge * bridge ,
710+ struct drm_bridge_state * bridge_state ,
676711 struct drm_crtc_state * crtc_state ,
677712 struct drm_connector_state * conn_state )
678713{
679714 return 0 ;
680715}
681716
682- static void meson_venc_hdmi_encoder_disable (struct drm_encoder * encoder )
717+ static void meson_venc_hdmi_encoder_disable (struct drm_bridge * bridge )
683718{
684- struct meson_dw_hdmi * dw_hdmi = encoder_to_meson_dw_hdmi ( encoder );
719+ struct meson_dw_hdmi * dw_hdmi = bridge_to_meson_dw_hdmi ( bridge );
685720 struct meson_drm * priv = dw_hdmi -> priv ;
686721
687722 DRM_DEBUG_DRIVER ("\n" );
@@ -693,9 +728,9 @@ static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder)
693728 writel_relaxed (0 , priv -> io_base + _REG (ENCP_VIDEO_EN ));
694729}
695730
696- static void meson_venc_hdmi_encoder_enable (struct drm_encoder * encoder )
731+ static void meson_venc_hdmi_encoder_enable (struct drm_bridge * bridge )
697732{
698- struct meson_dw_hdmi * dw_hdmi = encoder_to_meson_dw_hdmi ( encoder );
733+ struct meson_dw_hdmi * dw_hdmi = bridge_to_meson_dw_hdmi ( bridge );
699734 struct meson_drm * priv = dw_hdmi -> priv ;
700735
701736 DRM_DEBUG_DRIVER ("%s\n" , priv -> venc .hdmi_use_enci ? "VENCI" : "VENCP" );
@@ -706,11 +741,11 @@ static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder)
706741 writel_relaxed (1 , priv -> io_base + _REG (ENCP_VIDEO_EN ));
707742}
708743
709- static void meson_venc_hdmi_encoder_mode_set (struct drm_encoder * encoder ,
710- struct drm_display_mode * mode ,
711- struct drm_display_mode * adjusted_mode )
744+ static void meson_venc_hdmi_encoder_mode_set (struct drm_bridge * bridge ,
745+ const struct drm_display_mode * mode ,
746+ const struct drm_display_mode * adjusted_mode )
712747{
713- struct meson_dw_hdmi * dw_hdmi = encoder_to_meson_dw_hdmi ( encoder );
748+ struct meson_dw_hdmi * dw_hdmi = bridge_to_meson_dw_hdmi ( bridge );
714749 struct meson_drm * priv = dw_hdmi -> priv ;
715750 int vic = drm_match_cea_mode (mode );
716751
@@ -726,12 +761,15 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
726761 writel_relaxed (0 , priv -> io_base + _REG (VPU_HDMI_FMT_CTRL ));
727762}
728763
729- static const struct drm_encoder_helper_funcs
730- meson_venc_hdmi_encoder_helper_funcs = {
731- .atomic_check = meson_venc_hdmi_encoder_atomic_check ,
732- .disable = meson_venc_hdmi_encoder_disable ,
733- .enable = meson_venc_hdmi_encoder_enable ,
734- .mode_set = meson_venc_hdmi_encoder_mode_set ,
764+ static const struct drm_bridge_funcs meson_venc_hdmi_encoder_bridge_funcs = {
765+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state ,
766+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state ,
767+ .atomic_get_input_bus_fmts = meson_venc_hdmi_encoder_get_inp_bus_fmts ,
768+ .atomic_reset = drm_atomic_helper_bridge_reset ,
769+ .atomic_check = meson_venc_hdmi_encoder_atomic_check ,
770+ .enable = meson_venc_hdmi_encoder_enable ,
771+ .disable = meson_venc_hdmi_encoder_disable ,
772+ .mode_set = meson_venc_hdmi_encoder_mode_set ,
735773};
736774
737775/* DW HDMI Regmap */
@@ -852,6 +890,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
852890 struct drm_device * drm = data ;
853891 struct meson_drm * priv = drm -> dev_private ;
854892 struct dw_hdmi_plat_data * dw_plat_data ;
893+ struct drm_bridge * next_bridge ;
855894 struct drm_encoder * encoder ;
856895 struct resource * res ;
857896 int irq ;
@@ -953,15 +992,16 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
953992
954993 /* Encoder */
955994
956- drm_encoder_helper_add (encoder , & meson_venc_hdmi_encoder_helper_funcs );
957-
958995 ret = drm_encoder_init (drm , encoder , & meson_venc_hdmi_encoder_funcs ,
959996 DRM_MODE_ENCODER_TMDS , "meson_hdmi" );
960997 if (ret ) {
961998 dev_err (priv -> dev , "Failed to init HDMI encoder\n" );
962999 return ret ;
9631000 }
9641001
1002+ meson_dw_hdmi -> bridge .funcs = & meson_venc_hdmi_encoder_bridge_funcs ;
1003+ drm_bridge_attach (encoder , & meson_dw_hdmi -> bridge , NULL , 0 );
1004+
9651005 encoder -> possible_crtcs = BIT (0 );
9661006
9671007 DRM_DEBUG_DRIVER ("encoder initialized\n" );
@@ -984,11 +1024,16 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
9841024
9851025 platform_set_drvdata (pdev , meson_dw_hdmi );
9861026
987- meson_dw_hdmi -> hdmi = dw_hdmi_bind (pdev , encoder ,
988- & meson_dw_hdmi -> dw_plat_data );
1027+ meson_dw_hdmi -> hdmi = dw_hdmi_probe (pdev ,
1028+ & meson_dw_hdmi -> dw_plat_data );
9891029 if (IS_ERR (meson_dw_hdmi -> hdmi ))
9901030 return PTR_ERR (meson_dw_hdmi -> hdmi );
9911031
1032+ next_bridge = of_drm_find_bridge (pdev -> dev .of_node );
1033+ if (next_bridge )
1034+ drm_bridge_attach (encoder , next_bridge ,
1035+ & meson_dw_hdmi -> bridge , 0 );
1036+
9921037 DRM_DEBUG_DRIVER ("HDMI controller initialized\n" );
9931038
9941039 return 0 ;
0 commit comments