0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <drm/drm_atomic.h>
0013 #include <drm/drm_atomic_helper.h>
0014 #include <drm/drm_atomic_uapi.h>
0015 #include <drm/drm_blend.h>
0016 #include <drm/drm_crtc.h>
0017 #include <drm/drm_device.h>
0018 #include <drm/drm_fb_cma_helper.h>
0019 #include <drm/drm_fourcc.h>
0020 #include <drm/drm_framebuffer.h>
0021 #include <drm/drm_managed.h>
0022 #include <drm/drm_plane.h>
0023 #include <drm/drm_plane_helper.h>
0024 #include <drm/drm_vblank.h>
0025
0026 #include <linux/clk.h>
0027 #include <linux/delay.h>
0028 #include <linux/dma/xilinx_dpdma.h>
0029 #include <linux/dma-mapping.h>
0030 #include <linux/dmaengine.h>
0031 #include <linux/module.h>
0032 #include <linux/of.h>
0033 #include <linux/platform_device.h>
0034 #include <linux/pm_runtime.h>
0035 #include <linux/spinlock.h>
0036
0037 #include "zynqmp_disp.h"
0038 #include "zynqmp_disp_regs.h"
0039 #include "zynqmp_dp.h"
0040 #include "zynqmp_dpsub.h"
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 #define ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS 4
0074 #define ZYNQMP_DISP_AV_BUF_NUM_BUFFERS 6
0075
0076 #define ZYNQMP_DISP_NUM_LAYERS 2
0077 #define ZYNQMP_DISP_MAX_NUM_SUB_PLANES 3
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 struct zynqmp_disp_format {
0088 u32 drm_fmt;
0089 u32 buf_fmt;
0090 u32 bus_fmt;
0091 bool swap;
0092 const u32 *sf;
0093 };
0094
0095
0096
0097
0098
0099
0100 enum zynqmp_disp_layer_id {
0101 ZYNQMP_DISP_LAYER_VID,
0102 ZYNQMP_DISP_LAYER_GFX
0103 };
0104
0105
0106
0107
0108
0109
0110 enum zynqmp_disp_layer_mode {
0111 ZYNQMP_DISP_LAYER_NONLIVE,
0112 ZYNQMP_DISP_LAYER_LIVE
0113 };
0114
0115
0116
0117
0118
0119
0120
0121 struct zynqmp_disp_layer_dma {
0122 struct dma_chan *chan;
0123 struct dma_interleaved_template xt;
0124 struct data_chunk sgl;
0125 };
0126
0127
0128
0129
0130
0131
0132
0133 struct zynqmp_disp_layer_info {
0134 const struct zynqmp_disp_format *formats;
0135 unsigned int num_formats;
0136 unsigned int num_channels;
0137 };
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 struct zynqmp_disp_layer {
0151 struct drm_plane plane;
0152 enum zynqmp_disp_layer_id id;
0153 struct zynqmp_disp *disp;
0154 const struct zynqmp_disp_layer_info *info;
0155
0156 struct zynqmp_disp_layer_dma dmas[ZYNQMP_DISP_MAX_NUM_SUB_PLANES];
0157
0158 const struct zynqmp_disp_format *disp_fmt;
0159 const struct drm_format_info *drm_fmt;
0160 enum zynqmp_disp_layer_mode mode;
0161 };
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179 struct zynqmp_disp {
0180 struct device *dev;
0181 struct drm_device *drm;
0182 struct zynqmp_dpsub *dpsub;
0183
0184 struct drm_crtc crtc;
0185
0186 struct {
0187 void __iomem *base;
0188 } blend;
0189 struct {
0190 void __iomem *base;
0191 } avbuf;
0192 struct {
0193 void __iomem *base;
0194 struct clk *clk;
0195 bool clk_from_ps;
0196 } audio;
0197
0198 struct zynqmp_disp_layer layers[ZYNQMP_DISP_NUM_LAYERS];
0199
0200 struct drm_pending_vblank_event *event;
0201
0202 struct clk *pclk;
0203 bool pclk_from_ps;
0204 };
0205
0206
0207
0208
0209
0210 static const u32 scaling_factors_444[] = {
0211 ZYNQMP_DISP_AV_BUF_4BIT_SF,
0212 ZYNQMP_DISP_AV_BUF_4BIT_SF,
0213 ZYNQMP_DISP_AV_BUF_4BIT_SF,
0214 };
0215
0216 static const u32 scaling_factors_555[] = {
0217 ZYNQMP_DISP_AV_BUF_5BIT_SF,
0218 ZYNQMP_DISP_AV_BUF_5BIT_SF,
0219 ZYNQMP_DISP_AV_BUF_5BIT_SF,
0220 };
0221
0222 static const u32 scaling_factors_565[] = {
0223 ZYNQMP_DISP_AV_BUF_5BIT_SF,
0224 ZYNQMP_DISP_AV_BUF_6BIT_SF,
0225 ZYNQMP_DISP_AV_BUF_5BIT_SF,
0226 };
0227
0228 static const u32 scaling_factors_888[] = {
0229 ZYNQMP_DISP_AV_BUF_8BIT_SF,
0230 ZYNQMP_DISP_AV_BUF_8BIT_SF,
0231 ZYNQMP_DISP_AV_BUF_8BIT_SF,
0232 };
0233
0234 static const u32 scaling_factors_101010[] = {
0235 ZYNQMP_DISP_AV_BUF_10BIT_SF,
0236 ZYNQMP_DISP_AV_BUF_10BIT_SF,
0237 ZYNQMP_DISP_AV_BUF_10BIT_SF,
0238 };
0239
0240
0241 static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
0242 {
0243 .drm_fmt = DRM_FORMAT_VYUY,
0244 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
0245 .swap = true,
0246 .sf = scaling_factors_888,
0247 }, {
0248 .drm_fmt = DRM_FORMAT_UYVY,
0249 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_VYUY,
0250 .swap = false,
0251 .sf = scaling_factors_888,
0252 }, {
0253 .drm_fmt = DRM_FORMAT_YUYV,
0254 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
0255 .swap = false,
0256 .sf = scaling_factors_888,
0257 }, {
0258 .drm_fmt = DRM_FORMAT_YVYU,
0259 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUYV,
0260 .swap = true,
0261 .sf = scaling_factors_888,
0262 }, {
0263 .drm_fmt = DRM_FORMAT_YUV422,
0264 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
0265 .swap = false,
0266 .sf = scaling_factors_888,
0267 }, {
0268 .drm_fmt = DRM_FORMAT_YVU422,
0269 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16,
0270 .swap = true,
0271 .sf = scaling_factors_888,
0272 }, {
0273 .drm_fmt = DRM_FORMAT_YUV444,
0274 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
0275 .swap = false,
0276 .sf = scaling_factors_888,
0277 }, {
0278 .drm_fmt = DRM_FORMAT_YVU444,
0279 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24,
0280 .swap = true,
0281 .sf = scaling_factors_888,
0282 }, {
0283 .drm_fmt = DRM_FORMAT_NV16,
0284 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
0285 .swap = false,
0286 .sf = scaling_factors_888,
0287 }, {
0288 .drm_fmt = DRM_FORMAT_NV61,
0289 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI,
0290 .swap = true,
0291 .sf = scaling_factors_888,
0292 }, {
0293 .drm_fmt = DRM_FORMAT_BGR888,
0294 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
0295 .swap = false,
0296 .sf = scaling_factors_888,
0297 }, {
0298 .drm_fmt = DRM_FORMAT_RGB888,
0299 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888,
0300 .swap = true,
0301 .sf = scaling_factors_888,
0302 }, {
0303 .drm_fmt = DRM_FORMAT_XBGR8888,
0304 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
0305 .swap = false,
0306 .sf = scaling_factors_888,
0307 }, {
0308 .drm_fmt = DRM_FORMAT_XRGB8888,
0309 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGBA8880,
0310 .swap = true,
0311 .sf = scaling_factors_888,
0312 }, {
0313 .drm_fmt = DRM_FORMAT_XBGR2101010,
0314 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
0315 .swap = false,
0316 .sf = scaling_factors_101010,
0317 }, {
0318 .drm_fmt = DRM_FORMAT_XRGB2101010,
0319 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_RGB888_10,
0320 .swap = true,
0321 .sf = scaling_factors_101010,
0322 }, {
0323 .drm_fmt = DRM_FORMAT_YUV420,
0324 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
0325 .swap = false,
0326 .sf = scaling_factors_888,
0327 }, {
0328 .drm_fmt = DRM_FORMAT_YVU420,
0329 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16_420,
0330 .swap = true,
0331 .sf = scaling_factors_888,
0332 }, {
0333 .drm_fmt = DRM_FORMAT_NV12,
0334 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
0335 .swap = false,
0336 .sf = scaling_factors_888,
0337 }, {
0338 .drm_fmt = DRM_FORMAT_NV21,
0339 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
0340 .swap = true,
0341 .sf = scaling_factors_888,
0342 },
0343 };
0344
0345
0346 static const struct zynqmp_disp_format avbuf_gfx_fmts[] = {
0347 {
0348 .drm_fmt = DRM_FORMAT_ABGR8888,
0349 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
0350 .swap = false,
0351 .sf = scaling_factors_888,
0352 }, {
0353 .drm_fmt = DRM_FORMAT_ARGB8888,
0354 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA8888,
0355 .swap = true,
0356 .sf = scaling_factors_888,
0357 }, {
0358 .drm_fmt = DRM_FORMAT_RGBA8888,
0359 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
0360 .swap = false,
0361 .sf = scaling_factors_888,
0362 }, {
0363 .drm_fmt = DRM_FORMAT_BGRA8888,
0364 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_ABGR8888,
0365 .swap = true,
0366 .sf = scaling_factors_888,
0367 }, {
0368 .drm_fmt = DRM_FORMAT_BGR888,
0369 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB888,
0370 .swap = false,
0371 .sf = scaling_factors_888,
0372 }, {
0373 .drm_fmt = DRM_FORMAT_RGB888,
0374 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_BGR888,
0375 .swap = false,
0376 .sf = scaling_factors_888,
0377 }, {
0378 .drm_fmt = DRM_FORMAT_RGBA5551,
0379 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
0380 .swap = false,
0381 .sf = scaling_factors_555,
0382 }, {
0383 .drm_fmt = DRM_FORMAT_BGRA5551,
0384 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA5551,
0385 .swap = true,
0386 .sf = scaling_factors_555,
0387 }, {
0388 .drm_fmt = DRM_FORMAT_RGBA4444,
0389 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
0390 .swap = false,
0391 .sf = scaling_factors_444,
0392 }, {
0393 .drm_fmt = DRM_FORMAT_BGRA4444,
0394 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGBA4444,
0395 .swap = true,
0396 .sf = scaling_factors_444,
0397 }, {
0398 .drm_fmt = DRM_FORMAT_RGB565,
0399 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
0400 .swap = false,
0401 .sf = scaling_factors_565,
0402 }, {
0403 .drm_fmt = DRM_FORMAT_BGR565,
0404 .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_RGB565,
0405 .swap = true,
0406 .sf = scaling_factors_565,
0407 },
0408 };
0409
0410 static u32 zynqmp_disp_avbuf_read(struct zynqmp_disp *disp, int reg)
0411 {
0412 return readl(disp->avbuf.base + reg);
0413 }
0414
0415 static void zynqmp_disp_avbuf_write(struct zynqmp_disp *disp, int reg, u32 val)
0416 {
0417 writel(val, disp->avbuf.base + reg);
0418 }
0419
0420 static bool zynqmp_disp_layer_is_gfx(const struct zynqmp_disp_layer *layer)
0421 {
0422 return layer->id == ZYNQMP_DISP_LAYER_GFX;
0423 }
0424
0425 static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer)
0426 {
0427 return layer->id == ZYNQMP_DISP_LAYER_VID;
0428 }
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 static void zynqmp_disp_avbuf_set_format(struct zynqmp_disp *disp,
0439 struct zynqmp_disp_layer *layer,
0440 const struct zynqmp_disp_format *fmt)
0441 {
0442 unsigned int i;
0443 u32 val;
0444
0445 val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_FMT);
0446 val &= zynqmp_disp_layer_is_video(layer)
0447 ? ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK
0448 : ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK;
0449 val |= fmt->buf_fmt;
0450 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_FMT, val);
0451
0452 for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; i++) {
0453 unsigned int reg = zynqmp_disp_layer_is_video(layer)
0454 ? ZYNQMP_DISP_AV_BUF_VID_COMP_SF(i)
0455 : ZYNQMP_DISP_AV_BUF_GFX_COMP_SF(i);
0456
0457 zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
0458 }
0459 }
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472 static void
0473 zynqmp_disp_avbuf_set_clocks_sources(struct zynqmp_disp *disp,
0474 bool video_from_ps, bool audio_from_ps,
0475 bool timings_internal)
0476 {
0477 u32 val = 0;
0478
0479 if (video_from_ps)
0480 val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_FROM_PS;
0481 if (audio_from_ps)
0482 val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_AUD_FROM_PS;
0483 if (timings_internal)
0484 val |= ZYNQMP_DISP_AV_BUF_CLK_SRC_VID_INTERNAL_TIMING;
0485
0486 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CLK_SRC, val);
0487 }
0488
0489
0490
0491
0492
0493
0494
0495 static void zynqmp_disp_avbuf_enable_channels(struct zynqmp_disp *disp)
0496 {
0497 unsigned int i;
0498 u32 val;
0499
0500 val = ZYNQMP_DISP_AV_BUF_CHBUF_EN |
0501 (ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_MAX <<
0502 ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT);
0503
0504 for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_VID_GFX_BUFFERS; i++)
0505 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
0506 val);
0507
0508 val = ZYNQMP_DISP_AV_BUF_CHBUF_EN |
0509 (ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_AUD_MAX <<
0510 ZYNQMP_DISP_AV_BUF_CHBUF_BURST_LEN_SHIFT);
0511
0512 for (; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
0513 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
0514 val);
0515 }
0516
0517
0518
0519
0520
0521
0522
0523 static void zynqmp_disp_avbuf_disable_channels(struct zynqmp_disp *disp)
0524 {
0525 unsigned int i;
0526
0527 for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_BUFFERS; i++)
0528 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_CHBUF(i),
0529 ZYNQMP_DISP_AV_BUF_CHBUF_FLUSH);
0530 }
0531
0532
0533
0534
0535
0536
0537
0538 static void zynqmp_disp_avbuf_enable_audio(struct zynqmp_disp *disp)
0539 {
0540 u32 val;
0541
0542 val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
0543 val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
0544 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MEM;
0545 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
0546 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
0547 }
0548
0549
0550
0551
0552
0553
0554
0555 static void zynqmp_disp_avbuf_disable_audio(struct zynqmp_disp *disp)
0556 {
0557 u32 val;
0558
0559 val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
0560 val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_MASK;
0561 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_AUD1_DISABLE;
0562 val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_AUD2_EN;
0563 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
0564 }
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574 static void zynqmp_disp_avbuf_enable_video(struct zynqmp_disp *disp,
0575 struct zynqmp_disp_layer *layer,
0576 enum zynqmp_disp_layer_mode mode)
0577 {
0578 u32 val;
0579
0580 val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
0581 if (zynqmp_disp_layer_is_video(layer)) {
0582 val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
0583 if (mode == ZYNQMP_DISP_LAYER_NONLIVE)
0584 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MEM;
0585 else
0586 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_LIVE;
0587 } else {
0588 val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
0589 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
0590 if (mode == ZYNQMP_DISP_LAYER_NONLIVE)
0591 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MEM;
0592 else
0593 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_LIVE;
0594 }
0595 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
0596 }
0597
0598
0599
0600
0601
0602
0603
0604
0605 static void zynqmp_disp_avbuf_disable_video(struct zynqmp_disp *disp,
0606 struct zynqmp_disp_layer *layer)
0607 {
0608 u32 val;
0609
0610 val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_OUTPUT);
0611 if (zynqmp_disp_layer_is_video(layer)) {
0612 val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_MASK;
0613 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID1_NONE;
0614 } else {
0615 val &= ~ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_MASK;
0616 val |= ZYNQMP_DISP_AV_BUF_OUTPUT_VID2_DISABLE;
0617 }
0618 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_OUTPUT, val);
0619 }
0620
0621
0622
0623
0624
0625
0626
0627 static void zynqmp_disp_avbuf_enable(struct zynqmp_disp *disp)
0628 {
0629 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_SRST_REG, 0);
0630 }
0631
0632
0633
0634
0635
0636
0637
0638 static void zynqmp_disp_avbuf_disable(struct zynqmp_disp *disp)
0639 {
0640 zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_SRST_REG,
0641 ZYNQMP_DISP_AV_BUF_SRST_REG_VID_RST);
0642 }
0643
0644
0645
0646
0647
0648 static void zynqmp_disp_blend_write(struct zynqmp_disp *disp, int reg, u32 val)
0649 {
0650 writel(val, disp->blend.base + reg);
0651 }
0652
0653
0654
0655
0656
0657
0658 static const u16 csc_zero_matrix[] = {
0659 0x0, 0x0, 0x0,
0660 0x0, 0x0, 0x0,
0661 0x0, 0x0, 0x0
0662 };
0663
0664 static const u16 csc_identity_matrix[] = {
0665 0x1000, 0x0, 0x0,
0666 0x0, 0x1000, 0x0,
0667 0x0, 0x0, 0x1000
0668 };
0669
0670 static const u32 csc_zero_offsets[] = {
0671 0, 0, 0
0672 };
0673
0674 static const u16 csc_rgb_to_sdtv_matrix[] = {
0675 0x4c9, 0x864, 0x1d3,
0676 0x7d4d, 0x7ab3, 0x800,
0677 0x800, 0x794d, 0x7eb3
0678 };
0679
0680 static const u32 csc_rgb_to_sdtv_offsets[] = {
0681 0x0, 0x8000000, 0x8000000
0682 };
0683
0684 static const u16 csc_sdtv_to_rgb_matrix[] = {
0685 0x1000, 0x166f, 0x0,
0686 0x1000, 0x7483, 0x7a7f,
0687 0x1000, 0x0, 0x1c5a
0688 };
0689
0690 static const u32 csc_sdtv_to_rgb_offsets[] = {
0691 0x0, 0x1800, 0x1800
0692 };
0693
0694
0695
0696
0697
0698
0699
0700
0701 static void zynqmp_disp_blend_set_output_format(struct zynqmp_disp *disp,
0702 enum zynqmp_dpsub_format format)
0703 {
0704 static const unsigned int blend_output_fmts[] = {
0705 [ZYNQMP_DPSUB_FORMAT_RGB] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB,
0706 [ZYNQMP_DPSUB_FORMAT_YCRCB444] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR444,
0707 [ZYNQMP_DPSUB_FORMAT_YCRCB422] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YCBCR422
0708 | ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_EN_DOWNSAMPLE,
0709 [ZYNQMP_DPSUB_FORMAT_YONLY] = ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_YONLY,
0710 };
0711
0712 u32 fmt = blend_output_fmts[format];
0713 const u16 *coeffs;
0714 const u32 *offsets;
0715 unsigned int i;
0716
0717 zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT, fmt);
0718 if (fmt == ZYNQMP_DISP_V_BLEND_OUTPUT_VID_FMT_RGB) {
0719 coeffs = csc_identity_matrix;
0720 offsets = csc_zero_offsets;
0721 } else {
0722 coeffs = csc_rgb_to_sdtv_matrix;
0723 offsets = csc_rgb_to_sdtv_offsets;
0724 }
0725
0726 for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i++)
0727 zynqmp_disp_blend_write(disp,
0728 ZYNQMP_DISP_V_BLEND_RGB2YCBCR_COEFF(i),
0729 coeffs[i]);
0730
0731 for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
0732 zynqmp_disp_blend_write(disp,
0733 ZYNQMP_DISP_V_BLEND_OUTCSC_OFFSET(i),
0734 offsets[i]);
0735 }
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748 static void zynqmp_disp_blend_set_bg_color(struct zynqmp_disp *disp,
0749 u32 rcr, u32 gy, u32 bcb)
0750 {
0751 zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_0, rcr);
0752 zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_1, gy);
0753 zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_BG_CLR_2, bcb);
0754 }
0755
0756
0757
0758
0759
0760
0761
0762 static void zynqmp_disp_blend_set_global_alpha(struct zynqmp_disp *disp,
0763 bool enable, u32 alpha)
0764 {
0765 zynqmp_disp_blend_write(disp, ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA,
0766 ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_VALUE(alpha) |
0767 (enable ? ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_EN : 0));
0768 }
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781 static void zynqmp_disp_blend_layer_set_csc(struct zynqmp_disp *disp,
0782 struct zynqmp_disp_layer *layer,
0783 const u16 *coeffs,
0784 const u32 *offsets)
0785 {
0786 unsigned int swap[3] = { 0, 1, 2 };
0787 unsigned int reg;
0788 unsigned int i;
0789
0790 if (layer->disp_fmt->swap) {
0791 if (layer->drm_fmt->is_yuv) {
0792
0793 swap[1] = 2;
0794 swap[2] = 1;
0795 } else {
0796
0797 swap[0] = 2;
0798 swap[2] = 0;
0799 }
0800 }
0801
0802 if (zynqmp_disp_layer_is_video(layer))
0803 reg = ZYNQMP_DISP_V_BLEND_IN1CSC_COEFF(0);
0804 else
0805 reg = ZYNQMP_DISP_V_BLEND_IN2CSC_COEFF(0);
0806
0807 for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_COEFF; i += 3, reg += 12) {
0808 zynqmp_disp_blend_write(disp, reg + 0, coeffs[i + swap[0]]);
0809 zynqmp_disp_blend_write(disp, reg + 4, coeffs[i + swap[1]]);
0810 zynqmp_disp_blend_write(disp, reg + 8, coeffs[i + swap[2]]);
0811 }
0812
0813 if (zynqmp_disp_layer_is_video(layer))
0814 reg = ZYNQMP_DISP_V_BLEND_IN1CSC_OFFSET(0);
0815 else
0816 reg = ZYNQMP_DISP_V_BLEND_IN2CSC_OFFSET(0);
0817
0818 for (i = 0; i < ZYNQMP_DISP_V_BLEND_NUM_OFFSET; i++)
0819 zynqmp_disp_blend_write(disp, reg + i * 4, offsets[i]);
0820 }
0821
0822
0823
0824
0825
0826
0827 static void zynqmp_disp_blend_layer_enable(struct zynqmp_disp *disp,
0828 struct zynqmp_disp_layer *layer)
0829 {
0830 const u16 *coeffs;
0831 const u32 *offsets;
0832 u32 val;
0833
0834 val = (layer->drm_fmt->is_yuv ?
0835 0 : ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_RGB) |
0836 (layer->drm_fmt->hsub > 1 ?
0837 ZYNQMP_DISP_V_BLEND_LAYER_CONTROL_EN_US : 0);
0838
0839 zynqmp_disp_blend_write(disp,
0840 ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
0841 val);
0842
0843 if (layer->drm_fmt->is_yuv) {
0844 coeffs = csc_sdtv_to_rgb_matrix;
0845 offsets = csc_sdtv_to_rgb_offsets;
0846 } else {
0847 coeffs = csc_identity_matrix;
0848 offsets = csc_zero_offsets;
0849 }
0850
0851 zynqmp_disp_blend_layer_set_csc(disp, layer, coeffs, offsets);
0852 }
0853
0854
0855
0856
0857
0858
0859 static void zynqmp_disp_blend_layer_disable(struct zynqmp_disp *disp,
0860 struct zynqmp_disp_layer *layer)
0861 {
0862 zynqmp_disp_blend_write(disp,
0863 ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
0864 0);
0865
0866 zynqmp_disp_blend_layer_set_csc(disp, layer, csc_zero_matrix,
0867 csc_zero_offsets);
0868 }
0869
0870
0871
0872
0873
0874 static void zynqmp_disp_audio_write(struct zynqmp_disp *disp, int reg, u32 val)
0875 {
0876 writel(val, disp->audio.base + reg);
0877 }
0878
0879
0880
0881
0882
0883
0884
0885
0886 static void zynqmp_disp_audio_enable(struct zynqmp_disp *disp)
0887 {
0888
0889 zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_SOFT_RESET, 0);
0890 zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_MIXER_VOLUME,
0891 ZYNQMP_DISP_AUD_MIXER_VOLUME_NO_SCALE);
0892 }
0893
0894
0895
0896
0897
0898
0899
0900 static void zynqmp_disp_audio_disable(struct zynqmp_disp *disp)
0901 {
0902 zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_SOFT_RESET,
0903 ZYNQMP_DISP_AUD_SOFT_RESET_AUD_SRST);
0904 }
0905
0906 static void zynqmp_disp_audio_init(struct zynqmp_disp *disp)
0907 {
0908
0909 disp->audio.clk = devm_clk_get(disp->dev, "dp_live_audio_aclk");
0910 if (!IS_ERR(disp->audio.clk)) {
0911 disp->audio.clk_from_ps = false;
0912 return;
0913 }
0914
0915
0916 disp->audio.clk = devm_clk_get(disp->dev, "dp_aud_clk");
0917 if (!IS_ERR(disp->audio.clk)) {
0918 disp->audio.clk_from_ps = true;
0919 return;
0920 }
0921
0922 dev_err(disp->dev, "audio disabled due to missing clock\n");
0923 }
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936 void zynqmp_disp_handle_vblank(struct zynqmp_disp *disp)
0937 {
0938 struct drm_crtc *crtc = &disp->crtc;
0939
0940 drm_crtc_handle_vblank(crtc);
0941 }
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951 bool zynqmp_disp_audio_enabled(struct zynqmp_disp *disp)
0952 {
0953 return !!disp->audio.clk;
0954 }
0955
0956
0957
0958
0959
0960
0961
0962 unsigned int zynqmp_disp_get_audio_clk_rate(struct zynqmp_disp *disp)
0963 {
0964 if (zynqmp_disp_audio_enabled(disp))
0965 return 0;
0966 return clk_get_rate(disp->audio.clk);
0967 }
0968
0969
0970
0971
0972
0973
0974
0975 uint32_t zynqmp_disp_get_crtc_mask(struct zynqmp_disp *disp)
0976 {
0977 return drm_crtc_mask(&disp->crtc);
0978 }
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995 static const struct zynqmp_disp_format *
0996 zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
0997 u32 drm_fmt)
0998 {
0999 unsigned int i;
1000
1001 for (i = 0; i < layer->info->num_formats; i++) {
1002 if (layer->info->formats[i].drm_fmt == drm_fmt)
1003 return &layer->info->formats[i];
1004 }
1005
1006 return NULL;
1007 }
1008
1009
1010
1011
1012
1013
1014
1015
1016 static void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer)
1017 {
1018 zynqmp_disp_avbuf_enable_video(layer->disp, layer,
1019 ZYNQMP_DISP_LAYER_NONLIVE);
1020 zynqmp_disp_blend_layer_enable(layer->disp, layer);
1021
1022 layer->mode = ZYNQMP_DISP_LAYER_NONLIVE;
1023 }
1024
1025
1026
1027
1028
1029
1030
1031
1032 static void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer)
1033 {
1034 unsigned int i;
1035
1036 for (i = 0; i < layer->drm_fmt->num_planes; i++)
1037 dmaengine_terminate_sync(layer->dmas[i].chan);
1038
1039 zynqmp_disp_avbuf_disable_video(layer->disp, layer);
1040 zynqmp_disp_blend_layer_disable(layer->disp, layer);
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 static void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
1052 struct drm_plane_state *state)
1053 {
1054 const struct drm_format_info *info = state->fb->format;
1055 unsigned int i;
1056
1057 layer->disp_fmt = zynqmp_disp_layer_find_format(layer, info->format);
1058 layer->drm_fmt = info;
1059
1060 zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt);
1061
1062
1063
1064
1065
1066 for (i = 0; i < info->num_planes; i++) {
1067 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1068 struct xilinx_dpdma_peripheral_config pconfig = {
1069 .video_group = true,
1070 };
1071 struct dma_slave_config config = {
1072 .direction = DMA_MEM_TO_DEV,
1073 .peripheral_config = &pconfig,
1074 .peripheral_size = sizeof(pconfig),
1075 };
1076
1077 dmaengine_slave_config(dma->chan, &config);
1078 }
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091 static int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
1092 struct drm_plane_state *state)
1093 {
1094 const struct drm_format_info *info = layer->drm_fmt;
1095 unsigned int i;
1096
1097 for (i = 0; i < layer->drm_fmt->num_planes; i++) {
1098 unsigned int width = state->crtc_w / (i ? info->hsub : 1);
1099 unsigned int height = state->crtc_h / (i ? info->vsub : 1);
1100 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1101 struct dma_async_tx_descriptor *desc;
1102 dma_addr_t paddr;
1103
1104 paddr = drm_fb_cma_get_gem_addr(state->fb, state, i);
1105
1106 dma->xt.numf = height;
1107 dma->sgl.size = width * info->cpp[i];
1108 dma->sgl.icg = state->fb->pitches[i] - dma->sgl.size;
1109 dma->xt.src_start = paddr;
1110 dma->xt.frame_size = 1;
1111 dma->xt.dir = DMA_MEM_TO_DEV;
1112 dma->xt.src_sgl = true;
1113 dma->xt.dst_sgl = false;
1114
1115 desc = dmaengine_prep_interleaved_dma(dma->chan, &dma->xt,
1116 DMA_CTRL_ACK |
1117 DMA_PREP_REPEAT |
1118 DMA_PREP_LOAD_EOT);
1119 if (!desc) {
1120 dev_err(layer->disp->dev,
1121 "failed to prepare DMA descriptor\n");
1122 return -ENOMEM;
1123 }
1124
1125 dmaengine_submit(desc);
1126 dma_async_issue_pending(dma->chan);
1127 }
1128
1129 return 0;
1130 }
1131
1132 static inline struct zynqmp_disp_layer *plane_to_layer(struct drm_plane *plane)
1133 {
1134 return container_of(plane, struct zynqmp_disp_layer, plane);
1135 }
1136
1137 static int
1138 zynqmp_disp_plane_atomic_check(struct drm_plane *plane,
1139 struct drm_atomic_state *state)
1140 {
1141 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
1142 plane);
1143 struct drm_crtc_state *crtc_state;
1144
1145 if (!new_plane_state->crtc)
1146 return 0;
1147
1148 crtc_state = drm_atomic_get_crtc_state(state, new_plane_state->crtc);
1149 if (IS_ERR(crtc_state))
1150 return PTR_ERR(crtc_state);
1151
1152 return drm_atomic_helper_check_plane_state(new_plane_state,
1153 crtc_state,
1154 DRM_PLANE_HELPER_NO_SCALING,
1155 DRM_PLANE_HELPER_NO_SCALING,
1156 false, false);
1157 }
1158
1159 static void
1160 zynqmp_disp_plane_atomic_disable(struct drm_plane *plane,
1161 struct drm_atomic_state *state)
1162 {
1163 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
1164 plane);
1165 struct zynqmp_disp_layer *layer = plane_to_layer(plane);
1166
1167 if (!old_state->fb)
1168 return;
1169
1170 zynqmp_disp_layer_disable(layer);
1171
1172 if (zynqmp_disp_layer_is_gfx(layer))
1173 zynqmp_disp_blend_set_global_alpha(layer->disp, false,
1174 plane->state->alpha >> 8);
1175 }
1176
1177 static void
1178 zynqmp_disp_plane_atomic_update(struct drm_plane *plane,
1179 struct drm_atomic_state *state)
1180 {
1181 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
1182 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
1183 struct zynqmp_disp_layer *layer = plane_to_layer(plane);
1184 bool format_changed = false;
1185
1186 if (!old_state->fb ||
1187 old_state->fb->format->format != new_state->fb->format->format)
1188 format_changed = true;
1189
1190
1191
1192
1193
1194
1195 if (format_changed) {
1196 if (old_state->fb)
1197 zynqmp_disp_layer_disable(layer);
1198
1199 zynqmp_disp_layer_set_format(layer, new_state);
1200 }
1201
1202 zynqmp_disp_layer_update(layer, new_state);
1203
1204 if (zynqmp_disp_layer_is_gfx(layer))
1205 zynqmp_disp_blend_set_global_alpha(layer->disp, true,
1206 plane->state->alpha >> 8);
1207
1208
1209 if (format_changed)
1210 zynqmp_disp_layer_enable(layer);
1211 }
1212
1213 static const struct drm_plane_helper_funcs zynqmp_disp_plane_helper_funcs = {
1214 .atomic_check = zynqmp_disp_plane_atomic_check,
1215 .atomic_update = zynqmp_disp_plane_atomic_update,
1216 .atomic_disable = zynqmp_disp_plane_atomic_disable,
1217 };
1218
1219 static const struct drm_plane_funcs zynqmp_disp_plane_funcs = {
1220 .update_plane = drm_atomic_helper_update_plane,
1221 .disable_plane = drm_atomic_helper_disable_plane,
1222 .destroy = drm_plane_cleanup,
1223 .reset = drm_atomic_helper_plane_reset,
1224 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
1225 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
1226 };
1227
1228 static int zynqmp_disp_create_planes(struct zynqmp_disp *disp)
1229 {
1230 unsigned int i, j;
1231 int ret;
1232
1233 for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
1234 struct zynqmp_disp_layer *layer = &disp->layers[i];
1235 enum drm_plane_type type;
1236 u32 *drm_formats;
1237
1238 drm_formats = drmm_kcalloc(disp->drm, sizeof(*drm_formats),
1239 layer->info->num_formats,
1240 GFP_KERNEL);
1241 if (!drm_formats)
1242 return -ENOMEM;
1243
1244 for (j = 0; j < layer->info->num_formats; ++j)
1245 drm_formats[j] = layer->info->formats[j].drm_fmt;
1246
1247
1248 type = zynqmp_disp_layer_is_video(layer)
1249 ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY;
1250 ret = drm_universal_plane_init(disp->drm, &layer->plane, 0,
1251 &zynqmp_disp_plane_funcs,
1252 drm_formats,
1253 layer->info->num_formats,
1254 NULL, type, NULL);
1255 if (ret)
1256 return ret;
1257
1258 drm_plane_helper_add(&layer->plane,
1259 &zynqmp_disp_plane_helper_funcs);
1260
1261 drm_plane_create_zpos_immutable_property(&layer->plane, i);
1262 if (zynqmp_disp_layer_is_gfx(layer))
1263 drm_plane_create_alpha_property(&layer->plane);
1264 }
1265
1266 return 0;
1267 }
1268
1269
1270
1271
1272
1273
1274
1275
1276 static void zynqmp_disp_layer_release_dma(struct zynqmp_disp *disp,
1277 struct zynqmp_disp_layer *layer)
1278 {
1279 unsigned int i;
1280
1281 if (!layer->info)
1282 return;
1283
1284 for (i = 0; i < layer->info->num_channels; i++) {
1285 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1286
1287 if (!dma->chan)
1288 continue;
1289
1290
1291 dmaengine_terminate_sync(dma->chan);
1292 dma_release_channel(dma->chan);
1293 }
1294 }
1295
1296
1297
1298
1299
1300 static void zynqmp_disp_destroy_layers(struct zynqmp_disp *disp)
1301 {
1302 unsigned int i;
1303
1304 for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
1305 zynqmp_disp_layer_release_dma(disp, &disp->layers[i]);
1306 }
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317 static int zynqmp_disp_layer_request_dma(struct zynqmp_disp *disp,
1318 struct zynqmp_disp_layer *layer)
1319 {
1320 static const char * const dma_names[] = { "vid", "gfx" };
1321 unsigned int i;
1322 int ret;
1323
1324 for (i = 0; i < layer->info->num_channels; i++) {
1325 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1326 char dma_channel_name[16];
1327
1328 snprintf(dma_channel_name, sizeof(dma_channel_name),
1329 "%s%u", dma_names[layer->id], i);
1330 dma->chan = dma_request_chan(disp->dev, dma_channel_name);
1331 if (IS_ERR(dma->chan)) {
1332 dev_err(disp->dev, "failed to request dma channel\n");
1333 ret = PTR_ERR(dma->chan);
1334 dma->chan = NULL;
1335 return ret;
1336 }
1337 }
1338
1339 return 0;
1340 }
1341
1342
1343
1344
1345
1346
1347
1348 static int zynqmp_disp_create_layers(struct zynqmp_disp *disp)
1349 {
1350 static const struct zynqmp_disp_layer_info layer_info[] = {
1351 [ZYNQMP_DISP_LAYER_VID] = {
1352 .formats = avbuf_vid_fmts,
1353 .num_formats = ARRAY_SIZE(avbuf_vid_fmts),
1354 .num_channels = 3,
1355 },
1356 [ZYNQMP_DISP_LAYER_GFX] = {
1357 .formats = avbuf_gfx_fmts,
1358 .num_formats = ARRAY_SIZE(avbuf_gfx_fmts),
1359 .num_channels = 1,
1360 },
1361 };
1362
1363 unsigned int i;
1364 int ret;
1365
1366 for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++) {
1367 struct zynqmp_disp_layer *layer = &disp->layers[i];
1368
1369 layer->id = i;
1370 layer->disp = disp;
1371 layer->info = &layer_info[i];
1372
1373 ret = zynqmp_disp_layer_request_dma(disp, layer);
1374 if (ret)
1375 goto err;
1376 }
1377
1378 return 0;
1379
1380 err:
1381 zynqmp_disp_destroy_layers(disp);
1382 return ret;
1383 }
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393 static void zynqmp_disp_enable(struct zynqmp_disp *disp)
1394 {
1395 zynqmp_disp_avbuf_enable(disp);
1396
1397 zynqmp_disp_avbuf_set_clocks_sources(disp, disp->pclk_from_ps,
1398 disp->audio.clk_from_ps, true);
1399 zynqmp_disp_avbuf_enable_channels(disp);
1400 zynqmp_disp_avbuf_enable_audio(disp);
1401
1402 zynqmp_disp_audio_enable(disp);
1403 }
1404
1405
1406
1407
1408
1409 static void zynqmp_disp_disable(struct zynqmp_disp *disp)
1410 {
1411 zynqmp_disp_audio_disable(disp);
1412
1413 zynqmp_disp_avbuf_disable_audio(disp);
1414 zynqmp_disp_avbuf_disable_channels(disp);
1415 zynqmp_disp_avbuf_disable(disp);
1416 }
1417
1418 static inline struct zynqmp_disp *crtc_to_disp(struct drm_crtc *crtc)
1419 {
1420 return container_of(crtc, struct zynqmp_disp, crtc);
1421 }
1422
1423 static int zynqmp_disp_crtc_setup_clock(struct drm_crtc *crtc,
1424 struct drm_display_mode *adjusted_mode)
1425 {
1426 struct zynqmp_disp *disp = crtc_to_disp(crtc);
1427 unsigned long mode_clock = adjusted_mode->clock * 1000;
1428 unsigned long rate;
1429 long diff;
1430 int ret;
1431
1432 ret = clk_set_rate(disp->pclk, mode_clock);
1433 if (ret) {
1434 dev_err(disp->dev, "failed to set a pixel clock\n");
1435 return ret;
1436 }
1437
1438 rate = clk_get_rate(disp->pclk);
1439 diff = rate - mode_clock;
1440 if (abs(diff) > mode_clock / 20)
1441 dev_info(disp->dev,
1442 "requested pixel rate: %lu actual rate: %lu\n",
1443 mode_clock, rate);
1444 else
1445 dev_dbg(disp->dev,
1446 "requested pixel rate: %lu actual rate: %lu\n",
1447 mode_clock, rate);
1448
1449 return 0;
1450 }
1451
1452 static void
1453 zynqmp_disp_crtc_atomic_enable(struct drm_crtc *crtc,
1454 struct drm_atomic_state *state)
1455 {
1456 struct zynqmp_disp *disp = crtc_to_disp(crtc);
1457 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1458 int ret, vrefresh;
1459
1460 pm_runtime_get_sync(disp->dev);
1461
1462 zynqmp_disp_crtc_setup_clock(crtc, adjusted_mode);
1463
1464 ret = clk_prepare_enable(disp->pclk);
1465 if (ret) {
1466 dev_err(disp->dev, "failed to enable a pixel clock\n");
1467 pm_runtime_put_sync(disp->dev);
1468 return;
1469 }
1470
1471 zynqmp_disp_blend_set_output_format(disp, ZYNQMP_DPSUB_FORMAT_RGB);
1472 zynqmp_disp_blend_set_bg_color(disp, 0, 0, 0);
1473
1474 zynqmp_disp_enable(disp);
1475
1476
1477 vrefresh = (adjusted_mode->clock * 1000) /
1478 (adjusted_mode->vtotal * adjusted_mode->htotal);
1479 msleep(3 * 1000 / vrefresh);
1480 }
1481
1482 static void
1483 zynqmp_disp_crtc_atomic_disable(struct drm_crtc *crtc,
1484 struct drm_atomic_state *state)
1485 {
1486 struct zynqmp_disp *disp = crtc_to_disp(crtc);
1487 struct drm_plane_state *old_plane_state;
1488
1489
1490
1491
1492
1493
1494 old_plane_state = drm_atomic_get_old_plane_state(state, crtc->primary);
1495 if (old_plane_state)
1496 zynqmp_disp_plane_atomic_disable(crtc->primary, state);
1497
1498 zynqmp_disp_disable(disp);
1499
1500 drm_crtc_vblank_off(&disp->crtc);
1501
1502 spin_lock_irq(&crtc->dev->event_lock);
1503 if (crtc->state->event) {
1504 drm_crtc_send_vblank_event(crtc, crtc->state->event);
1505 crtc->state->event = NULL;
1506 }
1507 spin_unlock_irq(&crtc->dev->event_lock);
1508
1509 clk_disable_unprepare(disp->pclk);
1510 pm_runtime_put_sync(disp->dev);
1511 }
1512
1513 static int zynqmp_disp_crtc_atomic_check(struct drm_crtc *crtc,
1514 struct drm_atomic_state *state)
1515 {
1516 return drm_atomic_add_affected_planes(state, crtc);
1517 }
1518
1519 static void
1520 zynqmp_disp_crtc_atomic_begin(struct drm_crtc *crtc,
1521 struct drm_atomic_state *state)
1522 {
1523 drm_crtc_vblank_on(crtc);
1524 }
1525
1526 static void
1527 zynqmp_disp_crtc_atomic_flush(struct drm_crtc *crtc,
1528 struct drm_atomic_state *state)
1529 {
1530 if (crtc->state->event) {
1531 struct drm_pending_vblank_event *event;
1532
1533
1534 event = crtc->state->event;
1535 crtc->state->event = NULL;
1536
1537 event->pipe = drm_crtc_index(crtc);
1538
1539 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
1540
1541 spin_lock_irq(&crtc->dev->event_lock);
1542 drm_crtc_arm_vblank_event(crtc, event);
1543 spin_unlock_irq(&crtc->dev->event_lock);
1544 }
1545 }
1546
1547 static const struct drm_crtc_helper_funcs zynqmp_disp_crtc_helper_funcs = {
1548 .atomic_enable = zynqmp_disp_crtc_atomic_enable,
1549 .atomic_disable = zynqmp_disp_crtc_atomic_disable,
1550 .atomic_check = zynqmp_disp_crtc_atomic_check,
1551 .atomic_begin = zynqmp_disp_crtc_atomic_begin,
1552 .atomic_flush = zynqmp_disp_crtc_atomic_flush,
1553 };
1554
1555 static int zynqmp_disp_crtc_enable_vblank(struct drm_crtc *crtc)
1556 {
1557 struct zynqmp_disp *disp = crtc_to_disp(crtc);
1558
1559 zynqmp_dp_enable_vblank(disp->dpsub->dp);
1560
1561 return 0;
1562 }
1563
1564 static void zynqmp_disp_crtc_disable_vblank(struct drm_crtc *crtc)
1565 {
1566 struct zynqmp_disp *disp = crtc_to_disp(crtc);
1567
1568 zynqmp_dp_disable_vblank(disp->dpsub->dp);
1569 }
1570
1571 static const struct drm_crtc_funcs zynqmp_disp_crtc_funcs = {
1572 .destroy = drm_crtc_cleanup,
1573 .set_config = drm_atomic_helper_set_config,
1574 .page_flip = drm_atomic_helper_page_flip,
1575 .reset = drm_atomic_helper_crtc_reset,
1576 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
1577 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
1578 .enable_vblank = zynqmp_disp_crtc_enable_vblank,
1579 .disable_vblank = zynqmp_disp_crtc_disable_vblank,
1580 };
1581
1582 static int zynqmp_disp_create_crtc(struct zynqmp_disp *disp)
1583 {
1584 struct drm_plane *plane = &disp->layers[ZYNQMP_DISP_LAYER_GFX].plane;
1585 int ret;
1586
1587 ret = drm_crtc_init_with_planes(disp->drm, &disp->crtc, plane,
1588 NULL, &zynqmp_disp_crtc_funcs, NULL);
1589 if (ret < 0)
1590 return ret;
1591
1592 drm_crtc_helper_add(&disp->crtc, &zynqmp_disp_crtc_helper_funcs);
1593
1594
1595 drm_crtc_vblank_off(&disp->crtc);
1596
1597 return 0;
1598 }
1599
1600 static void zynqmp_disp_map_crtc_to_plane(struct zynqmp_disp *disp)
1601 {
1602 u32 possible_crtcs = drm_crtc_mask(&disp->crtc);
1603 unsigned int i;
1604
1605 for (i = 0; i < ZYNQMP_DISP_NUM_LAYERS; i++)
1606 disp->layers[i].plane.possible_crtcs = possible_crtcs;
1607 }
1608
1609
1610
1611
1612
1613 int zynqmp_disp_drm_init(struct zynqmp_dpsub *dpsub)
1614 {
1615 struct zynqmp_disp *disp = dpsub->disp;
1616 int ret;
1617
1618 ret = zynqmp_disp_create_planes(disp);
1619 if (ret)
1620 return ret;
1621
1622 ret = zynqmp_disp_create_crtc(disp);
1623 if (ret < 0)
1624 return ret;
1625
1626 zynqmp_disp_map_crtc_to_plane(disp);
1627
1628 return 0;
1629 }
1630
1631 int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub, struct drm_device *drm)
1632 {
1633 struct platform_device *pdev = to_platform_device(dpsub->dev);
1634 struct zynqmp_disp *disp;
1635 struct zynqmp_disp_layer *layer;
1636 struct resource *res;
1637 int ret;
1638
1639 disp = drmm_kzalloc(drm, sizeof(*disp), GFP_KERNEL);
1640 if (!disp)
1641 return -ENOMEM;
1642
1643 disp->dev = &pdev->dev;
1644 disp->dpsub = dpsub;
1645 disp->drm = drm;
1646
1647 dpsub->disp = disp;
1648
1649 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "blend");
1650 disp->blend.base = devm_ioremap_resource(disp->dev, res);
1651 if (IS_ERR(disp->blend.base))
1652 return PTR_ERR(disp->blend.base);
1653
1654 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "av_buf");
1655 disp->avbuf.base = devm_ioremap_resource(disp->dev, res);
1656 if (IS_ERR(disp->avbuf.base))
1657 return PTR_ERR(disp->avbuf.base);
1658
1659 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aud");
1660 disp->audio.base = devm_ioremap_resource(disp->dev, res);
1661 if (IS_ERR(disp->audio.base))
1662 return PTR_ERR(disp->audio.base);
1663
1664
1665 disp->pclk = devm_clk_get(disp->dev, "dp_live_video_in_clk");
1666 if (!IS_ERR(disp->pclk))
1667 disp->pclk_from_ps = false;
1668 else if (PTR_ERR(disp->pclk) == -EPROBE_DEFER)
1669 return PTR_ERR(disp->pclk);
1670
1671
1672 if (IS_ERR_OR_NULL(disp->pclk)) {
1673 disp->pclk = devm_clk_get(disp->dev, "dp_vtc_pixel_clk_in");
1674 if (IS_ERR(disp->pclk)) {
1675 dev_err(disp->dev, "failed to init any video clock\n");
1676 return PTR_ERR(disp->pclk);
1677 }
1678 disp->pclk_from_ps = true;
1679 }
1680
1681 zynqmp_disp_audio_init(disp);
1682
1683 ret = zynqmp_disp_create_layers(disp);
1684 if (ret)
1685 return ret;
1686
1687 layer = &disp->layers[ZYNQMP_DISP_LAYER_VID];
1688 dpsub->dma_align = 1 << layer->dmas[0].chan->device->copy_align;
1689
1690 return 0;
1691 }
1692
1693 void zynqmp_disp_remove(struct zynqmp_dpsub *dpsub)
1694 {
1695 struct zynqmp_disp *disp = dpsub->disp;
1696
1697 zynqmp_disp_destroy_layers(disp);
1698 }