1818#include <linux/dma/xilinx_dpdma.h>
1919#include <linux/dma-mapping.h>
2020#include <linux/dmaengine.h>
21+ #include <linux/media-bus-format.h>
2122#include <linux/module.h>
2223#include <linux/of.h>
2324#include <linux/platform_device.h>
@@ -77,12 +78,14 @@ enum zynqmp_dpsub_layer_mode {
7778/**
7879 * struct zynqmp_disp_format - Display subsystem format information
7980 * @drm_fmt: DRM format (4CC)
81+ * @bus_fmt: Media bus format
8082 * @buf_fmt: AV buffer format
8183 * @swap: Flag to swap R & B for RGB formats, and U & V for YUV formats
8284 * @sf: Scaling factors for color components
8385 */
8486struct zynqmp_disp_format {
8587 u32 drm_fmt ;
88+ u32 bus_fmt ;
8689 u32 buf_fmt ;
8790 bool swap ;
8891 const u32 * sf ;
@@ -182,6 +185,12 @@ static const u32 scaling_factors_565[] = {
182185 ZYNQMP_DISP_AV_BUF_5BIT_SF ,
183186};
184187
188+ static const u32 scaling_factors_666 [] = {
189+ ZYNQMP_DISP_AV_BUF_6BIT_SF ,
190+ ZYNQMP_DISP_AV_BUF_6BIT_SF ,
191+ ZYNQMP_DISP_AV_BUF_6BIT_SF ,
192+ };
193+
185194static const u32 scaling_factors_888 [] = {
186195 ZYNQMP_DISP_AV_BUF_8BIT_SF ,
187196 ZYNQMP_DISP_AV_BUF_8BIT_SF ,
@@ -364,6 +373,41 @@ static const struct zynqmp_disp_format avbuf_gfx_fmts[] = {
364373 },
365374};
366375
376+ /* List of live video layer formats */
377+ static const struct zynqmp_disp_format avbuf_live_fmts [] = {
378+ {
379+ .drm_fmt = DRM_FORMAT_RGB565 ,
380+ .bus_fmt = MEDIA_BUS_FMT_RGB666_1X18 ,
381+ .buf_fmt = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_6 |
382+ ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB ,
383+ .sf = scaling_factors_666 ,
384+ }, {
385+ .drm_fmt = DRM_FORMAT_RGB888 ,
386+ .bus_fmt = MEDIA_BUS_FMT_RGB888_1X24 ,
387+ .buf_fmt = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
388+ ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB ,
389+ .sf = scaling_factors_888 ,
390+ }, {
391+ .drm_fmt = DRM_FORMAT_YUV422 ,
392+ .bus_fmt = MEDIA_BUS_FMT_UYVY8_1X16 ,
393+ .buf_fmt = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
394+ ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422 ,
395+ .sf = scaling_factors_888 ,
396+ }, {
397+ .drm_fmt = DRM_FORMAT_YUV444 ,
398+ .bus_fmt = MEDIA_BUS_FMT_VUY8_1X24 ,
399+ .buf_fmt = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
400+ ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444 ,
401+ .sf = scaling_factors_888 ,
402+ }, {
403+ .drm_fmt = DRM_FORMAT_P210 ,
404+ .bus_fmt = MEDIA_BUS_FMT_UYVY10_1X20 ,
405+ .buf_fmt = ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_10 |
406+ ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422 ,
407+ .sf = scaling_factors_101010 ,
408+ },
409+ };
410+
367411static u32 zynqmp_disp_avbuf_read (struct zynqmp_disp * disp , int reg )
368412{
369413 return readl (disp -> avbuf .base + reg );
@@ -887,6 +931,11 @@ zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
887931 * @layer: The layer
888932 * @num_formats: Pointer to the returned number of formats
889933 *
934+ * NOTE: This function doesn't make sense for live video layers and will
935+ * always return an empty list in such cases. zynqmp_disp_live_layer_formats()
936+ * should be used to query a list of media bus formats supported by the live
937+ * video input layer.
938+ *
890939 * Return: A newly allocated u32 array that stores all the DRM formats
891940 * supported by the layer. The number of formats in the array is returned
892941 * through the num_formats argument.
@@ -897,10 +946,17 @@ u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer,
897946 unsigned int i ;
898947 u32 * formats ;
899948
949+ if (WARN_ON (!layer -> mode == ZYNQMP_DPSUB_LAYER_NONLIVE )) {
950+ * num_formats = 0 ;
951+ return NULL ;
952+ }
953+
900954 formats = kcalloc (layer -> info -> num_formats , sizeof (* formats ),
901955 GFP_KERNEL );
902- if (!formats )
956+ if (!formats ) {
957+ * num_formats = 0 ;
903958 return NULL ;
959+ }
904960
905961 for (i = 0 ; i < layer -> info -> num_formats ; ++ i )
906962 formats [i ] = layer -> info -> formats [i ].drm_fmt ;
@@ -909,6 +965,43 @@ u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer,
909965 return formats ;
910966}
911967
968+ /**
969+ * zynqmp_disp_live_layer_formats - Return the media bus formats supported by
970+ * the live video layer
971+ * @layer: The layer
972+ * @num_formats: Pointer to the returned number of formats
973+ *
974+ * NOTE: This function should be used only for live video input layers.
975+ *
976+ * Return: A newly allocated u32 array of media bus formats supported by the
977+ * layer. The number of formats in the array is returned through the
978+ * @num_formats argument.
979+ */
980+ u32 * zynqmp_disp_live_layer_formats (struct zynqmp_disp_layer * layer ,
981+ unsigned int * num_formats )
982+ {
983+ unsigned int i ;
984+ u32 * formats ;
985+
986+ if (WARN_ON (layer -> mode != ZYNQMP_DPSUB_LAYER_LIVE )) {
987+ * num_formats = 0 ;
988+ return NULL ;
989+ }
990+
991+ formats = kcalloc (layer -> info -> num_formats , sizeof (* formats ),
992+ GFP_KERNEL );
993+ if (!formats ) {
994+ * num_formats = 0 ;
995+ return NULL ;
996+ }
997+
998+ for (i = 0 ; i < layer -> info -> num_formats ; ++ i )
999+ formats [i ] = layer -> info -> formats [i ].bus_fmt ;
1000+
1001+ * num_formats = layer -> info -> num_formats ;
1002+ return formats ;
1003+ }
1004+
9121005/**
9131006 * zynqmp_disp_layer_enable - Enable a layer
9141007 * @layer: The layer
@@ -1131,6 +1224,11 @@ static int zynqmp_disp_create_layers(struct zynqmp_disp *disp)
11311224 .num_channels = 1 ,
11321225 },
11331226 };
1227+ static const struct zynqmp_disp_layer_info live_layer_info = {
1228+ .formats = avbuf_live_fmts ,
1229+ .num_formats = ARRAY_SIZE (avbuf_live_fmts ),
1230+ .num_channels = 0 ,
1231+ };
11341232
11351233 unsigned int i ;
11361234 int ret ;
@@ -1140,13 +1238,17 @@ static int zynqmp_disp_create_layers(struct zynqmp_disp *disp)
11401238
11411239 layer -> id = i ;
11421240 layer -> disp = disp ;
1143- layer -> info = & layer_info [i ];
11441241 /*
11451242 * For now assume dpsub works in either live or non-live mode for both layers.
11461243 * Hybrid mode is not supported yet.
11471244 */
1148- layer -> mode = disp -> dpsub -> dma_enabled ? ZYNQMP_DPSUB_LAYER_NONLIVE
1149- : ZYNQMP_DPSUB_LAYER_LIVE ;
1245+ if (disp -> dpsub -> dma_enabled ) {
1246+ layer -> mode = ZYNQMP_DPSUB_LAYER_NONLIVE ;
1247+ layer -> info = & layer_info [i ];
1248+ } else {
1249+ layer -> mode = ZYNQMP_DPSUB_LAYER_LIVE ;
1250+ layer -> info = & live_layer_info ;
1251+ }
11501252
11511253 ret = zynqmp_disp_layer_request_dma (disp , layer );
11521254 if (ret )
0 commit comments