0001
0002
0003
0004
0005
0006
0007 #include <linux/clk.h>
0008 #include <linux/component.h>
0009 #include <linux/delay.h>
0010 #include <linux/iopoll.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/of_device.h>
0015 #include <linux/overflow.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/pm_runtime.h>
0018 #include <linux/reset.h>
0019
0020 #include <drm/drm.h>
0021 #include <drm/drm_atomic.h>
0022 #include <drm/drm_atomic_uapi.h>
0023 #include <drm/drm_blend.h>
0024 #include <drm/drm_crtc.h>
0025 #include <drm/drm_flip_work.h>
0026 #include <drm/drm_fourcc.h>
0027 #include <drm/drm_framebuffer.h>
0028 #include <drm/drm_gem_atomic_helper.h>
0029 #include <drm/drm_gem_framebuffer_helper.h>
0030 #include <drm/drm_plane_helper.h>
0031 #include <drm/drm_probe_helper.h>
0032 #include <drm/drm_self_refresh_helper.h>
0033 #include <drm/drm_vblank.h>
0034
0035 #ifdef CONFIG_DRM_ANALOGIX_DP
0036 #include <drm/bridge/analogix_dp.h>
0037 #endif
0038
0039 #include "rockchip_drm_drv.h"
0040 #include "rockchip_drm_gem.h"
0041 #include "rockchip_drm_fb.h"
0042 #include "rockchip_drm_vop.h"
0043 #include "rockchip_rgb.h"
0044
0045 #define VOP_WIN_SET(vop, win, name, v) \
0046 vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
0047 #define VOP_SCL_SET(vop, win, name, v) \
0048 vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
0049 #define VOP_SCL_SET_EXT(vop, win, name, v) \
0050 vop_reg_set(vop, &win->phy->scl->ext->name, \
0051 win->base, ~0, v, #name)
0052
0053 #define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
0054 do { \
0055 if (win_yuv2yuv && win_yuv2yuv->name.mask) \
0056 vop_reg_set(vop, &win_yuv2yuv->name, 0, ~0, v, #name); \
0057 } while (0)
0058
0059 #define VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, win_yuv2yuv, name, v) \
0060 do { \
0061 if (win_yuv2yuv && win_yuv2yuv->phy->name.mask) \
0062 vop_reg_set(vop, &win_yuv2yuv->phy->name, win_yuv2yuv->base, ~0, v, #name); \
0063 } while (0)
0064
0065 #define VOP_INTR_SET_MASK(vop, name, mask, v) \
0066 vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
0067
0068 #define VOP_REG_SET(vop, group, name, v) \
0069 vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
0070
0071 #define VOP_INTR_SET_TYPE(vop, name, type, v) \
0072 do { \
0073 int i, reg = 0, mask = 0; \
0074 for (i = 0; i < vop->data->intr->nintrs; i++) { \
0075 if (vop->data->intr->intrs[i] & type) { \
0076 reg |= (v) << i; \
0077 mask |= 1 << i; \
0078 } \
0079 } \
0080 VOP_INTR_SET_MASK(vop, name, mask, reg); \
0081 } while (0)
0082 #define VOP_INTR_GET_TYPE(vop, name, type) \
0083 vop_get_intr_type(vop, &vop->data->intr->name, type)
0084
0085 #define VOP_WIN_GET(vop, win, name) \
0086 vop_read_reg(vop, win->base, &win->phy->name)
0087
0088 #define VOP_WIN_HAS_REG(win, name) \
0089 (!!(win->phy->name.mask))
0090
0091 #define VOP_WIN_GET_YRGBADDR(vop, win) \
0092 vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
0093
0094 #define VOP_WIN_TO_INDEX(vop_win) \
0095 ((vop_win) - (vop_win)->vop->win)
0096
0097 #define VOP_AFBC_SET(vop, name, v) \
0098 do { \
0099 if ((vop)->data->afbc) \
0100 vop_reg_set((vop), &(vop)->data->afbc->name, \
0101 0, ~0, v, #name); \
0102 } while (0)
0103
0104 #define to_vop(x) container_of(x, struct vop, crtc)
0105 #define to_vop_win(x) container_of(x, struct vop_win, base)
0106
0107 #define AFBC_FMT_RGB565 0x0
0108 #define AFBC_FMT_U8U8U8U8 0x5
0109 #define AFBC_FMT_U8U8U8 0x4
0110
0111 #define AFBC_TILE_16x16 BIT(4)
0112
0113
0114
0115
0116
0117
0118 static const uint32_t bt601_yuv2rgb[] = {
0119 0x4A8, 0x0, 0x662,
0120 0x4A8, 0x1E6F, 0x1CBF,
0121 0x4A8, 0x812, 0x0,
0122 0x321168, 0x0877CF, 0x2EB127
0123 };
0124
0125 enum vop_pending {
0126 VOP_PENDING_FB_UNREF,
0127 };
0128
0129 struct vop_win {
0130 struct drm_plane base;
0131 const struct vop_win_data *data;
0132 const struct vop_win_yuv2yuv_data *yuv2yuv_data;
0133 struct vop *vop;
0134 };
0135
0136 struct rockchip_rgb;
0137 struct vop {
0138 struct drm_crtc crtc;
0139 struct device *dev;
0140 struct drm_device *drm_dev;
0141 bool is_enabled;
0142
0143 struct completion dsp_hold_completion;
0144 unsigned int win_enabled;
0145
0146
0147 struct drm_pending_vblank_event *event;
0148
0149 struct drm_flip_work fb_unref_work;
0150 unsigned long pending;
0151
0152 struct completion line_flag_completion;
0153
0154 const struct vop_data *data;
0155
0156 uint32_t *regsbak;
0157 void __iomem *regs;
0158 void __iomem *lut_regs;
0159
0160
0161 uint32_t len;
0162
0163
0164 spinlock_t reg_lock;
0165
0166 spinlock_t irq_lock;
0167
0168 struct mutex vop_lock;
0169
0170 unsigned int irq;
0171
0172
0173 struct clk *hclk;
0174
0175 struct clk *dclk;
0176
0177 struct clk *aclk;
0178
0179
0180 struct reset_control *dclk_rst;
0181
0182
0183 struct rockchip_rgb *rgb;
0184
0185 struct vop_win win[];
0186 };
0187
0188 static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
0189 {
0190 writel(v, vop->regs + offset);
0191 vop->regsbak[offset >> 2] = v;
0192 }
0193
0194 static inline uint32_t vop_readl(struct vop *vop, uint32_t offset)
0195 {
0196 return readl(vop->regs + offset);
0197 }
0198
0199 static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
0200 const struct vop_reg *reg)
0201 {
0202 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
0203 }
0204
0205 static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
0206 uint32_t _offset, uint32_t _mask, uint32_t v,
0207 const char *reg_name)
0208 {
0209 int offset, mask, shift;
0210
0211 if (!reg || !reg->mask) {
0212 DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name);
0213 return;
0214 }
0215
0216 offset = reg->offset + _offset;
0217 mask = reg->mask & _mask;
0218 shift = reg->shift;
0219
0220 if (reg->write_mask) {
0221 v = ((v << shift) & 0xffff) | (mask << (shift + 16));
0222 } else {
0223 uint32_t cached_val = vop->regsbak[offset >> 2];
0224
0225 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
0226 vop->regsbak[offset >> 2] = v;
0227 }
0228
0229 if (reg->relaxed)
0230 writel_relaxed(v, vop->regs + offset);
0231 else
0232 writel(v, vop->regs + offset);
0233 }
0234
0235 static inline uint32_t vop_get_intr_type(struct vop *vop,
0236 const struct vop_reg *reg, int type)
0237 {
0238 uint32_t i, ret = 0;
0239 uint32_t regs = vop_read_reg(vop, 0, reg);
0240
0241 for (i = 0; i < vop->data->intr->nintrs; i++) {
0242 if ((type & vop->data->intr->intrs[i]) && (regs & 1 << i))
0243 ret |= vop->data->intr->intrs[i];
0244 }
0245
0246 return ret;
0247 }
0248
0249 static inline void vop_cfg_done(struct vop *vop)
0250 {
0251 VOP_REG_SET(vop, common, cfg_done, 1);
0252 }
0253
0254 static bool has_rb_swapped(uint32_t format)
0255 {
0256 switch (format) {
0257 case DRM_FORMAT_XBGR8888:
0258 case DRM_FORMAT_ABGR8888:
0259 case DRM_FORMAT_BGR888:
0260 case DRM_FORMAT_BGR565:
0261 return true;
0262 default:
0263 return false;
0264 }
0265 }
0266
0267 static bool has_uv_swapped(uint32_t format)
0268 {
0269 switch (format) {
0270 case DRM_FORMAT_NV21:
0271 case DRM_FORMAT_NV61:
0272 case DRM_FORMAT_NV42:
0273 return true;
0274 default:
0275 return false;
0276 }
0277 }
0278
0279 static enum vop_data_format vop_convert_format(uint32_t format)
0280 {
0281 switch (format) {
0282 case DRM_FORMAT_XRGB8888:
0283 case DRM_FORMAT_ARGB8888:
0284 case DRM_FORMAT_XBGR8888:
0285 case DRM_FORMAT_ABGR8888:
0286 return VOP_FMT_ARGB8888;
0287 case DRM_FORMAT_RGB888:
0288 case DRM_FORMAT_BGR888:
0289 return VOP_FMT_RGB888;
0290 case DRM_FORMAT_RGB565:
0291 case DRM_FORMAT_BGR565:
0292 return VOP_FMT_RGB565;
0293 case DRM_FORMAT_NV12:
0294 case DRM_FORMAT_NV21:
0295 return VOP_FMT_YUV420SP;
0296 case DRM_FORMAT_NV16:
0297 case DRM_FORMAT_NV61:
0298 return VOP_FMT_YUV422SP;
0299 case DRM_FORMAT_NV24:
0300 case DRM_FORMAT_NV42:
0301 return VOP_FMT_YUV444SP;
0302 default:
0303 DRM_ERROR("unsupported format[%08x]\n", format);
0304 return -EINVAL;
0305 }
0306 }
0307
0308 static int vop_convert_afbc_format(uint32_t format)
0309 {
0310 switch (format) {
0311 case DRM_FORMAT_XRGB8888:
0312 case DRM_FORMAT_ARGB8888:
0313 case DRM_FORMAT_XBGR8888:
0314 case DRM_FORMAT_ABGR8888:
0315 return AFBC_FMT_U8U8U8U8;
0316 case DRM_FORMAT_RGB888:
0317 case DRM_FORMAT_BGR888:
0318 return AFBC_FMT_U8U8U8;
0319 case DRM_FORMAT_RGB565:
0320 case DRM_FORMAT_BGR565:
0321 return AFBC_FMT_RGB565;
0322
0323 default:
0324 DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format);
0325 return -EINVAL;
0326 }
0327
0328 return -EINVAL;
0329 }
0330
0331 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
0332 uint32_t dst, bool is_horizontal,
0333 int vsu_mode, int *vskiplines)
0334 {
0335 uint16_t val = 1 << SCL_FT_DEFAULT_FIXPOINT_SHIFT;
0336
0337 if (vskiplines)
0338 *vskiplines = 0;
0339
0340 if (is_horizontal) {
0341 if (mode == SCALE_UP)
0342 val = GET_SCL_FT_BIC(src, dst);
0343 else if (mode == SCALE_DOWN)
0344 val = GET_SCL_FT_BILI_DN(src, dst);
0345 } else {
0346 if (mode == SCALE_UP) {
0347 if (vsu_mode == SCALE_UP_BIL)
0348 val = GET_SCL_FT_BILI_UP(src, dst);
0349 else
0350 val = GET_SCL_FT_BIC(src, dst);
0351 } else if (mode == SCALE_DOWN) {
0352 if (vskiplines) {
0353 *vskiplines = scl_get_vskiplines(src, dst);
0354 val = scl_get_bili_dn_vskip(src, dst,
0355 *vskiplines);
0356 } else {
0357 val = GET_SCL_FT_BILI_DN(src, dst);
0358 }
0359 }
0360 }
0361
0362 return val;
0363 }
0364
0365 static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
0366 uint32_t src_w, uint32_t src_h, uint32_t dst_w,
0367 uint32_t dst_h, const struct drm_format_info *info)
0368 {
0369 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
0370 uint16_t cbcr_hor_scl_mode = SCALE_NONE;
0371 uint16_t cbcr_ver_scl_mode = SCALE_NONE;
0372 bool is_yuv = false;
0373 uint16_t cbcr_src_w = src_w / info->hsub;
0374 uint16_t cbcr_src_h = src_h / info->vsub;
0375 uint16_t vsu_mode;
0376 uint16_t lb_mode;
0377 uint32_t val;
0378 int vskiplines;
0379
0380 if (info->is_yuv)
0381 is_yuv = true;
0382
0383 if (dst_w > 3840) {
0384 DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
0385 return;
0386 }
0387
0388 if (!win->phy->scl->ext) {
0389 VOP_SCL_SET(vop, win, scale_yrgb_x,
0390 scl_cal_scale2(src_w, dst_w));
0391 VOP_SCL_SET(vop, win, scale_yrgb_y,
0392 scl_cal_scale2(src_h, dst_h));
0393 if (is_yuv) {
0394 VOP_SCL_SET(vop, win, scale_cbcr_x,
0395 scl_cal_scale2(cbcr_src_w, dst_w));
0396 VOP_SCL_SET(vop, win, scale_cbcr_y,
0397 scl_cal_scale2(cbcr_src_h, dst_h));
0398 }
0399 return;
0400 }
0401
0402 yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
0403 yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
0404
0405 if (is_yuv) {
0406 cbcr_hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w);
0407 cbcr_ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h);
0408 if (cbcr_hor_scl_mode == SCALE_DOWN)
0409 lb_mode = scl_vop_cal_lb_mode(dst_w, true);
0410 else
0411 lb_mode = scl_vop_cal_lb_mode(cbcr_src_w, true);
0412 } else {
0413 if (yrgb_hor_scl_mode == SCALE_DOWN)
0414 lb_mode = scl_vop_cal_lb_mode(dst_w, false);
0415 else
0416 lb_mode = scl_vop_cal_lb_mode(src_w, false);
0417 }
0418
0419 VOP_SCL_SET_EXT(vop, win, lb_mode, lb_mode);
0420 if (lb_mode == LB_RGB_3840X2) {
0421 if (yrgb_ver_scl_mode != SCALE_NONE) {
0422 DRM_DEV_ERROR(vop->dev, "not allow yrgb ver scale\n");
0423 return;
0424 }
0425 if (cbcr_ver_scl_mode != SCALE_NONE) {
0426 DRM_DEV_ERROR(vop->dev, "not allow cbcr ver scale\n");
0427 return;
0428 }
0429 vsu_mode = SCALE_UP_BIL;
0430 } else if (lb_mode == LB_RGB_2560X4) {
0431 vsu_mode = SCALE_UP_BIL;
0432 } else {
0433 vsu_mode = SCALE_UP_BIC;
0434 }
0435
0436 val = scl_vop_cal_scale(yrgb_hor_scl_mode, src_w, dst_w,
0437 true, 0, NULL);
0438 VOP_SCL_SET(vop, win, scale_yrgb_x, val);
0439 val = scl_vop_cal_scale(yrgb_ver_scl_mode, src_h, dst_h,
0440 false, vsu_mode, &vskiplines);
0441 VOP_SCL_SET(vop, win, scale_yrgb_y, val);
0442
0443 VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt4, vskiplines == 4);
0444 VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt2, vskiplines == 2);
0445
0446 VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, yrgb_hor_scl_mode);
0447 VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, yrgb_ver_scl_mode);
0448 VOP_SCL_SET_EXT(vop, win, yrgb_hsd_mode, SCALE_DOWN_BIL);
0449 VOP_SCL_SET_EXT(vop, win, yrgb_vsd_mode, SCALE_DOWN_BIL);
0450 VOP_SCL_SET_EXT(vop, win, yrgb_vsu_mode, vsu_mode);
0451 if (is_yuv) {
0452 val = scl_vop_cal_scale(cbcr_hor_scl_mode, cbcr_src_w,
0453 dst_w, true, 0, NULL);
0454 VOP_SCL_SET(vop, win, scale_cbcr_x, val);
0455 val = scl_vop_cal_scale(cbcr_ver_scl_mode, cbcr_src_h,
0456 dst_h, false, vsu_mode, &vskiplines);
0457 VOP_SCL_SET(vop, win, scale_cbcr_y, val);
0458
0459 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt4, vskiplines == 4);
0460 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt2, vskiplines == 2);
0461 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, cbcr_hor_scl_mode);
0462 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, cbcr_ver_scl_mode);
0463 VOP_SCL_SET_EXT(vop, win, cbcr_hsd_mode, SCALE_DOWN_BIL);
0464 VOP_SCL_SET_EXT(vop, win, cbcr_vsd_mode, SCALE_DOWN_BIL);
0465 VOP_SCL_SET_EXT(vop, win, cbcr_vsu_mode, vsu_mode);
0466 }
0467 }
0468
0469 static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
0470 {
0471 unsigned long flags;
0472
0473 if (WARN_ON(!vop->is_enabled))
0474 return;
0475
0476 spin_lock_irqsave(&vop->irq_lock, flags);
0477
0478 VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1);
0479 VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1);
0480
0481 spin_unlock_irqrestore(&vop->irq_lock, flags);
0482 }
0483
0484 static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
0485 {
0486 unsigned long flags;
0487
0488 if (WARN_ON(!vop->is_enabled))
0489 return;
0490
0491 spin_lock_irqsave(&vop->irq_lock, flags);
0492
0493 VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0);
0494
0495 spin_unlock_irqrestore(&vop->irq_lock, flags);
0496 }
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520 static bool vop_line_flag_irq_is_enabled(struct vop *vop)
0521 {
0522 uint32_t line_flag_irq;
0523 unsigned long flags;
0524
0525 spin_lock_irqsave(&vop->irq_lock, flags);
0526
0527 line_flag_irq = VOP_INTR_GET_TYPE(vop, enable, LINE_FLAG_INTR);
0528
0529 spin_unlock_irqrestore(&vop->irq_lock, flags);
0530
0531 return !!line_flag_irq;
0532 }
0533
0534 static void vop_line_flag_irq_enable(struct vop *vop)
0535 {
0536 unsigned long flags;
0537
0538 if (WARN_ON(!vop->is_enabled))
0539 return;
0540
0541 spin_lock_irqsave(&vop->irq_lock, flags);
0542
0543 VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
0544 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
0545
0546 spin_unlock_irqrestore(&vop->irq_lock, flags);
0547 }
0548
0549 static void vop_line_flag_irq_disable(struct vop *vop)
0550 {
0551 unsigned long flags;
0552
0553 if (WARN_ON(!vop->is_enabled))
0554 return;
0555
0556 spin_lock_irqsave(&vop->irq_lock, flags);
0557
0558 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 0);
0559
0560 spin_unlock_irqrestore(&vop->irq_lock, flags);
0561 }
0562
0563 static int vop_core_clks_enable(struct vop *vop)
0564 {
0565 int ret;
0566
0567 ret = clk_enable(vop->hclk);
0568 if (ret < 0)
0569 return ret;
0570
0571 ret = clk_enable(vop->aclk);
0572 if (ret < 0)
0573 goto err_disable_hclk;
0574
0575 return 0;
0576
0577 err_disable_hclk:
0578 clk_disable(vop->hclk);
0579 return ret;
0580 }
0581
0582 static void vop_core_clks_disable(struct vop *vop)
0583 {
0584 clk_disable(vop->aclk);
0585 clk_disable(vop->hclk);
0586 }
0587
0588 static void vop_win_disable(struct vop *vop, const struct vop_win *vop_win)
0589 {
0590 const struct vop_win_data *win = vop_win->data;
0591
0592 if (win->phy->scl && win->phy->scl->ext) {
0593 VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
0594 VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
0595 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
0596 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
0597 }
0598
0599 VOP_WIN_SET(vop, win, enable, 0);
0600 vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win));
0601 }
0602
0603 static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
0604 {
0605 struct vop *vop = to_vop(crtc);
0606 int ret, i;
0607
0608 ret = pm_runtime_get_sync(vop->dev);
0609 if (ret < 0) {
0610 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
0611 return ret;
0612 }
0613
0614 ret = vop_core_clks_enable(vop);
0615 if (WARN_ON(ret < 0))
0616 goto err_put_pm_runtime;
0617
0618 ret = clk_enable(vop->dclk);
0619 if (WARN_ON(ret < 0))
0620 goto err_disable_core;
0621
0622
0623
0624
0625
0626
0627
0628 ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
0629 if (ret) {
0630 DRM_DEV_ERROR(vop->dev,
0631 "failed to attach dma mapping, %d\n", ret);
0632 goto err_disable_dclk;
0633 }
0634
0635 spin_lock(&vop->reg_lock);
0636 for (i = 0; i < vop->len; i += 4)
0637 writel_relaxed(vop->regsbak[i / 4], vop->regs + i);
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648 if (!old_state || !old_state->self_refresh_active) {
0649 for (i = 0; i < vop->data->win_size; i++) {
0650 struct vop_win *vop_win = &vop->win[i];
0651
0652 vop_win_disable(vop, vop_win);
0653 }
0654 }
0655
0656 if (vop->data->afbc) {
0657 struct rockchip_crtc_state *s;
0658
0659
0660
0661 VOP_AFBC_SET(vop, enable, 0);
0662 s = to_rockchip_crtc_state(crtc->state);
0663 s->enable_afbc = false;
0664 }
0665
0666 vop_cfg_done(vop);
0667
0668 spin_unlock(&vop->reg_lock);
0669
0670
0671
0672
0673 vop->is_enabled = true;
0674
0675 spin_lock(&vop->reg_lock);
0676
0677 VOP_REG_SET(vop, common, standby, 1);
0678
0679 spin_unlock(&vop->reg_lock);
0680
0681 drm_crtc_vblank_on(crtc);
0682
0683 return 0;
0684
0685 err_disable_dclk:
0686 clk_disable(vop->dclk);
0687 err_disable_core:
0688 vop_core_clks_disable(vop);
0689 err_put_pm_runtime:
0690 pm_runtime_put_sync(vop->dev);
0691 return ret;
0692 }
0693
0694 static void rockchip_drm_set_win_enabled(struct drm_crtc *crtc, bool enabled)
0695 {
0696 struct vop *vop = to_vop(crtc);
0697 int i;
0698
0699 spin_lock(&vop->reg_lock);
0700
0701 for (i = 0; i < vop->data->win_size; i++) {
0702 struct vop_win *vop_win = &vop->win[i];
0703 const struct vop_win_data *win = vop_win->data;
0704
0705 VOP_WIN_SET(vop, win, enable,
0706 enabled && (vop->win_enabled & BIT(i)));
0707 }
0708 vop_cfg_done(vop);
0709
0710 spin_unlock(&vop->reg_lock);
0711 }
0712
0713 static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
0714 struct drm_atomic_state *state)
0715 {
0716 struct vop *vop = to_vop(crtc);
0717
0718 WARN_ON(vop->event);
0719
0720 if (crtc->state->self_refresh_active)
0721 rockchip_drm_set_win_enabled(crtc, false);
0722
0723 mutex_lock(&vop->vop_lock);
0724
0725 drm_crtc_vblank_off(crtc);
0726
0727 if (crtc->state->self_refresh_active)
0728 goto out;
0729
0730
0731
0732
0733
0734
0735
0736
0737 reinit_completion(&vop->dsp_hold_completion);
0738 vop_dsp_hold_valid_irq_enable(vop);
0739
0740 spin_lock(&vop->reg_lock);
0741
0742 VOP_REG_SET(vop, common, standby, 1);
0743
0744 spin_unlock(&vop->reg_lock);
0745
0746 if (!wait_for_completion_timeout(&vop->dsp_hold_completion,
0747 msecs_to_jiffies(200)))
0748 WARN(1, "%s: timed out waiting for DSP hold", crtc->name);
0749
0750 vop_dsp_hold_valid_irq_disable(vop);
0751
0752 vop->is_enabled = false;
0753
0754
0755
0756
0757 rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
0758
0759 clk_disable(vop->dclk);
0760 vop_core_clks_disable(vop);
0761 pm_runtime_put(vop->dev);
0762
0763 out:
0764 mutex_unlock(&vop->vop_lock);
0765
0766 if (crtc->state->event && !crtc->state->active) {
0767 spin_lock_irq(&crtc->dev->event_lock);
0768 drm_crtc_send_vblank_event(crtc, crtc->state->event);
0769 spin_unlock_irq(&crtc->dev->event_lock);
0770
0771 crtc->state->event = NULL;
0772 }
0773 }
0774
0775 static void vop_plane_destroy(struct drm_plane *plane)
0776 {
0777 drm_plane_cleanup(plane);
0778 }
0779
0780 static inline bool rockchip_afbc(u64 modifier)
0781 {
0782 return modifier == ROCKCHIP_AFBC_MOD;
0783 }
0784
0785 static bool rockchip_mod_supported(struct drm_plane *plane,
0786 u32 format, u64 modifier)
0787 {
0788 if (modifier == DRM_FORMAT_MOD_LINEAR)
0789 return true;
0790
0791 if (!rockchip_afbc(modifier)) {
0792 DRM_DEBUG_KMS("Unsupported format modifier 0x%llx\n", modifier);
0793
0794 return false;
0795 }
0796
0797 return vop_convert_afbc_format(format) >= 0;
0798 }
0799
0800 static int vop_plane_atomic_check(struct drm_plane *plane,
0801 struct drm_atomic_state *state)
0802 {
0803 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
0804 plane);
0805 struct drm_crtc *crtc = new_plane_state->crtc;
0806 struct drm_crtc_state *crtc_state;
0807 struct drm_framebuffer *fb = new_plane_state->fb;
0808 struct vop_win *vop_win = to_vop_win(plane);
0809 const struct vop_win_data *win = vop_win->data;
0810 int ret;
0811 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
0812 DRM_PLANE_HELPER_NO_SCALING;
0813 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
0814 DRM_PLANE_HELPER_NO_SCALING;
0815
0816 if (!crtc || WARN_ON(!fb))
0817 return 0;
0818
0819 crtc_state = drm_atomic_get_existing_crtc_state(state,
0820 crtc);
0821 if (WARN_ON(!crtc_state))
0822 return -EINVAL;
0823
0824 ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
0825 min_scale, max_scale,
0826 true, true);
0827 if (ret)
0828 return ret;
0829
0830 if (!new_plane_state->visible)
0831 return 0;
0832
0833 ret = vop_convert_format(fb->format->format);
0834 if (ret < 0)
0835 return ret;
0836
0837
0838
0839
0840
0841 if (fb->format->is_yuv && ((new_plane_state->src.x1 >> 16) % 2)) {
0842 DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n");
0843 return -EINVAL;
0844 }
0845
0846 if (fb->format->is_yuv && new_plane_state->rotation & DRM_MODE_REFLECT_Y) {
0847 DRM_ERROR("Invalid Source: Yuv format does not support this rotation\n");
0848 return -EINVAL;
0849 }
0850
0851 if (rockchip_afbc(fb->modifier)) {
0852 struct vop *vop = to_vop(crtc);
0853
0854 if (!vop->data->afbc) {
0855 DRM_ERROR("vop does not support AFBC\n");
0856 return -EINVAL;
0857 }
0858
0859 ret = vop_convert_afbc_format(fb->format->format);
0860 if (ret < 0)
0861 return ret;
0862
0863 if (new_plane_state->src.x1 || new_plane_state->src.y1) {
0864 DRM_ERROR("AFBC does not support offset display, xpos=%d, ypos=%d, offset=%d\n",
0865 new_plane_state->src.x1,
0866 new_plane_state->src.y1, fb->offsets[0]);
0867 return -EINVAL;
0868 }
0869
0870 if (new_plane_state->rotation && new_plane_state->rotation != DRM_MODE_ROTATE_0) {
0871 DRM_ERROR("No rotation support in AFBC, rotation=%d\n",
0872 new_plane_state->rotation);
0873 return -EINVAL;
0874 }
0875 }
0876
0877 return 0;
0878 }
0879
0880 static void vop_plane_atomic_disable(struct drm_plane *plane,
0881 struct drm_atomic_state *state)
0882 {
0883 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
0884 plane);
0885 struct vop_win *vop_win = to_vop_win(plane);
0886 struct vop *vop = to_vop(old_state->crtc);
0887
0888 if (!old_state->crtc)
0889 return;
0890
0891 spin_lock(&vop->reg_lock);
0892
0893 vop_win_disable(vop, vop_win);
0894
0895 spin_unlock(&vop->reg_lock);
0896 }
0897
0898 static void vop_plane_atomic_update(struct drm_plane *plane,
0899 struct drm_atomic_state *state)
0900 {
0901 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
0902 plane);
0903 struct drm_crtc *crtc = new_state->crtc;
0904 struct vop_win *vop_win = to_vop_win(plane);
0905 const struct vop_win_data *win = vop_win->data;
0906 const struct vop_win_yuv2yuv_data *win_yuv2yuv = vop_win->yuv2yuv_data;
0907 struct vop *vop = to_vop(new_state->crtc);
0908 struct drm_framebuffer *fb = new_state->fb;
0909 unsigned int actual_w, actual_h;
0910 unsigned int dsp_stx, dsp_sty;
0911 uint32_t act_info, dsp_info, dsp_st;
0912 struct drm_rect *src = &new_state->src;
0913 struct drm_rect *dest = &new_state->dst;
0914 struct drm_gem_object *obj, *uv_obj;
0915 struct rockchip_gem_object *rk_obj, *rk_uv_obj;
0916 unsigned long offset;
0917 dma_addr_t dma_addr;
0918 uint32_t val;
0919 bool rb_swap, uv_swap;
0920 int win_index = VOP_WIN_TO_INDEX(vop_win);
0921 int format;
0922 int is_yuv = fb->format->is_yuv;
0923 int i;
0924
0925
0926
0927
0928 if (WARN_ON(!crtc))
0929 return;
0930
0931 if (WARN_ON(!vop->is_enabled))
0932 return;
0933
0934 if (!new_state->visible) {
0935 vop_plane_atomic_disable(plane, state);
0936 return;
0937 }
0938
0939 obj = fb->obj[0];
0940 rk_obj = to_rockchip_obj(obj);
0941
0942 actual_w = drm_rect_width(src) >> 16;
0943 actual_h = drm_rect_height(src) >> 16;
0944 act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
0945
0946 dsp_info = (drm_rect_height(dest) - 1) << 16;
0947 dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
0948
0949 dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
0950 dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
0951 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
0952
0953 offset = (src->x1 >> 16) * fb->format->cpp[0];
0954 offset += (src->y1 >> 16) * fb->pitches[0];
0955 dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
0956
0957
0958
0959
0960
0961 if (new_state->rotation & DRM_MODE_REFLECT_Y)
0962 dma_addr += (actual_h - 1) * fb->pitches[0];
0963
0964 format = vop_convert_format(fb->format->format);
0965
0966 spin_lock(&vop->reg_lock);
0967
0968 if (rockchip_afbc(fb->modifier)) {
0969 int afbc_format = vop_convert_afbc_format(fb->format->format);
0970
0971 VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16);
0972 VOP_AFBC_SET(vop, hreg_block_split, 0);
0973 VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win));
0974 VOP_AFBC_SET(vop, hdr_ptr, dma_addr);
0975 VOP_AFBC_SET(vop, pic_size, act_info);
0976 }
0977
0978 VOP_WIN_SET(vop, win, format, format);
0979 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
0980 VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
0981 VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
0982 VOP_WIN_SET(vop, win, y_mir_en,
0983 (new_state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0);
0984 VOP_WIN_SET(vop, win, x_mir_en,
0985 (new_state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
0986
0987 if (is_yuv) {
0988 int hsub = fb->format->hsub;
0989 int vsub = fb->format->vsub;
0990 int bpp = fb->format->cpp[1];
0991
0992 uv_obj = fb->obj[1];
0993 rk_uv_obj = to_rockchip_obj(uv_obj);
0994
0995 offset = (src->x1 >> 16) * bpp / hsub;
0996 offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
0997
0998 dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
0999 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
1000 VOP_WIN_SET(vop, win, uv_mst, dma_addr);
1001
1002 for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) {
1003 VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop,
1004 win_yuv2yuv,
1005 y2r_coefficients[i],
1006 bt601_yuv2rgb[i]);
1007 }
1008
1009 uv_swap = has_uv_swapped(fb->format->format);
1010 VOP_WIN_SET(vop, win, uv_swap, uv_swap);
1011 }
1012
1013 if (win->phy->scl)
1014 scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
1015 drm_rect_width(dest), drm_rect_height(dest),
1016 fb->format);
1017
1018 VOP_WIN_SET(vop, win, act_info, act_info);
1019 VOP_WIN_SET(vop, win, dsp_info, dsp_info);
1020 VOP_WIN_SET(vop, win, dsp_st, dsp_st);
1021
1022 rb_swap = has_rb_swapped(fb->format->format);
1023 VOP_WIN_SET(vop, win, rb_swap, rb_swap);
1024
1025
1026
1027
1028
1029
1030
1031
1032 if (fb->format->has_alpha && win_index > 0) {
1033 VOP_WIN_SET(vop, win, dst_alpha_ctl,
1034 DST_FACTOR_M0(ALPHA_SRC_INVERSE));
1035 val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
1036 SRC_ALPHA_M0(ALPHA_STRAIGHT) |
1037 SRC_BLEND_M0(ALPHA_PER_PIX) |
1038 SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
1039 SRC_FACTOR_M0(ALPHA_ONE);
1040 VOP_WIN_SET(vop, win, src_alpha_ctl, val);
1041
1042 VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL);
1043 VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX);
1044 VOP_WIN_SET(vop, win, alpha_en, 1);
1045 } else {
1046 VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0));
1047 VOP_WIN_SET(vop, win, alpha_en, 0);
1048 }
1049
1050 VOP_WIN_SET(vop, win, enable, 1);
1051 vop->win_enabled |= BIT(win_index);
1052 spin_unlock(&vop->reg_lock);
1053 }
1054
1055 static int vop_plane_atomic_async_check(struct drm_plane *plane,
1056 struct drm_atomic_state *state)
1057 {
1058 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
1059 plane);
1060 struct vop_win *vop_win = to_vop_win(plane);
1061 const struct vop_win_data *win = vop_win->data;
1062 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
1063 DRM_PLANE_HELPER_NO_SCALING;
1064 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
1065 DRM_PLANE_HELPER_NO_SCALING;
1066 struct drm_crtc_state *crtc_state;
1067
1068 if (plane != new_plane_state->crtc->cursor)
1069 return -EINVAL;
1070
1071 if (!plane->state)
1072 return -EINVAL;
1073
1074 if (!plane->state->fb)
1075 return -EINVAL;
1076
1077 if (state)
1078 crtc_state = drm_atomic_get_existing_crtc_state(state,
1079 new_plane_state->crtc);
1080 else
1081 crtc_state = plane->crtc->state;
1082
1083 return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
1084 min_scale, max_scale,
1085 true, true);
1086 }
1087
1088 static void vop_plane_atomic_async_update(struct drm_plane *plane,
1089 struct drm_atomic_state *state)
1090 {
1091 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
1092 plane);
1093 struct vop *vop = to_vop(plane->state->crtc);
1094 struct drm_framebuffer *old_fb = plane->state->fb;
1095
1096 plane->state->crtc_x = new_state->crtc_x;
1097 plane->state->crtc_y = new_state->crtc_y;
1098 plane->state->crtc_h = new_state->crtc_h;
1099 plane->state->crtc_w = new_state->crtc_w;
1100 plane->state->src_x = new_state->src_x;
1101 plane->state->src_y = new_state->src_y;
1102 plane->state->src_h = new_state->src_h;
1103 plane->state->src_w = new_state->src_w;
1104 swap(plane->state->fb, new_state->fb);
1105
1106 if (vop->is_enabled) {
1107 vop_plane_atomic_update(plane, state);
1108 spin_lock(&vop->reg_lock);
1109 vop_cfg_done(vop);
1110 spin_unlock(&vop->reg_lock);
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 if (old_fb && plane->state->fb != old_fb) {
1121 drm_framebuffer_get(old_fb);
1122 WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
1123 drm_flip_work_queue(&vop->fb_unref_work, old_fb);
1124 set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
1125 }
1126 }
1127 }
1128
1129 static const struct drm_plane_helper_funcs plane_helper_funcs = {
1130 .atomic_check = vop_plane_atomic_check,
1131 .atomic_update = vop_plane_atomic_update,
1132 .atomic_disable = vop_plane_atomic_disable,
1133 .atomic_async_check = vop_plane_atomic_async_check,
1134 .atomic_async_update = vop_plane_atomic_async_update,
1135 };
1136
1137 static const struct drm_plane_funcs vop_plane_funcs = {
1138 .update_plane = drm_atomic_helper_update_plane,
1139 .disable_plane = drm_atomic_helper_disable_plane,
1140 .destroy = vop_plane_destroy,
1141 .reset = drm_atomic_helper_plane_reset,
1142 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
1143 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
1144 .format_mod_supported = rockchip_mod_supported,
1145 };
1146
1147 static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
1148 {
1149 struct vop *vop = to_vop(crtc);
1150 unsigned long flags;
1151
1152 if (WARN_ON(!vop->is_enabled))
1153 return -EPERM;
1154
1155 spin_lock_irqsave(&vop->irq_lock, flags);
1156
1157 VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1);
1158 VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1);
1159
1160 spin_unlock_irqrestore(&vop->irq_lock, flags);
1161
1162 return 0;
1163 }
1164
1165 static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
1166 {
1167 struct vop *vop = to_vop(crtc);
1168 unsigned long flags;
1169
1170 if (WARN_ON(!vop->is_enabled))
1171 return;
1172
1173 spin_lock_irqsave(&vop->irq_lock, flags);
1174
1175 VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0);
1176
1177 spin_unlock_irqrestore(&vop->irq_lock, flags);
1178 }
1179
1180 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
1181 const struct drm_display_mode *mode,
1182 struct drm_display_mode *adjusted_mode)
1183 {
1184 struct vop *vop = to_vop(crtc);
1185 unsigned long rate;
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213 rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000);
1214 if (rate / 1000 != adjusted_mode->clock)
1215 rate = clk_round_rate(vop->dclk,
1216 adjusted_mode->clock * 1000 + 999);
1217 adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
1218
1219 return true;
1220 }
1221
1222 static bool vop_dsp_lut_is_enabled(struct vop *vop)
1223 {
1224 return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en);
1225 }
1226
1227 static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc)
1228 {
1229 struct drm_color_lut *lut = crtc->state->gamma_lut->data;
1230 unsigned int i;
1231
1232 for (i = 0; i < crtc->gamma_size; i++) {
1233 u32 word;
1234
1235 word = (drm_color_lut_extract(lut[i].red, 10) << 20) |
1236 (drm_color_lut_extract(lut[i].green, 10) << 10) |
1237 drm_color_lut_extract(lut[i].blue, 10);
1238 writel(word, vop->lut_regs + i * 4);
1239 }
1240 }
1241
1242 static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
1243 struct drm_crtc_state *old_state)
1244 {
1245 struct drm_crtc_state *state = crtc->state;
1246 unsigned int idle;
1247 int ret;
1248
1249 if (!vop->lut_regs)
1250 return;
1251
1252
1253
1254
1255 spin_lock(&vop->reg_lock);
1256 VOP_REG_SET(vop, common, dsp_lut_en, 0);
1257 vop_cfg_done(vop);
1258 spin_unlock(&vop->reg_lock);
1259
1260
1261
1262
1263
1264 ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
1265 idle, !idle, 5, 30 * 1000);
1266 if (ret) {
1267 DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
1268 return;
1269 }
1270
1271 if (!state->gamma_lut)
1272 return;
1273
1274 spin_lock(&vop->reg_lock);
1275 vop_crtc_write_gamma_lut(vop, crtc);
1276 VOP_REG_SET(vop, common, dsp_lut_en, 1);
1277 vop_cfg_done(vop);
1278 spin_unlock(&vop->reg_lock);
1279 }
1280
1281 static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
1282 struct drm_atomic_state *state)
1283 {
1284 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
1285 crtc);
1286 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1287 crtc);
1288 struct vop *vop = to_vop(crtc);
1289
1290
1291
1292
1293
1294 if (crtc_state->color_mgmt_changed &&
1295 !crtc_state->active_changed)
1296 vop_crtc_gamma_set(vop, crtc, old_crtc_state);
1297 }
1298
1299 static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
1300 struct drm_atomic_state *state)
1301 {
1302 struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
1303 crtc);
1304 struct vop *vop = to_vop(crtc);
1305 const struct vop_data *vop_data = vop->data;
1306 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
1307 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1308 u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
1309 u16 hdisplay = adjusted_mode->hdisplay;
1310 u16 htotal = adjusted_mode->htotal;
1311 u16 hact_st = adjusted_mode->htotal - adjusted_mode->hsync_start;
1312 u16 hact_end = hact_st + hdisplay;
1313 u16 vdisplay = adjusted_mode->vdisplay;
1314 u16 vtotal = adjusted_mode->vtotal;
1315 u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
1316 u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
1317 u16 vact_end = vact_st + vdisplay;
1318 uint32_t pin_pol, val;
1319 int dither_bpc = s->output_bpc ? s->output_bpc : 10;
1320 int ret;
1321
1322 if (old_state && old_state->self_refresh_active) {
1323 drm_crtc_vblank_on(crtc);
1324 rockchip_drm_set_win_enabled(crtc, true);
1325 return;
1326 }
1327
1328
1329
1330
1331
1332
1333 if (crtc->state->gamma_lut)
1334 vop_crtc_gamma_set(vop, crtc, old_state);
1335
1336 mutex_lock(&vop->vop_lock);
1337
1338 WARN_ON(vop->event);
1339
1340 ret = vop_enable(crtc, old_state);
1341 if (ret) {
1342 mutex_unlock(&vop->vop_lock);
1343 DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
1344 return;
1345 }
1346 pin_pol = (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ?
1347 BIT(HSYNC_POSITIVE) : 0;
1348 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
1349 BIT(VSYNC_POSITIVE) : 0;
1350 VOP_REG_SET(vop, output, pin_pol, pin_pol);
1351 VOP_REG_SET(vop, output, mipi_dual_channel_en, 0);
1352
1353 switch (s->output_type) {
1354 case DRM_MODE_CONNECTOR_LVDS:
1355 VOP_REG_SET(vop, output, rgb_dclk_pol, 1);
1356 VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
1357 VOP_REG_SET(vop, output, rgb_en, 1);
1358 break;
1359 case DRM_MODE_CONNECTOR_eDP:
1360 VOP_REG_SET(vop, output, edp_dclk_pol, 1);
1361 VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
1362 VOP_REG_SET(vop, output, edp_en, 1);
1363 break;
1364 case DRM_MODE_CONNECTOR_HDMIA:
1365 VOP_REG_SET(vop, output, hdmi_dclk_pol, 1);
1366 VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
1367 VOP_REG_SET(vop, output, hdmi_en, 1);
1368 break;
1369 case DRM_MODE_CONNECTOR_DSI:
1370 VOP_REG_SET(vop, output, mipi_dclk_pol, 1);
1371 VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
1372 VOP_REG_SET(vop, output, mipi_en, 1);
1373 VOP_REG_SET(vop, output, mipi_dual_channel_en,
1374 !!(s->output_flags & ROCKCHIP_OUTPUT_DSI_DUAL));
1375 break;
1376 case DRM_MODE_CONNECTOR_DisplayPort:
1377 VOP_REG_SET(vop, output, dp_dclk_pol, 0);
1378 VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
1379 VOP_REG_SET(vop, output, dp_en, 1);
1380 break;
1381 default:
1382 DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
1383 s->output_type);
1384 }
1385
1386
1387
1388
1389 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
1390 !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
1391 s->output_mode = ROCKCHIP_OUT_MODE_P888;
1392
1393 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8)
1394 VOP_REG_SET(vop, common, pre_dither_down, 1);
1395 else
1396 VOP_REG_SET(vop, common, pre_dither_down, 0);
1397
1398 if (dither_bpc == 6) {
1399 VOP_REG_SET(vop, common, dither_down_sel, DITHER_DOWN_ALLEGRO);
1400 VOP_REG_SET(vop, common, dither_down_mode, RGB888_TO_RGB666);
1401 VOP_REG_SET(vop, common, dither_down_en, 1);
1402 } else {
1403 VOP_REG_SET(vop, common, dither_down_en, 0);
1404 }
1405
1406 VOP_REG_SET(vop, common, out_mode, s->output_mode);
1407
1408 VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
1409 val = hact_st << 16;
1410 val |= hact_end;
1411 VOP_REG_SET(vop, modeset, hact_st_end, val);
1412 VOP_REG_SET(vop, modeset, hpost_st_end, val);
1413
1414 VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
1415 val = vact_st << 16;
1416 val |= vact_end;
1417 VOP_REG_SET(vop, modeset, vact_st_end, val);
1418 VOP_REG_SET(vop, modeset, vpost_st_end, val);
1419
1420 VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
1421
1422 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
1423
1424 VOP_REG_SET(vop, common, standby, 0);
1425 mutex_unlock(&vop->vop_lock);
1426 }
1427
1428 static bool vop_fs_irq_is_pending(struct vop *vop)
1429 {
1430 return VOP_INTR_GET_TYPE(vop, status, FS_INTR);
1431 }
1432
1433 static void vop_wait_for_irq_handler(struct vop *vop)
1434 {
1435 bool pending;
1436 int ret;
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446 ret = readx_poll_timeout_atomic(vop_fs_irq_is_pending, vop, pending,
1447 !pending, 0, 10 * 1000);
1448 if (ret)
1449 DRM_DEV_ERROR(vop->dev, "VOP vblank IRQ stuck for 10 ms\n");
1450
1451 synchronize_irq(vop->irq);
1452 }
1453
1454 static int vop_crtc_atomic_check(struct drm_crtc *crtc,
1455 struct drm_atomic_state *state)
1456 {
1457 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
1458 crtc);
1459 struct vop *vop = to_vop(crtc);
1460 struct drm_plane *plane;
1461 struct drm_plane_state *plane_state;
1462 struct rockchip_crtc_state *s;
1463 int afbc_planes = 0;
1464
1465 if (vop->lut_regs && crtc_state->color_mgmt_changed &&
1466 crtc_state->gamma_lut) {
1467 unsigned int len;
1468
1469 len = drm_color_lut_size(crtc_state->gamma_lut);
1470 if (len != crtc->gamma_size) {
1471 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
1472 len, crtc->gamma_size);
1473 return -EINVAL;
1474 }
1475 }
1476
1477 drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
1478 plane_state =
1479 drm_atomic_get_plane_state(crtc_state->state, plane);
1480 if (IS_ERR(plane_state)) {
1481 DRM_DEBUG_KMS("Cannot get plane state for plane %s\n",
1482 plane->name);
1483 return PTR_ERR(plane_state);
1484 }
1485
1486 if (drm_is_afbc(plane_state->fb->modifier))
1487 ++afbc_planes;
1488 }
1489
1490 if (afbc_planes > 1) {
1491 DRM_DEBUG_KMS("Invalid number of AFBC planes; got %d, expected at most 1\n", afbc_planes);
1492 return -EINVAL;
1493 }
1494
1495 s = to_rockchip_crtc_state(crtc_state);
1496 s->enable_afbc = afbc_planes > 0;
1497
1498 return 0;
1499 }
1500
1501 static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
1502 struct drm_atomic_state *state)
1503 {
1504 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1505 crtc);
1506 struct drm_atomic_state *old_state = old_crtc_state->state;
1507 struct drm_plane_state *old_plane_state, *new_plane_state;
1508 struct vop *vop = to_vop(crtc);
1509 struct drm_plane *plane;
1510 struct rockchip_crtc_state *s;
1511 int i;
1512
1513 if (WARN_ON(!vop->is_enabled))
1514 return;
1515
1516 spin_lock(&vop->reg_lock);
1517
1518
1519 s = to_rockchip_crtc_state(crtc->state);
1520 VOP_AFBC_SET(vop, enable, s->enable_afbc);
1521 vop_cfg_done(vop);
1522
1523 spin_unlock(&vop->reg_lock);
1524
1525
1526
1527
1528
1529
1530 vop_wait_for_irq_handler(vop);
1531
1532 spin_lock_irq(&crtc->dev->event_lock);
1533 if (crtc->state->event) {
1534 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
1535 WARN_ON(vop->event);
1536
1537 vop->event = crtc->state->event;
1538 crtc->state->event = NULL;
1539 }
1540 spin_unlock_irq(&crtc->dev->event_lock);
1541
1542 for_each_oldnew_plane_in_state(old_state, plane, old_plane_state,
1543 new_plane_state, i) {
1544 if (!old_plane_state->fb)
1545 continue;
1546
1547 if (old_plane_state->fb == new_plane_state->fb)
1548 continue;
1549
1550 drm_framebuffer_get(old_plane_state->fb);
1551 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
1552 drm_flip_work_queue(&vop->fb_unref_work, old_plane_state->fb);
1553 set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
1554 }
1555 }
1556
1557 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
1558 .mode_fixup = vop_crtc_mode_fixup,
1559 .atomic_check = vop_crtc_atomic_check,
1560 .atomic_begin = vop_crtc_atomic_begin,
1561 .atomic_flush = vop_crtc_atomic_flush,
1562 .atomic_enable = vop_crtc_atomic_enable,
1563 .atomic_disable = vop_crtc_atomic_disable,
1564 };
1565
1566 static void vop_crtc_destroy(struct drm_crtc *crtc)
1567 {
1568 drm_crtc_cleanup(crtc);
1569 }
1570
1571 static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
1572 {
1573 struct rockchip_crtc_state *rockchip_state;
1574
1575 if (WARN_ON(!crtc->state))
1576 return NULL;
1577
1578 rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
1579 if (!rockchip_state)
1580 return NULL;
1581
1582 __drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base);
1583 return &rockchip_state->base;
1584 }
1585
1586 static void vop_crtc_destroy_state(struct drm_crtc *crtc,
1587 struct drm_crtc_state *state)
1588 {
1589 struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
1590
1591 __drm_atomic_helper_crtc_destroy_state(&s->base);
1592 kfree(s);
1593 }
1594
1595 static void vop_crtc_reset(struct drm_crtc *crtc)
1596 {
1597 struct rockchip_crtc_state *crtc_state =
1598 kzalloc(sizeof(*crtc_state), GFP_KERNEL);
1599
1600 if (crtc->state)
1601 vop_crtc_destroy_state(crtc, crtc->state);
1602
1603 __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
1604 }
1605
1606 #ifdef CONFIG_DRM_ANALOGIX_DP
1607 static struct drm_connector *vop_get_edp_connector(struct vop *vop)
1608 {
1609 struct drm_connector *connector;
1610 struct drm_connector_list_iter conn_iter;
1611
1612 drm_connector_list_iter_begin(vop->drm_dev, &conn_iter);
1613 drm_for_each_connector_iter(connector, &conn_iter) {
1614 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1615 drm_connector_list_iter_end(&conn_iter);
1616 return connector;
1617 }
1618 }
1619 drm_connector_list_iter_end(&conn_iter);
1620
1621 return NULL;
1622 }
1623
1624 static int vop_crtc_set_crc_source(struct drm_crtc *crtc,
1625 const char *source_name)
1626 {
1627 struct vop *vop = to_vop(crtc);
1628 struct drm_connector *connector;
1629 int ret;
1630
1631 connector = vop_get_edp_connector(vop);
1632 if (!connector)
1633 return -EINVAL;
1634
1635 if (source_name && strcmp(source_name, "auto") == 0)
1636 ret = analogix_dp_start_crc(connector);
1637 else if (!source_name)
1638 ret = analogix_dp_stop_crc(connector);
1639 else
1640 ret = -EINVAL;
1641
1642 return ret;
1643 }
1644
1645 static int
1646 vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
1647 size_t *values_cnt)
1648 {
1649 if (source_name && strcmp(source_name, "auto") != 0)
1650 return -EINVAL;
1651
1652 *values_cnt = 3;
1653 return 0;
1654 }
1655
1656 #else
1657 static int vop_crtc_set_crc_source(struct drm_crtc *crtc,
1658 const char *source_name)
1659 {
1660 return -ENODEV;
1661 }
1662
1663 static int
1664 vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
1665 size_t *values_cnt)
1666 {
1667 return -ENODEV;
1668 }
1669 #endif
1670
1671 static const struct drm_crtc_funcs vop_crtc_funcs = {
1672 .set_config = drm_atomic_helper_set_config,
1673 .page_flip = drm_atomic_helper_page_flip,
1674 .destroy = vop_crtc_destroy,
1675 .reset = vop_crtc_reset,
1676 .atomic_duplicate_state = vop_crtc_duplicate_state,
1677 .atomic_destroy_state = vop_crtc_destroy_state,
1678 .enable_vblank = vop_crtc_enable_vblank,
1679 .disable_vblank = vop_crtc_disable_vblank,
1680 .set_crc_source = vop_crtc_set_crc_source,
1681 .verify_crc_source = vop_crtc_verify_crc_source,
1682 };
1683
1684 static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
1685 {
1686 struct vop *vop = container_of(work, struct vop, fb_unref_work);
1687 struct drm_framebuffer *fb = val;
1688
1689 drm_crtc_vblank_put(&vop->crtc);
1690 drm_framebuffer_put(fb);
1691 }
1692
1693 static void vop_handle_vblank(struct vop *vop)
1694 {
1695 struct drm_device *drm = vop->drm_dev;
1696 struct drm_crtc *crtc = &vop->crtc;
1697
1698 spin_lock(&drm->event_lock);
1699 if (vop->event) {
1700 drm_crtc_send_vblank_event(crtc, vop->event);
1701 drm_crtc_vblank_put(crtc);
1702 vop->event = NULL;
1703 }
1704 spin_unlock(&drm->event_lock);
1705
1706 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
1707 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
1708 }
1709
1710 static irqreturn_t vop_isr(int irq, void *data)
1711 {
1712 struct vop *vop = data;
1713 struct drm_crtc *crtc = &vop->crtc;
1714 uint32_t active_irqs;
1715 int ret = IRQ_NONE;
1716
1717
1718
1719
1720
1721 if (!pm_runtime_get_if_in_use(vop->dev))
1722 return IRQ_NONE;
1723
1724 if (vop_core_clks_enable(vop)) {
1725 DRM_DEV_ERROR_RATELIMITED(vop->dev, "couldn't enable clocks\n");
1726 goto out;
1727 }
1728
1729
1730
1731
1732
1733 spin_lock(&vop->irq_lock);
1734
1735 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK);
1736
1737 if (active_irqs)
1738 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1);
1739
1740 spin_unlock(&vop->irq_lock);
1741
1742
1743 if (!active_irqs)
1744 goto out_disable;
1745
1746 if (active_irqs & DSP_HOLD_VALID_INTR) {
1747 complete(&vop->dsp_hold_completion);
1748 active_irqs &= ~DSP_HOLD_VALID_INTR;
1749 ret = IRQ_HANDLED;
1750 }
1751
1752 if (active_irqs & LINE_FLAG_INTR) {
1753 complete(&vop->line_flag_completion);
1754 active_irqs &= ~LINE_FLAG_INTR;
1755 ret = IRQ_HANDLED;
1756 }
1757
1758 if (active_irqs & FS_INTR) {
1759 drm_crtc_handle_vblank(crtc);
1760 vop_handle_vblank(vop);
1761 active_irqs &= ~FS_INTR;
1762 ret = IRQ_HANDLED;
1763 }
1764
1765
1766 if (active_irqs)
1767 DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n",
1768 active_irqs);
1769
1770 out_disable:
1771 vop_core_clks_disable(vop);
1772 out:
1773 pm_runtime_put(vop->dev);
1774 return ret;
1775 }
1776
1777 static void vop_plane_add_properties(struct drm_plane *plane,
1778 const struct vop_win_data *win_data)
1779 {
1780 unsigned int flags = 0;
1781
1782 flags |= VOP_WIN_HAS_REG(win_data, x_mir_en) ? DRM_MODE_REFLECT_X : 0;
1783 flags |= VOP_WIN_HAS_REG(win_data, y_mir_en) ? DRM_MODE_REFLECT_Y : 0;
1784 if (flags)
1785 drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
1786 DRM_MODE_ROTATE_0 | flags);
1787 }
1788
1789 static int vop_create_crtc(struct vop *vop)
1790 {
1791 const struct vop_data *vop_data = vop->data;
1792 struct device *dev = vop->dev;
1793 struct drm_device *drm_dev = vop->drm_dev;
1794 struct drm_plane *primary = NULL, *cursor = NULL, *plane, *tmp;
1795 struct drm_crtc *crtc = &vop->crtc;
1796 struct device_node *port;
1797 int ret;
1798 int i;
1799
1800
1801
1802
1803
1804
1805 for (i = 0; i < vop_data->win_size; i++) {
1806 struct vop_win *vop_win = &vop->win[i];
1807 const struct vop_win_data *win_data = vop_win->data;
1808
1809 if (win_data->type != DRM_PLANE_TYPE_PRIMARY &&
1810 win_data->type != DRM_PLANE_TYPE_CURSOR)
1811 continue;
1812
1813 ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
1814 0, &vop_plane_funcs,
1815 win_data->phy->data_formats,
1816 win_data->phy->nformats,
1817 win_data->phy->format_modifiers,
1818 win_data->type, NULL);
1819 if (ret) {
1820 DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
1821 ret);
1822 goto err_cleanup_planes;
1823 }
1824
1825 plane = &vop_win->base;
1826 drm_plane_helper_add(plane, &plane_helper_funcs);
1827 vop_plane_add_properties(plane, win_data);
1828 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
1829 primary = plane;
1830 else if (plane->type == DRM_PLANE_TYPE_CURSOR)
1831 cursor = plane;
1832 }
1833
1834 ret = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,
1835 &vop_crtc_funcs, NULL);
1836 if (ret)
1837 goto err_cleanup_planes;
1838
1839 drm_crtc_helper_add(crtc, &vop_crtc_helper_funcs);
1840 if (vop->lut_regs) {
1841 drm_mode_crtc_set_gamma_size(crtc, vop_data->lut_size);
1842 drm_crtc_enable_color_mgmt(crtc, 0, false, vop_data->lut_size);
1843 }
1844
1845
1846
1847
1848
1849 for (i = 0; i < vop_data->win_size; i++) {
1850 struct vop_win *vop_win = &vop->win[i];
1851 const struct vop_win_data *win_data = vop_win->data;
1852 unsigned long possible_crtcs = drm_crtc_mask(crtc);
1853
1854 if (win_data->type != DRM_PLANE_TYPE_OVERLAY)
1855 continue;
1856
1857 ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
1858 possible_crtcs,
1859 &vop_plane_funcs,
1860 win_data->phy->data_formats,
1861 win_data->phy->nformats,
1862 win_data->phy->format_modifiers,
1863 win_data->type, NULL);
1864 if (ret) {
1865 DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
1866 ret);
1867 goto err_cleanup_crtc;
1868 }
1869 drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
1870 vop_plane_add_properties(&vop_win->base, win_data);
1871 }
1872
1873 port = of_get_child_by_name(dev->of_node, "port");
1874 if (!port) {
1875 DRM_DEV_ERROR(vop->dev, "no port node found in %pOF\n",
1876 dev->of_node);
1877 ret = -ENOENT;
1878 goto err_cleanup_crtc;
1879 }
1880
1881 drm_flip_work_init(&vop->fb_unref_work, "fb_unref",
1882 vop_fb_unref_worker);
1883
1884 init_completion(&vop->dsp_hold_completion);
1885 init_completion(&vop->line_flag_completion);
1886 crtc->port = port;
1887
1888 ret = drm_self_refresh_helper_init(crtc);
1889 if (ret)
1890 DRM_DEV_DEBUG_KMS(vop->dev,
1891 "Failed to init %s with SR helpers %d, ignoring\n",
1892 crtc->name, ret);
1893
1894 return 0;
1895
1896 err_cleanup_crtc:
1897 drm_crtc_cleanup(crtc);
1898 err_cleanup_planes:
1899 list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
1900 head)
1901 drm_plane_cleanup(plane);
1902 return ret;
1903 }
1904
1905 static void vop_destroy_crtc(struct vop *vop)
1906 {
1907 struct drm_crtc *crtc = &vop->crtc;
1908 struct drm_device *drm_dev = vop->drm_dev;
1909 struct drm_plane *plane, *tmp;
1910
1911 drm_self_refresh_helper_cleanup(crtc);
1912
1913 of_node_put(crtc->port);
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923 list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list,
1924 head)
1925 vop_plane_destroy(plane);
1926
1927
1928
1929
1930
1931 drm_crtc_cleanup(crtc);
1932 drm_flip_work_cleanup(&vop->fb_unref_work);
1933 }
1934
1935 static int vop_initial(struct vop *vop)
1936 {
1937 struct reset_control *ahb_rst;
1938 int i, ret;
1939
1940 vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
1941 if (IS_ERR(vop->hclk)) {
1942 DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n");
1943 return PTR_ERR(vop->hclk);
1944 }
1945 vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
1946 if (IS_ERR(vop->aclk)) {
1947 DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n");
1948 return PTR_ERR(vop->aclk);
1949 }
1950 vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
1951 if (IS_ERR(vop->dclk)) {
1952 DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n");
1953 return PTR_ERR(vop->dclk);
1954 }
1955
1956 ret = pm_runtime_get_sync(vop->dev);
1957 if (ret < 0) {
1958 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
1959 return ret;
1960 }
1961
1962 ret = clk_prepare(vop->dclk);
1963 if (ret < 0) {
1964 DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n");
1965 goto err_put_pm_runtime;
1966 }
1967
1968
1969 ret = clk_prepare_enable(vop->hclk);
1970 if (ret < 0) {
1971 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n");
1972 goto err_unprepare_dclk;
1973 }
1974
1975 ret = clk_prepare_enable(vop->aclk);
1976 if (ret < 0) {
1977 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n");
1978 goto err_disable_hclk;
1979 }
1980
1981
1982
1983
1984 ahb_rst = devm_reset_control_get(vop->dev, "ahb");
1985 if (IS_ERR(ahb_rst)) {
1986 DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n");
1987 ret = PTR_ERR(ahb_rst);
1988 goto err_disable_aclk;
1989 }
1990 reset_control_assert(ahb_rst);
1991 usleep_range(10, 20);
1992 reset_control_deassert(ahb_rst);
1993
1994 VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
1995 VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);
1996
1997 for (i = 0; i < vop->len; i += sizeof(u32))
1998 vop->regsbak[i / 4] = readl_relaxed(vop->regs + i);
1999
2000 VOP_REG_SET(vop, misc, global_regdone_en, 1);
2001 VOP_REG_SET(vop, common, dsp_blank, 0);
2002
2003 for (i = 0; i < vop->data->win_size; i++) {
2004 struct vop_win *vop_win = &vop->win[i];
2005 const struct vop_win_data *win = vop_win->data;
2006 int channel = i * 2 + 1;
2007
2008 VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
2009 vop_win_disable(vop, vop_win);
2010 VOP_WIN_SET(vop, win, gate, 1);
2011 }
2012
2013 vop_cfg_done(vop);
2014
2015
2016
2017
2018 vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk");
2019 if (IS_ERR(vop->dclk_rst)) {
2020 DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n");
2021 ret = PTR_ERR(vop->dclk_rst);
2022 goto err_disable_aclk;
2023 }
2024 reset_control_assert(vop->dclk_rst);
2025 usleep_range(10, 20);
2026 reset_control_deassert(vop->dclk_rst);
2027
2028 clk_disable(vop->hclk);
2029 clk_disable(vop->aclk);
2030
2031 vop->is_enabled = false;
2032
2033 pm_runtime_put_sync(vop->dev);
2034
2035 return 0;
2036
2037 err_disable_aclk:
2038 clk_disable_unprepare(vop->aclk);
2039 err_disable_hclk:
2040 clk_disable_unprepare(vop->hclk);
2041 err_unprepare_dclk:
2042 clk_unprepare(vop->dclk);
2043 err_put_pm_runtime:
2044 pm_runtime_put_sync(vop->dev);
2045 return ret;
2046 }
2047
2048
2049
2050
2051 static void vop_win_init(struct vop *vop)
2052 {
2053 const struct vop_data *vop_data = vop->data;
2054 unsigned int i;
2055
2056 for (i = 0; i < vop_data->win_size; i++) {
2057 struct vop_win *vop_win = &vop->win[i];
2058 const struct vop_win_data *win_data = &vop_data->win[i];
2059
2060 vop_win->data = win_data;
2061 vop_win->vop = vop;
2062
2063 if (vop_data->win_yuv2yuv)
2064 vop_win->yuv2yuv_data = &vop_data->win_yuv2yuv[i];
2065 }
2066 }
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078 int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
2079 {
2080 struct vop *vop = to_vop(crtc);
2081 unsigned long jiffies_left;
2082 int ret = 0;
2083
2084 if (!crtc || !vop->is_enabled)
2085 return -ENODEV;
2086
2087 mutex_lock(&vop->vop_lock);
2088 if (mstimeout <= 0) {
2089 ret = -EINVAL;
2090 goto out;
2091 }
2092
2093 if (vop_line_flag_irq_is_enabled(vop)) {
2094 ret = -EBUSY;
2095 goto out;
2096 }
2097
2098 reinit_completion(&vop->line_flag_completion);
2099 vop_line_flag_irq_enable(vop);
2100
2101 jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
2102 msecs_to_jiffies(mstimeout));
2103 vop_line_flag_irq_disable(vop);
2104
2105 if (jiffies_left == 0) {
2106 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
2107 ret = -ETIMEDOUT;
2108 goto out;
2109 }
2110
2111 out:
2112 mutex_unlock(&vop->vop_lock);
2113 return ret;
2114 }
2115 EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
2116
2117 static int vop_bind(struct device *dev, struct device *master, void *data)
2118 {
2119 struct platform_device *pdev = to_platform_device(dev);
2120 const struct vop_data *vop_data;
2121 struct drm_device *drm_dev = data;
2122 struct vop *vop;
2123 struct resource *res;
2124 int ret, irq;
2125
2126 vop_data = of_device_get_match_data(dev);
2127 if (!vop_data)
2128 return -ENODEV;
2129
2130
2131 vop = devm_kzalloc(dev, struct_size(vop, win, vop_data->win_size),
2132 GFP_KERNEL);
2133 if (!vop)
2134 return -ENOMEM;
2135
2136 vop->dev = dev;
2137 vop->data = vop_data;
2138 vop->drm_dev = drm_dev;
2139 dev_set_drvdata(dev, vop);
2140
2141 vop_win_init(vop);
2142
2143 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2144 vop->regs = devm_ioremap_resource(dev, res);
2145 if (IS_ERR(vop->regs))
2146 return PTR_ERR(vop->regs);
2147 vop->len = resource_size(res);
2148
2149 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2150 if (res) {
2151 if (!vop_data->lut_size) {
2152 DRM_DEV_ERROR(dev, "no gamma LUT size defined\n");
2153 return -EINVAL;
2154 }
2155 vop->lut_regs = devm_ioremap_resource(dev, res);
2156 if (IS_ERR(vop->lut_regs))
2157 return PTR_ERR(vop->lut_regs);
2158 }
2159
2160 vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
2161 if (!vop->regsbak)
2162 return -ENOMEM;
2163
2164 irq = platform_get_irq(pdev, 0);
2165 if (irq < 0) {
2166 DRM_DEV_ERROR(dev, "cannot find irq for vop\n");
2167 return irq;
2168 }
2169 vop->irq = (unsigned int)irq;
2170
2171 spin_lock_init(&vop->reg_lock);
2172 spin_lock_init(&vop->irq_lock);
2173 mutex_init(&vop->vop_lock);
2174
2175 ret = vop_create_crtc(vop);
2176 if (ret)
2177 return ret;
2178
2179 pm_runtime_enable(&pdev->dev);
2180
2181 ret = vop_initial(vop);
2182 if (ret < 0) {
2183 DRM_DEV_ERROR(&pdev->dev,
2184 "cannot initial vop dev - err %d\n", ret);
2185 goto err_disable_pm_runtime;
2186 }
2187
2188 ret = devm_request_irq(dev, vop->irq, vop_isr,
2189 IRQF_SHARED, dev_name(dev), vop);
2190 if (ret)
2191 goto err_disable_pm_runtime;
2192
2193 if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) {
2194 vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev);
2195 if (IS_ERR(vop->rgb)) {
2196 ret = PTR_ERR(vop->rgb);
2197 goto err_disable_pm_runtime;
2198 }
2199 }
2200
2201 rockchip_drm_dma_init_device(drm_dev, dev);
2202
2203 return 0;
2204
2205 err_disable_pm_runtime:
2206 pm_runtime_disable(&pdev->dev);
2207 vop_destroy_crtc(vop);
2208 return ret;
2209 }
2210
2211 static void vop_unbind(struct device *dev, struct device *master, void *data)
2212 {
2213 struct vop *vop = dev_get_drvdata(dev);
2214
2215 if (vop->rgb)
2216 rockchip_rgb_fini(vop->rgb);
2217
2218 pm_runtime_disable(dev);
2219 vop_destroy_crtc(vop);
2220
2221 clk_unprepare(vop->aclk);
2222 clk_unprepare(vop->hclk);
2223 clk_unprepare(vop->dclk);
2224 }
2225
2226 const struct component_ops vop_component_ops = {
2227 .bind = vop_bind,
2228 .unbind = vop_unbind,
2229 };
2230 EXPORT_SYMBOL_GPL(vop_component_ops);