18
18
#include <linux/dma/xilinx_dpdma.h>
19
19
#include <linux/dma-mapping.h>
20
20
#include <linux/dmaengine.h>
21
+ #include <linux/media-bus-format.h>
21
22
#include <linux/module.h>
22
23
#include <linux/of.h>
23
24
#include <linux/platform_device.h>
@@ -77,12 +78,14 @@ enum zynqmp_dpsub_layer_mode {
77
78
/**
78
79
* struct zynqmp_disp_format - Display subsystem format information
79
80
* @drm_fmt: DRM format (4CC)
81
+ * @bus_fmt: Media bus format
80
82
* @buf_fmt: AV buffer format
81
83
* @swap: Flag to swap R & B for RGB formats, and U & V for YUV formats
82
84
* @sf: Scaling factors for color components
83
85
*/
84
86
struct zynqmp_disp_format {
85
87
u32 drm_fmt ;
88
+ u32 bus_fmt ;
86
89
u32 buf_fmt ;
87
90
bool swap ;
88
91
const u32 * sf ;
@@ -182,6 +185,12 @@ static const u32 scaling_factors_565[] = {
182
185
ZYNQMP_DISP_AV_BUF_5BIT_SF ,
183
186
};
184
187
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
+
185
194
static const u32 scaling_factors_888 [] = {
186
195
ZYNQMP_DISP_AV_BUF_8BIT_SF ,
187
196
ZYNQMP_DISP_AV_BUF_8BIT_SF ,
@@ -364,6 +373,41 @@ static const struct zynqmp_disp_format avbuf_gfx_fmts[] = {
364
373
},
365
374
};
366
375
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
+
367
411
static u32 zynqmp_disp_avbuf_read (struct zynqmp_disp * disp , int reg )
368
412
{
369
413
return readl (disp -> avbuf .base + reg );
@@ -887,6 +931,11 @@ zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
887
931
* @layer: The layer
888
932
* @num_formats: Pointer to the returned number of formats
889
933
*
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
+ *
890
939
* Return: A newly allocated u32 array that stores all the DRM formats
891
940
* supported by the layer. The number of formats in the array is returned
892
941
* through the num_formats argument.
@@ -897,10 +946,17 @@ u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer,
897
946
unsigned int i ;
898
947
u32 * formats ;
899
948
949
+ if (WARN_ON (!layer -> mode == ZYNQMP_DPSUB_LAYER_NONLIVE )) {
950
+ * num_formats = 0 ;
951
+ return NULL ;
952
+ }
953
+
900
954
formats = kcalloc (layer -> info -> num_formats , sizeof (* formats ),
901
955
GFP_KERNEL );
902
- if (!formats )
956
+ if (!formats ) {
957
+ * num_formats = 0 ;
903
958
return NULL ;
959
+ }
904
960
905
961
for (i = 0 ; i < layer -> info -> num_formats ; ++ i )
906
962
formats [i ] = layer -> info -> formats [i ].drm_fmt ;
@@ -909,6 +965,43 @@ u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer,
909
965
return formats ;
910
966
}
911
967
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
+
912
1005
/**
913
1006
* zynqmp_disp_layer_enable - Enable a layer
914
1007
* @layer: The layer
@@ -1131,6 +1224,11 @@ static int zynqmp_disp_create_layers(struct zynqmp_disp *disp)
1131
1224
.num_channels = 1 ,
1132
1225
},
1133
1226
};
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
+ };
1134
1232
1135
1233
unsigned int i ;
1136
1234
int ret ;
@@ -1140,13 +1238,17 @@ static int zynqmp_disp_create_layers(struct zynqmp_disp *disp)
1140
1238
1141
1239
layer -> id = i ;
1142
1240
layer -> disp = disp ;
1143
- layer -> info = & layer_info [i ];
1144
1241
/*
1145
1242
* For now assume dpsub works in either live or non-live mode for both layers.
1146
1243
* Hybrid mode is not supported yet.
1147
1244
*/
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
+ }
1150
1252
1151
1253
ret = zynqmp_disp_layer_request_dma (disp , layer );
1152
1254
if (ret )
0 commit comments