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>
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,
107 * bus-format types.
141 mutex_lock(&vop2->vop2_lock);
146 mutex_unlock(&vop2->vop2_lock);
160 struct vop2 *vop2 = vp->vop2;
163 val |= BIT(vp->id) | (BIT(vp->id) << 16);
165 regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, val);
178 switch (format->format) {
235 return -EINVAL;
358 if (vop2->version == VOP_VERSION_RK3588) {
395 for (i = 0 ; i < plane->modifier_count; i++)
396 if (plane->modifiers[i] == modifier)
406 struct vop2 *vop2 = win->vop2;
411 if (vop2->version == VOP_VERSION_RK3568) {
414 drm_dbg_kms(vop2->drm,
422 if (vop2->version == VOP_VERSION_RK3588) {
424 drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
434 drm_dbg_kms(vop2->drm, "Unsupported format modifier 0x%llx\n",
449 if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90))
458 struct drm_rect *src = &pstate->src;
459 struct drm_framebuffer *fb = pstate->fb;
460 u32 bpp = vop2_get_bpp(fb->format);
461 u32 vir_width = (fb->pitches[0] << 3) / bpp;
464 u32 act_xoffset = src->x1 >> 16;
465 u32 act_yoffset = src->y1 >> 16;
474 align16_crop = 16 - (height & 0xf);
480 align64_crop = 64 - (height_tmp & 0x3f);
484 switch (pstate->rotation &
488 tx = 16 - ((act_xoffset + width) & 0xf);
489 ty = bottom_crop_line_num - act_yoffset;
492 tx = bottom_crop_line_num - act_yoffset;
493 ty = vir_width - width - act_xoffset;
500 tx = 16 - ((act_xoffset + width) & 0xf);
505 ty = bottom_crop_line_num - act_yoffset;
508 tx = bottom_crop_line_num - act_yoffset;
513 ty = vir_width - width - act_xoffset;
542 if ((pstate->rotation & DRM_MODE_ROTATE_270) ||
543 (pstate->rotation & DRM_MODE_ROTATE_90))
568 src--;
569 dst--;
571 fac = DIV_ROUND_UP(src << shift, dst) - 1;
619 if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
621 drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n",
622 win->data->name, dst_w);
644 if (info->is_yuv) {
645 cbcr_src_w /= info->hsub;
646 cbcr_src_h /= info->vsub;
700 * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
701 * RGB --> R2Y __/
703 * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020)
704 * RGB --> 709To2020->R2Y __/
706 * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709)
707 * RGB --> R2Y __/
709 * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
710 * RGB --> 709To2020->R2Y __/
712 * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709)
713 * RGB --> R2Y __/
715 * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601)
716 * RGB --> R2Y(601) __/
718 * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709)
719 * RGB --> bypass __/
721 * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020)
723 * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709)
725 * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601)
727 * 11. RGB --> bypass --> RGB_OUTPUT(709)
734 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
735 int is_input_yuv = pstate->fb->format->is_yuv;
736 int is_output_yuv = is_yuv_output(vcstate->bus_format);
738 int output_csc = vcstate->color_space;
763 struct vop2 *vop2 = vp->vop2;
765 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq);
766 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq);
771 struct vop2 *vop2 = vp->vop2;
773 vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16);
780 ret = clk_prepare_enable(vop2->hclk);
782 drm_err(vop2->drm, "failed to enable hclk - %d\n", ret);
786 ret = clk_prepare_enable(vop2->aclk);
788 drm_err(vop2->drm, "failed to enable aclk - %d\n", ret);
792 ret = clk_prepare_enable(vop2->pclk);
794 drm_err(vop2->drm, "failed to enable pclk - %d\n", ret);
800 clk_disable_unprepare(vop2->aclk);
802 clk_disable_unprepare(vop2->hclk);
823 ret = pm_runtime_resume_and_get(vop2->dev);
825 drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
831 pm_runtime_put_sync(vop2->dev);
835 ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev);
837 drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret);
842 if (version != vop2->version) {
843 drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
851 if (vop2->data->soc_id == 3566)
854 if (vop2->version == VOP_VERSION_RK3588)
863 regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL,
878 rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
880 pm_runtime_put_sync(vop2->dev);
882 regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
884 clk_disable_unprepare(vop2->pclk);
885 clk_disable_unprepare(vop2->aclk);
886 clk_disable_unprepare(vop2->hclk);
910 drm_err(vp->vop2->drm, "display LUT RAM enable timeout!\n");
935 return vop2->version != VOP_VERSION_RK3568;
940 const int nr_vps = vop2->data->nr_vps;
944 if (vop2_vp_dsp_lut_is_enabled(&vop2->vps[gamma_en_vp_id]))
947 return gamma_en_vp_id != nr_vps && gamma_en_vp_id != vp->id;
954 struct vop2 *vop2 = vp->vop2;
966 * Vop standby will take effect at end of current frame,
967 * if dsp hold valid irq happen, it means standby complete.
969 * we must wait standby complete when we want to disable aclk,
972 reinit_completion(&vp->dsp_hold_completion);
978 ret = wait_for_completion_timeout(&vp->dsp_hold_completion,
981 drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id);
985 if (vp->dclk_src)
986 clk_set_parent(vp->dclk, vp->dclk_src);
988 clk_disable_unprepare(vp->dclk);
990 vop2->enable_count--;
992 if (!vop2->enable_count)
997 if (crtc->state->event && !crtc->state->active) {
998 spin_lock_irq(&crtc->dev->event_lock);
999 drm_crtc_send_vblank_event(crtc, crtc->state->event);
1000 spin_unlock_irq(&crtc->dev->event_lock);
1002 crtc->state->event = NULL;
1010 struct drm_framebuffer *fb = pstate->fb;
1011 struct drm_crtc *crtc = pstate->crtc;
1016 struct drm_rect *dest = &pstate->dst;
1017 struct drm_rect *src = &pstate->src;
1027 vop2 = vp->vop2;
1028 vop2_data = vop2->data;
1030 cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc);
1032 return -EINVAL;
1040 if (!pstate->visible)
1043 format = vop2_convert_format(fb->format->format);
1049 drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n",
1052 pstate->visible = false;
1056 if (drm_rect_width(src) >> 16 > vop2_data->max_input.width ||
1057 drm_rect_height(src) >> 16 > vop2_data->max_input.height) {
1058 drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n",
1061 vop2_data->max_input.width,
1062 vop2_data->max_input.height);
1063 return -EINVAL;
1070 if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) {
1071 drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n");
1072 return -EINVAL;
1083 struct vop2 *vop2 = win->vop2;
1085 drm_dbg(vop2->drm, "%s disable\n", win->data->name);
1089 if (old_pstate && !old_pstate->crtc)
1102 struct drm_plane_state *pstate = plane->state;
1103 struct drm_framebuffer *fb = pstate->fb;
1110 if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) {
1115 switch (fb->format->format) {
1149 struct drm_plane_state *pstate = plane->state;
1150 struct drm_crtc *crtc = pstate->crtc;
1153 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1154 struct vop2 *vop2 = win->vop2;
1155 struct drm_framebuffer *fb = pstate->fb;
1156 u32 bpp = vop2_get_bpp(fb->format);
1163 struct drm_rect *src = &pstate->src;
1164 struct drm_rect *dest = &pstate->dst;
1168 bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
1169 bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
1170 bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
1171 bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
1185 if (!pstate->visible) {
1190 afbc_en = rockchip_afbc(plane, fb->modifier);
1192 offset = (src->x1 >> 16) * fb->format->cpp[0];
1199 else if (pstate->rotation & DRM_MODE_REFLECT_Y)
1200 offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
1202 offset += (src->y1 >> 16) * fb->pitches[0];
1204 rk_obj = to_rockchip_obj(fb->obj[0]);
1206 yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
1207 if (fb->format->is_yuv) {
1208 int hsub = fb->format->hsub;
1209 int vsub = fb->format->vsub;
1211 offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub;
1212 offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
1214 if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en)
1215 offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub;
1217 rk_obj = to_rockchip_obj(fb->obj[0]);
1218 uv_mst = rk_obj->dma_addr + offset + fb->offsets[1];
1225 if (dest->x1 + dsp_w > adjusted_mode->hdisplay) {
1226 drm_dbg_kms(vop2->drm,
1227 "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
1228 vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay);
1229 dsp_w = adjusted_mode->hdisplay - dest->x1;
1237 if (dest->y1 + dsp_h > adjusted_mode->vdisplay) {
1238 drm_dbg_kms(vop2->drm,
1239 "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
1240 vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay);
1241 dsp_h = adjusted_mode->vdisplay - dest->y1;
1251 if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
1253 drm_dbg_kms(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n",
1254 vp->id, win->data->name, actual_w);
1255 actual_w -= 1;
1260 drm_dbg_kms(vop2->drm, "vp%d %s actual_w[%d] not 4 pixel aligned\n",
1261 vp->id, win->data->name, actual_w);
1265 act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
1266 dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff);
1268 format = vop2_convert_format(fb->format->format);
1271 drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n",
1272 vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h,
1273 dest->x1, dest->y1,
1274 &fb->format->format,
1277 if (vop2->version > VOP_VERSION_RK3568) {
1278 vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
1279 vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
1280 vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
1283 if (vop2->version >= VOP_VERSION_RK3576)
1284 vop2_win_write(win, VOP2_WIN_VP_SEL, vp->id);
1293 block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16;
1295 afbc_format = vop2_convert_afbc_format(fb->format->format);
1298 if (fb->modifier & AFBC_FORMAT_MOD_YTR)
1307 stride = (fb->pitches[0] << 3) / bpp;
1309 drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
1310 vp->id, win->data->name, stride);
1315 uv_swap = vop2_afbc_uv_swap(fb->format->format);
1325 if (fb->format->is_yuv && bpp == 10)
1340 if (vop2->version == VOP_VERSION_RK3568)
1345 if (fb->modifier & AFBC_FORMAT_MOD_SPLIT)
1350 if (vop2->version >= VOP_VERSION_RK3576) {
1359 vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1));
1360 vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16)));
1372 vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4));
1386 rb_swap = vop2_win_rb_swap(fb->format->format);
1388 uv_swap = vop2_win_uv_swap(fb->format->format);
1391 if (fb->format->is_yuv) {
1392 vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4));
1396 vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format);
1401 vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff));
1405 dither_up = vop2_win_dither_up(fb->format->format);
1463 const struct vop2_video_port_data *vp_data = &vop2->data->vp[vp->id];
1464 struct drm_color_lut *lut = crtc->state->gamma_lut->data;
1465 unsigned int i, bpc = ilog2(vp_data->gamma_lut_len);
1468 for (i = 0; i < crtc->gamma_size; i++) {
1473 writel(word, vop2->lut_regs + i * 4);
1482 FIELD_PREP(RK3588_LUT_PORT_SEL__GAMMA_AHB_WRITE_SEL, vp->id));
1497 vop2_writel(vop2, RK3568_LUT_PORT_SEL, vp->id);
1507 if (!vop2->lut_regs)
1510 if (!crtc_state->gamma_lut) {
1533 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1535 switch (vcstate->bus_format) {
1553 if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA)
1563 struct vop2 *vop2 = vp->vop2;
1564 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1565 u16 vtotal = mode->crtc_vtotal;
1566 u16 hdisplay = mode->crtc_hdisplay;
1567 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1568 u16 vdisplay = mode->crtc_vdisplay;
1569 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1577 vop2->ops->setup_bg_dly(vp);
1581 hact_st += hdisplay * (100 - left_margin) / 200;
1586 vact_st += vdisplay * (100 - top_margin) / 200;
1602 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1615 return us * mode->clock / mode->htotal / 1000;
1622 struct vop2 *vop2 = vp->vop2;
1623 const struct vop2_data *vop2_data = vop2->data;
1624 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
1626 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1627 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1628 unsigned long clock = mode->crtc_clock * 1000;
1629 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
1630 u16 hdisplay = mode->crtc_hdisplay;
1631 u16 htotal = mode->crtc_htotal;
1632 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1634 u16 vdisplay = mode->crtc_vdisplay;
1635 u16 vtotal = mode->crtc_vtotal;
1636 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
1637 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1646 drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n",
1647 hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
1648 drm_mode_vrefresh(mode), vcstate->output_type, vp->id);
1652 ret = clk_prepare_enable(vp->dclk);
1654 drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n",
1655 vp->id, ret);
1660 if (!vop2->enable_count)
1663 vop2->enable_count++;
1665 vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format);
1670 if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
1672 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
1674 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
1677 drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
1683 * system cru may be the 1/2 or 1/4 of mode->clock.
1685 clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
1693 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
1694 !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))
1697 out_mode = vcstate->output_mode;
1701 if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode))
1703 if (vop2_output_rg_swap(vop2, vcstate->bus_format))
1706 if (vcstate->yuv_overlay)
1720 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1738 vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id),
1739 (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end);
1743 if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
1754 if ((vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) && clock <= VOP2_MAX_DCLK_RATE) {
1755 drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
1758 if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
1759 if (!vop2->pll_hdmiphy0)
1762 if (!vp->dclk_src)
1763 vp->dclk_src = clk_get_parent(vp->dclk);
1765 ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
1767 drm_warn(vop2->drm,
1772 if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI1) {
1773 if (!vop2->pll_hdmiphy1)
1776 if (!vp->dclk_src)
1777 vp->dclk_src = clk_get_parent(vp->dclk);
1779 ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy1);
1781 drm_warn(vop2->drm,
1788 clk_set_rate(vp->dclk, clock);
1808 struct vop2 *vop2 = vp->vop2;
1811 if (!vp->vop2->lut_regs || !crtc_state->color_mgmt_changed ||
1812 !crtc_state->gamma_lut)
1815 len = drm_color_lut_size(crtc_state->gamma_lut);
1816 if (len != crtc->gamma_size) {
1817 drm_dbg(vop2->drm, "Invalid LUT size; got %d, expected %d\n",
1818 len, crtc->gamma_size);
1819 return -EINVAL;
1823 drm_info(vop2->drm, "Gamma LUT can be enabled for only one CRTC at a time\n");
1824 return -EINVAL;
1846 if (nplanes > vp->nlayers)
1847 return -EINVAL;
1856 struct vop2 *vop2 = vp->vop2;
1858 vop2->ops->setup_overlay(vp);
1866 struct vop2 *vop2 = vp->vop2;
1869 if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed)
1876 spin_lock_irq(&crtc->dev->event_lock);
1878 if (crtc->state->event) {
1880 vp->event = crtc->state->event;
1881 crtc->state->event = NULL;
1884 spin_unlock_irq(&crtc->dev->event_lock);
1901 drm_connector_list_iter_begin(crtc->dev, &conn_iter);
1903 if (crtc->state->connector_mask & drm_connector_mask(connector))
1904 seq_printf(s, " Connector: %s\n", connector->name);
1912 struct drm_plane_state *pstate = plane->state;
1924 seq_printf(s, " %s: %s\n", win->data->name, !pstate ?
1925 "DISABLED" : pstate->crtc ? "ACTIVE" : "DISABLED");
1927 if (!pstate || !pstate->fb)
1930 fb = pstate->fb;
1931 src = &pstate->src;
1932 dst = &pstate->dst;
1933 xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
1934 ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
1935 rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
1936 rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
1938 seq_printf(s, "\twin_id: %d\n", win->win_id);
1941 &fb->format->format,
1942 drm_is_afbc(fb->modifier) ? "[AFBC]" : "",
1943 pstate->alpha >> 8);
1946 seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos);
1947 seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16,
1948 src->y1 >> 16, drm_rect_width(src) >> 16,
1950 seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1,
1953 for (i = 0; i < fb->format->num_planes; i++) {
1954 obj = fb->obj[i];
1956 fb_addr = rk_obj->dma_addr + fb->offsets[i];
1959 i, &fb_addr, fb->pitches[i], fb->offsets[i]);
1968 struct drm_crtc_state *cstate = crtc->state;
1974 seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ?
1975 "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED");
1977 if (!cstate || !cstate->active)
1980 mode = &crtc->state->adjusted_mode;
1982 interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
1985 seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format,
1986 drm_get_bus_format_name(vcstate->bus_format));
1987 seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
1988 seq_printf(s, " color_space[%d]\n", vcstate->color_space);
1990 mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
1993 mode->clock, mode->crtc_clock, mode->type, mode->flags);
1994 seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
1995 mode->hsync_end, mode->htotal);
1996 seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
1997 mode->vsync_end, mode->vtotal);
2008 struct drm_info_node *node = s->private;
2009 struct drm_minor *minor = node->minor;
2010 struct drm_device *drm_dev = minor->dev;
2029 if (dump->en_mask && active_only) {
2030 val = vop2_readl(vop2, dump->base + dump->en_reg);
2031 if ((val & dump->en_mask) != dump->en_val)
2035 seq_printf(s, "\n%s:\n", dump->name);
2037 start = vop2->res->start + dump->base;
2038 for (i = 0; i < dump->size >> 2; i += 4) {
2040 vop2_readl(vop2, dump->base + (4 * i)),
2041 vop2_readl(vop2, dump->base + (4 * (i + 1))),
2042 vop2_readl(vop2, dump->base + (4 * (i + 2))),
2043 vop2_readl(vop2, dump->base + (4 * (i + 3))));
2049 struct drm_info_node *node = s->private;
2050 struct vop2 *vop2 = node->info_ent->data;
2051 struct drm_minor *minor = node->minor;
2052 struct drm_device *drm_dev = minor->dev;
2058 regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
2060 if (vop2->enable_count) {
2061 for (i = 0; i < vop2->data->regs_dump_size; i++) {
2062 dump = &vop2->data->regs_dump[i];
2096 root = debugfs_create_dir("vop2", minor->debugfs_root);
2110 struct vop2 *vop2 = vp->vop2;
2113 vop2_debugfs_init(vop2, crtc->dev->primary);
2122 if (WARN_ON(!crtc->state))
2125 vcstate = kmemdup(to_rockchip_crtc_state(crtc->state),
2130 __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base);
2132 return &vcstate->base;
2140 __drm_atomic_helper_crtc_destroy_state(&vcstate->base);
2149 if (crtc->state)
2150 vop2_crtc_destroy_state(crtc, crtc->state);
2153 __drm_atomic_helper_crtc_reset(crtc, &vcstate->base);
2173 struct vop2 *vop2 = vp->vop2;
2174 struct drm_crtc *crtc = &vp->crtc;
2178 if (!pm_runtime_get_if_in_use(vop2->dev))
2181 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
2182 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
2185 complete(&vp->dsp_hold_completion);
2191 spin_lock(&crtc->dev->event_lock);
2192 if (vp->event) {
2195 if (!(val & BIT(vp->id))) {
2196 drm_crtc_send_vblank_event(crtc, vp->event);
2197 vp->event = NULL;
2201 spin_unlock(&crtc->dev->event_lock);
2207 drm_err_ratelimited(vop2->drm, "POST_BUF_EMPTY irq err at vp%d\n", vp->id);
2211 pm_runtime_put(vop2->dev);
2219 const struct vop2_data *vop2_data = vop2->data;
2225 * The irq is shared with the iommu. If the runtime-pm state of the
2226 * vop2-device is disabled the irq has to be targeted at the iommu.
2228 if (!pm_runtime_get_if_in_use(vop2->dev))
2231 if (vop2->version < VOP_VERSION_RK3576) {
2232 for (i = 0; i < vop2_data->nr_vps; i++) {
2233 struct vop2_video_port *vp = &vop2->vps[i];
2234 struct drm_crtc *crtc = &vp->crtc;
2237 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
2238 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
2241 complete(&vp->dsp_hold_completion);
2247 spin_lock(&crtc->dev->event_lock);
2248 if (vp->event) {
2251 if (!(val & BIT(vp->id))) {
2252 drm_crtc_send_vblank_event(crtc, vp->event);
2253 vp->event = NULL;
2257 spin_unlock(&crtc->dev->event_lock);
2263 drm_err_ratelimited(vop2->drm,
2265 vp->id);
2278 drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n");
2283 pm_runtime_put(vop2->dev);
2291 const struct vop2_win_data *win_data = win->data;
2297 ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs,
2298 &vop2_plane_funcs, win_data->formats,
2299 win_data->nformats,
2300 win_data->format_modifiers,
2301 win->type, win_data->name);
2303 drm_err(vop2->drm, "failed to initialize plane %d\n", ret);
2307 drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs);
2309 if (win->data->supported_rotations)
2310 drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0,
2312 win->data->supported_rotations);
2313 drm_plane_create_alpha_property(&win->base);
2314 drm_plane_create_blend_mode_property(&win->base, blend_caps);
2315 drm_plane_create_zpos_property(&win->base, win->win_id, 0,
2316 vop2->registered_num_wins - 1);
2330 struct vop2 *vop2 = win->vop2;
2332 if (vop2->data->soc_id == 3566) {
2333 switch (win->data->phys_id) {
2348 const struct vop2_data *vop2_data = vop2->data;
2349 struct drm_device *drm = vop2->drm;
2350 struct device *dev = vop2->dev;
2359 for (i = 0; i < vop2_data->nr_vps; i++) {
2364 vp_data = &vop2_data->vp[i];
2365 vp = &vop2->vps[i];
2366 vp->vop2 = vop2;
2367 vp->id = vp_data->id;
2368 vp->data = vp_data;
2370 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id);
2371 vp->dclk = devm_clk_get(vop2->dev, dclk_name);
2372 if (IS_ERR(vp->dclk))
2373 return dev_err_probe(drm->dev, PTR_ERR(vp->dclk),
2376 np = of_graph_get_remote_node(dev->of_node, i, -1);
2378 drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i);
2383 port = of_graph_get_port_by_id(dev->of_node, i);
2385 return dev_err_probe(drm->dev, -ENOENT,
2387 vp->crtc.port = port;
2393 for (i = 0; i < vop2_data->nr_vps; i++) {
2394 vp = &vop2->vps[i];
2396 if (!vp->crtc.port)
2399 for (j = 0; j < vop2->registered_num_wins; j++) {
2400 win = &vop2->win[j];
2403 if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
2407 if (!(win->data->possible_vp_mask & BIT(vp->id)))
2413 if (win->type == DRM_PLANE_TYPE_PRIMARY) {
2415 vp->primary_plane = win;
2418 return dev_err_probe(drm->dev, ret,
2420 win->data->name);
2428 for (i = 0; i < vop2->registered_num_wins; i++) {
2429 win = &vop2->win[i];
2432 if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
2438 win->type = DRM_PLANE_TYPE_OVERLAY;
2442 for (j = 0; j < vop2_data->nr_vps; j++) {
2443 vp = &vop2->vps[j];
2445 if (!vp->crtc.port)
2448 if (win->data->possible_vp_mask & BIT(vp->id))
2455 return dev_err_probe(drm->dev, ret, "failed to init overlay plane %s\n",
2456 win->data->name);
2459 for (i = 0; i < vop2_data->nr_vps; i++) {
2460 vp = &vop2->vps[i];
2462 if (!vp->crtc.port)
2465 plane = &vp->primary_plane->base;
2467 ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL,
2469 "video_port%d", vp->id);
2471 return dev_err_probe(drm->dev, ret,
2474 drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs);
2475 if (vop2->lut_regs) {
2476 const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
2478 drm_mode_crtc_set_gamma_size(&vp->crtc, vp_data->gamma_lut_len);
2479 drm_crtc_enable_color_mgmt(&vp->crtc, 0, false, vp_data->gamma_lut_len);
2481 init_completion(&vp->dsp_hold_completion);
2489 for (i = 0; i < vop2->data->nr_vps; i++) {
2490 struct vop2_video_port *vp = &vop2->vps[i];
2492 if (vp->crtc.port)
2493 vp->nlayers = vop2_data->win_size / nvps;
2501 struct drm_device *drm = vop2->drm;
2502 struct list_head *crtc_list = &drm->mode_config.crtc_list;
2503 struct list_head *plane_list = &drm->mode_config.plane_list;
2515 of_node_put(crtc->port);
2522 struct device_node *node = vop2->dev->of_node;
2526 for (i = 0; i < vop2->data->nr_vps; i++) {
2536 return -ENOENT;
2542 struct vop2 *vop2 = win->vop2;
2548 regs[i].reg + win->offset : regs[i].reg,
2553 win->reg[i] = devm_regmap_field_alloc(vop2->dev, vop2->map, field);
2554 if (IS_ERR(win->reg[i]))
2555 return PTR_ERR(win->reg[i]);
2563 const struct vop2_data *vop2_data = vop2->data;
2567 for (i = 0; i < vop2_data->win_size; i++) {
2568 const struct vop2_win_data *win_data = &vop2_data->win[i];
2570 win = &vop2->win[i];
2571 win->data = win_data;
2572 win->type = win_data->type;
2573 win->offset = win_data->base;
2574 win->win_id = i;
2575 win->vop2 = vop2;
2577 ret = vop2_regmap_init(win, vop2->data->cluster_reg,
2578 vop2->data->nr_cluster_regs);
2580 ret = vop2_regmap_init(win, vop2->data->smart_reg,
2581 vop2->data->nr_smart_regs);
2586 vop2->registered_num_wins = vop2_data->win_size;
2593 * Until that they read back the old value. As we read-modify-write
2594 * these registers mark them as non-volatile. This makes sure we read
2628 return -ENODEV;
2631 alloc_size = struct_size(vop2, win, vop2_data->win_size);
2634 return -ENOMEM;
2636 vop2->dev = dev;
2637 vop2->data = vop2_data;
2638 vop2->ops = vop2_data->ops;
2639 vop2->version = vop2_data->version;
2640 vop2->drm = drm;
2646 return dev_err_probe(drm->dev, -EINVAL,
2649 vop2->res = res;
2650 vop2->regs = devm_ioremap_resource(dev, res);
2651 if (IS_ERR(vop2->regs))
2652 return PTR_ERR(vop2->regs);
2653 vop2->len = resource_size(res);
2655 vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config);
2656 if (IS_ERR(vop2->map))
2657 return PTR_ERR(vop2->map);
2663 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma-lut");
2665 vop2->lut_regs = devm_ioremap_resource(dev, res);
2666 if (IS_ERR(vop2->lut_regs))
2667 return PTR_ERR(vop2->lut_regs);
2669 if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_GRF) {
2670 vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
2671 if (IS_ERR(vop2->sys_grf))
2672 return dev_err_probe(drm->dev, PTR_ERR(vop2->sys_grf),
2676 if (vop2_data->feature & VOP2_FEATURE_HAS_VOP_GRF) {
2677 vop2->vop_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf");
2678 if (IS_ERR(vop2->vop_grf))
2679 return dev_err_probe(drm->dev, PTR_ERR(vop2->vop_grf),
2683 if (vop2_data->feature & VOP2_FEATURE_HAS_VO1_GRF) {
2684 vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf");
2685 if (IS_ERR(vop2->vo1_grf))
2686 return dev_err_probe(drm->dev, PTR_ERR(vop2->vo1_grf),
2690 if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_PMU) {
2691 vop2->sys_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu");
2692 if (IS_ERR(vop2->sys_pmu))
2693 return dev_err_probe(drm->dev, PTR_ERR(vop2->sys_pmu),
2697 vop2->hclk = devm_clk_get(vop2->dev, "hclk");
2698 if (IS_ERR(vop2->hclk))
2699 return dev_err_probe(drm->dev, PTR_ERR(vop2->hclk),
2702 vop2->aclk = devm_clk_get(vop2->dev, "aclk");
2703 if (IS_ERR(vop2->aclk))
2704 return dev_err_probe(drm->dev, PTR_ERR(vop2->aclk),
2707 vop2->pclk = devm_clk_get_optional(vop2->dev, "pclk_vop");
2708 if (IS_ERR(vop2->pclk))
2709 return dev_err_probe(drm->dev, PTR_ERR(vop2->pclk),
2712 vop2->pll_hdmiphy0 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy0");
2713 if (IS_ERR(vop2->pll_hdmiphy0))
2714 return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy0),
2717 vop2->pll_hdmiphy1 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy1");
2718 if (IS_ERR(vop2->pll_hdmiphy1))
2719 return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy1),
2722 vop2->irq = platform_get_irq(pdev, 0);
2723 if (vop2->irq < 0)
2724 return dev_err_probe(drm->dev, vop2->irq, "cannot find irq for vop2\n");
2726 mutex_init(&vop2->vop2_lock);
2728 ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2);
2736 if (vop2->version >= VOP_VERSION_RK3576) {
2742 const char *irq_name = devm_kasprintf(dev, GFP_KERNEL, "vp%d", vp->id);
2745 return -ENOMEM;
2749 return dev_err_probe(drm->dev, vp_irq,
2750 "cannot find irq for vop2 vp%d\n", vp->id);
2755 dev_err_probe(drm->dev, ret,
2756 "request irq for vop2 vp%d failed\n", vp->id);
2762 vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
2763 vop2->drm, ret);
2764 if (IS_ERR(vop2->rgb)) {
2765 if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) {
2766 ret = PTR_ERR(vop2->rgb);
2769 vop2->rgb = NULL;
2773 rockchip_drm_dma_init_device(vop2->drm, vop2->dev);
2775 pm_runtime_enable(&pdev->dev);
2791 if (vop2->rgb)
2792 rockchip_rgb_fini(vop2->rgb);