Lines Matching full:vop
44 #define VOP_WIN_SET(vop, win, name, v) \ argument
45 vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
46 #define VOP_SCL_SET(vop, win, name, v) \ argument
47 vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
48 #define VOP_SCL_SET_EXT(vop, win, name, v) \ argument
49 vop_reg_set(vop, &win->phy->scl->ext->name, \
52 #define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \ argument
55 vop_reg_set(vop, &win_yuv2yuv->name, 0, ~0, v, #name); \
58 #define VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, win_yuv2yuv, name, v) \ argument
61 vop_reg_set(vop, &win_yuv2yuv->phy->name, win_yuv2yuv->base, ~0, v, #name); \
64 #define VOP_INTR_SET_MASK(vop, name, mask, v) \ argument
65 vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
67 #define VOP_REG_SET(vop, group, name, v) \ argument
68 vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
70 #define VOP_HAS_REG(vop, group, name) \ argument
71 (!!(vop->data->group->name.mask))
73 #define VOP_INTR_SET_TYPE(vop, name, type, v) \ argument
76 for (i = 0; i < vop->data->intr->nintrs; i++) { \
77 if (vop->data->intr->intrs[i] & type) { \
82 VOP_INTR_SET_MASK(vop, name, mask, reg); \
84 #define VOP_INTR_GET_TYPE(vop, name, type) \ argument
85 vop_get_intr_type(vop, &vop->data->intr->name, type)
87 #define VOP_WIN_GET(vop, win, name) \ argument
88 vop_read_reg(vop, win->base, &win->phy->name)
93 #define VOP_WIN_GET_YRGBADDR(vop, win) \ argument
94 vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
97 ((vop_win) - (vop_win)->vop->win)
99 #define VOP_AFBC_SET(vop, name, v) \ argument
101 if ((vop)->data->afbc) \
102 vop_reg_set((vop), &(vop)->data->afbc->name, \
106 #define to_vop(x) container_of(x, struct vop, crtc)
135 struct vop *vop; member
139 struct vop { struct
162 /* physical map length of vop register */ argument
167 /* lock vop irq reg */ argument
174 /* vop AHP clk */ argument
176 /* vop dclk */ argument
178 /* vop share memory frequency */ argument
181 /* vop dclk reset */ argument
190 static inline uint32_t vop_readl(struct vop *vop, uint32_t offset) in vop_readl() argument
192 return readl(vop->regs + offset); in vop_readl()
195 static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base, in vop_read_reg() argument
198 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask; in vop_read_reg()
201 static void vop_reg_set(struct vop *vop, const struct vop_reg *reg, in vop_reg_set() argument
208 DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name); in vop_reg_set()
219 uint32_t cached_val = vop->regsbak[offset >> 2]; in vop_reg_set()
222 vop->regsbak[offset >> 2] = v; in vop_reg_set()
226 writel_relaxed(v, vop->regs + offset); in vop_reg_set()
228 writel(v, vop->regs + offset); in vop_reg_set()
231 static inline uint32_t vop_get_intr_type(struct vop *vop, in vop_get_intr_type() argument
235 uint32_t regs = vop_read_reg(vop, 0, reg); in vop_get_intr_type()
237 for (i = 0; i < vop->data->intr->nintrs; i++) { in vop_get_intr_type()
238 if ((type & vop->data->intr->intrs[i]) && (regs & 1 << i)) in vop_get_intr_type()
239 ret |= vop->data->intr->intrs[i]; in vop_get_intr_type()
245 static inline void vop_cfg_done(struct vop *vop) in vop_cfg_done() argument
247 VOP_REG_SET(vop, common, cfg_done, 1); in vop_cfg_done()
260 * check for 3.x to also only rb swap BGR888 for unknown vop version in has_rb_swapped()
381 static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win, in scl_vop_cal_scl_fac() argument
400 DRM_DEV_ERROR(vop->dev, "Maximum dst width (4096) exceeded\n"); in scl_vop_cal_scl_fac()
405 VOP_SCL_SET(vop, win, scale_yrgb_x, in scl_vop_cal_scl_fac()
407 VOP_SCL_SET(vop, win, scale_yrgb_y, in scl_vop_cal_scl_fac()
410 VOP_SCL_SET(vop, win, scale_cbcr_x, in scl_vop_cal_scl_fac()
412 VOP_SCL_SET(vop, win, scale_cbcr_y, in scl_vop_cal_scl_fac()
435 VOP_SCL_SET_EXT(vop, win, lb_mode, lb_mode); in scl_vop_cal_scl_fac()
438 DRM_DEV_ERROR(vop->dev, "not allow yrgb ver scale\n"); in scl_vop_cal_scl_fac()
442 DRM_DEV_ERROR(vop->dev, "not allow cbcr ver scale\n"); in scl_vop_cal_scl_fac()
454 VOP_SCL_SET(vop, win, scale_yrgb_x, val); in scl_vop_cal_scl_fac()
457 VOP_SCL_SET(vop, win, scale_yrgb_y, val); in scl_vop_cal_scl_fac()
459 VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt4, vskiplines == 4); in scl_vop_cal_scl_fac()
460 VOP_SCL_SET_EXT(vop, win, vsd_yrgb_gt2, vskiplines == 2); in scl_vop_cal_scl_fac()
462 VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, yrgb_hor_scl_mode); in scl_vop_cal_scl_fac()
463 VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, yrgb_ver_scl_mode); in scl_vop_cal_scl_fac()
464 VOP_SCL_SET_EXT(vop, win, yrgb_hsd_mode, SCALE_DOWN_BIL); in scl_vop_cal_scl_fac()
465 VOP_SCL_SET_EXT(vop, win, yrgb_vsd_mode, SCALE_DOWN_BIL); in scl_vop_cal_scl_fac()
466 VOP_SCL_SET_EXT(vop, win, yrgb_vsu_mode, vsu_mode); in scl_vop_cal_scl_fac()
470 VOP_SCL_SET(vop, win, scale_cbcr_x, val); in scl_vop_cal_scl_fac()
473 VOP_SCL_SET(vop, win, scale_cbcr_y, val); in scl_vop_cal_scl_fac()
475 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt4, vskiplines == 4); in scl_vop_cal_scl_fac()
476 VOP_SCL_SET_EXT(vop, win, vsd_cbcr_gt2, vskiplines == 2); in scl_vop_cal_scl_fac()
477 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, cbcr_hor_scl_mode); in scl_vop_cal_scl_fac()
478 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, cbcr_ver_scl_mode); in scl_vop_cal_scl_fac()
479 VOP_SCL_SET_EXT(vop, win, cbcr_hsd_mode, SCALE_DOWN_BIL); in scl_vop_cal_scl_fac()
480 VOP_SCL_SET_EXT(vop, win, cbcr_vsd_mode, SCALE_DOWN_BIL); in scl_vop_cal_scl_fac()
481 VOP_SCL_SET_EXT(vop, win, cbcr_vsu_mode, vsu_mode); in scl_vop_cal_scl_fac()
485 static void vop_dsp_hold_valid_irq_enable(struct vop *vop) in vop_dsp_hold_valid_irq_enable() argument
489 if (WARN_ON(!vop->is_enabled)) in vop_dsp_hold_valid_irq_enable()
492 spin_lock_irqsave(&vop->irq_lock, flags); in vop_dsp_hold_valid_irq_enable()
494 VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1); in vop_dsp_hold_valid_irq_enable()
495 VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1); in vop_dsp_hold_valid_irq_enable()
497 spin_unlock_irqrestore(&vop->irq_lock, flags); in vop_dsp_hold_valid_irq_enable()
500 static void vop_dsp_hold_valid_irq_disable(struct vop *vop) in vop_dsp_hold_valid_irq_disable() argument
504 if (WARN_ON(!vop->is_enabled)) in vop_dsp_hold_valid_irq_disable()
507 spin_lock_irqsave(&vop->irq_lock, flags); in vop_dsp_hold_valid_irq_disable()
509 VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0); in vop_dsp_hold_valid_irq_disable()
511 spin_unlock_irqrestore(&vop->irq_lock, flags); in vop_dsp_hold_valid_irq_disable()
536 static bool vop_line_flag_irq_is_enabled(struct vop *vop) in vop_line_flag_irq_is_enabled() argument
541 spin_lock_irqsave(&vop->irq_lock, flags); in vop_line_flag_irq_is_enabled()
543 line_flag_irq = VOP_INTR_GET_TYPE(vop, enable, LINE_FLAG_INTR); in vop_line_flag_irq_is_enabled()
545 spin_unlock_irqrestore(&vop->irq_lock, flags); in vop_line_flag_irq_is_enabled()
550 static void vop_line_flag_irq_enable(struct vop *vop) in vop_line_flag_irq_enable() argument
554 if (WARN_ON(!vop->is_enabled)) in vop_line_flag_irq_enable()
557 spin_lock_irqsave(&vop->irq_lock, flags); in vop_line_flag_irq_enable()
559 VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1); in vop_line_flag_irq_enable()
560 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1); in vop_line_flag_irq_enable()
562 spin_unlock_irqrestore(&vop->irq_lock, flags); in vop_line_flag_irq_enable()
565 static void vop_line_flag_irq_disable(struct vop *vop) in vop_line_flag_irq_disable() argument
569 if (WARN_ON(!vop->is_enabled)) in vop_line_flag_irq_disable()
572 spin_lock_irqsave(&vop->irq_lock, flags); in vop_line_flag_irq_disable()
574 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 0); in vop_line_flag_irq_disable()
576 spin_unlock_irqrestore(&vop->irq_lock, flags); in vop_line_flag_irq_disable()
579 static int vop_core_clks_enable(struct vop *vop) in vop_core_clks_enable() argument
583 ret = clk_enable(vop->hclk); in vop_core_clks_enable()
587 ret = clk_enable(vop->aclk); in vop_core_clks_enable()
594 clk_disable(vop->hclk); in vop_core_clks_enable()
598 static void vop_core_clks_disable(struct vop *vop) in vop_core_clks_disable() argument
600 clk_disable(vop->aclk); in vop_core_clks_disable()
601 clk_disable(vop->hclk); in vop_core_clks_disable()
604 static void vop_win_disable(struct vop *vop, const struct vop_win *vop_win) in vop_win_disable() argument
609 VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE); in vop_win_disable()
610 VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE); in vop_win_disable()
611 VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE); in vop_win_disable()
612 VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE); in vop_win_disable()
615 VOP_WIN_SET(vop, win, enable, 0); in vop_win_disable()
616 vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win)); in vop_win_disable()
621 struct vop *vop = to_vop(crtc); in vop_enable() local
624 ret = pm_runtime_resume_and_get(vop->dev); in vop_enable()
626 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret); in vop_enable()
630 ret = vop_core_clks_enable(vop); in vop_enable()
634 ret = clk_enable(vop->dclk); in vop_enable()
639 * Slave iommu shares power, irq and clock with vop. It was associated in vop_enable()
644 ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev); in vop_enable()
646 DRM_DEV_ERROR(vop->dev, in vop_enable()
651 spin_lock(&vop->reg_lock); in vop_enable()
652 for (i = 0; i < vop->len; i += 4) in vop_enable()
653 writel_relaxed(vop->regsbak[i / 4], vop->regs + i); in vop_enable()
665 for (i = 0; i < vop->data->win_size; i++) { in vop_enable()
666 struct vop_win *vop_win = &vop->win[i]; in vop_enable()
668 vop_win_disable(vop, vop_win); in vop_enable()
672 if (vop->data->afbc) { in vop_enable()
675 * Disable AFBC and forget there was a vop window with AFBC in vop_enable()
677 VOP_AFBC_SET(vop, enable, 0); in vop_enable()
682 vop_cfg_done(vop); in vop_enable()
684 spin_unlock(&vop->reg_lock); in vop_enable()
687 * At here, vop clock & iommu is enable, R/W vop regs would be safe. in vop_enable()
689 vop->is_enabled = true; in vop_enable()
691 spin_lock(&vop->reg_lock); in vop_enable()
693 VOP_REG_SET(vop, common, standby, 1); in vop_enable()
695 spin_unlock(&vop->reg_lock); in vop_enable()
702 clk_disable(vop->dclk); in vop_enable()
704 vop_core_clks_disable(vop); in vop_enable()
706 pm_runtime_put_sync(vop->dev); in vop_enable()
712 struct vop *vop = to_vop(crtc); in rockchip_drm_set_win_enabled() local
715 spin_lock(&vop->reg_lock); in rockchip_drm_set_win_enabled()
717 for (i = 0; i < vop->data->win_size; i++) { in rockchip_drm_set_win_enabled()
718 struct vop_win *vop_win = &vop->win[i]; in rockchip_drm_set_win_enabled()
721 VOP_WIN_SET(vop, win, enable, in rockchip_drm_set_win_enabled()
722 enabled && (vop->win_enabled & BIT(i))); in rockchip_drm_set_win_enabled()
724 vop_cfg_done(vop); in rockchip_drm_set_win_enabled()
726 spin_unlock(&vop->reg_lock); in rockchip_drm_set_win_enabled()
732 struct vop *vop = to_vop(crtc); in vop_crtc_atomic_disable() local
734 WARN_ON(vop->event); in vop_crtc_atomic_disable()
742 mutex_lock(&vop->vop_lock); in vop_crtc_atomic_disable()
747 * Vop standby will take effect at end of current frame, in vop_crtc_atomic_disable()
753 reinit_completion(&vop->dsp_hold_completion); in vop_crtc_atomic_disable()
754 vop_dsp_hold_valid_irq_enable(vop); in vop_crtc_atomic_disable()
756 spin_lock(&vop->reg_lock); in vop_crtc_atomic_disable()
758 VOP_REG_SET(vop, common, standby, 1); in vop_crtc_atomic_disable()
760 spin_unlock(&vop->reg_lock); in vop_crtc_atomic_disable()
762 if (!wait_for_completion_timeout(&vop->dsp_hold_completion, in vop_crtc_atomic_disable()
766 vop_dsp_hold_valid_irq_disable(vop); in vop_crtc_atomic_disable()
768 vop->is_enabled = false; in vop_crtc_atomic_disable()
771 * vop standby complete, so iommu detach is safe. in vop_crtc_atomic_disable()
773 rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev); in vop_crtc_atomic_disable()
775 clk_disable(vop->dclk); in vop_crtc_atomic_disable()
776 vop_core_clks_disable(vop); in vop_crtc_atomic_disable()
777 pm_runtime_put(vop->dev); in vop_crtc_atomic_disable()
779 mutex_unlock(&vop->vop_lock); in vop_crtc_atomic_disable()
863 struct vop *vop = to_vop(crtc); in vop_plane_atomic_check() local
865 if (!vop->data->afbc) { in vop_plane_atomic_check()
866 DRM_DEBUG_KMS("vop does not support AFBC\n"); in vop_plane_atomic_check()
898 struct vop *vop = to_vop(old_state->crtc); in vop_plane_atomic_disable() local
903 spin_lock(&vop->reg_lock); in vop_plane_atomic_disable()
905 vop_win_disable(vop, vop_win); in vop_plane_atomic_disable()
907 spin_unlock(&vop->reg_lock); in vop_plane_atomic_disable()
919 struct vop *vop = to_vop(new_state->crtc); in vop_plane_atomic_update() local
938 * can't update plane when vop is disabled. in vop_plane_atomic_update()
943 if (WARN_ON(!vop->is_enabled)) in vop_plane_atomic_update()
983 spin_lock(&vop->reg_lock); in vop_plane_atomic_update()
988 VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16); in vop_plane_atomic_update()
989 VOP_AFBC_SET(vop, hreg_block_split, 0); in vop_plane_atomic_update()
990 VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win)); in vop_plane_atomic_update()
991 VOP_AFBC_SET(vop, hdr_ptr, dma_addr); in vop_plane_atomic_update()
992 VOP_AFBC_SET(vop, pic_size, act_info); in vop_plane_atomic_update()
995 VOP_WIN_SET(vop, win, format, format); in vop_plane_atomic_update()
996 VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format)); in vop_plane_atomic_update()
997 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4)); in vop_plane_atomic_update()
998 VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); in vop_plane_atomic_update()
999 VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); in vop_plane_atomic_update()
1000 VOP_WIN_SET(vop, win, y_mir_en, in vop_plane_atomic_update()
1002 VOP_WIN_SET(vop, win, x_mir_en, in vop_plane_atomic_update()
1018 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); in vop_plane_atomic_update()
1019 VOP_WIN_SET(vop, win, uv_mst, dma_addr); in vop_plane_atomic_update()
1022 VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, in vop_plane_atomic_update()
1029 VOP_WIN_SET(vop, win, uv_swap, uv_swap); in vop_plane_atomic_update()
1033 scl_vop_cal_scl_fac(vop, win, actual_w, actual_h, in vop_plane_atomic_update()
1037 VOP_WIN_SET(vop, win, act_info, act_info); in vop_plane_atomic_update()
1038 VOP_WIN_SET(vop, win, dsp_info, dsp_info); in vop_plane_atomic_update()
1039 VOP_WIN_SET(vop, win, dsp_st, dsp_st); in vop_plane_atomic_update()
1041 rb_swap = has_rb_swapped(vop->data->version, fb->format->format); in vop_plane_atomic_update()
1042 VOP_WIN_SET(vop, win, rb_swap, rb_swap); in vop_plane_atomic_update()
1052 VOP_WIN_SET(vop, win, dst_alpha_ctl, in vop_plane_atomic_update()
1059 VOP_WIN_SET(vop, win, src_alpha_ctl, val); in vop_plane_atomic_update()
1061 VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL); in vop_plane_atomic_update()
1062 VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX); in vop_plane_atomic_update()
1063 VOP_WIN_SET(vop, win, alpha_en, 1); in vop_plane_atomic_update()
1065 VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0)); in vop_plane_atomic_update()
1066 VOP_WIN_SET(vop, win, alpha_en, 0); in vop_plane_atomic_update()
1069 VOP_WIN_SET(vop, win, enable, 1); in vop_plane_atomic_update()
1070 vop->win_enabled |= BIT(win_index); in vop_plane_atomic_update()
1071 spin_unlock(&vop->reg_lock); in vop_plane_atomic_update()
1112 struct vop *vop = to_vop(plane->state->crtc); in vop_plane_atomic_async_update() local
1125 if (vop->is_enabled) { in vop_plane_atomic_async_update()
1127 spin_lock(&vop->reg_lock); in vop_plane_atomic_async_update()
1128 vop_cfg_done(vop); in vop_plane_atomic_async_update()
1129 spin_unlock(&vop->reg_lock); in vop_plane_atomic_async_update()
1142 drm_flip_work_queue(&vop->fb_unref_work, old_fb); in vop_plane_atomic_async_update()
1143 set_bit(VOP_PENDING_FB_UNREF, &vop->pending); in vop_plane_atomic_async_update()
1168 struct vop *vop = to_vop(crtc); in vop_crtc_enable_vblank() local
1171 if (WARN_ON(!vop->is_enabled)) in vop_crtc_enable_vblank()
1174 spin_lock_irqsave(&vop->irq_lock, flags); in vop_crtc_enable_vblank()
1176 VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1); in vop_crtc_enable_vblank()
1177 VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1); in vop_crtc_enable_vblank()
1179 spin_unlock_irqrestore(&vop->irq_lock, flags); in vop_crtc_enable_vblank()
1186 struct vop *vop = to_vop(crtc); in vop_crtc_disable_vblank() local
1189 if (WARN_ON(!vop->is_enabled)) in vop_crtc_disable_vblank()
1192 spin_lock_irqsave(&vop->irq_lock, flags); in vop_crtc_disable_vblank()
1194 VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0); in vop_crtc_disable_vblank()
1196 spin_unlock_irqrestore(&vop->irq_lock, flags); in vop_crtc_disable_vblank()
1202 struct vop *vop = to_vop(crtc); in vop_crtc_mode_valid() local
1204 if (vop->data->max_output.width && mode->hdisplay > vop->data->max_output.width) in vop_crtc_mode_valid()
1214 struct vop *vop = to_vop(crtc); in vop_crtc_mode_fixup() local
1243 rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000); in vop_crtc_mode_fixup()
1245 rate = clk_round_rate(vop->dclk, in vop_crtc_mode_fixup()
1252 static bool vop_dsp_lut_is_enabled(struct vop *vop) in vop_dsp_lut_is_enabled() argument
1254 return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en); in vop_dsp_lut_is_enabled()
1257 static u32 vop_lut_buffer_index(struct vop *vop) in vop_lut_buffer_index() argument
1259 return vop_read_reg(vop, 0, &vop->data->common->lut_buffer_index); in vop_lut_buffer_index()
1262 static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc) in vop_crtc_write_gamma_lut() argument
1265 unsigned int i, bpc = ilog2(vop->data->lut_size); in vop_crtc_write_gamma_lut()
1273 writel(word, vop->lut_regs + i * 4); in vop_crtc_write_gamma_lut()
1277 static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc, in vop_crtc_gamma_set() argument
1285 if (!vop->lut_regs) in vop_crtc_gamma_set()
1288 if (!state->gamma_lut || !VOP_HAS_REG(vop, common, update_gamma_lut)) { in vop_crtc_gamma_set()
1293 spin_lock(&vop->reg_lock); in vop_crtc_gamma_set()
1294 VOP_REG_SET(vop, common, dsp_lut_en, 0); in vop_crtc_gamma_set()
1295 vop_cfg_done(vop); in vop_crtc_gamma_set()
1296 spin_unlock(&vop->reg_lock); in vop_crtc_gamma_set()
1302 ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop, in vop_crtc_gamma_set()
1305 DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n"); in vop_crtc_gamma_set()
1316 old_idx = vop_lut_buffer_index(vop); in vop_crtc_gamma_set()
1319 spin_lock(&vop->reg_lock); in vop_crtc_gamma_set()
1320 vop_crtc_write_gamma_lut(vop, crtc); in vop_crtc_gamma_set()
1321 VOP_REG_SET(vop, common, dsp_lut_en, 1); in vop_crtc_gamma_set()
1322 VOP_REG_SET(vop, common, update_gamma_lut, 1); in vop_crtc_gamma_set()
1323 vop_cfg_done(vop); in vop_crtc_gamma_set()
1324 spin_unlock(&vop->reg_lock); in vop_crtc_gamma_set()
1326 if (VOP_HAS_REG(vop, common, update_gamma_lut)) { in vop_crtc_gamma_set()
1327 ret = readx_poll_timeout(vop_lut_buffer_index, vop, in vop_crtc_gamma_set()
1330 DRM_DEV_ERROR(vop->dev, "gamma LUT update timeout!\n"); in vop_crtc_gamma_set()
1338 spin_lock(&vop->reg_lock); in vop_crtc_gamma_set()
1339 VOP_REG_SET(vop, common, update_gamma_lut, 0); in vop_crtc_gamma_set()
1340 spin_unlock(&vop->reg_lock); in vop_crtc_gamma_set()
1351 struct vop *vop = to_vop(crtc); in vop_crtc_atomic_begin() local
1359 vop_crtc_gamma_set(vop, crtc, old_crtc_state); in vop_crtc_atomic_begin()
1367 struct vop *vop = to_vop(crtc); in vop_crtc_atomic_enable() local
1368 const struct vop_data *vop_data = vop->data; in vop_crtc_atomic_enable()
1391 mutex_lock(&vop->vop_lock); in vop_crtc_atomic_enable()
1393 WARN_ON(vop->event); in vop_crtc_atomic_enable()
1397 mutex_unlock(&vop->vop_lock); in vop_crtc_atomic_enable()
1398 DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret); in vop_crtc_atomic_enable()
1405 VOP_REG_SET(vop, output, pin_pol, pin_pol); in vop_crtc_atomic_enable()
1406 VOP_REG_SET(vop, output, mipi_dual_channel_en, 0); in vop_crtc_atomic_enable()
1410 VOP_REG_SET(vop, output, rgb_dclk_pol, 1); in vop_crtc_atomic_enable()
1411 VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol); in vop_crtc_atomic_enable()
1412 VOP_REG_SET(vop, output, rgb_en, 1); in vop_crtc_atomic_enable()
1415 VOP_REG_SET(vop, output, edp_dclk_pol, 1); in vop_crtc_atomic_enable()
1416 VOP_REG_SET(vop, output, edp_pin_pol, pin_pol); in vop_crtc_atomic_enable()
1417 VOP_REG_SET(vop, output, edp_en, 1); in vop_crtc_atomic_enable()
1420 VOP_REG_SET(vop, output, hdmi_dclk_pol, 1); in vop_crtc_atomic_enable()
1421 VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol); in vop_crtc_atomic_enable()
1422 VOP_REG_SET(vop, output, hdmi_en, 1); in vop_crtc_atomic_enable()
1425 VOP_REG_SET(vop, output, mipi_dclk_pol, 1); in vop_crtc_atomic_enable()
1426 VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol); in vop_crtc_atomic_enable()
1427 VOP_REG_SET(vop, output, mipi_en, 1); in vop_crtc_atomic_enable()
1428 VOP_REG_SET(vop, output, mipi_dual_channel_en, in vop_crtc_atomic_enable()
1432 VOP_REG_SET(vop, output, dp_dclk_pol, 0); in vop_crtc_atomic_enable()
1433 VOP_REG_SET(vop, output, dp_pin_pol, pin_pol); in vop_crtc_atomic_enable()
1434 VOP_REG_SET(vop, output, dp_en, 1); in vop_crtc_atomic_enable()
1437 DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n", in vop_crtc_atomic_enable()
1442 * if vop is not support RGB10 output, need force RGB10 to RGB888. in vop_crtc_atomic_enable()
1449 VOP_REG_SET(vop, common, pre_dither_down, 1); in vop_crtc_atomic_enable()
1451 VOP_REG_SET(vop, common, pre_dither_down, 0); in vop_crtc_atomic_enable()
1454 VOP_REG_SET(vop, common, dither_down_sel, DITHER_DOWN_ALLEGRO); in vop_crtc_atomic_enable()
1455 VOP_REG_SET(vop, common, dither_down_mode, RGB888_TO_RGB666); in vop_crtc_atomic_enable()
1456 VOP_REG_SET(vop, common, dither_down_en, 1); in vop_crtc_atomic_enable()
1458 VOP_REG_SET(vop, common, dither_down_en, 0); in vop_crtc_atomic_enable()
1461 VOP_REG_SET(vop, common, out_mode, s->output_mode); in vop_crtc_atomic_enable()
1463 VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len); in vop_crtc_atomic_enable()
1466 VOP_REG_SET(vop, modeset, hact_st_end, val); in vop_crtc_atomic_enable()
1467 VOP_REG_SET(vop, modeset, hpost_st_end, val); in vop_crtc_atomic_enable()
1469 VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len); in vop_crtc_atomic_enable()
1472 VOP_REG_SET(vop, modeset, vact_st_end, val); in vop_crtc_atomic_enable()
1473 VOP_REG_SET(vop, modeset, vpost_st_end, val); in vop_crtc_atomic_enable()
1475 VOP_REG_SET(vop, intr, line_flag_num[0], vact_end); in vop_crtc_atomic_enable()
1477 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); in vop_crtc_atomic_enable()
1479 VOP_REG_SET(vop, common, standby, 0); in vop_crtc_atomic_enable()
1480 mutex_unlock(&vop->vop_lock); in vop_crtc_atomic_enable()
1488 vop_crtc_gamma_set(vop, crtc, old_state); in vop_crtc_atomic_enable()
1491 static bool vop_fs_irq_is_pending(struct vop *vop) in vop_fs_irq_is_pending() argument
1493 return VOP_INTR_GET_TYPE(vop, status, FS_INTR); in vop_fs_irq_is_pending()
1496 static void vop_wait_for_irq_handler(struct vop *vop) in vop_wait_for_irq_handler() argument
1509 ret = readx_poll_timeout_atomic(vop_fs_irq_is_pending, vop, pending, in vop_wait_for_irq_handler()
1512 DRM_DEV_ERROR(vop->dev, "VOP vblank IRQ stuck for 10 ms\n"); in vop_wait_for_irq_handler()
1514 synchronize_irq(vop->irq); in vop_wait_for_irq_handler()
1522 struct vop *vop = to_vop(crtc); in vop_crtc_atomic_check() local
1528 if (vop->lut_regs && crtc_state->color_mgmt_changed && in vop_crtc_atomic_check()
1571 struct vop *vop = to_vop(crtc); in vop_crtc_atomic_flush() local
1576 if (WARN_ON(!vop->is_enabled)) in vop_crtc_atomic_flush()
1579 spin_lock(&vop->reg_lock); in vop_crtc_atomic_flush()
1583 VOP_AFBC_SET(vop, enable, s->enable_afbc); in vop_crtc_atomic_flush()
1584 vop_cfg_done(vop); in vop_crtc_atomic_flush()
1587 if (VOP_HAS_REG(vop, common, dma_stop)) in vop_crtc_atomic_flush()
1588 VOP_REG_SET(vop, common, dma_stop, 0); in vop_crtc_atomic_flush()
1590 spin_unlock(&vop->reg_lock); in vop_crtc_atomic_flush()
1597 vop_wait_for_irq_handler(vop); in vop_crtc_atomic_flush()
1602 WARN_ON(vop->event); in vop_crtc_atomic_flush()
1604 vop->event = crtc->state->event; in vop_crtc_atomic_flush()
1619 drm_flip_work_queue(&vop->fb_unref_work, old_plane_state->fb); in vop_crtc_atomic_flush()
1620 set_bit(VOP_PENDING_FB_UNREF, &vop->pending); in vop_crtc_atomic_flush()
1674 static struct drm_connector *vop_get_edp_connector(struct vop *vop) in vop_get_edp_connector() argument
1679 drm_connector_list_iter_begin(vop->drm_dev, &conn_iter); in vop_get_edp_connector()
1694 struct vop *vop = to_vop(crtc); in vop_crtc_set_crc_source() local
1698 connector = vop_get_edp_connector(vop); in vop_crtc_set_crc_source()
1753 struct vop *vop = container_of(work, struct vop, fb_unref_work); in vop_fb_unref_worker() local
1756 drm_crtc_vblank_put(&vop->crtc); in vop_fb_unref_worker()
1760 static void vop_handle_vblank(struct vop *vop) in vop_handle_vblank() argument
1762 struct drm_device *drm = vop->drm_dev; in vop_handle_vblank()
1763 struct drm_crtc *crtc = &vop->crtc; in vop_handle_vblank()
1766 if (vop->event) { in vop_handle_vblank()
1767 drm_crtc_send_vblank_event(crtc, vop->event); in vop_handle_vblank()
1769 vop->event = NULL; in vop_handle_vblank()
1773 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending)) in vop_handle_vblank()
1774 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq); in vop_handle_vblank()
1779 struct vop *vop = data; in vop_isr() local
1780 struct drm_crtc *crtc = &vop->crtc; in vop_isr()
1786 * vop-device is disabled the irq has to be targeted at the iommu. in vop_isr()
1788 if (!pm_runtime_get_if_in_use(vop->dev)) in vop_isr()
1791 if (vop_core_clks_enable(vop)) { in vop_isr()
1792 DRM_DEV_ERROR_RATELIMITED(vop->dev, "couldn't enable clocks\n"); in vop_isr()
1800 spin_lock(&vop->irq_lock); in vop_isr()
1802 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK); in vop_isr()
1805 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1); in vop_isr()
1807 spin_unlock(&vop->irq_lock); in vop_isr()
1809 /* This is expected for vop iommu irqs, since the irq is shared */ in vop_isr()
1814 complete(&vop->dsp_hold_completion); in vop_isr()
1820 complete(&vop->line_flag_completion); in vop_isr()
1827 vop_handle_vblank(vop); in vop_isr()
1834 DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n", in vop_isr()
1838 vop_core_clks_disable(vop); in vop_isr()
1840 pm_runtime_put(vop->dev); in vop_isr()
1856 static int vop_create_crtc(struct vop *vop) in vop_create_crtc() argument
1858 const struct vop_data *vop_data = vop->data; in vop_create_crtc()
1859 struct device *dev = vop->dev; in vop_create_crtc()
1860 struct drm_device *drm_dev = vop->drm_dev; in vop_create_crtc()
1862 struct drm_crtc *crtc = &vop->crtc; in vop_create_crtc()
1873 struct vop_win *vop_win = &vop->win[i]; in vop_create_crtc()
1880 ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base, in vop_create_crtc()
1887 DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n", in vop_create_crtc()
1907 if (vop->lut_regs) { in vop_create_crtc()
1917 struct vop_win *vop_win = &vop->win[i]; in vop_create_crtc()
1924 ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base, in vop_create_crtc()
1932 DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n", in vop_create_crtc()
1942 DRM_DEV_ERROR(vop->dev, "no port node found in %pOF\n", in vop_create_crtc()
1948 drm_flip_work_init(&vop->fb_unref_work, "fb_unref", in vop_create_crtc()
1951 init_completion(&vop->dsp_hold_completion); in vop_create_crtc()
1952 init_completion(&vop->line_flag_completion); in vop_create_crtc()
1957 DRM_DEV_DEBUG_KMS(vop->dev, in vop_create_crtc()
1972 static void vop_destroy_crtc(struct vop *vop) in vop_destroy_crtc() argument
1974 struct drm_crtc *crtc = &vop->crtc; in vop_destroy_crtc()
1975 struct drm_device *drm_dev = vop->drm_dev; in vop_destroy_crtc()
1985 * The planes are "&vop->win[i].base". That means the memory is in vop_destroy_crtc()
1986 * all part of the big "struct vop" chunk of memory. That memory in vop_destroy_crtc()
1999 drm_flip_work_cleanup(&vop->fb_unref_work); in vop_destroy_crtc()
2002 static int vop_initial(struct vop *vop) in vop_initial() argument
2007 vop->hclk = devm_clk_get(vop->dev, "hclk_vop"); in vop_initial()
2008 if (IS_ERR(vop->hclk)) { in vop_initial()
2009 DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n"); in vop_initial()
2010 return PTR_ERR(vop->hclk); in vop_initial()
2012 vop->aclk = devm_clk_get(vop->dev, "aclk_vop"); in vop_initial()
2013 if (IS_ERR(vop->aclk)) { in vop_initial()
2014 DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n"); in vop_initial()
2015 return PTR_ERR(vop->aclk); in vop_initial()
2017 vop->dclk = devm_clk_get(vop->dev, "dclk_vop"); in vop_initial()
2018 if (IS_ERR(vop->dclk)) { in vop_initial()
2019 DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n"); in vop_initial()
2020 return PTR_ERR(vop->dclk); in vop_initial()
2023 ret = pm_runtime_resume_and_get(vop->dev); in vop_initial()
2025 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret); in vop_initial()
2029 ret = clk_prepare(vop->dclk); in vop_initial()
2031 DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n"); in vop_initial()
2035 /* Enable both the hclk and aclk to setup the vop */ in vop_initial()
2036 ret = clk_prepare_enable(vop->hclk); in vop_initial()
2038 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n"); in vop_initial()
2042 ret = clk_prepare_enable(vop->aclk); in vop_initial()
2044 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n"); in vop_initial()
2049 * do hclk_reset, reset all vop registers. in vop_initial()
2051 ahb_rst = devm_reset_control_get(vop->dev, "ahb"); in vop_initial()
2053 DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n"); in vop_initial()
2061 VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1); in vop_initial()
2062 VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0); in vop_initial()
2064 for (i = 0; i < vop->len; i += sizeof(u32)) in vop_initial()
2065 vop->regsbak[i / 4] = readl_relaxed(vop->regs + i); in vop_initial()
2067 VOP_REG_SET(vop, misc, global_regdone_en, 1); in vop_initial()
2068 VOP_REG_SET(vop, common, dsp_blank, 0); in vop_initial()
2070 for (i = 0; i < vop->data->win_size; i++) { in vop_initial()
2071 struct vop_win *vop_win = &vop->win[i]; in vop_initial()
2075 VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel); in vop_initial()
2076 vop_win_disable(vop, vop_win); in vop_initial()
2077 VOP_WIN_SET(vop, win, gate, 1); in vop_initial()
2080 vop_cfg_done(vop); in vop_initial()
2085 vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk"); in vop_initial()
2086 if (IS_ERR(vop->dclk_rst)) { in vop_initial()
2087 DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n"); in vop_initial()
2088 ret = PTR_ERR(vop->dclk_rst); in vop_initial()
2091 reset_control_assert(vop->dclk_rst); in vop_initial()
2093 reset_control_deassert(vop->dclk_rst); in vop_initial()
2095 clk_disable(vop->hclk); in vop_initial()
2096 clk_disable(vop->aclk); in vop_initial()
2098 vop->is_enabled = false; in vop_initial()
2100 pm_runtime_put_sync(vop->dev); in vop_initial()
2105 clk_disable_unprepare(vop->aclk); in vop_initial()
2107 clk_disable_unprepare(vop->hclk); in vop_initial()
2109 clk_unprepare(vop->dclk); in vop_initial()
2111 pm_runtime_put_sync(vop->dev); in vop_initial()
2116 * Initialize the vop->win array elements.
2118 static void vop_win_init(struct vop *vop) in vop_win_init() argument
2120 const struct vop_data *vop_data = vop->data; in vop_win_init()
2124 struct vop_win *vop_win = &vop->win[i]; in vop_win_init()
2128 vop_win->vop = vop; in vop_win_init()
2147 struct vop *vop = to_vop(crtc); in rockchip_drm_wait_vact_end() local
2151 if (!crtc || !vop->is_enabled) in rockchip_drm_wait_vact_end()
2154 mutex_lock(&vop->vop_lock); in rockchip_drm_wait_vact_end()
2160 if (vop_line_flag_irq_is_enabled(vop)) { in rockchip_drm_wait_vact_end()
2165 reinit_completion(&vop->line_flag_completion); in rockchip_drm_wait_vact_end()
2166 vop_line_flag_irq_enable(vop); in rockchip_drm_wait_vact_end()
2168 jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion, in rockchip_drm_wait_vact_end()
2170 vop_line_flag_irq_disable(vop); in rockchip_drm_wait_vact_end()
2173 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n"); in rockchip_drm_wait_vact_end()
2179 mutex_unlock(&vop->vop_lock); in rockchip_drm_wait_vact_end()
2189 struct vop *vop; in vop_bind() local
2197 /* Allocate vop struct and its vop_win array */ in vop_bind()
2198 vop = devm_kzalloc(dev, struct_size(vop, win, vop_data->win_size), in vop_bind()
2200 if (!vop) in vop_bind()
2203 vop->dev = dev; in vop_bind()
2204 vop->data = vop_data; in vop_bind()
2205 vop->drm_dev = drm_dev; in vop_bind()
2206 dev_set_drvdata(dev, vop); in vop_bind()
2208 vop_win_init(vop); in vop_bind()
2211 vop->regs = devm_ioremap_resource(dev, res); in vop_bind()
2212 if (IS_ERR(vop->regs)) in vop_bind()
2213 return PTR_ERR(vop->regs); in vop_bind()
2214 vop->len = resource_size(res); in vop_bind()
2222 vop->lut_regs = devm_ioremap_resource(dev, res); in vop_bind()
2223 if (IS_ERR(vop->lut_regs)) in vop_bind()
2224 return PTR_ERR(vop->lut_regs); in vop_bind()
2227 vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL); in vop_bind()
2228 if (!vop->regsbak) in vop_bind()
2233 DRM_DEV_ERROR(dev, "cannot find irq for vop\n"); in vop_bind()
2236 vop->irq = (unsigned int)irq; in vop_bind()
2238 spin_lock_init(&vop->reg_lock); in vop_bind()
2239 spin_lock_init(&vop->irq_lock); in vop_bind()
2240 mutex_init(&vop->vop_lock); in vop_bind()
2242 ret = vop_create_crtc(vop); in vop_bind()
2248 ret = vop_initial(vop); in vop_bind()
2251 "cannot initial vop dev - err %d\n", ret); in vop_bind()
2255 ret = devm_request_irq(dev, vop->irq, vop_isr, in vop_bind()
2256 IRQF_SHARED, dev_name(dev), vop); in vop_bind()
2260 if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) { in vop_bind()
2261 vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev, 0); in vop_bind()
2262 if (IS_ERR(vop->rgb)) { in vop_bind()
2263 ret = PTR_ERR(vop->rgb); in vop_bind()
2274 vop_destroy_crtc(vop); in vop_bind()
2280 struct vop *vop = dev_get_drvdata(dev); in vop_unbind() local
2282 if (vop->rgb) in vop_unbind()
2283 rockchip_rgb_fini(vop->rgb); in vop_unbind()
2286 vop_destroy_crtc(vop); in vop_unbind()
2288 clk_unprepare(vop->aclk); in vop_unbind()
2289 clk_unprepare(vop->hclk); in vop_unbind()
2290 clk_unprepare(vop->dclk); in vop_unbind()