@@ -436,19 +436,29 @@ static void zynqmp_disp_avbuf_set_format(struct zynqmp_disp *disp,
436436 const struct zynqmp_disp_format * fmt )
437437{
438438 unsigned int i ;
439- u32 val ;
439+ u32 val , reg ;
440440
441- val = zynqmp_disp_avbuf_read (disp , ZYNQMP_DISP_AV_BUF_FMT );
442- val &= zynqmp_disp_layer_is_video (layer )
443- ? ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK
444- : ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK ;
445- val |= fmt -> buf_fmt ;
446- zynqmp_disp_avbuf_write (disp , ZYNQMP_DISP_AV_BUF_FMT , val );
441+ layer -> disp_fmt = fmt ;
442+ if (layer -> mode == ZYNQMP_DPSUB_LAYER_NONLIVE ) {
443+ reg = ZYNQMP_DISP_AV_BUF_FMT ;
444+ val = zynqmp_disp_avbuf_read (disp , ZYNQMP_DISP_AV_BUF_FMT );
445+ val &= zynqmp_disp_layer_is_video (layer )
446+ ? ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK
447+ : ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK ;
448+ val |= fmt -> buf_fmt ;
449+ zynqmp_disp_avbuf_write (disp , reg , val );
450+ } else {
451+ reg = zynqmp_disp_layer_is_video (layer )
452+ ? ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG
453+ : ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG ;
454+ val = fmt -> buf_fmt ;
455+ zynqmp_disp_avbuf_write (disp , reg , val );
456+ }
447457
448458 for (i = 0 ; i < ZYNQMP_DISP_AV_BUF_NUM_SF ; i ++ ) {
449- unsigned int reg = zynqmp_disp_layer_is_video (layer )
450- ? ZYNQMP_DISP_AV_BUF_VID_COMP_SF (i )
451- : ZYNQMP_DISP_AV_BUF_GFX_COMP_SF (i );
459+ reg = zynqmp_disp_layer_is_video (layer )
460+ ? ZYNQMP_DISP_AV_BUF_VID_COMP_SF (i )
461+ : ZYNQMP_DISP_AV_BUF_GFX_COMP_SF (i );
452462
453463 zynqmp_disp_avbuf_write (disp , reg , fmt -> sf [i ]);
454464 }
@@ -926,6 +936,31 @@ zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
926936 return NULL ;
927937}
928938
939+ /**
940+ * zynqmp_disp_layer_find_live_format - Find format information for given
941+ * media bus format
942+ * @layer: The layer
943+ * @drm_fmt: Media bus format to search
944+ *
945+ * Search display subsystem format information corresponding to the given media
946+ * bus format @media_bus_format for the @layer, and return a pointer to the
947+ * format descriptor.
948+ *
949+ * Return: A pointer to the format descriptor if found, NULL otherwise
950+ */
951+ static const struct zynqmp_disp_format *
952+ zynqmp_disp_layer_find_live_format (struct zynqmp_disp_layer * layer ,
953+ u32 media_bus_format )
954+ {
955+ unsigned int i ;
956+
957+ for (i = 0 ; i < layer -> info -> num_formats ; i ++ )
958+ if (layer -> info -> formats [i ].bus_fmt == media_bus_format )
959+ return & layer -> info -> formats [i ];
960+
961+ return NULL ;
962+ }
963+
929964/**
930965 * zynqmp_disp_layer_drm_formats - Return the DRM formats supported by the layer
931966 * @layer: The layer
@@ -1040,21 +1075,26 @@ void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer)
10401075 * @layer: The layer
10411076 * @info: The format info
10421077 *
1078+ * NOTE: Use zynqmp_disp_layer_set_live_format() to set media bus format for
1079+ * live video layers.
1080+ *
10431081 * Set the format for @layer to @info. The layer must be disabled.
10441082 */
10451083void zynqmp_disp_layer_set_format (struct zynqmp_disp_layer * layer ,
10461084 const struct drm_format_info * info )
10471085{
10481086 unsigned int i ;
10491087
1088+ if (WARN_ON (layer -> mode != ZYNQMP_DPSUB_LAYER_NONLIVE ))
1089+ return ;
1090+
10501091 layer -> disp_fmt = zynqmp_disp_layer_find_format (layer , info -> format );
1092+ if (WARN_ON (!layer -> disp_fmt ))
1093+ return ;
10511094 layer -> drm_fmt = info ;
10521095
10531096 zynqmp_disp_avbuf_set_format (layer -> disp , layer , layer -> disp_fmt );
10541097
1055- if (layer -> mode == ZYNQMP_DPSUB_LAYER_LIVE )
1056- return ;
1057-
10581098 /*
10591099 * Set pconfig for each DMA channel to indicate they're part of a
10601100 * video group.
@@ -1074,6 +1114,32 @@ void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
10741114 }
10751115}
10761116
1117+ /**
1118+ * zynqmp_disp_layer_set_live_format - Set the live video layer format
1119+ * @layer: The layer
1120+ * @info: The format info
1121+ *
1122+ * NOTE: This function should not be used to set format for non-live video
1123+ * layer. Use zynqmp_disp_layer_set_format() instead.
1124+ *
1125+ * Set the display format for the live @layer. The layer must be disabled.
1126+ */
1127+ void zynqmp_disp_layer_set_live_format (struct zynqmp_disp_layer * layer ,
1128+ u32 media_bus_format )
1129+ {
1130+ if (WARN_ON (layer -> mode != ZYNQMP_DPSUB_LAYER_LIVE ))
1131+ return ;
1132+
1133+ layer -> disp_fmt = zynqmp_disp_layer_find_live_format (layer ,
1134+ media_bus_format );
1135+ if (WARN_ON (!layer -> disp_fmt ))
1136+ return ;
1137+
1138+ zynqmp_disp_avbuf_set_format (layer -> disp , layer , layer -> disp_fmt );
1139+
1140+ layer -> drm_fmt = drm_format_info (layer -> disp_fmt -> drm_fmt );
1141+ }
1142+
10771143/**
10781144 * zynqmp_disp_layer_update - Update the layer framebuffer
10791145 * @layer: The layer
0 commit comments