Lines Matching +full:rk3568 +full:- +full:vop
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
4 * Author: Andy Yan <andy.yan@rock-chips.com>
12 #include <linux/media-bus-format.h>
34 #include <dt-bindings/soc/rockchip,vop2.h>
44 +----------+ +-------------+ +-----------+
47 +----------+ +-------------+ +---------------+ +-------------+ +-----------+
48 +----------+ +-------------+ |N from 6 layers| | |
49 | Cluster | | Sel 1 from 6| | Overlay0 +--->| Video Port0 | +-----------+
51 +----------+ +-------------+ +---------------+ +-------------+ | LVDS |
52 +----------+ +-------------+ +-----------+
54 | window0 | | Layer2 | +---------------+ +-------------+ +-----------+
55 +----------+ +-------------+ |N from 6 Layers| | | +--> | 1 from 3 |
56 +----------+ +-------------+ --------> | Overlay1 +--->| Video Port1 | | MIPI |
57 | Esmart | | Sel 1 from 6| --------> | | | | +-----------+
58 | Window1 | | Layer3 | +---------------+ +-------------+
59 +----------+ +-------------+ +-----------+
60 +----------+ +-------------+ | 1 from 3 |
61 | Smart | | Sel 1 from 6| +---------------+ +-------------+ | HDMI |
62 | Window0 | | Layer4 | |N from 6 Layers| | | +-----------+
63 +----------+ +-------------+ | Overlay2 +--->| Video Port2 |
64 +----------+ +-------------+ | | | | +-----------+
65 | Smart | | Sel 1 from 6| +---------------+ +-------------+ | 1 from 3 |
67 +----------+ +-------------+ +-----------+
101 VOP2_AFBC_FMT_INVALID = -1,
232 mutex_lock(&vop2->vop2_lock); in vop2_lock()
237 mutex_unlock(&vop2->vop2_lock); in vop2_unlock()
242 regmap_write(vop2->map, offset, v); in vop2_writel()
247 regmap_write(vp->vop2->map, vp->data->offset + offset, v); in vop2_vp_write()
254 regmap_read(vop2->map, offset, &val); in vop2_readl()
261 regmap_field_write(win->reg[reg], v); in vop2_win_write()
266 return win->data->feature & WIN_FEATURE_CLUSTER; in vop2_cluster_window()
271 struct vop2 *vop2 = vp->vop2; in vop2_cfg_done()
273 regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, in vop2_cfg_done()
274 BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); in vop2_cfg_done()
313 return -EINVAL; in vop2_convert_format()
451 for (i = 0 ; i < plane->modifier_count; i++) in rockchip_afbc()
452 if (plane->modifiers[i] == modifier) in rockchip_afbc()
462 struct vop2 *vop2 = win->vop2; in rockchip_vop2_mod_supported()
467 if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) { in rockchip_vop2_mod_supported()
470 drm_dbg_kms(vop2->drm, in rockchip_vop2_mod_supported()
481 drm_err(vop2->drm, "Unsupported format modifier 0x%llx\n", in rockchip_vop2_mod_supported()
493 struct drm_rect *src = &pstate->src; in vop2_afbc_transform_offset()
494 struct drm_framebuffer *fb = pstate->fb; in vop2_afbc_transform_offset()
495 u32 bpp = fb->format->cpp[0] * 8; in vop2_afbc_transform_offset()
496 u32 vir_width = (fb->pitches[0] << 3) / bpp; in vop2_afbc_transform_offset()
499 u32 act_xoffset = src->x1 >> 16; in vop2_afbc_transform_offset()
500 u32 act_yoffset = src->y1 >> 16; in vop2_afbc_transform_offset()
509 align16_crop = 16 - (height & 0xf); in vop2_afbc_transform_offset()
515 align64_crop = 64 - (height_tmp & 0x3f); in vop2_afbc_transform_offset()
519 switch (pstate->rotation & in vop2_afbc_transform_offset()
523 tx = 16 - ((act_xoffset + width) & 0xf); in vop2_afbc_transform_offset()
524 ty = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
527 tx = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
528 ty = vir_width - width - act_xoffset; in vop2_afbc_transform_offset()
535 tx = 16 - ((act_xoffset + width) & 0xf); in vop2_afbc_transform_offset()
540 ty = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
543 tx = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
548 ty = vir_width - width - act_xoffset; in vop2_afbc_transform_offset()
577 if ((pstate->rotation & DRM_MODE_ROTATE_270) || in vop2_get_cluster_lb_mode()
578 (pstate->rotation & DRM_MODE_ROTATE_90)) in vop2_get_cluster_lb_mode()
603 src--; in vop2_scale_factor()
604 dst--; in vop2_scale_factor()
606 fac = DIV_ROUND_UP(src << shift, dst) - 1; in vop2_scale_factor()
651 * RK3568 VOP Esmart/Smart dsp_w should be even pixel in vop2_setup_scale()
654 if (!(win->data->feature & WIN_FEATURE_AFBDC)) { in vop2_setup_scale()
656 drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n", in vop2_setup_scale()
657 win->data->name, dst_w); in vop2_setup_scale()
679 if (info->is_yuv) { in vop2_setup_scale()
680 cbcr_src_w /= info->hsub; in vop2_setup_scale()
681 cbcr_src_h /= info->vsub; in vop2_setup_scale()
735 * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
736 * RGB --> R2Y __/
738 * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020)
739 * RGB --> 709To2020->R2Y __/
741 * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709)
742 * RGB --> R2Y __/
744 * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
745 * RGB --> 709To2020->R2Y __/
747 * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709)
748 * RGB --> R2Y __/
750 * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601)
751 * RGB --> R2Y(601) __/
753 * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709)
754 * RGB --> bypass __/
756 * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020)
758 * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709)
760 * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601)
762 * 11. RGB --> bypass --> RGB_OUTPUT(709)
769 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); in vop2_setup_csc_mode()
770 int is_input_yuv = pstate->fb->format->is_yuv; in vop2_setup_csc_mode()
771 int is_output_yuv = is_yuv_output(vcstate->bus_format); in vop2_setup_csc_mode()
773 int output_csc = vcstate->color_space; in vop2_setup_csc_mode()
798 struct vop2 *vop2 = vp->vop2; in vop2_crtc_enable_irq()
800 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq); in vop2_crtc_enable_irq()
801 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq); in vop2_crtc_enable_irq()
806 struct vop2 *vop2 = vp->vop2; in vop2_crtc_disable_irq()
808 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16); in vop2_crtc_disable_irq()
815 ret = clk_prepare_enable(vop2->hclk); in vop2_core_clks_prepare_enable()
817 drm_err(vop2->drm, "failed to enable hclk - %d\n", ret); in vop2_core_clks_prepare_enable()
821 ret = clk_prepare_enable(vop2->aclk); in vop2_core_clks_prepare_enable()
823 drm_err(vop2->drm, "failed to enable aclk - %d\n", ret); in vop2_core_clks_prepare_enable()
829 clk_disable_unprepare(vop2->hclk); in vop2_core_clks_prepare_enable()
838 ret = pm_runtime_resume_and_get(vop2->dev); in vop2_enable()
840 drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret); in vop2_enable()
846 pm_runtime_put_sync(vop2->dev); in vop2_enable()
850 ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev); in vop2_enable()
852 drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret); in vop2_enable()
856 regcache_sync(vop2->map); in vop2_enable()
858 if (vop2->data->soc_id == 3566) in vop2_enable()
867 regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL, in vop2_enable()
882 rockchip_drm_dma_detach_device(vop2->drm, vop2->dev); in vop2_disable()
884 pm_runtime_put_sync(vop2->dev); in vop2_disable()
886 regcache_mark_dirty(vop2->map); in vop2_disable()
888 clk_disable_unprepare(vop2->aclk); in vop2_disable()
889 clk_disable_unprepare(vop2->hclk); in vop2_disable()
896 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_disable()
908 * Vop standby will take effect at end of current frame, in vop2_crtc_atomic_disable()
914 reinit_completion(&vp->dsp_hold_completion); in vop2_crtc_atomic_disable()
920 ret = wait_for_completion_timeout(&vp->dsp_hold_completion, in vop2_crtc_atomic_disable()
923 drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id); in vop2_crtc_atomic_disable()
927 clk_disable_unprepare(vp->dclk); in vop2_crtc_atomic_disable()
929 vop2->enable_count--; in vop2_crtc_atomic_disable()
931 if (!vop2->enable_count) in vop2_crtc_atomic_disable()
936 if (crtc->state->event && !crtc->state->active) { in vop2_crtc_atomic_disable()
937 spin_lock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_disable()
938 drm_crtc_send_vblank_event(crtc, crtc->state->event); in vop2_crtc_atomic_disable()
939 spin_unlock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_disable()
941 crtc->state->event = NULL; in vop2_crtc_atomic_disable()
949 struct drm_framebuffer *fb = pstate->fb; in vop2_plane_atomic_check()
950 struct drm_crtc *crtc = pstate->crtc; in vop2_plane_atomic_check()
955 struct drm_rect *dest = &pstate->dst; in vop2_plane_atomic_check()
956 struct drm_rect *src = &pstate->src; in vop2_plane_atomic_check()
966 vop2 = vp->vop2; in vop2_plane_atomic_check()
967 vop2_data = vop2->data; in vop2_plane_atomic_check()
969 cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc); in vop2_plane_atomic_check()
971 return -EINVAL; in vop2_plane_atomic_check()
979 if (!pstate->visible) in vop2_plane_atomic_check()
982 format = vop2_convert_format(fb->format->format); in vop2_plane_atomic_check()
988 drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n", in vop2_plane_atomic_check()
991 pstate->visible = false; in vop2_plane_atomic_check()
995 if (drm_rect_width(src) >> 16 > vop2_data->max_input.width || in vop2_plane_atomic_check()
996 drm_rect_height(src) >> 16 > vop2_data->max_input.height) { in vop2_plane_atomic_check()
997 drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n", in vop2_plane_atomic_check()
1000 vop2_data->max_input.width, in vop2_plane_atomic_check()
1001 vop2_data->max_input.height); in vop2_plane_atomic_check()
1002 return -EINVAL; in vop2_plane_atomic_check()
1009 if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) { in vop2_plane_atomic_check()
1010 drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n"); in vop2_plane_atomic_check()
1011 return -EINVAL; in vop2_plane_atomic_check()
1022 struct vop2 *vop2 = win->vop2; in vop2_plane_atomic_disable()
1024 drm_dbg(vop2->drm, "%s disable\n", win->data->name); in vop2_plane_atomic_disable()
1028 if (old_pstate && !old_pstate->crtc) in vop2_plane_atomic_disable()
1041 struct drm_plane_state *pstate = plane->state; in vop2_plane_setup_color_key()
1042 struct drm_framebuffer *fb = pstate->fb; in vop2_plane_setup_color_key()
1049 if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) { in vop2_plane_setup_color_key()
1054 switch (fb->format->format) { in vop2_plane_setup_color_key()
1088 struct drm_plane_state *pstate = plane->state; in vop2_plane_atomic_update()
1089 struct drm_crtc *crtc = pstate->crtc; in vop2_plane_atomic_update()
1092 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; in vop2_plane_atomic_update()
1093 struct vop2 *vop2 = win->vop2; in vop2_plane_atomic_update()
1094 struct drm_framebuffer *fb = pstate->fb; in vop2_plane_atomic_update()
1095 u32 bpp = fb->format->cpp[0] * 8; in vop2_plane_atomic_update()
1102 struct drm_rect *src = &pstate->src; in vop2_plane_atomic_update()
1103 struct drm_rect *dest = &pstate->dst; in vop2_plane_atomic_update()
1107 bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false; in vop2_plane_atomic_update()
1108 bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false; in vop2_plane_atomic_update()
1109 bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270; in vop2_plane_atomic_update()
1110 bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; in vop2_plane_atomic_update()
1123 if (!pstate->visible) { in vop2_plane_atomic_update()
1128 afbc_en = rockchip_afbc(plane, fb->modifier); in vop2_plane_atomic_update()
1130 offset = (src->x1 >> 16) * fb->format->cpp[0]; in vop2_plane_atomic_update()
1137 else if (pstate->rotation & DRM_MODE_REFLECT_Y) in vop2_plane_atomic_update()
1138 offset += ((src->y2 >> 16) - 1) * fb->pitches[0]; in vop2_plane_atomic_update()
1140 offset += (src->y1 >> 16) * fb->pitches[0]; in vop2_plane_atomic_update()
1142 rk_obj = to_rockchip_obj(fb->obj[0]); in vop2_plane_atomic_update()
1144 yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; in vop2_plane_atomic_update()
1145 if (fb->format->is_yuv) { in vop2_plane_atomic_update()
1146 int hsub = fb->format->hsub; in vop2_plane_atomic_update()
1147 int vsub = fb->format->vsub; in vop2_plane_atomic_update()
1149 offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub; in vop2_plane_atomic_update()
1150 offset += (src->y1 >> 16) * fb->pitches[1] / vsub; in vop2_plane_atomic_update()
1152 if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en) in vop2_plane_atomic_update()
1153 offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub; in vop2_plane_atomic_update()
1155 rk_obj = to_rockchip_obj(fb->obj[0]); in vop2_plane_atomic_update()
1156 uv_mst = rk_obj->dma_addr + offset + fb->offsets[1]; in vop2_plane_atomic_update()
1163 if (dest->x1 + dsp_w > adjusted_mode->hdisplay) { in vop2_plane_atomic_update()
1164 drm_err(vop2->drm, "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n", in vop2_plane_atomic_update()
1165 vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay); in vop2_plane_atomic_update()
1166 dsp_w = adjusted_mode->hdisplay - dest->x1; in vop2_plane_atomic_update()
1174 if (dest->y1 + dsp_h > adjusted_mode->vdisplay) { in vop2_plane_atomic_update()
1175 drm_err(vop2->drm, "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n", in vop2_plane_atomic_update()
1176 vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay); in vop2_plane_atomic_update()
1177 dsp_h = adjusted_mode->vdisplay - dest->y1; in vop2_plane_atomic_update()
1187 if (!(win->data->feature & WIN_FEATURE_AFBDC)) { in vop2_plane_atomic_update()
1189 drm_err(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n", in vop2_plane_atomic_update()
1190 vp->id, win->data->name, actual_w); in vop2_plane_atomic_update()
1191 actual_w -= 1; in vop2_plane_atomic_update()
1196 drm_err(vop2->drm, "vp%d %s actual_w[%d] not 4 pixel aligned\n", in vop2_plane_atomic_update()
1197 vp->id, win->data->name, actual_w); in vop2_plane_atomic_update()
1201 act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff); in vop2_plane_atomic_update()
1202 dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); in vop2_plane_atomic_update()
1204 format = vop2_convert_format(fb->format->format); in vop2_plane_atomic_update()
1206 drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n", in vop2_plane_atomic_update()
1207 vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h, in vop2_plane_atomic_update()
1208 dest->x1, dest->y1, in vop2_plane_atomic_update()
1209 &fb->format->format, in vop2_plane_atomic_update()
1216 afbc_format = vop2_convert_afbc_format(fb->format->format); in vop2_plane_atomic_update()
1219 if (fb->modifier & AFBC_FORMAT_MOD_YTR) in vop2_plane_atomic_update()
1228 stride = (fb->pitches[0] << 3) / bpp; in vop2_plane_atomic_update()
1230 drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n", in vop2_plane_atomic_update()
1231 vp->id, win->data->name, stride); in vop2_plane_atomic_update()
1233 rb_swap = vop2_afbc_rb_swap(fb->format->format); in vop2_plane_atomic_update()
1234 uv_swap = vop2_afbc_uv_swap(fb->format->format); in vop2_plane_atomic_update()
1244 if (fb->format->is_yuv && bpp == 10) in vop2_plane_atomic_update()
1254 if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) { in vop2_plane_atomic_update()
1264 vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1)); in vop2_plane_atomic_update()
1265 vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16))); in vop2_plane_atomic_update()
1277 vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); in vop2_plane_atomic_update()
1291 rb_swap = vop2_win_rb_swap(fb->format->format); in vop2_plane_atomic_update()
1294 uv_swap = vop2_win_uv_swap(fb->format->format); in vop2_plane_atomic_update()
1298 if (fb->format->is_yuv) { in vop2_plane_atomic_update()
1299 vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4)); in vop2_plane_atomic_update()
1303 vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format); in vop2_plane_atomic_update()
1308 vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff)); in vop2_plane_atomic_update()
1312 dither_up = vop2_win_dither_up(fb->format->format); in vop2_plane_atomic_update()
1369 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); in vop2_dither_setup()
1371 switch (vcstate->bus_format) { in vop2_dither_setup()
1389 if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA) in vop2_dither_setup()
1399 struct drm_display_mode *mode = &crtc->state->adjusted_mode; in vop2_post_config()
1400 u16 vtotal = mode->crtc_vtotal; in vop2_post_config()
1401 u16 hdisplay = mode->crtc_hdisplay; in vop2_post_config()
1402 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; in vop2_post_config()
1403 u16 vdisplay = mode->crtc_vdisplay; in vop2_post_config()
1404 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; in vop2_post_config()
1409 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; in vop2_post_config()
1415 bg_dly = vp->data->pre_scan_max_dly[3]; in vop2_post_config()
1416 vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id), in vop2_post_config()
1419 pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; in vop2_post_config()
1424 hact_st += hdisplay * (100 - left_margin) / 200; in vop2_post_config()
1429 vact_st += vdisplay * (100 - top_margin) / 200; in vop2_post_config()
1445 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { in vop2_post_config()
1459 struct vop2 *vop2 = vp->vop2; in rk3568_set_intf_mux()
1469 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id); in rk3568_set_intf_mux()
1473 regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); in rk3568_set_intf_mux()
1475 regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); in rk3568_set_intf_mux()
1480 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id); in rk3568_set_intf_mux()
1487 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id); in rk3568_set_intf_mux()
1494 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id); in rk3568_set_intf_mux()
1501 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); in rk3568_set_intf_mux()
1508 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id); in rk3568_set_intf_mux()
1515 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id); in rk3568_set_intf_mux()
1520 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); in rk3568_set_intf_mux()
1532 return us * mode->clock / mode->htotal / 1000; in us_to_vertical_line()
1539 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_enable()
1540 const struct vop2_data *vop2_data = vop2->data; in vop2_crtc_atomic_enable()
1541 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; in vop2_crtc_atomic_enable()
1543 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); in vop2_crtc_atomic_enable()
1544 struct drm_display_mode *mode = &crtc->state->adjusted_mode; in vop2_crtc_atomic_enable()
1545 unsigned long clock = mode->crtc_clock * 1000; in vop2_crtc_atomic_enable()
1546 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; in vop2_crtc_atomic_enable()
1547 u16 hdisplay = mode->crtc_hdisplay; in vop2_crtc_atomic_enable()
1548 u16 htotal = mode->crtc_htotal; in vop2_crtc_atomic_enable()
1549 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; in vop2_crtc_atomic_enable()
1551 u16 vdisplay = mode->crtc_vdisplay; in vop2_crtc_atomic_enable()
1552 u16 vtotal = mode->crtc_vtotal; in vop2_crtc_atomic_enable()
1553 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; in vop2_crtc_atomic_enable()
1554 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; in vop2_crtc_atomic_enable()
1563 drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n", in vop2_crtc_atomic_enable()
1564 hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", in vop2_crtc_atomic_enable()
1565 drm_mode_vrefresh(mode), vcstate->output_type, vp->id); in vop2_crtc_atomic_enable()
1569 ret = clk_prepare_enable(vp->dclk); in vop2_crtc_atomic_enable()
1571 drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n", in vop2_crtc_atomic_enable()
1572 vp->id, ret); in vop2_crtc_atomic_enable()
1577 if (!vop2->enable_count) in vop2_crtc_atomic_enable()
1580 vop2->enable_count++; in vop2_crtc_atomic_enable()
1582 vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format); in vop2_crtc_atomic_enable()
1587 if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) in vop2_crtc_atomic_enable()
1589 if (mode->flags & DRM_MODE_FLAG_PHSYNC) in vop2_crtc_atomic_enable()
1591 if (mode->flags & DRM_MODE_FLAG_PVSYNC) in vop2_crtc_atomic_enable()
1594 drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { in vop2_crtc_atomic_enable()
1597 rk3568_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); in vop2_crtc_atomic_enable()
1600 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && in vop2_crtc_atomic_enable()
1601 !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) in vop2_crtc_atomic_enable()
1604 out_mode = vcstate->output_mode; in vop2_crtc_atomic_enable()
1608 if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) in vop2_crtc_atomic_enable()
1611 if (vcstate->yuv_overlay) in vop2_crtc_atomic_enable()
1625 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { in vop2_crtc_atomic_enable()
1643 vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id), in vop2_crtc_atomic_enable()
1644 (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end); in vop2_crtc_atomic_enable()
1648 if (mode->flags & DRM_MODE_FLAG_DBLCLK) { in vop2_crtc_atomic_enable()
1655 clk_set_rate(vp->dclk, clock); in vop2_crtc_atomic_enable()
1679 if (nplanes > vp->nlayers) in vop2_crtc_atomic_check()
1680 return -EINVAL; in vop2_crtc_atomic_check()
1693 int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1; in vop2_parse_alpha()
1694 int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1; in vop2_parse_alpha()
1695 int src_color_mode = alpha_config->src_premulti_en ? in vop2_parse_alpha()
1697 int dst_color_mode = alpha_config->dst_premulti_en ? in vop2_parse_alpha()
1700 alpha->src_color_ctrl.val = 0; in vop2_parse_alpha()
1701 alpha->dst_color_ctrl.val = 0; in vop2_parse_alpha()
1702 alpha->src_alpha_ctrl.val = 0; in vop2_parse_alpha()
1703 alpha->dst_alpha_ctrl.val = 0; in vop2_parse_alpha()
1705 if (!alpha_config->src_pixel_alpha_en) in vop2_parse_alpha()
1706 alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; in vop2_parse_alpha()
1707 else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en) in vop2_parse_alpha()
1708 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX; in vop2_parse_alpha()
1710 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; in vop2_parse_alpha()
1712 alpha->src_color_ctrl.bits.alpha_en = 1; in vop2_parse_alpha()
1714 if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) { in vop2_parse_alpha()
1715 alpha->src_color_ctrl.bits.color_mode = src_color_mode; in vop2_parse_alpha()
1716 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; in vop2_parse_alpha()
1717 } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) { in vop2_parse_alpha()
1718 alpha->src_color_ctrl.bits.color_mode = src_color_mode; in vop2_parse_alpha()
1719 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE; in vop2_parse_alpha()
1721 alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL; in vop2_parse_alpha()
1722 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; in vop2_parse_alpha()
1724 alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8; in vop2_parse_alpha()
1725 alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
1726 alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; in vop2_parse_alpha()
1728 alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
1729 alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; in vop2_parse_alpha()
1730 alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; in vop2_parse_alpha()
1731 alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8; in vop2_parse_alpha()
1732 alpha->dst_color_ctrl.bits.color_mode = dst_color_mode; in vop2_parse_alpha()
1733 alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; in vop2_parse_alpha()
1735 alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
1736 alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode; in vop2_parse_alpha()
1737 alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; in vop2_parse_alpha()
1738 alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE; in vop2_parse_alpha()
1740 alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
1741 if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en) in vop2_parse_alpha()
1742 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX; in vop2_parse_alpha()
1744 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; in vop2_parse_alpha()
1745 alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION; in vop2_parse_alpha()
1746 alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; in vop2_parse_alpha()
1756 vp = &vop2->vps[i]; in vop2_find_start_mixer_id_for_vp()
1757 used_layer += hweight32(vp->win_mask); in vop2_find_start_mixer_id_for_vp()
1775 bottom_win_pstate = main_win->base.state; in vop2_setup_cluster_alpha()
1777 dst_glb_alpha_val = main_win->base.state->alpha; in vop2_setup_cluster_alpha()
1779 if (!bottom_win_pstate->fb) in vop2_setup_cluster_alpha()
1792 switch (main_win->data->phys_id) { in vop2_setup_cluster_alpha()
1819 struct vop2 *vop2 = vp->vop2; in vop2_setup_alpha()
1831 mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id); in vop2_setup_alpha()
1834 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { in vop2_setup_alpha()
1837 if (plane->state->normalized_zpos == 0 && in vop2_setup_alpha()
1838 !is_opaque(plane->state->alpha) && in vop2_setup_alpha()
1846 dst_global_alpha = plane->state->alpha; in vop2_setup_alpha()
1850 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { in vop2_setup_alpha()
1852 int zpos = plane->state->normalized_zpos; in vop2_setup_alpha()
1860 if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) in vop2_setup_alpha()
1865 plane = &win->base; in vop2_setup_alpha()
1866 fb = plane->state->fb; in vop2_setup_alpha()
1868 pixel_alpha_en = fb->format->has_alpha; in vop2_setup_alpha()
1874 /* Cd = Cs + (1 - As) * Cd * Agd */ in vop2_setup_alpha()
1877 alpha_config.src_glb_alpha_value = plane->state->alpha; in vop2_setup_alpha()
1886 /* Cd = Cs + (1 - As) * Cd */ in vop2_setup_alpha()
1889 alpha_config.src_glb_alpha_value = plane->state->alpha; in vop2_setup_alpha()
1895 offset = (mixer_id + zpos - 1) * 0x10; in vop2_setup_alpha()
1906 if (vp->id == 0) { in vop2_setup_alpha()
1932 struct vop2 *vop2 = vp->vop2; in vop2_setup_layer_mixer()
1942 struct vop2_video_port *vp0 = &vop2->vps[0]; in vop2_setup_layer_mixer()
1943 struct vop2_video_port *vp1 = &vop2->vps[1]; in vop2_setup_layer_mixer()
1944 struct vop2_video_port *vp2 = &vop2->vps[2]; in vop2_setup_layer_mixer()
1945 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); in vop2_setup_layer_mixer()
1949 if (vcstate->yuv_overlay) in vop2_setup_layer_mixer()
1950 ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id); in vop2_setup_layer_mixer()
1952 ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id); in vop2_setup_layer_mixer()
1959 if (vp0->nlayers) in vop2_setup_layer_mixer()
1961 vp0->nlayers - 1); in vop2_setup_layer_mixer()
1965 if (vp1->nlayers) in vop2_setup_layer_mixer()
1967 (vp0->nlayers + vp1->nlayers - 1)); in vop2_setup_layer_mixer()
1971 if (vp2->nlayers) in vop2_setup_layer_mixer()
1973 (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1)); in vop2_setup_layer_mixer()
1980 for (i = 0; i < vp->id; i++) in vop2_setup_layer_mixer()
1981 ofs += vop2->vps[i].nlayers; in vop2_setup_layer_mixer()
1983 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { in vop2_setup_layer_mixer()
1987 layer_id = (u8)(plane->state->normalized_zpos + ofs); in vop2_setup_layer_mixer()
1992 for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) { in vop2_setup_layer_mixer()
1994 if (layer_sel_id == win->data->layer_sel_id) in vop2_setup_layer_mixer()
2001 for (i = 0; i < vop2->data->win_size; i++) { in vop2_setup_layer_mixer()
2002 old_win = &vop2->win[i]; in vop2_setup_layer_mixer()
2004 if (layer_sel_id == old_win->data->layer_sel_id) in vop2_setup_layer_mixer()
2008 switch (win->data->phys_id) { in vop2_setup_layer_mixer()
2011 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id); in vop2_setup_layer_mixer()
2015 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id); in vop2_setup_layer_mixer()
2019 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id); in vop2_setup_layer_mixer()
2023 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id); in vop2_setup_layer_mixer()
2027 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id); in vop2_setup_layer_mixer()
2031 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id); in vop2_setup_layer_mixer()
2036 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id); in vop2_setup_layer_mixer()
2042 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id); in vop2_setup_layer_mixer()
2055 for (i = 0; i < vop2->data->win_size; i++) { in vop2_setup_dly_for_windows()
2058 win = &vop2->win[i]; in vop2_setup_dly_for_windows()
2059 dly = win->delay; in vop2_setup_dly_for_windows()
2061 switch (win->data->phys_id) { in vop2_setup_dly_for_windows()
2093 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_begin()
2096 vp->win_mask = 0; in vop2_crtc_atomic_begin()
2101 win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT]; in vop2_crtc_atomic_begin()
2103 vp->win_mask |= BIT(win->data->phys_id); in vop2_crtc_atomic_begin()
2109 if (!vp->win_mask) in vop2_crtc_atomic_begin()
2126 spin_lock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_flush()
2128 if (crtc->state->event) { in vop2_crtc_atomic_flush()
2130 vp->event = crtc->state->event; in vop2_crtc_atomic_flush()
2131 crtc->state->event = NULL; in vop2_crtc_atomic_flush()
2134 spin_unlock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_flush()
2150 if (WARN_ON(!crtc->state)) in vop2_crtc_duplicate_state()
2153 vcstate = kmemdup(to_rockchip_crtc_state(crtc->state), in vop2_crtc_duplicate_state()
2158 __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base); in vop2_crtc_duplicate_state()
2160 return &vcstate->base; in vop2_crtc_duplicate_state()
2168 __drm_atomic_helper_crtc_destroy_state(&vcstate->base); in vop2_crtc_destroy_state()
2177 if (crtc->state) in vop2_crtc_reset()
2178 vop2_crtc_destroy_state(crtc, crtc->state); in vop2_crtc_reset()
2181 __drm_atomic_helper_crtc_reset(crtc, &vcstate->base); in vop2_crtc_reset()
2200 const struct vop2_data *vop2_data = vop2->data; in vop2_isr()
2206 * The irq is shared with the iommu. If the runtime-pm state of the in vop2_isr()
2207 * vop2-device is disabled the irq has to be targeted at the iommu. in vop2_isr()
2209 if (!pm_runtime_get_if_in_use(vop2->dev)) in vop2_isr()
2212 for (i = 0; i < vop2_data->nr_vps; i++) { in vop2_isr()
2213 struct vop2_video_port *vp = &vop2->vps[i]; in vop2_isr()
2214 struct drm_crtc *crtc = &vp->crtc; in vop2_isr()
2217 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id)); in vop2_isr()
2218 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs); in vop2_isr()
2221 complete(&vp->dsp_hold_completion); in vop2_isr()
2227 spin_lock(&crtc->dev->event_lock); in vop2_isr()
2228 if (vp->event) { in vop2_isr()
2231 if (!(val & BIT(vp->id))) { in vop2_isr()
2232 drm_crtc_send_vblank_event(crtc, vp->event); in vop2_isr()
2233 vp->event = NULL; in vop2_isr()
2237 spin_unlock(&crtc->dev->event_lock); in vop2_isr()
2243 drm_err_ratelimited(vop2->drm, in vop2_isr()
2245 vp->id); in vop2_isr()
2257 drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n"); in vop2_isr()
2262 pm_runtime_put(vop2->dev); in vop2_isr()
2270 const struct vop2_win_data *win_data = win->data; in vop2_plane_init()
2276 ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs, in vop2_plane_init()
2277 &vop2_plane_funcs, win_data->formats, in vop2_plane_init()
2278 win_data->nformats, in vop2_plane_init()
2279 win_data->format_modifiers, in vop2_plane_init()
2280 win->type, win_data->name); in vop2_plane_init()
2282 drm_err(vop2->drm, "failed to initialize plane %d\n", ret); in vop2_plane_init()
2286 drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs); in vop2_plane_init()
2288 if (win->data->supported_rotations) in vop2_plane_init()
2289 drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0, in vop2_plane_init()
2291 win->data->supported_rotations); in vop2_plane_init()
2292 drm_plane_create_alpha_property(&win->base); in vop2_plane_init()
2293 drm_plane_create_blend_mode_property(&win->base, blend_caps); in vop2_plane_init()
2294 drm_plane_create_zpos_property(&win->base, win->win_id, 0, in vop2_plane_init()
2295 vop2->registered_num_wins - 1); in vop2_plane_init()
2304 for (i = 0; i < vop2->data->nr_vps; i++) { in find_vp_without_primary()
2305 struct vop2_video_port *vp = &vop2->vps[i]; in find_vp_without_primary()
2307 if (!vp->crtc.port) in find_vp_without_primary()
2309 if (vp->primary_plane) in find_vp_without_primary()
2322 const struct vop2_data *vop2_data = vop2->data; in vop2_create_crtcs()
2323 struct drm_device *drm = vop2->drm; in vop2_create_crtcs()
2324 struct device *dev = vop2->dev; in vop2_create_crtcs()
2331 for (i = 0; i < vop2_data->nr_vps; i++) { in vop2_create_crtcs()
2336 vp_data = &vop2_data->vp[i]; in vop2_create_crtcs()
2337 vp = &vop2->vps[i]; in vop2_create_crtcs()
2338 vp->vop2 = vop2; in vop2_create_crtcs()
2339 vp->id = vp_data->id; in vop2_create_crtcs()
2340 vp->regs = vp_data->regs; in vop2_create_crtcs()
2341 vp->data = vp_data; in vop2_create_crtcs()
2343 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); in vop2_create_crtcs()
2344 vp->dclk = devm_clk_get(vop2->dev, dclk_name); in vop2_create_crtcs()
2345 if (IS_ERR(vp->dclk)) { in vop2_create_crtcs()
2346 drm_err(vop2->drm, "failed to get %s\n", dclk_name); in vop2_create_crtcs()
2347 return PTR_ERR(vp->dclk); in vop2_create_crtcs()
2350 np = of_graph_get_remote_node(dev->of_node, i, -1); in vop2_create_crtcs()
2352 drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i); in vop2_create_crtcs()
2357 port = of_graph_get_port_by_id(dev->of_node, i); in vop2_create_crtcs()
2359 drm_err(vop2->drm, "no port node found for video_port%d\n", i); in vop2_create_crtcs()
2360 return -ENOENT; in vop2_create_crtcs()
2363 vp->crtc.port = port; in vop2_create_crtcs()
2368 for (i = 0; i < vop2->registered_num_wins; i++) { in vop2_create_crtcs()
2369 struct vop2_win *win = &vop2->win[i]; in vop2_create_crtcs()
2372 if (vop2->data->soc_id == 3566) { in vop2_create_crtcs()
2378 switch (win->data->phys_id) { in vop2_create_crtcs()
2386 if (win->type == DRM_PLANE_TYPE_PRIMARY) { in vop2_create_crtcs()
2390 vp->primary_plane = win; in vop2_create_crtcs()
2394 win->type = DRM_PLANE_TYPE_OVERLAY; in vop2_create_crtcs()
2398 if (win->type == DRM_PLANE_TYPE_OVERLAY) in vop2_create_crtcs()
2399 possible_crtcs = (1 << nvps) - 1; in vop2_create_crtcs()
2403 drm_err(vop2->drm, "failed to init plane %s: %d\n", in vop2_create_crtcs()
2404 win->data->name, ret); in vop2_create_crtcs()
2409 for (i = 0; i < vop2_data->nr_vps; i++) { in vop2_create_crtcs()
2410 vp = &vop2->vps[i]; in vop2_create_crtcs()
2412 if (!vp->crtc.port) in vop2_create_crtcs()
2415 plane = &vp->primary_plane->base; in vop2_create_crtcs()
2417 ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL, in vop2_create_crtcs()
2419 "video_port%d", vp->id); in vop2_create_crtcs()
2421 drm_err(vop2->drm, "crtc init for video_port%d failed\n", i); in vop2_create_crtcs()
2425 drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs); in vop2_create_crtcs()
2427 init_completion(&vp->dsp_hold_completion); in vop2_create_crtcs()
2435 for (i = 0; i < vop2->data->nr_vps; i++) { in vop2_create_crtcs()
2436 struct vop2_video_port *vp = &vop2->vps[i]; in vop2_create_crtcs()
2438 if (vp->crtc.port) in vop2_create_crtcs()
2439 vp->nlayers = NR_LAYERS / nvps; in vop2_create_crtcs()
2447 struct drm_device *drm = vop2->drm; in vop2_destroy_crtcs()
2448 struct list_head *crtc_list = &drm->mode_config.crtc_list; in vop2_destroy_crtcs()
2449 struct list_head *plane_list = &drm->mode_config.plane_list; in vop2_destroy_crtcs()
2461 of_node_put(crtc->port); in vop2_destroy_crtcs()
2468 struct device_node *node = vop2->dev->of_node; in vop2_find_rgb_encoder()
2472 for (i = 0; i < vop2->data->nr_vps; i++) { in vop2_find_rgb_encoder()
2482 return -ENOENT; in vop2_find_rgb_encoder()
2551 struct vop2 *vop2 = win->vop2; in vop2_cluster_init()
2558 return -ENOMEM; in vop2_cluster_init()
2562 cluster_regs[i].reg += win->offset; in vop2_cluster_init()
2564 ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, in vop2_cluster_init()
2635 struct vop2 *vop2 = win->vop2; in vop2_esmart_init()
2642 return -ENOMEM; in vop2_esmart_init()
2646 esmart_regs[i].reg += win->offset; in vop2_esmart_init()
2648 ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, in vop2_esmart_init()
2659 const struct vop2_data *vop2_data = vop2->data; in vop2_win_init()
2663 for (i = 0; i < vop2_data->win_size; i++) { in vop2_win_init()
2664 const struct vop2_win_data *win_data = &vop2_data->win[i]; in vop2_win_init()
2666 win = &vop2->win[i]; in vop2_win_init()
2667 win->data = win_data; in vop2_win_init()
2668 win->type = win_data->type; in vop2_win_init()
2669 win->offset = win_data->base; in vop2_win_init()
2670 win->win_id = i; in vop2_win_init()
2671 win->vop2 = vop2; in vop2_win_init()
2680 vop2->registered_num_wins = vop2_data->win_size; in vop2_win_init()
2687 * Until that they read back the old value. As we read-modify-write
2688 * these registers mark them as non-volatile. This makes sure we read
2722 return -ENODEV; in vop2_bind()
2725 alloc_size = struct_size(vop2, win, vop2_data->win_size); in vop2_bind()
2728 return -ENOMEM; in vop2_bind()
2730 vop2->dev = dev; in vop2_bind()
2731 vop2->data = vop2_data; in vop2_bind()
2732 vop2->drm = drm; in vop2_bind()
2736 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vop"); in vop2_bind()
2738 drm_err(vop2->drm, "failed to get vop2 register byname\n"); in vop2_bind()
2739 return -EINVAL; in vop2_bind()
2742 vop2->regs = devm_ioremap_resource(dev, res); in vop2_bind()
2743 if (IS_ERR(vop2->regs)) in vop2_bind()
2744 return PTR_ERR(vop2->regs); in vop2_bind()
2745 vop2->len = resource_size(res); in vop2_bind()
2747 vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config); in vop2_bind()
2748 if (IS_ERR(vop2->map)) in vop2_bind()
2749 return PTR_ERR(vop2->map); in vop2_bind()
2755 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma-lut"); in vop2_bind()
2757 vop2->lut_regs = devm_ioremap_resource(dev, res); in vop2_bind()
2758 if (IS_ERR(vop2->lut_regs)) in vop2_bind()
2759 return PTR_ERR(vop2->lut_regs); in vop2_bind()
2762 vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); in vop2_bind()
2764 vop2->hclk = devm_clk_get(vop2->dev, "hclk"); in vop2_bind()
2765 if (IS_ERR(vop2->hclk)) { in vop2_bind()
2766 drm_err(vop2->drm, "failed to get hclk source\n"); in vop2_bind()
2767 return PTR_ERR(vop2->hclk); in vop2_bind()
2770 vop2->aclk = devm_clk_get(vop2->dev, "aclk"); in vop2_bind()
2771 if (IS_ERR(vop2->aclk)) { in vop2_bind()
2772 drm_err(vop2->drm, "failed to get aclk source\n"); in vop2_bind()
2773 return PTR_ERR(vop2->aclk); in vop2_bind()
2776 vop2->irq = platform_get_irq(pdev, 0); in vop2_bind()
2777 if (vop2->irq < 0) { in vop2_bind()
2778 drm_err(vop2->drm, "cannot find irq for vop2\n"); in vop2_bind()
2779 return vop2->irq; in vop2_bind()
2782 mutex_init(&vop2->vop2_lock); in vop2_bind()
2784 ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2); in vop2_bind()
2794 vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc, in vop2_bind()
2795 vop2->drm, ret); in vop2_bind()
2796 if (IS_ERR(vop2->rgb)) { in vop2_bind()
2797 if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) { in vop2_bind()
2798 ret = PTR_ERR(vop2->rgb); in vop2_bind()
2801 vop2->rgb = NULL; in vop2_bind()
2805 rockchip_drm_dma_init_device(vop2->drm, vop2->dev); in vop2_bind()
2807 pm_runtime_enable(&pdev->dev); in vop2_bind()
2823 if (vop2->rgb) in vop2_unbind()
2824 rockchip_rgb_fini(vop2->rgb); in vop2_unbind()