Lines Matching +full:dsp +full:- +full:standby
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>
36 #include <dt-bindings/soc/rockchip,vop2.h>
45 +----------+ +-------------+ +-----------+
48 +----------+ +-------------+ +---------------+ +-------------+ +-----------+
49 +----------+ +-------------+ |N from 6 layers| | |
50 | Cluster | | Sel 1 from 6| | Overlay0 +--->| Video Port0 | +-----------+
52 +----------+ +-------------+ +---------------+ +-------------+ | LVDS |
53 +----------+ +-------------+ +-----------+
55 | window0 | | Layer2 | +---------------+ +-------------+ +-----------+
56 +----------+ +-------------+ |N from 6 Layers| | | +--> | 1 from 3 |
57 +----------+ +-------------+ --------> | Overlay1 +--->| Video Port1 | | MIPI |
58 | Esmart | | Sel 1 from 6| --------> | | | | +-----------+
59 | Window1 | | Layer3 | +---------------+ +-------------+
60 +----------+ +-------------+ +-----------+
61 +----------+ +-------------+ | 1 from 3 |
62 | Smart | | Sel 1 from 6| +---------------+ +-------------+ | HDMI |
63 | Window0 | | Layer4 | |N from 6 Layers| | | +-----------+
64 +----------+ +-------------+ | Overlay2 +--->| Video Port2 |
65 +----------+ +-------------+ | | | | +-----------+
66 | Smart | | Sel 1 from 6| +---------------+ +-------------+ | 1 from 3 |
68 +----------+ +-------------+ +-----------+
102 VOP2_AFBC_FMT_INVALID = -1,
243 * bus-format types.
287 mutex_lock(&vop2->vop2_lock); in vop2_lock()
292 mutex_unlock(&vop2->vop2_lock); in vop2_unlock()
297 regmap_write(vop2->map, offset, v); in vop2_writel()
302 regmap_write(vp->vop2->map, vp->data->offset + offset, v); in vop2_vp_write()
309 regmap_read(vop2->map, offset, &val); in vop2_readl()
318 regmap_read(vp->vop2->map, vp->data->offset + offset, &val); in vop2_vp_read()
325 regmap_field_write(win->reg[reg], v); in vop2_win_write()
330 return win->data->feature & WIN_FEATURE_CLUSTER; in vop2_cluster_window()
344 struct vop2 *vop2 = vp->vop2; in vop2_cfg_done()
347 val |= BIT(vp->id) | (BIT(vp->id) << 16); in vop2_cfg_done()
349 regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, val); in vop2_cfg_done()
362 switch (format->format) { in vop2_get_bpp()
419 return -EINVAL; in vop2_convert_format()
542 if (vop2->data->soc_id == 3588) { in vop2_output_rg_swap()
579 for (i = 0 ; i < plane->modifier_count; i++) in rockchip_afbc()
580 if (plane->modifiers[i] == modifier) in rockchip_afbc()
590 struct vop2 *vop2 = win->vop2; in rockchip_vop2_mod_supported()
595 if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) { in rockchip_vop2_mod_supported()
598 drm_dbg_kms(vop2->drm, in rockchip_vop2_mod_supported()
606 if (vop2->data->soc_id == 3588) { in rockchip_vop2_mod_supported()
608 drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n"); in rockchip_vop2_mod_supported()
618 drm_dbg_kms(vop2->drm, "Unsupported format modifier 0x%llx\n", in rockchip_vop2_mod_supported()
633 if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) in vop2_half_block_enable()
642 struct drm_rect *src = &pstate->src; in vop2_afbc_transform_offset()
643 struct drm_framebuffer *fb = pstate->fb; in vop2_afbc_transform_offset()
644 u32 bpp = vop2_get_bpp(fb->format); in vop2_afbc_transform_offset()
645 u32 vir_width = (fb->pitches[0] << 3) / bpp; in vop2_afbc_transform_offset()
648 u32 act_xoffset = src->x1 >> 16; in vop2_afbc_transform_offset()
649 u32 act_yoffset = src->y1 >> 16; in vop2_afbc_transform_offset()
658 align16_crop = 16 - (height & 0xf); in vop2_afbc_transform_offset()
664 align64_crop = 64 - (height_tmp & 0x3f); in vop2_afbc_transform_offset()
668 switch (pstate->rotation & in vop2_afbc_transform_offset()
672 tx = 16 - ((act_xoffset + width) & 0xf); in vop2_afbc_transform_offset()
673 ty = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
676 tx = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
677 ty = vir_width - width - act_xoffset; in vop2_afbc_transform_offset()
684 tx = 16 - ((act_xoffset + width) & 0xf); in vop2_afbc_transform_offset()
689 ty = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
692 tx = bottom_crop_line_num - act_yoffset; in vop2_afbc_transform_offset()
697 ty = vir_width - width - act_xoffset; in vop2_afbc_transform_offset()
726 if ((pstate->rotation & DRM_MODE_ROTATE_270) || in vop2_get_cluster_lb_mode()
727 (pstate->rotation & DRM_MODE_ROTATE_90)) in vop2_get_cluster_lb_mode()
752 src--; in vop2_scale_factor()
753 dst--; in vop2_scale_factor()
755 fac = DIV_ROUND_UP(src << shift, dst) - 1; in vop2_scale_factor()
803 if (!(win->data->feature & WIN_FEATURE_AFBDC)) { in vop2_setup_scale()
805 drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n", in vop2_setup_scale()
806 win->data->name, dst_w); in vop2_setup_scale()
828 if (info->is_yuv) { in vop2_setup_scale()
829 cbcr_src_w /= info->hsub; in vop2_setup_scale()
830 cbcr_src_h /= info->vsub; in vop2_setup_scale()
884 * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
885 * RGB --> R2Y __/
887 * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020)
888 * RGB --> 709To2020->R2Y __/
890 * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709)
891 * RGB --> R2Y __/
893 * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
894 * RGB --> 709To2020->R2Y __/
896 * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709)
897 * RGB --> R2Y __/
899 * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601)
900 * RGB --> R2Y(601) __/
902 * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709)
903 * RGB --> bypass __/
905 * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020)
907 * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709)
909 * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601)
911 * 11. RGB --> bypass --> RGB_OUTPUT(709)
918 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); in vop2_setup_csc_mode()
919 int is_input_yuv = pstate->fb->format->is_yuv; in vop2_setup_csc_mode()
920 int is_output_yuv = is_yuv_output(vcstate->bus_format); in vop2_setup_csc_mode()
922 int output_csc = vcstate->color_space; in vop2_setup_csc_mode()
947 struct vop2 *vop2 = vp->vop2; in vop2_crtc_enable_irq()
949 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq); in vop2_crtc_enable_irq()
950 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq); in vop2_crtc_enable_irq()
955 struct vop2 *vop2 = vp->vop2; in vop2_crtc_disable_irq()
957 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16); in vop2_crtc_disable_irq()
964 ret = clk_prepare_enable(vop2->hclk); in vop2_core_clks_prepare_enable()
966 drm_err(vop2->drm, "failed to enable hclk - %d\n", ret); in vop2_core_clks_prepare_enable()
970 ret = clk_prepare_enable(vop2->aclk); in vop2_core_clks_prepare_enable()
972 drm_err(vop2->drm, "failed to enable aclk - %d\n", ret); in vop2_core_clks_prepare_enable()
976 ret = clk_prepare_enable(vop2->pclk); in vop2_core_clks_prepare_enable()
978 drm_err(vop2->drm, "failed to enable pclk - %d\n", ret); in vop2_core_clks_prepare_enable()
984 clk_disable_unprepare(vop2->aclk); in vop2_core_clks_prepare_enable()
986 clk_disable_unprepare(vop2->hclk); in vop2_core_clks_prepare_enable()
1006 ret = pm_runtime_resume_and_get(vop2->dev); in vop2_enable()
1008 drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret); in vop2_enable()
1014 pm_runtime_put_sync(vop2->dev); in vop2_enable()
1018 ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev); in vop2_enable()
1020 drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret); in vop2_enable()
1024 if (vop2->data->soc_id == 3566) in vop2_enable()
1027 if (vop2->data->soc_id == 3588) in vop2_enable()
1036 regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL, in vop2_enable()
1051 rockchip_drm_dma_detach_device(vop2->drm, vop2->dev); in vop2_disable()
1053 pm_runtime_put_sync(vop2->dev); in vop2_disable()
1055 regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register); in vop2_disable()
1057 clk_disable_unprepare(vop2->pclk); in vop2_disable()
1058 clk_disable_unprepare(vop2->aclk); in vop2_disable()
1059 clk_disable_unprepare(vop2->hclk); in vop2_disable()
1083 drm_err(vp->vop2->drm, "display LUT RAM enable timeout!\n"); in vop2_vp_dsp_lut_poll_disabled()
1108 return (vop2->data->soc_id != 3566 && vop2->data->soc_id != 3568); in vop2_supports_seamless_gamma_lut_update()
1113 const int nr_vps = vop2->data->nr_vps; in vop2_gamma_lut_in_use()
1117 if (vop2_vp_dsp_lut_is_enabled(&vop2->vps[gamma_en_vp_id])) in vop2_gamma_lut_in_use()
1120 return gamma_en_vp_id != nr_vps && gamma_en_vp_id != vp->id; in vop2_gamma_lut_in_use()
1127 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_disable()
1139 * Vop standby will take effect at end of current frame, in vop2_crtc_atomic_disable()
1140 * if dsp hold valid irq happen, it means standby complete. in vop2_crtc_atomic_disable()
1142 * we must wait standby complete when we want to disable aclk, in vop2_crtc_atomic_disable()
1145 reinit_completion(&vp->dsp_hold_completion); in vop2_crtc_atomic_disable()
1151 ret = wait_for_completion_timeout(&vp->dsp_hold_completion, in vop2_crtc_atomic_disable()
1154 drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id); in vop2_crtc_atomic_disable()
1158 clk_disable_unprepare(vp->dclk); in vop2_crtc_atomic_disable()
1160 vop2->enable_count--; in vop2_crtc_atomic_disable()
1162 if (!vop2->enable_count) in vop2_crtc_atomic_disable()
1167 if (crtc->state->event && !crtc->state->active) { in vop2_crtc_atomic_disable()
1168 spin_lock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_disable()
1169 drm_crtc_send_vblank_event(crtc, crtc->state->event); in vop2_crtc_atomic_disable()
1170 spin_unlock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_disable()
1172 crtc->state->event = NULL; in vop2_crtc_atomic_disable()
1180 struct drm_framebuffer *fb = pstate->fb; in vop2_plane_atomic_check()
1181 struct drm_crtc *crtc = pstate->crtc; in vop2_plane_atomic_check()
1186 struct drm_rect *dest = &pstate->dst; in vop2_plane_atomic_check()
1187 struct drm_rect *src = &pstate->src; in vop2_plane_atomic_check()
1197 vop2 = vp->vop2; in vop2_plane_atomic_check()
1198 vop2_data = vop2->data; in vop2_plane_atomic_check()
1200 cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc); in vop2_plane_atomic_check()
1202 return -EINVAL; in vop2_plane_atomic_check()
1210 if (!pstate->visible) in vop2_plane_atomic_check()
1213 format = vop2_convert_format(fb->format->format); in vop2_plane_atomic_check()
1219 drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n", in vop2_plane_atomic_check()
1222 pstate->visible = false; in vop2_plane_atomic_check()
1226 if (drm_rect_width(src) >> 16 > vop2_data->max_input.width || in vop2_plane_atomic_check()
1227 drm_rect_height(src) >> 16 > vop2_data->max_input.height) { in vop2_plane_atomic_check()
1228 drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n", in vop2_plane_atomic_check()
1231 vop2_data->max_input.width, in vop2_plane_atomic_check()
1232 vop2_data->max_input.height); in vop2_plane_atomic_check()
1233 return -EINVAL; in vop2_plane_atomic_check()
1240 if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) { in vop2_plane_atomic_check()
1241 drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n"); in vop2_plane_atomic_check()
1242 return -EINVAL; in vop2_plane_atomic_check()
1253 struct vop2 *vop2 = win->vop2; in vop2_plane_atomic_disable()
1255 drm_dbg(vop2->drm, "%s disable\n", win->data->name); in vop2_plane_atomic_disable()
1259 if (old_pstate && !old_pstate->crtc) in vop2_plane_atomic_disable()
1272 struct drm_plane_state *pstate = plane->state; in vop2_plane_setup_color_key()
1273 struct drm_framebuffer *fb = pstate->fb; in vop2_plane_setup_color_key()
1280 if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) { in vop2_plane_setup_color_key()
1285 switch (fb->format->format) { in vop2_plane_setup_color_key()
1319 struct drm_plane_state *pstate = plane->state; in vop2_plane_atomic_update()
1320 struct drm_crtc *crtc = pstate->crtc; in vop2_plane_atomic_update()
1323 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; in vop2_plane_atomic_update()
1324 struct vop2 *vop2 = win->vop2; in vop2_plane_atomic_update()
1325 struct drm_framebuffer *fb = pstate->fb; in vop2_plane_atomic_update()
1326 u32 bpp = vop2_get_bpp(fb->format); in vop2_plane_atomic_update()
1333 struct drm_rect *src = &pstate->src; in vop2_plane_atomic_update()
1334 struct drm_rect *dest = &pstate->dst; in vop2_plane_atomic_update()
1338 bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false; in vop2_plane_atomic_update()
1339 bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false; in vop2_plane_atomic_update()
1340 bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270; in vop2_plane_atomic_update()
1341 bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; in vop2_plane_atomic_update()
1355 if (!pstate->visible) { in vop2_plane_atomic_update()
1360 afbc_en = rockchip_afbc(plane, fb->modifier); in vop2_plane_atomic_update()
1362 offset = (src->x1 >> 16) * fb->format->cpp[0]; in vop2_plane_atomic_update()
1369 else if (pstate->rotation & DRM_MODE_REFLECT_Y) in vop2_plane_atomic_update()
1370 offset += ((src->y2 >> 16) - 1) * fb->pitches[0]; in vop2_plane_atomic_update()
1372 offset += (src->y1 >> 16) * fb->pitches[0]; in vop2_plane_atomic_update()
1374 rk_obj = to_rockchip_obj(fb->obj[0]); in vop2_plane_atomic_update()
1376 yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; in vop2_plane_atomic_update()
1377 if (fb->format->is_yuv) { in vop2_plane_atomic_update()
1378 int hsub = fb->format->hsub; in vop2_plane_atomic_update()
1379 int vsub = fb->format->vsub; in vop2_plane_atomic_update()
1381 offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub; in vop2_plane_atomic_update()
1382 offset += (src->y1 >> 16) * fb->pitches[1] / vsub; in vop2_plane_atomic_update()
1384 if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en) in vop2_plane_atomic_update()
1385 offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub; in vop2_plane_atomic_update()
1387 rk_obj = to_rockchip_obj(fb->obj[0]); in vop2_plane_atomic_update()
1388 uv_mst = rk_obj->dma_addr + offset + fb->offsets[1]; in vop2_plane_atomic_update()
1395 if (dest->x1 + dsp_w > adjusted_mode->hdisplay) { in vop2_plane_atomic_update()
1396 drm_dbg_kms(vop2->drm, in vop2_plane_atomic_update()
1397 "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n", in vop2_plane_atomic_update()
1398 vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay); in vop2_plane_atomic_update()
1399 dsp_w = adjusted_mode->hdisplay - dest->x1; in vop2_plane_atomic_update()
1407 if (dest->y1 + dsp_h > adjusted_mode->vdisplay) { in vop2_plane_atomic_update()
1408 drm_dbg_kms(vop2->drm, in vop2_plane_atomic_update()
1409 "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n", in vop2_plane_atomic_update()
1410 vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay); in vop2_plane_atomic_update()
1411 dsp_h = adjusted_mode->vdisplay - dest->y1; in vop2_plane_atomic_update()
1421 if (!(win->data->feature & WIN_FEATURE_AFBDC)) { in vop2_plane_atomic_update()
1423 drm_dbg_kms(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n", in vop2_plane_atomic_update()
1424 vp->id, win->data->name, actual_w); in vop2_plane_atomic_update()
1425 actual_w -= 1; in vop2_plane_atomic_update()
1430 drm_dbg_kms(vop2->drm, "vp%d %s actual_w[%d] not 4 pixel aligned\n", in vop2_plane_atomic_update()
1431 vp->id, win->data->name, actual_w); in vop2_plane_atomic_update()
1435 act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff); in vop2_plane_atomic_update()
1436 dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); in vop2_plane_atomic_update()
1438 format = vop2_convert_format(fb->format->format); in vop2_plane_atomic_update()
1441 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()
1442 vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h, in vop2_plane_atomic_update()
1443 dest->x1, dest->y1, in vop2_plane_atomic_update()
1444 &fb->format->format, in vop2_plane_atomic_update()
1447 if (vop2->data->soc_id > 3568) { in vop2_plane_atomic_update()
1448 vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id); in vop2_plane_atomic_update()
1449 vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id); in vop2_plane_atomic_update()
1450 vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id); in vop2_plane_atomic_update()
1460 block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16; in vop2_plane_atomic_update()
1462 afbc_format = vop2_convert_afbc_format(fb->format->format); in vop2_plane_atomic_update()
1465 if (fb->modifier & AFBC_FORMAT_MOD_YTR) in vop2_plane_atomic_update()
1474 stride = (fb->pitches[0] << 3) / bpp; in vop2_plane_atomic_update()
1476 drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n", in vop2_plane_atomic_update()
1477 vp->id, win->data->name, stride); in vop2_plane_atomic_update()
1482 uv_swap = vop2_afbc_uv_swap(fb->format->format); in vop2_plane_atomic_update()
1492 if (fb->format->is_yuv && bpp == 10) in vop2_plane_atomic_update()
1507 if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568) in vop2_plane_atomic_update()
1512 if (fb->modifier & AFBC_FORMAT_MOD_SPLIT) in vop2_plane_atomic_update()
1521 vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1)); in vop2_plane_atomic_update()
1522 vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16))); in vop2_plane_atomic_update()
1534 vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); in vop2_plane_atomic_update()
1548 rb_swap = vop2_win_rb_swap(fb->format->format); in vop2_plane_atomic_update()
1551 uv_swap = vop2_win_uv_swap(fb->format->format); in vop2_plane_atomic_update()
1555 if (fb->format->is_yuv) { in vop2_plane_atomic_update()
1556 vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4)); in vop2_plane_atomic_update()
1560 vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format); in vop2_plane_atomic_update()
1565 vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff)); in vop2_plane_atomic_update()
1569 dither_up = vop2_win_dither_up(fb->format->format); in vop2_plane_atomic_update()
1627 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id]; in vop2_crtc_write_gamma_lut()
1628 struct drm_color_lut *lut = crtc->state->gamma_lut->data; in vop2_crtc_write_gamma_lut()
1629 unsigned int i, bpc = ilog2(vp_data->gamma_lut_len); in vop2_crtc_write_gamma_lut()
1632 for (i = 0; i < crtc->gamma_size; i++) { in vop2_crtc_write_gamma_lut()
1637 writel(word, vop2->lut_regs + i * 4); in vop2_crtc_write_gamma_lut()
1646 FIELD_PREP(RK3588_LUT_PORT_SEL__GAMMA_AHB_WRITE_SEL, vp->id)); in vop2_crtc_atomic_set_gamma_seamless()
1661 vop2_writel(vop2, RK3568_LUT_PORT_SEL, vp->id); in vop2_crtc_atomic_set_gamma_rk356x()
1671 if (!vop2->lut_regs) in vop2_crtc_atomic_try_set_gamma()
1674 if (!crtc_state->gamma_lut) { in vop2_crtc_atomic_try_set_gamma()
1697 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); in vop2_dither_setup()
1699 switch (vcstate->bus_format) { in vop2_dither_setup()
1717 if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA) in vop2_dither_setup()
1727 struct drm_display_mode *mode = &crtc->state->adjusted_mode; in vop2_post_config()
1728 u16 vtotal = mode->crtc_vtotal; in vop2_post_config()
1729 u16 hdisplay = mode->crtc_hdisplay; in vop2_post_config()
1730 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; in vop2_post_config()
1731 u16 vdisplay = mode->crtc_vdisplay; in vop2_post_config()
1732 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; in vop2_post_config()
1737 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; in vop2_post_config()
1743 bg_dly = vp->data->pre_scan_max_dly[3]; in vop2_post_config()
1744 vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id), in vop2_post_config()
1747 pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; in vop2_post_config()
1752 hact_st += hdisplay * (100 - left_margin) / 200; in vop2_post_config()
1757 vact_st += vdisplay * (100 - top_margin) / 200; in vop2_post_config()
1773 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { in vop2_post_config()
1786 struct vop2 *vop2 = vp->vop2; in rk3568_set_intf_mux()
1787 struct drm_crtc *crtc = &vp->crtc; in rk3568_set_intf_mux()
1797 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id); in rk3568_set_intf_mux()
1801 regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); in rk3568_set_intf_mux()
1803 regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); in rk3568_set_intf_mux()
1808 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id); in rk3568_set_intf_mux()
1815 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id); in rk3568_set_intf_mux()
1822 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id); in rk3568_set_intf_mux()
1829 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); in rk3568_set_intf_mux()
1836 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id); in rk3568_set_intf_mux()
1843 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id); in rk3568_set_intf_mux()
1848 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); in rk3568_set_intf_mux()
1857 return crtc->state->adjusted_mode.crtc_clock * 1000LL; in rk3568_set_intf_mux()
1886 struct vop2 *vop2 = vp->vop2; in rk3588_calc_cru_cfg()
1887 struct drm_crtc *crtc = &vp->crtc; in rk3588_calc_cru_cfg()
1888 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; in rk3588_calc_cru_cfg()
1889 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); in rk3588_calc_cru_cfg()
1890 int output_mode = vcstate->output_mode; in rk3588_calc_cru_cfg()
1891 unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */ in rk3588_calc_cru_cfg()
1936 drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n", in rk3588_calc_cru_cfg()
1953 drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n", in rk3588_calc_cru_cfg()
1972 drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n", in rk3588_calc_cru_cfg()
2006 struct vop2 *vop2 = vp->vop2; in rk3588_set_intf_mux()
2031 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); in rk3588_set_intf_mux()
2033 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1)); in rk3588_set_intf_mux()
2034 regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5)); in rk3588_set_intf_mux()
2043 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); in rk3588_set_intf_mux()
2045 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4)); in rk3588_set_intf_mux()
2046 regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7)); in rk3588_set_intf_mux()
2055 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); in rk3588_set_intf_mux()
2056 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0)); in rk3588_set_intf_mux()
2065 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); in rk3588_set_intf_mux()
2066 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3)); in rk3588_set_intf_mux()
2072 val = rk3588_get_mipi_port_mux(vp->id); in rk3588_set_intf_mux()
2080 val = rk3588_get_mipi_port_mux(vp->id); in rk3588_set_intf_mux()
2087 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id); in rk3588_set_intf_mux()
2094 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); in rk3588_set_intf_mux()
2099 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); in rk3588_set_intf_mux()
2115 struct vop2 *vop2 = vp->vop2; in vop2_set_intf_mux()
2117 if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568) in vop2_set_intf_mux()
2119 else if (vop2->data->soc_id == 3588) in vop2_set_intf_mux()
2127 return us * mode->clock / mode->htotal / 1000; in us_to_vertical_line()
2134 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_enable()
2135 const struct vop2_data *vop2_data = vop2->data; in vop2_crtc_atomic_enable()
2136 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; in vop2_crtc_atomic_enable()
2138 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); in vop2_crtc_atomic_enable()
2139 struct drm_display_mode *mode = &crtc->state->adjusted_mode; in vop2_crtc_atomic_enable()
2140 unsigned long clock = mode->crtc_clock * 1000; in vop2_crtc_atomic_enable()
2141 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; in vop2_crtc_atomic_enable()
2142 u16 hdisplay = mode->crtc_hdisplay; in vop2_crtc_atomic_enable()
2143 u16 htotal = mode->crtc_htotal; in vop2_crtc_atomic_enable()
2144 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; in vop2_crtc_atomic_enable()
2146 u16 vdisplay = mode->crtc_vdisplay; in vop2_crtc_atomic_enable()
2147 u16 vtotal = mode->crtc_vtotal; in vop2_crtc_atomic_enable()
2148 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; in vop2_crtc_atomic_enable()
2149 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; in vop2_crtc_atomic_enable()
2158 drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n", in vop2_crtc_atomic_enable()
2159 hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", in vop2_crtc_atomic_enable()
2160 drm_mode_vrefresh(mode), vcstate->output_type, vp->id); in vop2_crtc_atomic_enable()
2164 ret = clk_prepare_enable(vp->dclk); in vop2_crtc_atomic_enable()
2166 drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n", in vop2_crtc_atomic_enable()
2167 vp->id, ret); in vop2_crtc_atomic_enable()
2172 if (!vop2->enable_count) in vop2_crtc_atomic_enable()
2175 vop2->enable_count++; in vop2_crtc_atomic_enable()
2177 vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format); in vop2_crtc_atomic_enable()
2182 if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) in vop2_crtc_atomic_enable()
2184 if (mode->flags & DRM_MODE_FLAG_PHSYNC) in vop2_crtc_atomic_enable()
2186 if (mode->flags & DRM_MODE_FLAG_PVSYNC) in vop2_crtc_atomic_enable()
2189 drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { in vop2_crtc_atomic_enable()
2195 * system cru may be the 1/2 or 1/4 of mode->clock. in vop2_crtc_atomic_enable()
2197 clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); in vop2_crtc_atomic_enable()
2205 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && in vop2_crtc_atomic_enable()
2206 !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT)) in vop2_crtc_atomic_enable()
2209 out_mode = vcstate->output_mode; in vop2_crtc_atomic_enable()
2213 if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) in vop2_crtc_atomic_enable()
2215 if (vop2_output_rg_swap(vop2, vcstate->bus_format)) in vop2_crtc_atomic_enable()
2218 if (vcstate->yuv_overlay) in vop2_crtc_atomic_enable()
2232 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { in vop2_crtc_atomic_enable()
2250 vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id), in vop2_crtc_atomic_enable()
2251 (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end); in vop2_crtc_atomic_enable()
2255 if (mode->flags & DRM_MODE_FLAG_DBLCLK) { in vop2_crtc_atomic_enable()
2262 clk_set_rate(vp->dclk, clock); in vop2_crtc_atomic_enable()
2282 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_check_gamma()
2285 if (!vp->vop2->lut_regs || !crtc_state->color_mgmt_changed || in vop2_crtc_atomic_check_gamma()
2286 !crtc_state->gamma_lut) in vop2_crtc_atomic_check_gamma()
2289 len = drm_color_lut_size(crtc_state->gamma_lut); in vop2_crtc_atomic_check_gamma()
2290 if (len != crtc->gamma_size) { in vop2_crtc_atomic_check_gamma()
2291 drm_dbg(vop2->drm, "Invalid LUT size; got %d, expected %d\n", in vop2_crtc_atomic_check_gamma()
2292 len, crtc->gamma_size); in vop2_crtc_atomic_check_gamma()
2293 return -EINVAL; in vop2_crtc_atomic_check_gamma()
2297 drm_info(vop2->drm, "Gamma LUT can be enabled for only one CRTC at a time\n"); in vop2_crtc_atomic_check_gamma()
2298 return -EINVAL; in vop2_crtc_atomic_check_gamma()
2320 if (nplanes > vp->nlayers) in vop2_crtc_atomic_check()
2321 return -EINVAL; in vop2_crtc_atomic_check()
2334 int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1; in vop2_parse_alpha()
2335 int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1; in vop2_parse_alpha()
2336 int src_color_mode = alpha_config->src_premulti_en ? in vop2_parse_alpha()
2338 int dst_color_mode = alpha_config->dst_premulti_en ? in vop2_parse_alpha()
2341 alpha->src_color_ctrl.val = 0; in vop2_parse_alpha()
2342 alpha->dst_color_ctrl.val = 0; in vop2_parse_alpha()
2343 alpha->src_alpha_ctrl.val = 0; in vop2_parse_alpha()
2344 alpha->dst_alpha_ctrl.val = 0; in vop2_parse_alpha()
2346 if (!alpha_config->src_pixel_alpha_en) in vop2_parse_alpha()
2347 alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; in vop2_parse_alpha()
2348 else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en) in vop2_parse_alpha()
2349 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX; in vop2_parse_alpha()
2351 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; in vop2_parse_alpha()
2353 alpha->src_color_ctrl.bits.alpha_en = 1; in vop2_parse_alpha()
2355 if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) { in vop2_parse_alpha()
2356 alpha->src_color_ctrl.bits.color_mode = src_color_mode; in vop2_parse_alpha()
2357 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; in vop2_parse_alpha()
2358 } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) { in vop2_parse_alpha()
2359 alpha->src_color_ctrl.bits.color_mode = src_color_mode; in vop2_parse_alpha()
2360 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE; in vop2_parse_alpha()
2362 alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL; in vop2_parse_alpha()
2363 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; in vop2_parse_alpha()
2365 alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8; in vop2_parse_alpha()
2366 alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
2367 alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; in vop2_parse_alpha()
2369 alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
2370 alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; in vop2_parse_alpha()
2371 alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; in vop2_parse_alpha()
2372 alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8; in vop2_parse_alpha()
2373 alpha->dst_color_ctrl.bits.color_mode = dst_color_mode; in vop2_parse_alpha()
2374 alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; in vop2_parse_alpha()
2376 alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
2377 alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode; in vop2_parse_alpha()
2378 alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; in vop2_parse_alpha()
2379 alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE; in vop2_parse_alpha()
2381 alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; in vop2_parse_alpha()
2382 if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en) in vop2_parse_alpha()
2383 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX; in vop2_parse_alpha()
2385 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; in vop2_parse_alpha()
2386 alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION; in vop2_parse_alpha()
2387 alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; in vop2_parse_alpha()
2397 vp = &vop2->vps[i]; in vop2_find_start_mixer_id_for_vp()
2398 used_layer += hweight32(vp->win_mask); in vop2_find_start_mixer_id_for_vp()
2416 bottom_win_pstate = main_win->base.state; in vop2_setup_cluster_alpha()
2418 dst_glb_alpha_val = main_win->base.state->alpha; in vop2_setup_cluster_alpha()
2420 if (!bottom_win_pstate->fb) in vop2_setup_cluster_alpha()
2433 switch (main_win->data->phys_id) { in vop2_setup_cluster_alpha()
2460 struct vop2 *vop2 = vp->vop2; in vop2_setup_alpha()
2472 mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id); in vop2_setup_alpha()
2475 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { in vop2_setup_alpha()
2478 if (plane->state->normalized_zpos == 0 && in vop2_setup_alpha()
2479 !is_opaque(plane->state->alpha) && in vop2_setup_alpha()
2487 dst_global_alpha = plane->state->alpha; in vop2_setup_alpha()
2491 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { in vop2_setup_alpha()
2493 int zpos = plane->state->normalized_zpos; in vop2_setup_alpha()
2501 if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) in vop2_setup_alpha()
2506 plane = &win->base; in vop2_setup_alpha()
2507 fb = plane->state->fb; in vop2_setup_alpha()
2509 pixel_alpha_en = fb->format->has_alpha; in vop2_setup_alpha()
2515 /* Cd = Cs + (1 - As) * Cd * Agd */ in vop2_setup_alpha()
2518 alpha_config.src_glb_alpha_value = plane->state->alpha; in vop2_setup_alpha()
2527 /* Cd = Cs + (1 - As) * Cd */ in vop2_setup_alpha()
2530 alpha_config.src_glb_alpha_value = plane->state->alpha; in vop2_setup_alpha()
2536 offset = (mixer_id + zpos - 1) * 0x10; in vop2_setup_alpha()
2547 if (vp->id == 0) { in vop2_setup_alpha()
2573 struct vop2 *vop2 = vp->vop2; in vop2_setup_layer_mixer()
2583 struct vop2_video_port *vp0 = &vop2->vps[0]; in vop2_setup_layer_mixer()
2584 struct vop2_video_port *vp1 = &vop2->vps[1]; in vop2_setup_layer_mixer()
2585 struct vop2_video_port *vp2 = &vop2->vps[2]; in vop2_setup_layer_mixer()
2586 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); in vop2_setup_layer_mixer()
2590 if (vcstate->yuv_overlay) in vop2_setup_layer_mixer()
2591 ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id); in vop2_setup_layer_mixer()
2593 ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id); in vop2_setup_layer_mixer()
2600 if (vp0->nlayers) in vop2_setup_layer_mixer()
2602 vp0->nlayers - 1); in vop2_setup_layer_mixer()
2606 if (vp1->nlayers) in vop2_setup_layer_mixer()
2608 (vp0->nlayers + vp1->nlayers - 1)); in vop2_setup_layer_mixer()
2612 if (vp2->nlayers) in vop2_setup_layer_mixer()
2614 (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1)); in vop2_setup_layer_mixer()
2621 for (i = 0; i < vp->id; i++) in vop2_setup_layer_mixer()
2622 ofs += vop2->vps[i].nlayers; in vop2_setup_layer_mixer()
2624 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { in vop2_setup_layer_mixer()
2628 layer_id = (u8)(plane->state->normalized_zpos + ofs); in vop2_setup_layer_mixer()
2633 for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) { in vop2_setup_layer_mixer()
2635 if (layer_sel_id == win->data->layer_sel_id) in vop2_setup_layer_mixer()
2642 for (i = 0; i < vop2->data->win_size; i++) { in vop2_setup_layer_mixer()
2643 old_win = &vop2->win[i]; in vop2_setup_layer_mixer()
2645 if (layer_sel_id == old_win->data->layer_sel_id) in vop2_setup_layer_mixer()
2649 switch (win->data->phys_id) { in vop2_setup_layer_mixer()
2652 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id); in vop2_setup_layer_mixer()
2656 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id); in vop2_setup_layer_mixer()
2660 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id); in vop2_setup_layer_mixer()
2664 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id); in vop2_setup_layer_mixer()
2668 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id); in vop2_setup_layer_mixer()
2672 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id); in vop2_setup_layer_mixer()
2676 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id); in vop2_setup_layer_mixer()
2680 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id); in vop2_setup_layer_mixer()
2684 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id); in vop2_setup_layer_mixer()
2688 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id); in vop2_setup_layer_mixer()
2693 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id); in vop2_setup_layer_mixer()
2699 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id); in vop2_setup_layer_mixer()
2712 for (i = 0; i < vop2->data->win_size; i++) { in vop2_setup_dly_for_windows()
2715 win = &vop2->win[i]; in vop2_setup_dly_for_windows()
2716 dly = win->delay; in vop2_setup_dly_for_windows()
2718 switch (win->data->phys_id) { in vop2_setup_dly_for_windows()
2752 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_begin()
2755 vp->win_mask = 0; in vop2_crtc_atomic_begin()
2760 win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT]; in vop2_crtc_atomic_begin()
2762 vp->win_mask |= BIT(win->data->phys_id); in vop2_crtc_atomic_begin()
2768 if (!vp->win_mask) in vop2_crtc_atomic_begin()
2781 struct vop2 *vop2 = vp->vop2; in vop2_crtc_atomic_flush()
2784 if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed) in vop2_crtc_atomic_flush()
2791 spin_lock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_flush()
2793 if (crtc->state->event) { in vop2_crtc_atomic_flush()
2795 vp->event = crtc->state->event; in vop2_crtc_atomic_flush()
2796 crtc->state->event = NULL; in vop2_crtc_atomic_flush()
2799 spin_unlock_irq(&crtc->dev->event_lock); in vop2_crtc_atomic_flush()
2816 drm_connector_list_iter_begin(crtc->dev, &conn_iter); in vop2_dump_connector_on_crtc()
2818 if (crtc->state->connector_mask & drm_connector_mask(connector)) in vop2_dump_connector_on_crtc()
2819 seq_printf(s, " Connector: %s\n", connector->name); in vop2_dump_connector_on_crtc()
2827 struct drm_plane_state *pstate = plane->state; in vop2_plane_state_dump()
2839 seq_printf(s, " %s: %s\n", win->data->name, !pstate ? in vop2_plane_state_dump()
2840 "DISABLED" : pstate->crtc ? "ACTIVE" : "DISABLED"); in vop2_plane_state_dump()
2842 if (!pstate || !pstate->fb) in vop2_plane_state_dump()
2845 fb = pstate->fb; in vop2_plane_state_dump()
2846 src = &pstate->src; in vop2_plane_state_dump()
2847 dst = &pstate->dst; in vop2_plane_state_dump()
2848 xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false; in vop2_plane_state_dump()
2849 ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false; in vop2_plane_state_dump()
2850 rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270; in vop2_plane_state_dump()
2851 rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; in vop2_plane_state_dump()
2853 seq_printf(s, "\twin_id: %d\n", win->win_id); in vop2_plane_state_dump()
2856 &fb->format->format, in vop2_plane_state_dump()
2857 drm_is_afbc(fb->modifier) ? "[AFBC]" : "", in vop2_plane_state_dump()
2858 pstate->alpha >> 8); in vop2_plane_state_dump()
2861 seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos); in vop2_plane_state_dump()
2862 seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16, in vop2_plane_state_dump()
2863 src->y1 >> 16, drm_rect_width(src) >> 16, in vop2_plane_state_dump()
2865 seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1, in vop2_plane_state_dump()
2868 for (i = 0; i < fb->format->num_planes; i++) { in vop2_plane_state_dump()
2869 obj = fb->obj[i]; in vop2_plane_state_dump()
2871 fb_addr = rk_obj->dma_addr + fb->offsets[i]; in vop2_plane_state_dump()
2874 i, &fb_addr, fb->pitches[i], fb->offsets[i]); in vop2_plane_state_dump()
2883 struct drm_crtc_state *cstate = crtc->state; in vop2_crtc_state_dump()
2889 seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ? in vop2_crtc_state_dump()
2890 "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED"); in vop2_crtc_state_dump()
2892 if (!cstate || !cstate->active) in vop2_crtc_state_dump()
2895 mode = &crtc->state->adjusted_mode; in vop2_crtc_state_dump()
2897 interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); in vop2_crtc_state_dump()
2900 seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format, in vop2_crtc_state_dump()
2901 drm_get_bus_format_name(vcstate->bus_format)); in vop2_crtc_state_dump()
2902 seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode); in vop2_crtc_state_dump()
2903 seq_printf(s, " color_space[%d]\n", vcstate->color_space); in vop2_crtc_state_dump()
2905 mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p", in vop2_crtc_state_dump()
2908 mode->clock, mode->crtc_clock, mode->type, mode->flags); in vop2_crtc_state_dump()
2909 seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start, in vop2_crtc_state_dump()
2910 mode->hsync_end, mode->htotal); in vop2_crtc_state_dump()
2911 seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start, in vop2_crtc_state_dump()
2912 mode->vsync_end, mode->vtotal); in vop2_crtc_state_dump()
2923 struct drm_info_node *node = s->private; in vop2_summary_show()
2924 struct drm_minor *minor = node->minor; in vop2_summary_show()
2925 struct drm_device *drm_dev = minor->dev; in vop2_summary_show()
2944 if (dump->en_mask && active_only) { in vop2_regs_print()
2945 val = vop2_readl(vop2, dump->base + dump->en_reg); in vop2_regs_print()
2946 if ((val & dump->en_mask) != dump->en_val) in vop2_regs_print()
2950 seq_printf(s, "\n%s:\n", dump->name); in vop2_regs_print()
2952 start = vop2->res->start + dump->base; in vop2_regs_print()
2953 for (i = 0; i < dump->size >> 2; i += 4) { in vop2_regs_print()
2955 vop2_readl(vop2, dump->base + (4 * i)), in vop2_regs_print()
2956 vop2_readl(vop2, dump->base + (4 * (i + 1))), in vop2_regs_print()
2957 vop2_readl(vop2, dump->base + (4 * (i + 2))), in vop2_regs_print()
2958 vop2_readl(vop2, dump->base + (4 * (i + 3)))); in vop2_regs_print()
2964 struct drm_info_node *node = s->private; in __vop2_regs_dump()
2965 struct vop2 *vop2 = node->info_ent->data; in __vop2_regs_dump()
2966 struct drm_minor *minor = node->minor; in __vop2_regs_dump()
2967 struct drm_device *drm_dev = minor->dev; in __vop2_regs_dump()
2973 regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register); in __vop2_regs_dump()
2975 if (vop2->enable_count) { in __vop2_regs_dump()
2976 for (i = 0; i < vop2->data->regs_dump_size; i++) { in __vop2_regs_dump()
2977 dump = &vop2->data->regs_dump[i]; in __vop2_regs_dump()
3011 root = debugfs_create_dir("vop2", minor->debugfs_root); in vop2_debugfs_init()
3025 struct vop2 *vop2 = vp->vop2; in vop2_crtc_late_register()
3028 vop2_debugfs_init(vop2, crtc->dev->primary); in vop2_crtc_late_register()
3037 if (WARN_ON(!crtc->state)) in vop2_crtc_duplicate_state()
3040 vcstate = kmemdup(to_rockchip_crtc_state(crtc->state), in vop2_crtc_duplicate_state()
3045 __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base); in vop2_crtc_duplicate_state()
3047 return &vcstate->base; in vop2_crtc_duplicate_state()
3055 __drm_atomic_helper_crtc_destroy_state(&vcstate->base); in vop2_crtc_destroy_state()
3064 if (crtc->state) in vop2_crtc_reset()
3065 vop2_crtc_destroy_state(crtc, crtc->state); in vop2_crtc_reset()
3068 __drm_atomic_helper_crtc_reset(crtc, &vcstate->base); in vop2_crtc_reset()
3088 const struct vop2_data *vop2_data = vop2->data; in vop2_isr()
3094 * The irq is shared with the iommu. If the runtime-pm state of the in vop2_isr()
3095 * vop2-device is disabled the irq has to be targeted at the iommu. in vop2_isr()
3097 if (!pm_runtime_get_if_in_use(vop2->dev)) in vop2_isr()
3100 for (i = 0; i < vop2_data->nr_vps; i++) { in vop2_isr()
3101 struct vop2_video_port *vp = &vop2->vps[i]; in vop2_isr()
3102 struct drm_crtc *crtc = &vp->crtc; in vop2_isr()
3105 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id)); in vop2_isr()
3106 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs); in vop2_isr()
3109 complete(&vp->dsp_hold_completion); in vop2_isr()
3115 spin_lock(&crtc->dev->event_lock); in vop2_isr()
3116 if (vp->event) { in vop2_isr()
3119 if (!(val & BIT(vp->id))) { in vop2_isr()
3120 drm_crtc_send_vblank_event(crtc, vp->event); in vop2_isr()
3121 vp->event = NULL; in vop2_isr()
3125 spin_unlock(&crtc->dev->event_lock); in vop2_isr()
3131 drm_err_ratelimited(vop2->drm, in vop2_isr()
3133 vp->id); in vop2_isr()
3145 drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n"); in vop2_isr()
3150 pm_runtime_put(vop2->dev); in vop2_isr()
3158 const struct vop2_win_data *win_data = win->data; in vop2_plane_init()
3164 ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs, in vop2_plane_init()
3165 &vop2_plane_funcs, win_data->formats, in vop2_plane_init()
3166 win_data->nformats, in vop2_plane_init()
3167 win_data->format_modifiers, in vop2_plane_init()
3168 win->type, win_data->name); in vop2_plane_init()
3170 drm_err(vop2->drm, "failed to initialize plane %d\n", ret); in vop2_plane_init()
3174 drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs); in vop2_plane_init()
3176 if (win->data->supported_rotations) in vop2_plane_init()
3177 drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0, in vop2_plane_init()
3179 win->data->supported_rotations); in vop2_plane_init()
3180 drm_plane_create_alpha_property(&win->base); in vop2_plane_init()
3181 drm_plane_create_blend_mode_property(&win->base, blend_caps); in vop2_plane_init()
3182 drm_plane_create_zpos_property(&win->base, win->win_id, 0, in vop2_plane_init()
3183 vop2->registered_num_wins - 1); in vop2_plane_init()
3192 for (i = 0; i < vop2->data->nr_vps; i++) { in find_vp_without_primary()
3193 struct vop2_video_port *vp = &vop2->vps[i]; in find_vp_without_primary()
3195 if (!vp->crtc.port) in find_vp_without_primary()
3197 if (vp->primary_plane) in find_vp_without_primary()
3208 const struct vop2_data *vop2_data = vop2->data; in vop2_create_crtcs()
3209 struct drm_device *drm = vop2->drm; in vop2_create_crtcs()
3210 struct device *dev = vop2->dev; in vop2_create_crtcs()
3217 for (i = 0; i < vop2_data->nr_vps; i++) { in vop2_create_crtcs()
3222 vp_data = &vop2_data->vp[i]; in vop2_create_crtcs()
3223 vp = &vop2->vps[i]; in vop2_create_crtcs()
3224 vp->vop2 = vop2; in vop2_create_crtcs()
3225 vp->id = vp_data->id; in vop2_create_crtcs()
3226 vp->data = vp_data; in vop2_create_crtcs()
3228 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); in vop2_create_crtcs()
3229 vp->dclk = devm_clk_get(vop2->dev, dclk_name); in vop2_create_crtcs()
3230 if (IS_ERR(vp->dclk)) { in vop2_create_crtcs()
3231 drm_err(vop2->drm, "failed to get %s\n", dclk_name); in vop2_create_crtcs()
3232 return PTR_ERR(vp->dclk); in vop2_create_crtcs()
3235 np = of_graph_get_remote_node(dev->of_node, i, -1); in vop2_create_crtcs()
3237 drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i); in vop2_create_crtcs()
3242 port = of_graph_get_port_by_id(dev->of_node, i); in vop2_create_crtcs()
3244 drm_err(vop2->drm, "no port node found for video_port%d\n", i); in vop2_create_crtcs()
3245 return -ENOENT; in vop2_create_crtcs()
3248 vp->crtc.port = port; in vop2_create_crtcs()
3253 for (i = 0; i < vop2->registered_num_wins; i++) { in vop2_create_crtcs()
3254 struct vop2_win *win = &vop2->win[i]; in vop2_create_crtcs()
3257 if (vop2->data->soc_id == 3566) { in vop2_create_crtcs()
3263 switch (win->data->phys_id) { in vop2_create_crtcs()
3271 if (win->type == DRM_PLANE_TYPE_PRIMARY) { in vop2_create_crtcs()
3275 vp->primary_plane = win; in vop2_create_crtcs()
3279 win->type = DRM_PLANE_TYPE_OVERLAY; in vop2_create_crtcs()
3283 if (win->type == DRM_PLANE_TYPE_OVERLAY) in vop2_create_crtcs()
3284 possible_crtcs = (1 << nvps) - 1; in vop2_create_crtcs()
3288 drm_err(vop2->drm, "failed to init plane %s: %d\n", in vop2_create_crtcs()
3289 win->data->name, ret); in vop2_create_crtcs()
3294 for (i = 0; i < vop2_data->nr_vps; i++) { in vop2_create_crtcs()
3295 vp = &vop2->vps[i]; in vop2_create_crtcs()
3297 if (!vp->crtc.port) in vop2_create_crtcs()
3300 plane = &vp->primary_plane->base; in vop2_create_crtcs()
3302 ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL, in vop2_create_crtcs()
3304 "video_port%d", vp->id); in vop2_create_crtcs()
3306 drm_err(vop2->drm, "crtc init for video_port%d failed\n", i); in vop2_create_crtcs()
3310 drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs); in vop2_create_crtcs()
3311 if (vop2->lut_regs) { in vop2_create_crtcs()
3312 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; in vop2_create_crtcs()
3314 drm_mode_crtc_set_gamma_size(&vp->crtc, vp_data->gamma_lut_len); in vop2_create_crtcs()
3315 drm_crtc_enable_color_mgmt(&vp->crtc, 0, false, vp_data->gamma_lut_len); in vop2_create_crtcs()
3317 init_completion(&vp->dsp_hold_completion); in vop2_create_crtcs()
3325 for (i = 0; i < vop2->data->nr_vps; i++) { in vop2_create_crtcs()
3326 struct vop2_video_port *vp = &vop2->vps[i]; in vop2_create_crtcs()
3328 if (vp->crtc.port) in vop2_create_crtcs()
3329 vp->nlayers = vop2_data->win_size / nvps; in vop2_create_crtcs()
3337 struct drm_device *drm = vop2->drm; in vop2_destroy_crtcs()
3338 struct list_head *crtc_list = &drm->mode_config.crtc_list; in vop2_destroy_crtcs()
3339 struct list_head *plane_list = &drm->mode_config.plane_list; in vop2_destroy_crtcs()
3351 of_node_put(crtc->port); in vop2_destroy_crtcs()
3358 struct device_node *node = vop2->dev->of_node; in vop2_find_rgb_encoder()
3362 for (i = 0; i < vop2->data->nr_vps; i++) { in vop2_find_rgb_encoder()
3372 return -ENOENT; in vop2_find_rgb_encoder()
3445 struct vop2 *vop2 = win->vop2; in vop2_cluster_init()
3452 return -ENOMEM; in vop2_cluster_init()
3456 cluster_regs[i].reg += win->offset; in vop2_cluster_init()
3458 ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, in vop2_cluster_init()
3533 struct vop2 *vop2 = win->vop2; in vop2_esmart_init()
3540 return -ENOMEM; in vop2_esmart_init()
3544 esmart_regs[i].reg += win->offset; in vop2_esmart_init()
3546 ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg, in vop2_esmart_init()
3557 const struct vop2_data *vop2_data = vop2->data; in vop2_win_init()
3561 for (i = 0; i < vop2_data->win_size; i++) { in vop2_win_init()
3562 const struct vop2_win_data *win_data = &vop2_data->win[i]; in vop2_win_init()
3564 win = &vop2->win[i]; in vop2_win_init()
3565 win->data = win_data; in vop2_win_init()
3566 win->type = win_data->type; in vop2_win_init()
3567 win->offset = win_data->base; in vop2_win_init()
3568 win->win_id = i; in vop2_win_init()
3569 win->vop2 = vop2; in vop2_win_init()
3578 vop2->registered_num_wins = vop2_data->win_size; in vop2_win_init()
3585 * Until that they read back the old value. As we read-modify-write
3586 * these registers mark them as non-volatile. This makes sure we read
3620 return -ENODEV; in vop2_bind()
3623 alloc_size = struct_size(vop2, win, vop2_data->win_size); in vop2_bind()
3626 return -ENOMEM; in vop2_bind()
3628 vop2->dev = dev; in vop2_bind()
3629 vop2->data = vop2_data; in vop2_bind()
3630 vop2->drm = drm; in vop2_bind()
3636 drm_err(vop2->drm, "failed to get vop2 register byname\n"); in vop2_bind()
3637 return -EINVAL; in vop2_bind()
3640 vop2->res = res; in vop2_bind()
3641 vop2->regs = devm_ioremap_resource(dev, res); in vop2_bind()
3642 if (IS_ERR(vop2->regs)) in vop2_bind()
3643 return PTR_ERR(vop2->regs); in vop2_bind()
3644 vop2->len = resource_size(res); in vop2_bind()
3646 vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config); in vop2_bind()
3647 if (IS_ERR(vop2->map)) in vop2_bind()
3648 return PTR_ERR(vop2->map); in vop2_bind()
3654 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma-lut"); in vop2_bind()
3656 vop2->lut_regs = devm_ioremap_resource(dev, res); in vop2_bind()
3657 if (IS_ERR(vop2->lut_regs)) in vop2_bind()
3658 return PTR_ERR(vop2->lut_regs); in vop2_bind()
3660 if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_GRF) { in vop2_bind()
3661 vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); in vop2_bind()
3662 if (IS_ERR(vop2->sys_grf)) in vop2_bind()
3663 return dev_err_probe(dev, PTR_ERR(vop2->sys_grf), "cannot get sys_grf"); in vop2_bind()
3666 if (vop2_data->feature & VOP2_FEATURE_HAS_VOP_GRF) { in vop2_bind()
3667 vop2->vop_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf"); in vop2_bind()
3668 if (IS_ERR(vop2->vop_grf)) in vop2_bind()
3669 return dev_err_probe(dev, PTR_ERR(vop2->vop_grf), "cannot get vop_grf"); in vop2_bind()
3672 if (vop2_data->feature & VOP2_FEATURE_HAS_VO1_GRF) { in vop2_bind()
3673 vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf"); in vop2_bind()
3674 if (IS_ERR(vop2->vo1_grf)) in vop2_bind()
3675 return dev_err_probe(dev, PTR_ERR(vop2->vo1_grf), "cannot get vo1_grf"); in vop2_bind()
3678 if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_PMU) { in vop2_bind()
3679 vop2->sys_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu"); in vop2_bind()
3680 if (IS_ERR(vop2->sys_pmu)) in vop2_bind()
3681 return dev_err_probe(dev, PTR_ERR(vop2->sys_pmu), "cannot get sys_pmu"); in vop2_bind()
3684 vop2->hclk = devm_clk_get(vop2->dev, "hclk"); in vop2_bind()
3685 if (IS_ERR(vop2->hclk)) { in vop2_bind()
3686 drm_err(vop2->drm, "failed to get hclk source\n"); in vop2_bind()
3687 return PTR_ERR(vop2->hclk); in vop2_bind()
3690 vop2->aclk = devm_clk_get(vop2->dev, "aclk"); in vop2_bind()
3691 if (IS_ERR(vop2->aclk)) { in vop2_bind()
3692 drm_err(vop2->drm, "failed to get aclk source\n"); in vop2_bind()
3693 return PTR_ERR(vop2->aclk); in vop2_bind()
3696 vop2->pclk = devm_clk_get_optional(vop2->dev, "pclk_vop"); in vop2_bind()
3697 if (IS_ERR(vop2->pclk)) { in vop2_bind()
3698 drm_err(vop2->drm, "failed to get pclk source\n"); in vop2_bind()
3699 return PTR_ERR(vop2->pclk); in vop2_bind()
3702 vop2->irq = platform_get_irq(pdev, 0); in vop2_bind()
3703 if (vop2->irq < 0) { in vop2_bind()
3704 drm_err(vop2->drm, "cannot find irq for vop2\n"); in vop2_bind()
3705 return vop2->irq; in vop2_bind()
3708 mutex_init(&vop2->vop2_lock); in vop2_bind()
3710 ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2); in vop2_bind()
3720 vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc, in vop2_bind()
3721 vop2->drm, ret); in vop2_bind()
3722 if (IS_ERR(vop2->rgb)) { in vop2_bind()
3723 if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) { in vop2_bind()
3724 ret = PTR_ERR(vop2->rgb); in vop2_bind()
3727 vop2->rgb = NULL; in vop2_bind()
3731 rockchip_drm_dma_init_device(vop2->drm, vop2->dev); in vop2_bind()
3733 pm_runtime_enable(&pdev->dev); in vop2_bind()
3749 if (vop2->rgb) in vop2_unbind()
3750 rockchip_rgb_fini(vop2->rgb); in vop2_unbind()