This source file includes following definitions.
- vop_writel
- vop_readl
- vop_read_reg
- vop_reg_set
- vop_get_intr_type
- vop_cfg_done
- has_rb_swapped
- vop_convert_format
- scl_vop_cal_scale
- scl_vop_cal_scl_fac
- vop_dsp_hold_valid_irq_enable
- vop_dsp_hold_valid_irq_disable
- vop_line_flag_irq_is_enabled
- vop_line_flag_irq_enable
- vop_line_flag_irq_disable
- vop_core_clks_enable
- vop_core_clks_disable
- vop_win_disable
- vop_enable
- rockchip_drm_set_win_enabled
- vop_crtc_atomic_disable
- vop_plane_destroy
- vop_plane_atomic_check
- vop_plane_atomic_disable
- vop_plane_atomic_update
- vop_plane_atomic_async_check
- vop_plane_atomic_async_update
- vop_crtc_enable_vblank
- vop_crtc_disable_vblank
- vop_crtc_mode_fixup
- vop_crtc_atomic_enable
- vop_fs_irq_is_pending
- vop_wait_for_irq_handler
- vop_crtc_atomic_flush
- vop_crtc_destroy
- vop_crtc_duplicate_state
- vop_crtc_destroy_state
- vop_crtc_reset
- vop_get_edp_connector
- vop_crtc_set_crc_source
- vop_crtc_verify_crc_source
- vop_crtc_set_crc_source
- vop_crtc_verify_crc_source
- vop_fb_unref_worker
- vop_handle_vblank
- vop_isr
- vop_plane_add_properties
- vop_create_crtc
- vop_destroy_crtc
- vop_initial
- vop_win_init
- rockchip_drm_wait_vact_end
- vop_bind
- vop_unbind
1
2
3
4
5
6
7 #include <linux/clk.h>
8 #include <linux/component.h>
9 #include <linux/delay.h>
10 #include <linux/iopoll.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/of_device.h>
15 #include <linux/overflow.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/reset.h>
19
20 #include <drm/drm.h>
21 #include <drm/drm_atomic.h>
22 #include <drm/drm_atomic_uapi.h>
23 #include <drm/drm_crtc.h>
24 #include <drm/drm_flip_work.h>
25 #include <drm/drm_fourcc.h>
26 #include <drm/drm_gem_framebuffer_helper.h>
27 #include <drm/drm_plane_helper.h>
28 #include <drm/drm_probe_helper.h>
29 #include <drm/drm_self_refresh_helper.h>
30 #include <drm/drm_vblank.h>
31
32 #ifdef CONFIG_DRM_ANALOGIX_DP
33 #include <drm/bridge/analogix_dp.h>
34 #endif
35
36 #include "rockchip_drm_drv.h"
37 #include "rockchip_drm_gem.h"
38 #include "rockchip_drm_fb.h"
39 #include "rockchip_drm_vop.h"
40 #include "rockchip_rgb.h"
41
42 #define VOP_WIN_SET(vop, win, name, v) \
43 vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
44 #define VOP_SCL_SET(vop, win, name, v) \
45 vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
46 #define VOP_SCL_SET_EXT(vop, win, name, v) \
47 vop_reg_set(vop, &win->phy->scl->ext->name, \
48 win->base, ~0, v, #name)
49
50 #define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
51 do { \
52 if (win_yuv2yuv && win_yuv2yuv->name.mask) \
53 vop_reg_set(vop, &win_yuv2yuv->name, 0, ~0, v, #name); \
54 } while (0)
55
56 #define VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, win_yuv2yuv, name, v) \
57 do { \
58 if (win_yuv2yuv && win_yuv2yuv->phy->name.mask) \
59 vop_reg_set(vop, &win_yuv2yuv->phy->name, win_yuv2yuv->base, ~0, v, #name); \
60 } while (0)
61
62 #define VOP_INTR_SET_MASK(vop, name, mask, v) \
63 vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
64
65 #define VOP_REG_SET(vop, group, name, v) \
66 vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
67
68 #define VOP_INTR_SET_TYPE(vop, name, type, v) \
69 do { \
70 int i, reg = 0, mask = 0; \
71 for (i = 0; i < vop->data->intr->nintrs; i++) { \
72 if (vop->data->intr->intrs[i] & type) { \
73 reg |= (v) << i; \
74 mask |= 1 << i; \
75 } \
76 } \
77 VOP_INTR_SET_MASK(vop, name, mask, reg); \
78 } while (0)
79 #define VOP_INTR_GET_TYPE(vop, name, type) \
80 vop_get_intr_type(vop, &vop->data->intr->name, type)
81
82 #define VOP_WIN_GET(vop, win, name) \
83 vop_read_reg(vop, win->base, &win->phy->name)
84
85 #define VOP_WIN_HAS_REG(win, name) \
86 (!!(win->phy->name.mask))
87
88 #define VOP_WIN_GET_YRGBADDR(vop, win) \
89 vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
90
91 #define VOP_WIN_TO_INDEX(vop_win) \
92 ((vop_win) - (vop_win)->vop->win)
93
94 #define to_vop(x) container_of(x, struct vop, crtc)
95 #define to_vop_win(x) container_of(x, struct vop_win, base)
96
97
98
99
100
101
102 static const uint32_t bt601_yuv2rgb[] = {
103 0x4A8, 0x0, 0x662,
104 0x4A8, 0x1E6F, 0x1CBF,
105 0x4A8, 0x812, 0x0,
106 0x321168, 0x0877CF, 0x2EB127
107 };
108
109 enum vop_pending {
110 VOP_PENDING_FB_UNREF,
111 };
112
113 struct vop_win {
114 struct drm_plane base;
115 const struct vop_win_data *data;
116 const struct vop_win_yuv2yuv_data *yuv2yuv_data;
117 struct vop *vop;
118 };
119
120 struct rockchip_rgb;
121 struct vop {
122 struct drm_crtc crtc;
123 struct device *dev;
124 struct drm_device *drm_dev;
125 bool is_enabled;
126
127 struct completion dsp_hold_completion;
128 unsigned int win_enabled;
129
130
131 struct drm_pending_vblank_event *event;
132
133 struct drm_flip_work fb_unref_work;
134 unsigned long pending;
135
136 struct completion line_flag_completion;
137
138 const struct vop_data *data;
139
140 uint32_t *regsbak;
141 void __iomem *regs;
142
143
144 uint32_t len;
145
146
147 spinlock_t reg_lock;
148
149 spinlock_t irq_lock;
150
151 struct mutex vop_lock;
152
153 unsigned int irq;
154
155
156 struct clk *hclk;
157
158 struct clk *dclk;
159
160 struct clk *aclk;
161
162
163 struct reset_control *dclk_rst;
164
165
166 struct rockchip_rgb *rgb;
167
168 struct vop_win win[];
169 };
170
171 static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
172 {
173 writel(v, vop->regs + offset);
174 vop->regsbak[offset >> 2] = v;
175 }
176
177 static inline uint32_t vop_readl(struct vop *vop, uint32_t offset)
178 {
179 return readl(vop->regs + offset);
180 }
181
182 static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
183 const struct vop_reg *reg)
184 {
185 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
186 }
187
188 static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
189 uint32_t _offset, uint32_t _mask, uint32_t v,
190 const char *reg_name)
191 {
192 int offset, mask, shift;
193
194 if (!reg || !reg->mask) {
195 DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name);
196 return;
197 }
198
199 offset = reg->offset + _offset;
200 mask = reg->mask & _mask;
201 shift = reg->shift;
202
203 if (reg->write_mask) {
204 v = ((v << shift) & 0xffff) | (mask << (shift + 16));
205 } else {
206 uint32_t cached_val = vop->regsbak[offset >> 2];
207
208 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
209 vop->regsbak[offset >> 2] = v;
210 }
211
212 if (reg->relaxed)
213 writel_relaxed(v, vop->regs + offset);
214 else
215 writel(v, vop->regs + offset);
216 }
217
218 static inline uint32_t vop_get_intr_type(struct vop *vop,
219 const struct vop_reg *reg, int type)
220 {
221 uint32_t i, ret = 0;
222 uint32_t regs = vop_read_reg(vop, 0, reg);
223
224 for (i = 0; i < vop->data->intr->nintrs; i++) {
225 if ((type & vop->data->intr->intrs[i]) && (regs & 1 << i))
226 ret |= vop->data->intr->intrs[i];
227 }
228
229 return ret;
230 }
231
232 static inline void vop_cfg_done(struct vop *vop)
233 {
234 VOP_REG_SET(vop, common, cfg_done, 1);
235 }
236
237 static bool has_rb_swapped(uint32_t format)
238 {
239 switch (format) {
240 case DRM_FORMAT_XBGR8888:
241 case DRM_FORMAT_ABGR8888:
242 case DRM_FORMAT_BGR888:
243 case DRM_FORMAT_BGR565:
244 return true;
245 default:
246 return false;
247 }
248 }
249
250 static enum vop_data_format vop_convert_format(uint32_t format)
251 {
252 switch (format) {
253 case DRM_FORMAT_XRGB8888:
254 case DRM_FORMAT_ARGB8888:
255 case DRM_FORMAT_XBGR8888:
256 case DRM_FORMAT_ABGR8888:
257 return VOP_FMT_ARGB8888;
258 case DRM_FORMAT_RGB888:
259 case DRM_FORMAT_BGR888:
260 return VOP_FMT_RGB888;
261 case DRM_FORMAT_RGB565:
262 case DRM_FORMAT_BGR565:
263 return VOP_FMT_RGB565;
264 case DRM_FORMAT_NV12:
265 return VOP_FMT_YUV420SP;
266 case DRM_FORMAT_NV16:
267 return VOP_FMT_YUV422SP;
268 case DRM_FORMAT_NV24:
269 return VOP_FMT_YUV444SP;
270 default:
271 DRM_ERROR("unsupported format[%08x]\n", format);
272 return -EINVAL;
273 }
274 }
275
276 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
277 uint32_t dst, bool is_horizontal,
278 int vsu_mode, int *vskiplines)
279 {
280 uint16_t val = 1 << SCL_FT_DEFAULT_FIXPOINT_SHIFT;
281
282 if (vskiplines)
283 *vskiplines = 0;
284
285 if (is_horizontal) {
286 if (mode == SCALE_UP)
287 val = GET_SCL_FT_BIC(src, dst);
288 else if (mode == SCALE_DOWN)
289 val = GET_SCL_FT_BILI_DN(src, dst);
290 } else {
291 if (mode == SCALE_UP) {
292 if (vsu_mode == SCALE_UP_BIL)
293 val = GET_SCL_FT_BILI_UP(src, dst);
294 else
295 val = GET_SCL_FT_BIC(src, dst);
296 } else if (mode == SCALE_DOWN) {
297 if (vskiplines) {
298 *vskiplines = scl_get_vskiplines(src, dst);
299 val = scl_get_bili_dn_vskip(src, dst,
300 *vskiplines);
301 } else {
302 val = GET_SCL_FT_BILI_DN(src, dst);
303 }
304 }
305 }
306
307 return val;
308 }
309
310 static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
311 uint32_t src_w, uint32_t src_h, uint32_t dst_w,
312 uint32_t dst_h, const struct drm_format_info *info)
313 {
314 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
315 uint16_t cbcr_hor_scl_mode = SCALE_NONE;
316 uint16_t cbcr_ver_scl_mode = SCALE_NONE;
317 bool is_yuv = false;
318 uint16_t cbcr_src_w = src_w / info->hsub;
319 uint16_t cbcr_src_h = src_h / info->vsub;
320 uint16_t vsu_mode;
321 uint16_t lb_mode;
322 uint32_t val;
323 int vskiplines;
324
325 if (info->is_yuv)
326 is_yuv = true;
327
328 if (dst_w > 3840) {
329 DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
330 return;
331 }
332
333 if (!win->phy->scl->ext) {
334 VOP_SCL_SET(vop, win, scale_yrgb_x,
335 scl_cal_scale2(src_w, dst_w));
336 VOP_SCL_SET(vop, win, scale_yrgb_y,
337 scl_cal_scale2(src_h, dst_h));
338 if (is_yuv) {
339 VOP_SCL_SET(vop, win, scale_cbcr_x,
340 scl_cal_scale2(cbcr_src_w, dst_w));
341 VOP_SCL_SET(vop, win, scale_cbcr_y,
342 scl_cal_scale2(cbcr_src_h, dst_h));
343 }
344 return;
345 }
346
347 yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
348 yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
349
350 if (is_yuv) {
351 cbcr_hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w);
352 cbcr_ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h);
353 if (cbcr_hor_scl_mode == SCALE_DOWN)
354 lb_mode = scl_vop_cal_lb_mode(dst_w, true);
355 else
356 lb_mode = scl_vop_cal_lb_mode(cbcr_src_w, true);
357 } else {
358 if (yrgb_hor_scl_mode == SCALE_DOWN)
359 lb_mode = scl_vop_cal_lb_mode(dst_w, false);
360 else
361 lb_mode = scl_vop_cal_lb_mode(src_w, false);
362 }
363
364 VOP_SCL_SET_EXT(vop, win, lb_mode, lb_mode);
365 if (lb_mode == LB_RGB_3840X2) {
366 if (yrgb_ver_scl_mode != SCALE_NONE) {
367 DRM_DEV_ERROR(vop->dev, "not allow yrgb ver scale\n");
368 return;
369 }
370 if (cbcr_ver_scl_mode != SCALE_NONE) {
371 DRM_DEV_ERROR(vop->dev, "not allow cbcr ver scale\n");
372 return;
373 }
374 vsu_mode = SCALE_UP_BIL;
375 } else if (lb_mode == LB_RGB_2560X4) {
376 vsu_mode = SCALE_UP_BIL;
377 } else {
378 vsu_mode = SCALE_UP_BIC;
379 }
380
381 val = scl_vop_cal_scale(yrgb_hor_scl_mode, src_w, dst_w,
382 true, 0, NULL);
383 VOP_SCL_SET(vop, win, scale_yrgb_x, val);
384 val = scl_vop_cal_scale(yrgb_ver_scl_mode, src_h, dst_h,
385 false, vsu_mode, &vskiplines);
386 VOP_SCL_SET(vop, win, scale_yrgb_y, val);
387
388 VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt4, vskiplines == 4);
389 VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt2, vskiplines == 2);
390
391 VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, yrgb_hor_scl_mode);
392 VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, yrgb_ver_scl_mode);
393 VOP_SCL_SET_EXT(vop, win, yrgb_hsd_mode, SCALE_DOWN_BIL);
394 VOP_SCL_SET_EXT(vop, win, yrgb_vsd_mode, SCALE_DOWN_BIL);
395 VOP_SCL_SET_EXT(vop, win, yrgb_vsu_mode, vsu_mode);
396 if (is_yuv) {
397 val = scl_vop_cal_scale(cbcr_hor_scl_mode, cbcr_src_w,
398 dst_w, true, 0, NULL);
399 VOP_SCL_SET(vop, win, scale_cbcr_x, val);
400 val = scl_vop_cal_scale(cbcr_ver_scl_mode, cbcr_src_h,
401 dst_h, false, vsu_mode, &vskiplines);
402 VOP_SCL_SET(vop, win, scale_cbcr_y, val);
403
404 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt4, vskiplines == 4);
405 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt2, vskiplines == 2);
406 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, cbcr_hor_scl_mode);
407 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, cbcr_ver_scl_mode);
408 VOP_SCL_SET_EXT(vop, win, cbcr_hsd_mode, SCALE_DOWN_BIL);
409 VOP_SCL_SET_EXT(vop, win, cbcr_vsd_mode, SCALE_DOWN_BIL);
410 VOP_SCL_SET_EXT(vop, win, cbcr_vsu_mode, vsu_mode);
411 }
412 }
413
414 static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
415 {
416 unsigned long flags;
417
418 if (WARN_ON(!vop->is_enabled))
419 return;
420
421 spin_lock_irqsave(&vop->irq_lock, flags);
422
423 VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1);
424 VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1);
425
426 spin_unlock_irqrestore(&vop->irq_lock, flags);
427 }
428
429 static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
430 {
431 unsigned long flags;
432
433 if (WARN_ON(!vop->is_enabled))
434 return;
435
436 spin_lock_irqsave(&vop->irq_lock, flags);
437
438 VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0);
439
440 spin_unlock_irqrestore(&vop->irq_lock, flags);
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465 static bool vop_line_flag_irq_is_enabled(struct vop *vop)
466 {
467 uint32_t line_flag_irq;
468 unsigned long flags;
469
470 spin_lock_irqsave(&vop->irq_lock, flags);
471
472 line_flag_irq = VOP_INTR_GET_TYPE(vop, enable, LINE_FLAG_INTR);
473
474 spin_unlock_irqrestore(&vop->irq_lock, flags);
475
476 return !!line_flag_irq;
477 }
478
479 static void vop_line_flag_irq_enable(struct vop *vop)
480 {
481 unsigned long flags;
482
483 if (WARN_ON(!vop->is_enabled))
484 return;
485
486 spin_lock_irqsave(&vop->irq_lock, flags);
487
488 VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
489 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
490
491 spin_unlock_irqrestore(&vop->irq_lock, flags);
492 }
493
494 static void vop_line_flag_irq_disable(struct vop *vop)
495 {
496 unsigned long flags;
497
498 if (WARN_ON(!vop->is_enabled))
499 return;
500
501 spin_lock_irqsave(&vop->irq_lock, flags);
502
503 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 0);
504
505 spin_unlock_irqrestore(&vop->irq_lock, flags);
506 }
507
508 static int vop_core_clks_enable(struct vop *vop)
509 {
510 int ret;
511
512 ret = clk_enable(vop->hclk);
513 if (ret < 0)
514 return ret;
515
516 ret = clk_enable(vop->aclk);
517 if (ret < 0)
518 goto err_disable_hclk;
519
520 return 0;
521
522 err_disable_hclk:
523 clk_disable(vop->hclk);
524 return ret;
525 }
526
527 static void vop_core_clks_disable(struct vop *vop)
528 {
529 clk_disable(vop->aclk);
530 clk_disable(vop->hclk);
531 }
532
533 static void vop_win_disable(struct vop *vop, const struct vop_win *vop_win)
534 {
535 const struct vop_win_data *win = vop_win->data;
536
537 if (win->phy->scl && win->phy->scl->ext) {
538 VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
539 VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
540 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
541 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
542 }
543
544 VOP_WIN_SET(vop, win, enable, 0);
545 vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win));
546 }
547
548 static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
549 {
550 struct vop *vop = to_vop(crtc);
551 int ret, i;
552
553 ret = pm_runtime_get_sync(vop->dev);
554 if (ret < 0) {
555 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
556 return ret;
557 }
558
559 ret = vop_core_clks_enable(vop);
560 if (WARN_ON(ret < 0))
561 goto err_put_pm_runtime;
562
563 ret = clk_enable(vop->dclk);
564 if (WARN_ON(ret < 0))
565 goto err_disable_core;
566
567
568
569
570
571
572
573 ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
574 if (ret) {
575 DRM_DEV_ERROR(vop->dev,
576 "failed to attach dma mapping, %d\n", ret);
577 goto err_disable_dclk;
578 }
579
580 spin_lock(&vop->reg_lock);
581 for (i = 0; i < vop->len; i += 4)
582 writel_relaxed(vop->regsbak[i / 4], vop->regs + i);
583
584
585
586
587
588
589
590
591
592
593 if (!old_state || !old_state->self_refresh_active) {
594 for (i = 0; i < vop->data->win_size; i++) {
595 struct vop_win *vop_win = &vop->win[i];
596
597 vop_win_disable(vop, vop_win);
598 }
599 }
600 spin_unlock(&vop->reg_lock);
601
602 vop_cfg_done(vop);
603
604
605
606
607 vop->is_enabled = true;
608
609 spin_lock(&vop->reg_lock);
610
611 VOP_REG_SET(vop, common, standby, 1);
612
613 spin_unlock(&vop->reg_lock);
614
615 drm_crtc_vblank_on(crtc);
616
617 return 0;
618
619 err_disable_dclk:
620 clk_disable(vop->dclk);
621 err_disable_core:
622 vop_core_clks_disable(vop);
623 err_put_pm_runtime:
624 pm_runtime_put_sync(vop->dev);
625 return ret;
626 }
627
628 static void rockchip_drm_set_win_enabled(struct drm_crtc *crtc, bool enabled)
629 {
630 struct vop *vop = to_vop(crtc);
631 int i;
632
633 spin_lock(&vop->reg_lock);
634
635 for (i = 0; i < vop->data->win_size; i++) {
636 struct vop_win *vop_win = &vop->win[i];
637 const struct vop_win_data *win = vop_win->data;
638
639 VOP_WIN_SET(vop, win, enable,
640 enabled && (vop->win_enabled & BIT(i)));
641 }
642 vop_cfg_done(vop);
643
644 spin_unlock(&vop->reg_lock);
645 }
646
647 static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
648 struct drm_crtc_state *old_state)
649 {
650 struct vop *vop = to_vop(crtc);
651
652 WARN_ON(vop->event);
653
654 if (crtc->state->self_refresh_active)
655 rockchip_drm_set_win_enabled(crtc, false);
656
657 mutex_lock(&vop->vop_lock);
658
659 drm_crtc_vblank_off(crtc);
660
661 if (crtc->state->self_refresh_active)
662 goto out;
663
664
665
666
667
668
669
670
671 reinit_completion(&vop->dsp_hold_completion);
672 vop_dsp_hold_valid_irq_enable(vop);
673
674 spin_lock(&vop->reg_lock);
675
676 VOP_REG_SET(vop, common, standby, 1);
677
678 spin_unlock(&vop->reg_lock);
679
680 wait_for_completion(&vop->dsp_hold_completion);
681
682 vop_dsp_hold_valid_irq_disable(vop);
683
684 vop->is_enabled = false;
685
686
687
688
689 rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
690
691 clk_disable(vop->dclk);
692 vop_core_clks_disable(vop);
693 pm_runtime_put(vop->dev);
694
695 out:
696 mutex_unlock(&vop->vop_lock);
697
698 if (crtc->state->event && !crtc->state->active) {
699 spin_lock_irq(&crtc->dev->event_lock);
700 drm_crtc_send_vblank_event(crtc, crtc->state->event);
701 spin_unlock_irq(&crtc->dev->event_lock);
702
703 crtc->state->event = NULL;
704 }
705 }
706
707 static void vop_plane_destroy(struct drm_plane *plane)
708 {
709 drm_plane_cleanup(plane);
710 }
711
712 static int vop_plane_atomic_check(struct drm_plane *plane,
713 struct drm_plane_state *state)
714 {
715 struct drm_crtc *crtc = state->crtc;
716 struct drm_crtc_state *crtc_state;
717 struct drm_framebuffer *fb = state->fb;
718 struct vop_win *vop_win = to_vop_win(plane);
719 const struct vop_win_data *win = vop_win->data;
720 int ret;
721 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
722 DRM_PLANE_HELPER_NO_SCALING;
723 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
724 DRM_PLANE_HELPER_NO_SCALING;
725
726 if (!crtc || !fb)
727 return 0;
728
729 crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
730 if (WARN_ON(!crtc_state))
731 return -EINVAL;
732
733 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
734 min_scale, max_scale,
735 true, true);
736 if (ret)
737 return ret;
738
739 if (!state->visible)
740 return 0;
741
742 ret = vop_convert_format(fb->format->format);
743 if (ret < 0)
744 return ret;
745
746
747
748
749
750 if (fb->format->is_yuv && ((state->src.x1 >> 16) % 2)) {
751 DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n");
752 return -EINVAL;
753 }
754
755 if (fb->format->is_yuv && state->rotation & DRM_MODE_REFLECT_Y) {
756 DRM_ERROR("Invalid Source: Yuv format does not support this rotation\n");
757 return -EINVAL;
758 }
759
760 return 0;
761 }
762
763 static void vop_plane_atomic_disable(struct drm_plane *plane,
764 struct drm_plane_state *old_state)
765 {
766 struct vop_win *vop_win = to_vop_win(plane);
767 struct vop *vop = to_vop(old_state->crtc);
768
769 if (!old_state->crtc)
770 return;
771
772 spin_lock(&vop->reg_lock);
773
774 vop_win_disable(vop, vop_win);
775
776 spin_unlock(&vop->reg_lock);
777 }
778
779 static void vop_plane_atomic_update(struct drm_plane *plane,
780 struct drm_plane_state *old_state)
781 {
782 struct drm_plane_state *state = plane->state;
783 struct drm_crtc *crtc = state->crtc;
784 struct vop_win *vop_win = to_vop_win(plane);
785 const struct vop_win_data *win = vop_win->data;
786 const struct vop_win_yuv2yuv_data *win_yuv2yuv = vop_win->yuv2yuv_data;
787 struct vop *vop = to_vop(state->crtc);
788 struct drm_framebuffer *fb = state->fb;
789 unsigned int actual_w, actual_h;
790 unsigned int dsp_stx, dsp_sty;
791 uint32_t act_info, dsp_info, dsp_st;
792 struct drm_rect *src = &state->src;
793 struct drm_rect *dest = &state->dst;
794 struct drm_gem_object *obj, *uv_obj;
795 struct rockchip_gem_object *rk_obj, *rk_uv_obj;
796 unsigned long offset;
797 dma_addr_t dma_addr;
798 uint32_t val;
799 bool rb_swap;
800 int win_index = VOP_WIN_TO_INDEX(vop_win);
801 int format;
802 int is_yuv = fb->format->is_yuv;
803 int i;
804
805
806
807
808 if (WARN_ON(!crtc))
809 return;
810
811 if (WARN_ON(!vop->is_enabled))
812 return;
813
814 if (!state->visible) {
815 vop_plane_atomic_disable(plane, old_state);
816 return;
817 }
818
819 obj = fb->obj[0];
820 rk_obj = to_rockchip_obj(obj);
821
822 actual_w = drm_rect_width(src) >> 16;
823 actual_h = drm_rect_height(src) >> 16;
824 act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
825
826 dsp_info = (drm_rect_height(dest) - 1) << 16;
827 dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
828
829 dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
830 dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
831 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
832
833 offset = (src->x1 >> 16) * fb->format->cpp[0];
834 offset += (src->y1 >> 16) * fb->pitches[0];
835 dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
836
837
838
839
840
841 if (state->rotation & DRM_MODE_REFLECT_Y)
842 dma_addr += (actual_h - 1) * fb->pitches[0];
843
844 format = vop_convert_format(fb->format->format);
845
846 spin_lock(&vop->reg_lock);
847
848 VOP_WIN_SET(vop, win, format, format);
849 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
850 VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
851 VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
852 VOP_WIN_SET(vop, win, y_mir_en,
853 (state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0);
854 VOP_WIN_SET(vop, win, x_mir_en,
855 (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
856
857 if (is_yuv) {
858 int hsub = fb->format->hsub;
859 int vsub = fb->format->vsub;
860 int bpp = fb->format->cpp[1];
861
862 uv_obj = fb->obj[1];
863 rk_uv_obj = to_rockchip_obj(uv_obj);
864
865 offset = (src->x1 >> 16) * bpp / hsub;
866 offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
867
868 dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
869 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
870 VOP_WIN_SET(vop, win, uv_mst, dma_addr);
871
872 for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) {
873 VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop,
874 win_yuv2yuv,
875 y2r_coefficients[i],
876 bt601_yuv2rgb[i]);
877 }
878 }
879
880 if (win->phy->scl)
881 scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
882 drm_rect_width(dest), drm_rect_height(dest),
883 fb->format);
884
885 VOP_WIN_SET(vop, win, act_info, act_info);
886 VOP_WIN_SET(vop, win, dsp_info, dsp_info);
887 VOP_WIN_SET(vop, win, dsp_st, dsp_st);
888
889 rb_swap = has_rb_swapped(fb->format->format);
890 VOP_WIN_SET(vop, win, rb_swap, rb_swap);
891
892
893
894
895
896
897
898
899 if (fb->format->has_alpha && win_index > 0) {
900 VOP_WIN_SET(vop, win, dst_alpha_ctl,
901 DST_FACTOR_M0(ALPHA_SRC_INVERSE));
902 val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
903 SRC_ALPHA_M0(ALPHA_STRAIGHT) |
904 SRC_BLEND_M0(ALPHA_PER_PIX) |
905 SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
906 SRC_FACTOR_M0(ALPHA_ONE);
907 VOP_WIN_SET(vop, win, src_alpha_ctl, val);
908 } else {
909 VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0));
910 }
911
912 VOP_WIN_SET(vop, win, enable, 1);
913 vop->win_enabled |= BIT(win_index);
914 spin_unlock(&vop->reg_lock);
915 }
916
917 static int vop_plane_atomic_async_check(struct drm_plane *plane,
918 struct drm_plane_state *state)
919 {
920 struct vop_win *vop_win = to_vop_win(plane);
921 const struct vop_win_data *win = vop_win->data;
922 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
923 DRM_PLANE_HELPER_NO_SCALING;
924 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
925 DRM_PLANE_HELPER_NO_SCALING;
926 struct drm_crtc_state *crtc_state;
927
928 if (plane != state->crtc->cursor)
929 return -EINVAL;
930
931 if (!plane->state)
932 return -EINVAL;
933
934 if (!plane->state->fb)
935 return -EINVAL;
936
937 if (state->state)
938 crtc_state = drm_atomic_get_existing_crtc_state(state->state,
939 state->crtc);
940 else
941 crtc_state = plane->crtc->state;
942
943 return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
944 min_scale, max_scale,
945 true, true);
946 }
947
948 static void vop_plane_atomic_async_update(struct drm_plane *plane,
949 struct drm_plane_state *new_state)
950 {
951 struct vop *vop = to_vop(plane->state->crtc);
952 struct drm_framebuffer *old_fb = plane->state->fb;
953
954 plane->state->crtc_x = new_state->crtc_x;
955 plane->state->crtc_y = new_state->crtc_y;
956 plane->state->crtc_h = new_state->crtc_h;
957 plane->state->crtc_w = new_state->crtc_w;
958 plane->state->src_x = new_state->src_x;
959 plane->state->src_y = new_state->src_y;
960 plane->state->src_h = new_state->src_h;
961 plane->state->src_w = new_state->src_w;
962 swap(plane->state->fb, new_state->fb);
963
964 if (vop->is_enabled) {
965 vop_plane_atomic_update(plane, plane->state);
966 spin_lock(&vop->reg_lock);
967 vop_cfg_done(vop);
968 spin_unlock(&vop->reg_lock);
969
970
971
972
973
974
975
976
977
978 if (old_fb && plane->state->fb != old_fb) {
979 drm_framebuffer_get(old_fb);
980 WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
981 drm_flip_work_queue(&vop->fb_unref_work, old_fb);
982 set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
983 }
984 }
985 }
986
987 static const struct drm_plane_helper_funcs plane_helper_funcs = {
988 .atomic_check = vop_plane_atomic_check,
989 .atomic_update = vop_plane_atomic_update,
990 .atomic_disable = vop_plane_atomic_disable,
991 .atomic_async_check = vop_plane_atomic_async_check,
992 .atomic_async_update = vop_plane_atomic_async_update,
993 .prepare_fb = drm_gem_fb_prepare_fb,
994 };
995
996 static const struct drm_plane_funcs vop_plane_funcs = {
997 .update_plane = drm_atomic_helper_update_plane,
998 .disable_plane = drm_atomic_helper_disable_plane,
999 .destroy = vop_plane_destroy,
1000 .reset = drm_atomic_helper_plane_reset,
1001 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
1002 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
1003 };
1004
1005 static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
1006 {
1007 struct vop *vop = to_vop(crtc);
1008 unsigned long flags;
1009
1010 if (WARN_ON(!vop->is_enabled))
1011 return -EPERM;
1012
1013 spin_lock_irqsave(&vop->irq_lock, flags);
1014
1015 VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1);
1016 VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1);
1017
1018 spin_unlock_irqrestore(&vop->irq_lock, flags);
1019
1020 return 0;
1021 }
1022
1023 static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
1024 {
1025 struct vop *vop = to_vop(crtc);
1026 unsigned long flags;
1027
1028 if (WARN_ON(!vop->is_enabled))
1029 return;
1030
1031 spin_lock_irqsave(&vop->irq_lock, flags);
1032
1033 VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0);
1034
1035 spin_unlock_irqrestore(&vop->irq_lock, flags);
1036 }
1037
1038 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
1039 const struct drm_display_mode *mode,
1040 struct drm_display_mode *adjusted_mode)
1041 {
1042 struct vop *vop = to_vop(crtc);
1043 unsigned long rate;
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076 rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
1077 adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
1078
1079 return true;
1080 }
1081
1082 static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
1083 struct drm_crtc_state *old_state)
1084 {
1085 struct vop *vop = to_vop(crtc);
1086 const struct vop_data *vop_data = vop->data;
1087 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
1088 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1089 u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
1090 u16 hdisplay = adjusted_mode->hdisplay;
1091 u16 htotal = adjusted_mode->htotal;
1092 u16 hact_st = adjusted_mode->htotal - adjusted_mode->hsync_start;
1093 u16 hact_end = hact_st + hdisplay;
1094 u16 vdisplay = adjusted_mode->vdisplay;
1095 u16 vtotal = adjusted_mode->vtotal;
1096 u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
1097 u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
1098 u16 vact_end = vact_st + vdisplay;
1099 uint32_t pin_pol, val;
1100 int dither_bpc = s->output_bpc ? s->output_bpc : 10;
1101 int ret;
1102
1103 if (old_state && old_state->self_refresh_active) {
1104 drm_crtc_vblank_on(crtc);
1105 rockchip_drm_set_win_enabled(crtc, true);
1106 return;
1107 }
1108
1109 mutex_lock(&vop->vop_lock);
1110
1111 WARN_ON(vop->event);
1112
1113 ret = vop_enable(crtc, old_state);
1114 if (ret) {
1115 mutex_unlock(&vop->vop_lock);
1116 DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
1117 return;
1118 }
1119
1120 pin_pol = BIT(DCLK_INVERT);
1121 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ?
1122 BIT(HSYNC_POSITIVE) : 0;
1123 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
1124 BIT(VSYNC_POSITIVE) : 0;
1125 VOP_REG_SET(vop, output, pin_pol, pin_pol);
1126 VOP_REG_SET(vop, output, mipi_dual_channel_en, 0);
1127
1128 switch (s->output_type) {
1129 case DRM_MODE_CONNECTOR_LVDS:
1130 VOP_REG_SET(vop, output, rgb_en, 1);
1131 VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
1132 break;
1133 case DRM_MODE_CONNECTOR_eDP:
1134 VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
1135 VOP_REG_SET(vop, output, edp_en, 1);
1136 break;
1137 case DRM_MODE_CONNECTOR_HDMIA:
1138 VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
1139 VOP_REG_SET(vop, output, hdmi_en, 1);
1140 break;
1141 case DRM_MODE_CONNECTOR_DSI:
1142 VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
1143 VOP_REG_SET(vop, output, mipi_en, 1);
1144 VOP_REG_SET(vop, output, mipi_dual_channel_en,
1145 !!(s->output_flags & ROCKCHIP_OUTPUT_DSI_DUAL));
1146 break;
1147 case DRM_MODE_CONNECTOR_DisplayPort:
1148 pin_pol &= ~BIT(DCLK_INVERT);
1149 VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
1150 VOP_REG_SET(vop, output, dp_en, 1);
1151 break;
1152 default:
1153 DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
1154 s->output_type);
1155 }
1156
1157
1158
1159
1160 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
1161 !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
1162 s->output_mode = ROCKCHIP_OUT_MODE_P888;
1163
1164 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8)
1165 VOP_REG_SET(vop, common, pre_dither_down, 1);
1166 else
1167 VOP_REG_SET(vop, common, pre_dither_down, 0);
1168
1169 if (dither_bpc == 6) {
1170 VOP_REG_SET(vop, common, dither_down_sel, DITHER_DOWN_ALLEGRO);
1171 VOP_REG_SET(vop, common, dither_down_mode, RGB888_TO_RGB666);
1172 VOP_REG_SET(vop, common, dither_down_en, 1);
1173 } else {
1174 VOP_REG_SET(vop, common, dither_down_en, 0);
1175 }
1176
1177 VOP_REG_SET(vop, common, out_mode, s->output_mode);
1178
1179 VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
1180 val = hact_st << 16;
1181 val |= hact_end;
1182 VOP_REG_SET(vop, modeset, hact_st_end, val);
1183 VOP_REG_SET(vop, modeset, hpost_st_end, val);
1184
1185 VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
1186 val = vact_st << 16;
1187 val |= vact_end;
1188 VOP_REG_SET(vop, modeset, vact_st_end, val);
1189 VOP_REG_SET(vop, modeset, vpost_st_end, val);
1190
1191 VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
1192
1193 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
1194
1195 VOP_REG_SET(vop, common, standby, 0);
1196 mutex_unlock(&vop->vop_lock);
1197 }
1198
1199 static bool vop_fs_irq_is_pending(struct vop *vop)
1200 {
1201 return VOP_INTR_GET_TYPE(vop, status, FS_INTR);
1202 }
1203
1204 static void vop_wait_for_irq_handler(struct vop *vop)
1205 {
1206 bool pending;
1207 int ret;
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217 ret = readx_poll_timeout_atomic(vop_fs_irq_is_pending, vop, pending,
1218 !pending, 0, 10 * 1000);
1219 if (ret)
1220 DRM_DEV_ERROR(vop->dev, "VOP vblank IRQ stuck for 10 ms\n");
1221
1222 synchronize_irq(vop->irq);
1223 }
1224
1225 static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
1226 struct drm_crtc_state *old_crtc_state)
1227 {
1228 struct drm_atomic_state *old_state = old_crtc_state->state;
1229 struct drm_plane_state *old_plane_state, *new_plane_state;
1230 struct vop *vop = to_vop(crtc);
1231 struct drm_plane *plane;
1232 int i;
1233
1234 if (WARN_ON(!vop->is_enabled))
1235 return;
1236
1237 spin_lock(&vop->reg_lock);
1238
1239 vop_cfg_done(vop);
1240
1241 spin_unlock(&vop->reg_lock);
1242
1243
1244
1245
1246
1247
1248 vop_wait_for_irq_handler(vop);
1249
1250 spin_lock_irq(&crtc->dev->event_lock);
1251 if (crtc->state->event) {
1252 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
1253 WARN_ON(vop->event);
1254
1255 vop->event = crtc->state->event;
1256 crtc->state->event = NULL;
1257 }
1258 spin_unlock_irq(&crtc->dev->event_lock);
1259
1260 for_each_oldnew_plane_in_state(old_state, plane, old_plane_state,
1261 new_plane_state, i) {
1262 if (!old_plane_state->fb)
1263 continue;
1264
1265 if (old_plane_state->fb == new_plane_state->fb)
1266 continue;
1267
1268 drm_framebuffer_get(old_plane_state->fb);
1269 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
1270 drm_flip_work_queue(&vop->fb_unref_work, old_plane_state->fb);
1271 set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
1272 }
1273 }
1274
1275 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
1276 .mode_fixup = vop_crtc_mode_fixup,
1277 .atomic_flush = vop_crtc_atomic_flush,
1278 .atomic_enable = vop_crtc_atomic_enable,
1279 .atomic_disable = vop_crtc_atomic_disable,
1280 };
1281
1282 static void vop_crtc_destroy(struct drm_crtc *crtc)
1283 {
1284 drm_crtc_cleanup(crtc);
1285 }
1286
1287 static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
1288 {
1289 struct rockchip_crtc_state *rockchip_state;
1290
1291 rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
1292 if (!rockchip_state)
1293 return NULL;
1294
1295 __drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base);
1296 return &rockchip_state->base;
1297 }
1298
1299 static void vop_crtc_destroy_state(struct drm_crtc *crtc,
1300 struct drm_crtc_state *state)
1301 {
1302 struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
1303
1304 __drm_atomic_helper_crtc_destroy_state(&s->base);
1305 kfree(s);
1306 }
1307
1308 static void vop_crtc_reset(struct drm_crtc *crtc)
1309 {
1310 struct rockchip_crtc_state *crtc_state =
1311 kzalloc(sizeof(*crtc_state), GFP_KERNEL);
1312
1313 if (crtc->state)
1314 vop_crtc_destroy_state(crtc, crtc->state);
1315
1316 __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
1317 }
1318
1319 #ifdef CONFIG_DRM_ANALOGIX_DP
1320 static struct drm_connector *vop_get_edp_connector(struct vop *vop)
1321 {
1322 struct drm_connector *connector;
1323 struct drm_connector_list_iter conn_iter;
1324
1325 drm_connector_list_iter_begin(vop->drm_dev, &conn_iter);
1326 drm_for_each_connector_iter(connector, &conn_iter) {
1327 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1328 drm_connector_list_iter_end(&conn_iter);
1329 return connector;
1330 }
1331 }
1332 drm_connector_list_iter_end(&conn_iter);
1333
1334 return NULL;
1335 }
1336
1337 static int vop_crtc_set_crc_source(struct drm_crtc *crtc,
1338 const char *source_name)
1339 {
1340 struct vop *vop = to_vop(crtc);
1341 struct drm_connector *connector;
1342 int ret;
1343
1344 connector = vop_get_edp_connector(vop);
1345 if (!connector)
1346 return -EINVAL;
1347
1348 if (source_name && strcmp(source_name, "auto") == 0)
1349 ret = analogix_dp_start_crc(connector);
1350 else if (!source_name)
1351 ret = analogix_dp_stop_crc(connector);
1352 else
1353 ret = -EINVAL;
1354
1355 return ret;
1356 }
1357
1358 static int
1359 vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
1360 size_t *values_cnt)
1361 {
1362 if (source_name && strcmp(source_name, "auto") != 0)
1363 return -EINVAL;
1364
1365 *values_cnt = 3;
1366 return 0;
1367 }
1368
1369 #else
1370 static int vop_crtc_set_crc_source(struct drm_crtc *crtc,
1371 const char *source_name)
1372 {
1373 return -ENODEV;
1374 }
1375
1376 static int
1377 vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
1378 size_t *values_cnt)
1379 {
1380 return -ENODEV;
1381 }
1382 #endif
1383
1384 static const struct drm_crtc_funcs vop_crtc_funcs = {
1385 .set_config = drm_atomic_helper_set_config,
1386 .page_flip = drm_atomic_helper_page_flip,
1387 .destroy = vop_crtc_destroy,
1388 .reset = vop_crtc_reset,
1389 .atomic_duplicate_state = vop_crtc_duplicate_state,
1390 .atomic_destroy_state = vop_crtc_destroy_state,
1391 .enable_vblank = vop_crtc_enable_vblank,
1392 .disable_vblank = vop_crtc_disable_vblank,
1393 .set_crc_source = vop_crtc_set_crc_source,
1394 .verify_crc_source = vop_crtc_verify_crc_source,
1395 };
1396
1397 static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
1398 {
1399 struct vop *vop = container_of(work, struct vop, fb_unref_work);
1400 struct drm_framebuffer *fb = val;
1401
1402 drm_crtc_vblank_put(&vop->crtc);
1403 drm_framebuffer_put(fb);
1404 }
1405
1406 static void vop_handle_vblank(struct vop *vop)
1407 {
1408 struct drm_device *drm = vop->drm_dev;
1409 struct drm_crtc *crtc = &vop->crtc;
1410
1411 spin_lock(&drm->event_lock);
1412 if (vop->event) {
1413 drm_crtc_send_vblank_event(crtc, vop->event);
1414 drm_crtc_vblank_put(crtc);
1415 vop->event = NULL;
1416 }
1417 spin_unlock(&drm->event_lock);
1418
1419 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
1420 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
1421 }
1422
1423 static irqreturn_t vop_isr(int irq, void *data)
1424 {
1425 struct vop *vop = data;
1426 struct drm_crtc *crtc = &vop->crtc;
1427 uint32_t active_irqs;
1428 int ret = IRQ_NONE;
1429
1430
1431
1432
1433
1434 if (!pm_runtime_get_if_in_use(vop->dev))
1435 return IRQ_NONE;
1436
1437 if (vop_core_clks_enable(vop)) {
1438 DRM_DEV_ERROR_RATELIMITED(vop->dev, "couldn't enable clocks\n");
1439 goto out;
1440 }
1441
1442
1443
1444
1445
1446 spin_lock(&vop->irq_lock);
1447
1448 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK);
1449
1450 if (active_irqs)
1451 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1);
1452
1453 spin_unlock(&vop->irq_lock);
1454
1455
1456 if (!active_irqs)
1457 goto out_disable;
1458
1459 if (active_irqs & DSP_HOLD_VALID_INTR) {
1460 complete(&vop->dsp_hold_completion);
1461 active_irqs &= ~DSP_HOLD_VALID_INTR;
1462 ret = IRQ_HANDLED;
1463 }
1464
1465 if (active_irqs & LINE_FLAG_INTR) {
1466 complete(&vop->line_flag_completion);
1467 active_irqs &= ~LINE_FLAG_INTR;
1468 ret = IRQ_HANDLED;
1469 }
1470
1471 if (active_irqs & FS_INTR) {
1472 drm_crtc_handle_vblank(crtc);
1473 vop_handle_vblank(vop);
1474 active_irqs &= ~FS_INTR;
1475 ret = IRQ_HANDLED;
1476 }
1477
1478
1479 if (active_irqs)
1480 DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n",
1481 active_irqs);
1482
1483 out_disable:
1484 vop_core_clks_disable(vop);
1485 out:
1486 pm_runtime_put(vop->dev);
1487 return ret;
1488 }
1489
1490 static void vop_plane_add_properties(struct drm_plane *plane,
1491 const struct vop_win_data *win_data)
1492 {
1493 unsigned int flags = 0;
1494
1495 flags |= VOP_WIN_HAS_REG(win_data, x_mir_en) ? DRM_MODE_REFLECT_X : 0;
1496 flags |= VOP_WIN_HAS_REG(win_data, y_mir_en) ? DRM_MODE_REFLECT_Y : 0;
1497 if (flags)
1498 drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
1499 DRM_MODE_ROTATE_0 | flags);
1500 }
1501
1502 static int vop_create_crtc(struct vop *vop)
1503 {
1504 const struct vop_data *vop_data = vop->data;
1505 struct device *dev = vop->dev;
1506 struct drm_device *drm_dev = vop->drm_dev;
1507 struct drm_plane *primary = NULL, *cursor = NULL, *plane, *tmp;
1508 struct drm_crtc *crtc = &vop->crtc;
1509 struct device_node *port;
1510 int ret;
1511 int i;
1512
1513
1514
1515
1516
1517
1518 for (i = 0; i < vop_data->win_size; i++) {
1519 struct vop_win *vop_win = &vop->win[i];
1520 const struct vop_win_data *win_data = vop_win->data;
1521
1522 if (win_data->type != DRM_PLANE_TYPE_PRIMARY &&
1523 win_data->type != DRM_PLANE_TYPE_CURSOR)
1524 continue;
1525
1526 ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
1527 0, &vop_plane_funcs,
1528 win_data->phy->data_formats,
1529 win_data->phy->nformats,
1530 NULL, win_data->type, NULL);
1531 if (ret) {
1532 DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
1533 ret);
1534 goto err_cleanup_planes;
1535 }
1536
1537 plane = &vop_win->base;
1538 drm_plane_helper_add(plane, &plane_helper_funcs);
1539 vop_plane_add_properties(plane, win_data);
1540 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
1541 primary = plane;
1542 else if (plane->type == DRM_PLANE_TYPE_CURSOR)
1543 cursor = plane;
1544 }
1545
1546 ret = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,
1547 &vop_crtc_funcs, NULL);
1548 if (ret)
1549 goto err_cleanup_planes;
1550
1551 drm_crtc_helper_add(crtc, &vop_crtc_helper_funcs);
1552
1553
1554
1555
1556
1557 for (i = 0; i < vop_data->win_size; i++) {
1558 struct vop_win *vop_win = &vop->win[i];
1559 const struct vop_win_data *win_data = vop_win->data;
1560 unsigned long possible_crtcs = drm_crtc_mask(crtc);
1561
1562 if (win_data->type != DRM_PLANE_TYPE_OVERLAY)
1563 continue;
1564
1565 ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
1566 possible_crtcs,
1567 &vop_plane_funcs,
1568 win_data->phy->data_formats,
1569 win_data->phy->nformats,
1570 NULL, win_data->type, NULL);
1571 if (ret) {
1572 DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
1573 ret);
1574 goto err_cleanup_crtc;
1575 }
1576 drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
1577 vop_plane_add_properties(&vop_win->base, win_data);
1578 }
1579
1580 port = of_get_child_by_name(dev->of_node, "port");
1581 if (!port) {
1582 DRM_DEV_ERROR(vop->dev, "no port node found in %pOF\n",
1583 dev->of_node);
1584 ret = -ENOENT;
1585 goto err_cleanup_crtc;
1586 }
1587
1588 drm_flip_work_init(&vop->fb_unref_work, "fb_unref",
1589 vop_fb_unref_worker);
1590
1591 init_completion(&vop->dsp_hold_completion);
1592 init_completion(&vop->line_flag_completion);
1593 crtc->port = port;
1594
1595 ret = drm_self_refresh_helper_init(crtc);
1596 if (ret)
1597 DRM_DEV_DEBUG_KMS(vop->dev,
1598 "Failed to init %s with SR helpers %d, ignoring\n",
1599 crtc->name, ret);
1600
1601 return 0;
1602
1603 err_cleanup_crtc:
1604 drm_crtc_cleanup(crtc);
1605 err_cleanup_planes:
1606 list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
1607 head)
1608 drm_plane_cleanup(plane);
1609 return ret;
1610 }
1611
1612 static void vop_destroy_crtc(struct vop *vop)
1613 {
1614 struct drm_crtc *crtc = &vop->crtc;
1615 struct drm_device *drm_dev = vop->drm_dev;
1616 struct drm_plane *plane, *tmp;
1617
1618 drm_self_refresh_helper_cleanup(crtc);
1619
1620 of_node_put(crtc->port);
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630 list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
1631 head)
1632 vop_plane_destroy(plane);
1633
1634
1635
1636
1637
1638 drm_crtc_cleanup(crtc);
1639 drm_flip_work_cleanup(&vop->fb_unref_work);
1640 }
1641
1642 static int vop_initial(struct vop *vop)
1643 {
1644 struct reset_control *ahb_rst;
1645 int i, ret;
1646
1647 vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
1648 if (IS_ERR(vop->hclk)) {
1649 DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n");
1650 return PTR_ERR(vop->hclk);
1651 }
1652 vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
1653 if (IS_ERR(vop->aclk)) {
1654 DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n");
1655 return PTR_ERR(vop->aclk);
1656 }
1657 vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
1658 if (IS_ERR(vop->dclk)) {
1659 DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n");
1660 return PTR_ERR(vop->dclk);
1661 }
1662
1663 ret = pm_runtime_get_sync(vop->dev);
1664 if (ret < 0) {
1665 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
1666 return ret;
1667 }
1668
1669 ret = clk_prepare(vop->dclk);
1670 if (ret < 0) {
1671 DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n");
1672 goto err_put_pm_runtime;
1673 }
1674
1675
1676 ret = clk_prepare_enable(vop->hclk);
1677 if (ret < 0) {
1678 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n");
1679 goto err_unprepare_dclk;
1680 }
1681
1682 ret = clk_prepare_enable(vop->aclk);
1683 if (ret < 0) {
1684 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n");
1685 goto err_disable_hclk;
1686 }
1687
1688
1689
1690
1691 ahb_rst = devm_reset_control_get(vop->dev, "ahb");
1692 if (IS_ERR(ahb_rst)) {
1693 DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n");
1694 ret = PTR_ERR(ahb_rst);
1695 goto err_disable_aclk;
1696 }
1697 reset_control_assert(ahb_rst);
1698 usleep_range(10, 20);
1699 reset_control_deassert(ahb_rst);
1700
1701 VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
1702 VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);
1703
1704 for (i = 0; i < vop->len; i += sizeof(u32))
1705 vop->regsbak[i / 4] = readl_relaxed(vop->regs + i);
1706
1707 VOP_REG_SET(vop, misc, global_regdone_en, 1);
1708 VOP_REG_SET(vop, common, dsp_blank, 0);
1709
1710 for (i = 0; i < vop->data->win_size; i++) {
1711 struct vop_win *vop_win = &vop->win[i];
1712 const struct vop_win_data *win = vop_win->data;
1713 int channel = i * 2 + 1;
1714
1715 VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
1716 vop_win_disable(vop, vop_win);
1717 VOP_WIN_SET(vop, win, gate, 1);
1718 }
1719
1720 vop_cfg_done(vop);
1721
1722
1723
1724
1725 vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk");
1726 if (IS_ERR(vop->dclk_rst)) {
1727 DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n");
1728 ret = PTR_ERR(vop->dclk_rst);
1729 goto err_disable_aclk;
1730 }
1731 reset_control_assert(vop->dclk_rst);
1732 usleep_range(10, 20);
1733 reset_control_deassert(vop->dclk_rst);
1734
1735 clk_disable(vop->hclk);
1736 clk_disable(vop->aclk);
1737
1738 vop->is_enabled = false;
1739
1740 pm_runtime_put_sync(vop->dev);
1741
1742 return 0;
1743
1744 err_disable_aclk:
1745 clk_disable_unprepare(vop->aclk);
1746 err_disable_hclk:
1747 clk_disable_unprepare(vop->hclk);
1748 err_unprepare_dclk:
1749 clk_unprepare(vop->dclk);
1750 err_put_pm_runtime:
1751 pm_runtime_put_sync(vop->dev);
1752 return ret;
1753 }
1754
1755
1756
1757
1758 static void vop_win_init(struct vop *vop)
1759 {
1760 const struct vop_data *vop_data = vop->data;
1761 unsigned int i;
1762
1763 for (i = 0; i < vop_data->win_size; i++) {
1764 struct vop_win *vop_win = &vop->win[i];
1765 const struct vop_win_data *win_data = &vop_data->win[i];
1766
1767 vop_win->data = win_data;
1768 vop_win->vop = vop;
1769
1770 if (vop_data->win_yuv2yuv)
1771 vop_win->yuv2yuv_data = &vop_data->win_yuv2yuv[i];
1772 }
1773 }
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785 int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
1786 {
1787 struct vop *vop = to_vop(crtc);
1788 unsigned long jiffies_left;
1789 int ret = 0;
1790
1791 if (!crtc || !vop->is_enabled)
1792 return -ENODEV;
1793
1794 mutex_lock(&vop->vop_lock);
1795 if (mstimeout <= 0) {
1796 ret = -EINVAL;
1797 goto out;
1798 }
1799
1800 if (vop_line_flag_irq_is_enabled(vop)) {
1801 ret = -EBUSY;
1802 goto out;
1803 }
1804
1805 reinit_completion(&vop->line_flag_completion);
1806 vop_line_flag_irq_enable(vop);
1807
1808 jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
1809 msecs_to_jiffies(mstimeout));
1810 vop_line_flag_irq_disable(vop);
1811
1812 if (jiffies_left == 0) {
1813 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
1814 ret = -ETIMEDOUT;
1815 goto out;
1816 }
1817
1818 out:
1819 mutex_unlock(&vop->vop_lock);
1820 return ret;
1821 }
1822 EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
1823
1824 static int vop_bind(struct device *dev, struct device *master, void *data)
1825 {
1826 struct platform_device *pdev = to_platform_device(dev);
1827 const struct vop_data *vop_data;
1828 struct drm_device *drm_dev = data;
1829 struct vop *vop;
1830 struct resource *res;
1831 int ret, irq;
1832
1833 vop_data = of_device_get_match_data(dev);
1834 if (!vop_data)
1835 return -ENODEV;
1836
1837
1838 vop = devm_kzalloc(dev, struct_size(vop, win, vop_data->win_size),
1839 GFP_KERNEL);
1840 if (!vop)
1841 return -ENOMEM;
1842
1843 vop->dev = dev;
1844 vop->data = vop_data;
1845 vop->drm_dev = drm_dev;
1846 dev_set_drvdata(dev, vop);
1847
1848 vop_win_init(vop);
1849
1850 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1851 vop->len = resource_size(res);
1852 vop->regs = devm_ioremap_resource(dev, res);
1853 if (IS_ERR(vop->regs))
1854 return PTR_ERR(vop->regs);
1855
1856 vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
1857 if (!vop->regsbak)
1858 return -ENOMEM;
1859
1860 irq = platform_get_irq(pdev, 0);
1861 if (irq < 0) {
1862 DRM_DEV_ERROR(dev, "cannot find irq for vop\n");
1863 return irq;
1864 }
1865 vop->irq = (unsigned int)irq;
1866
1867 spin_lock_init(&vop->reg_lock);
1868 spin_lock_init(&vop->irq_lock);
1869 mutex_init(&vop->vop_lock);
1870
1871 ret = vop_create_crtc(vop);
1872 if (ret)
1873 return ret;
1874
1875 pm_runtime_enable(&pdev->dev);
1876
1877 ret = vop_initial(vop);
1878 if (ret < 0) {
1879 DRM_DEV_ERROR(&pdev->dev,
1880 "cannot initial vop dev - err %d\n", ret);
1881 goto err_disable_pm_runtime;
1882 }
1883
1884 ret = devm_request_irq(dev, vop->irq, vop_isr,
1885 IRQF_SHARED, dev_name(dev), vop);
1886 if (ret)
1887 goto err_disable_pm_runtime;
1888
1889 if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) {
1890 vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev);
1891 if (IS_ERR(vop->rgb)) {
1892 ret = PTR_ERR(vop->rgb);
1893 goto err_disable_pm_runtime;
1894 }
1895 }
1896
1897 return 0;
1898
1899 err_disable_pm_runtime:
1900 pm_runtime_disable(&pdev->dev);
1901 vop_destroy_crtc(vop);
1902 return ret;
1903 }
1904
1905 static void vop_unbind(struct device *dev, struct device *master, void *data)
1906 {
1907 struct vop *vop = dev_get_drvdata(dev);
1908
1909 if (vop->rgb)
1910 rockchip_rgb_fini(vop->rgb);
1911
1912 pm_runtime_disable(dev);
1913 vop_destroy_crtc(vop);
1914
1915 clk_unprepare(vop->aclk);
1916 clk_unprepare(vop->hclk);
1917 clk_unprepare(vop->dclk);
1918 }
1919
1920 const struct component_ops vop_component_ops = {
1921 .bind = vop_bind,
1922 .unbind = vop_unbind,
1923 };
1924 EXPORT_SYMBOL_GPL(vop_component_ops);