@@ -554,6 +554,7 @@ struct vc4_dsi {
554554 struct mipi_dsi_host dsi_host ;
555555 struct drm_encoder * encoder ;
556556 struct drm_bridge * out_bridge ;
557+ struct drm_bridge bridge ;
557558
558559 void __iomem * regs ;
559560
@@ -655,6 +656,12 @@ to_vc4_dsi_encoder(struct drm_encoder *encoder)
655656 return container_of (encoder , struct vc4_dsi_encoder , base .base );
656657}
657658
659+ static inline struct vc4_dsi *
660+ bridge_to_vc4_dsi (struct drm_bridge * bridge )
661+ {
662+ return container_of (bridge , struct vc4_dsi , bridge );
663+ }
664+
658665static const struct debugfs_reg32 dsi0_regs [] = {
659666 VC4_REG32 (DSI0_CTRL ),
660667 VC4_REG32 (DSI0_STAT ),
@@ -792,11 +799,21 @@ dsi_esc_timing(u32 ns)
792799 return DIV_ROUND_UP (ns , ESC_TIME_NS );
793800}
794801
795- static void vc4_dsi_encoder_disable (struct drm_encoder * encoder ,
796- struct drm_atomic_state * state )
802+ static void vc4_dsi_bridge_disable (struct drm_bridge * bridge ,
803+ struct drm_bridge_state * state )
804+ {
805+ struct vc4_dsi * dsi = bridge_to_vc4_dsi (bridge );
806+ u32 disp0_ctrl ;
807+
808+ disp0_ctrl = DSI_PORT_READ (DISP0_CTRL );
809+ disp0_ctrl &= ~DSI_DISP0_ENABLE ;
810+ DSI_PORT_WRITE (DISP0_CTRL , disp0_ctrl );
811+ }
812+
813+ static void vc4_dsi_bridge_post_disable (struct drm_bridge * bridge ,
814+ struct drm_bridge_state * state )
797815{
798- struct vc4_dsi_encoder * vc4_encoder = to_vc4_dsi_encoder (encoder );
799- struct vc4_dsi * dsi = vc4_encoder -> dsi ;
816+ struct vc4_dsi * dsi = bridge_to_vc4_dsi (bridge );
800817 struct device * dev = & dsi -> pdev -> dev ;
801818
802819 vc4_dsi_ulps (dsi , true);
@@ -821,12 +838,11 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder,
821838 * higher-than-expected clock rate to the panel, but that's what the
822839 * firmware does too.
823840 */
824- static bool vc4_dsi_encoder_mode_fixup (struct drm_encoder * encoder ,
825- const struct drm_display_mode * mode ,
826- struct drm_display_mode * adjusted_mode )
841+ static bool vc4_dsi_bridge_mode_fixup (struct drm_bridge * bridge ,
842+ const struct drm_display_mode * mode ,
843+ struct drm_display_mode * adjusted_mode )
827844{
828- struct vc4_dsi_encoder * vc4_encoder = to_vc4_dsi_encoder (encoder );
829- struct vc4_dsi * dsi = vc4_encoder -> dsi ;
845+ struct vc4_dsi * dsi = bridge_to_vc4_dsi (bridge );
830846 struct clk * phy_parent = clk_get_parent (dsi -> pll_phy_clock );
831847 unsigned long parent_rate = clk_get_rate (phy_parent );
832848 unsigned long pixel_clock_hz = mode -> clock * 1000 ;
@@ -858,16 +874,18 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
858874 return true;
859875}
860876
861- static void vc4_dsi_encoder_mode_set (struct drm_encoder * encoder ,
862- struct drm_crtc_state * crtc_state ,
863- struct drm_connector_state * conn_state )
877+ static void vc4_dsi_bridge_pre_enable (struct drm_bridge * bridge ,
878+ struct drm_bridge_state * old_state )
864879{
865- struct vc4_dsi_encoder * vc4_encoder = to_vc4_dsi_encoder (encoder );
866- struct vc4_dsi * dsi = vc4_encoder -> dsi ;
880+ struct drm_atomic_state * state = old_state -> base .state ;
881+ struct vc4_dsi * dsi = bridge_to_vc4_dsi (bridge );
882+ const struct drm_crtc_state * crtc_state ;
867883 struct device * dev = & dsi -> pdev -> dev ;
868884 const struct drm_display_mode * mode ;
885+ struct drm_connector * connector ;
869886 bool debug_dump_regs = false;
870887 unsigned long hs_clock ;
888+ struct drm_crtc * crtc ;
871889 u32 ui_ns ;
872890 /* Minimum LP state duration in escape clock cycles. */
873891 u32 lpx = dsi_esc_timing (60 );
@@ -888,6 +906,14 @@ static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
888906 drm_print_regset32 (& p , & dsi -> regset );
889907 }
890908
909+ /*
910+ * Retrieve the CRTC adjusted mode. This requires a little dance to go
911+ * from the bridge to the encoder, to the connector and to the CRTC.
912+ */
913+ connector = drm_atomic_get_new_connector_for_encoder (state ,
914+ bridge -> encoder );
915+ crtc = drm_atomic_get_new_connector_state (state , connector )-> crtc ;
916+ crtc_state = drm_atomic_get_new_crtc_state (state , crtc );
891917 mode = & crtc_state -> adjusted_mode ;
892918
893919 pixel_clock_hz = mode -> clock * 1000 ;
@@ -1102,14 +1128,6 @@ static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
11021128 ~DSI_PORT_BIT (PHY_AFEC0_RESET ));
11031129
11041130 vc4_dsi_ulps (dsi , false);
1105- }
1106-
1107- static void vc4_dsi_encoder_enable (struct drm_encoder * encoder ,
1108- struct drm_atomic_state * state )
1109- {
1110- struct vc4_dsi_encoder * vc4_encoder = to_vc4_dsi_encoder (encoder );
1111- struct vc4_dsi * dsi = vc4_encoder -> dsi ;
1112- bool debug_dump_regs = false;
11131131
11141132 if (dsi -> mode_flags & MIPI_DSI_MODE_VIDEO ) {
11151133 DSI_PORT_WRITE (DISP0_CTRL ,
@@ -1118,13 +1136,23 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
11181136 VC4_SET_FIELD (dsi -> format , DSI_DISP0_PFORMAT ) |
11191137 VC4_SET_FIELD (DSI_DISP0_LP_STOP_PERFRAME ,
11201138 DSI_DISP0_LP_STOP_CTRL ) |
1121- DSI_DISP0_ST_END |
1122- DSI_DISP0_ENABLE );
1139+ DSI_DISP0_ST_END );
11231140 } else {
11241141 DSI_PORT_WRITE (DISP0_CTRL ,
1125- DSI_DISP0_COMMAND_MODE |
1126- DSI_DISP0_ENABLE );
1142+ DSI_DISP0_COMMAND_MODE );
11271143 }
1144+ }
1145+
1146+ static void vc4_dsi_bridge_enable (struct drm_bridge * bridge ,
1147+ struct drm_bridge_state * old_state )
1148+ {
1149+ struct vc4_dsi * dsi = bridge_to_vc4_dsi (bridge );
1150+ bool debug_dump_regs = false;
1151+ u32 disp0_ctrl ;
1152+
1153+ disp0_ctrl = DSI_PORT_READ (DISP0_CTRL );
1154+ disp0_ctrl |= DSI_DISP0_ENABLE ;
1155+ DSI_PORT_WRITE (DISP0_CTRL , disp0_ctrl );
11281156
11291157 if (debug_dump_regs ) {
11301158 struct drm_printer p = drm_info_printer (& dsi -> pdev -> dev );
@@ -1133,6 +1161,16 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
11331161 }
11341162}
11351163
1164+ static int vc4_dsi_bridge_attach (struct drm_bridge * bridge ,
1165+ enum drm_bridge_attach_flags flags )
1166+ {
1167+ struct vc4_dsi * dsi = bridge_to_vc4_dsi (bridge );
1168+
1169+ /* Attach the panel or bridge to the dsi bridge */
1170+ return drm_bridge_attach (bridge -> encoder , dsi -> out_bridge ,
1171+ & dsi -> bridge , flags );
1172+ }
1173+
11361174static ssize_t vc4_dsi_host_transfer (struct mipi_dsi_host * host ,
11371175 const struct mipi_dsi_msg * msg )
11381176{
@@ -1309,6 +1347,7 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host,
13091347 struct mipi_dsi_device * device )
13101348{
13111349 struct vc4_dsi * dsi = host_to_dsi (host );
1350+ int ret ;
13121351
13131352 dsi -> lanes = device -> lanes ;
13141353 dsi -> channel = device -> channel ;
@@ -1343,7 +1382,15 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host,
13431382 return 0 ;
13441383 }
13451384
1346- return component_add (& dsi -> pdev -> dev , & vc4_dsi_ops );
1385+ drm_bridge_add (& dsi -> bridge );
1386+
1387+ ret = component_add (& dsi -> pdev -> dev , & vc4_dsi_ops );
1388+ if (ret ) {
1389+ drm_bridge_remove (& dsi -> bridge );
1390+ return ret ;
1391+ }
1392+
1393+ return 0 ;
13471394}
13481395
13491396static int vc4_dsi_host_detach (struct mipi_dsi_host * host ,
@@ -1352,6 +1399,7 @@ static int vc4_dsi_host_detach(struct mipi_dsi_host *host,
13521399 struct vc4_dsi * dsi = host_to_dsi (host );
13531400
13541401 component_del (& dsi -> pdev -> dev , & vc4_dsi_ops );
1402+ drm_bridge_remove (& dsi -> bridge );
13551403 return 0 ;
13561404}
13571405
@@ -1361,11 +1409,16 @@ static const struct mipi_dsi_host_ops vc4_dsi_host_ops = {
13611409 .transfer = vc4_dsi_host_transfer ,
13621410};
13631411
1364- static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = {
1365- .atomic_disable = vc4_dsi_encoder_disable ,
1366- .atomic_enable = vc4_dsi_encoder_enable ,
1367- .mode_fixup = vc4_dsi_encoder_mode_fixup ,
1368- .atomic_mode_set = vc4_dsi_encoder_mode_set ,
1412+ static const struct drm_bridge_funcs vc4_dsi_bridge_funcs = {
1413+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state ,
1414+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state ,
1415+ .atomic_reset = drm_atomic_helper_bridge_reset ,
1416+ .atomic_pre_enable = vc4_dsi_bridge_pre_enable ,
1417+ .atomic_enable = vc4_dsi_bridge_enable ,
1418+ .atomic_disable = vc4_dsi_bridge_disable ,
1419+ .atomic_post_disable = vc4_dsi_bridge_post_disable ,
1420+ .attach = vc4_dsi_bridge_attach ,
1421+ .mode_fixup = vc4_dsi_bridge_mode_fixup ,
13691422};
13701423
13711424static const struct vc4_dsi_variant bcm2711_dsi1_variant = {
@@ -1691,9 +1744,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
16911744 goto err_free_dma ;
16921745
16931746 drm_simple_encoder_init (drm , dsi -> encoder , DRM_MODE_ENCODER_DSI );
1694- drm_encoder_helper_add (dsi -> encoder , & vc4_dsi_encoder_helper_funcs );
16951747
1696- ret = drm_bridge_attach (dsi -> encoder , dsi -> out_bridge , NULL , 0 );
1748+ ret = drm_bridge_attach (dsi -> encoder , & dsi -> bridge , NULL , 0 );
16971749 if (ret ) {
16981750 dev_err (dev , "bridge attach failed: %d\n" , ret );
16991751 goto err_free_dma ;
@@ -1755,6 +1807,10 @@ static int vc4_dsi_dev_probe(struct platform_device *pdev)
17551807 return - ENOMEM ;
17561808 dev_set_drvdata (dev , dsi );
17571809
1810+ dsi -> bridge .funcs = & vc4_dsi_bridge_funcs ;
1811+ dsi -> bridge .of_node = dev -> of_node ;
1812+ dsi -> bridge .type = DRM_MODE_CONNECTOR_DSI ;
1813+
17581814 dsi -> pdev = pdev ;
17591815 dsi -> dsi_host .ops = & vc4_dsi_host_ops ;
17601816 dsi -> dsi_host .dev = dev ;
0 commit comments