• Home
  • Raw
  • Download

Lines Matching refs:vop

16596 +	  debug node: /d/dri/0/ff900000.vop/vop_dump/dump
16597 + cat /d/dri/0/ff900000.vop/vop_dump/dump get more help
16598 + the upper ff900000.vop is different at different SOC platform.
16684 + rockchip vop, This is used for some test.
16690 + don't need a real vop driver(et: you just want rockchip drm
16776 - * @lcdsel_big: reg value of selecting vop big for eDP
16777 - * @lcdsel_lit: reg value of selecting vop little for eDP
17040 DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
18734 * @lcdsel_big: reg value of selecting vop big for HDMI
18735 * @lcdsel_lit: reg value of selecting vop little for HDMI
20271 + DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
21318 - DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
23330 + private->default_pll.pll = devm_clk_get_optional(dev, "default-vop-pll");
23335 + dev_err(dev, "failed to get default vop pll\n");
23887 + * @vop_dump_status the status of vop dump control
23888 + * @vop_dump_list_head the list head of vop dump list
24108 + * @regs_dump: dump vop current register config.
24110 + * @crtc_close: close vop.
25530 -#define VOP_WIN_SET(vop, win, name, v) \
25531 - vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
25532 -#define VOP_SCL_SET(vop, win, name, v) \
25533 - vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
25534 -#define VOP_SCL_SET_EXT(vop, win, name, v) \
25535 - vop_reg_set(vop, &win->phy->scl->ext->name, \
25537 +#define VOP_REG_SUPPORT(vop, reg) \
25540 + (reg.major == VOP_MAJOR(vop->version) && \
25541 + reg.begin_minor <= VOP_MINOR(vop->version) && \
25542 + reg.end_minor >= VOP_MINOR(vop->version))))
25544 -#define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
25547 - vop_reg_set(vop, &win_yuv2yuv->name, 0, ~0, v, #name); \
25549 +#define VOP_WIN_SUPPORT(vop, win, name) \
25550 + VOP_REG_SUPPORT(vop, win->phy->name)
25552 +#define VOP_WIN_SCL_EXT_SUPPORT(vop, win, name) \
25554 + VOP_REG_SUPPORT(vop, win->phy->scl->ext->name))
25556 -#define VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, win_yuv2yuv, name, v) \
25557 +#define VOP_CTRL_SUPPORT(vop, name) \
25558 + VOP_REG_SUPPORT(vop, vop->data->ctrl->name)
25560 +#define VOP_INTR_SUPPORT(vop, name) \
25561 + VOP_REG_SUPPORT(vop, vop->data->intr->name)
25566 +#define _REG_SET(vop, name, off, reg, mask, v, relaxed) \
25569 - vop_reg_set(vop, &win_yuv2yuv->phy->name, win_yuv2yuv->base, ~0, v, #name); \
25570 + if (VOP_REG_SUPPORT(vop, reg)) \
25571 + __REG_SET(vop, off + reg.offset, mask, reg.shift, \
25574 + dev_dbg(vop->dev, "Warning: not support "#name"\n"); \
25594 +#define VOP_INTR_GET(vop, name) \
25595 + vop_read_reg(vop, 0, &vop->data->ctrl->name)
25597 +#define VOP_INTR_SET(vop, name, v) \
25598 + REG_SET(vop, name, 0, vop->data->intr->name, \
25600 #define VOP_INTR_SET_MASK(vop, name, mask, v) \
25601 - vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
25602 + REG_SET_MASK(vop, name, 0, vop->data->intr->name, \
25606 #define VOP_REG_SET(vop, group, name, v) \
25607 vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
25609 #define VOP_INTR_GET_TYPE(vop, name, type) \
25610 vop_get_intr_type(vop, &vop->data->intr->name, type)
25612 -#define VOP_WIN_GET(vop, win, name) \
25613 - vop_read_reg(vop, win->base, &win->phy->name)
25615 + vop_read_reg(x, 0, &vop->data->ctrl->name)
25619 +#define VOP_WIN_GET(vop, win, name) \
25620 + vop_read_reg(vop, win->offset, &VOP_WIN_NAME(win, name))
25622 -#define VOP_WIN_GET_YRGBADDR(vop, win) \
25623 - vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
25628 ((vop_win) - (vop_win)->vop->win)
25630 -#define VOP_AFBC_SET(vop, name, v) \
25631 +#define VOP_GRF_SET(vop, reg, v) \
25633 - if ((vop)->data->afbc) \
25634 - vop_reg_set((vop), &(vop)->data->afbc->name, \
25636 + if (vop->data->grf_ctrl) { \
25637 + vop_grf_writel(vop, vop->data->grf_ctrl->reg, v); \
25641 -#define to_vop(x) container_of(x, struct vop, crtc)
25725 struct vop *vop;
25738 struct vop {
25774 @@ -149,14 +265,22 @@ struct vop {
25785 /* physical map length of vop register */
25797 /* lock vop irq reg */
25798 @@ -172,16 +296,83 @@ struct vop {
25800 /* vop share memory frequency */
25802 + /* vop source handling, optional */
25805 /* vop dclk reset */
25847 +static inline struct vop *to_vop(struct drm_crtc *crtc)
25853 + return container_of(rockchip_crtc, struct vop, rockchip_crtc);
25856 +static void vop_lock(struct vop *vop)
25858 + mutex_lock(&vop->vop_lock);
25862 +static void vop_unlock(struct vop *vop)
25865 + mutex_unlock(&vop->vop_lock);
25868 +static inline void vop_grf_writel(struct vop *vop, struct vop_reg reg, u32 v)
25872 + if (IS_ERR_OR_NULL(vop->grf))
25875 + if (VOP_REG_SUPPORT(vop, reg)) {
25877 + regmap_write(vop->grf, reg.offset, val);
25881 static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
25883 writel(v, vop->regs + offset);
25884 @@ -199,23 +390,15 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
25885 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
25888 -static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
25891 +static inline void vop_mask_write(struct vop *vop, uint32_t offset,
25898 - DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name);
25912 uint32_t cached_val = vop->regsbak[offset >> 2];
25914 @@ -223,12 +406,21 @@ static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
25915 vop->regsbak[offset >> 2] = v;
25920 writel_relaxed(v, vop->regs + offset);
25922 writel(v, vop->regs + offset);
25934 static inline uint32_t vop_get_intr_type(struct vop *vop,
25937 @@ -243,9 +435,147 @@ static inline uint32_t vop_get_intr_type(struct vop *vop,
25941 +static void vop_load_hdr2sdr_table(struct vop *vop)
25944 + const struct vop_hdr_table *table = vop->data->hdr_table;
25951 + vop_writel(vop, table->hdr2sdr_eetf_oetf_y0_offset,
25954 + vop_writel(vop,
25958 + vop_writel(vop, table->hdr2sdr_sat_y0_offset,
25961 + vop_writel(vop, table->hdr2sdr_sat_y1_offset + (i - 1) * 4,
25964 + VOP_CTRL_SET(vop, hdr2sdr_src_min, table->hdr2sdr_src_range_min);
25965 + VOP_CTRL_SET(vop, hdr2sdr_src_max, table->hdr2sdr_src_range_max);
25966 + VOP_CTRL_SET(vop, hdr2sdr_normfaceetf, table->hdr2sdr_normfaceetf);
25967 + VOP_CTRL_SET(vop, hdr2sdr_dst_min, table->hdr2sdr_dst_range_min);
25968 + VOP_CTRL_SET(vop, hdr2sdr_dst_max, table->hdr2sdr_dst_range_max);
25969 + VOP_CTRL_SET(vop, hdr2sdr_normfacgamma, table->hdr2sdr_normfacgamma);
25972 +static void vop_load_sdr2hdr_table(struct vop *vop, uint32_t cmd)
25975 + const struct vop_hdr_table *table = vop->data->hdr_table;
25993 + vop_writel(vop, table->sdr2hdr_eotf_oetf_y0_offset,
25996 + vop_writel(vop, table->sdr2hdr_eotf_oetf_y1_offset +
26002 + vop_writel(vop, table->sdr2hdr_oetf_dx_dxpow1_offset + i * 4,
26007 + vop_writel(vop, table->sdr2hdr_oetf_xn1_offset + i * 4,
26011 +static void vop_load_csc_table(struct vop *vop, u32 offset, const u32 *table)
26023 + vop_writel(vop, offset + i * 4, table[i]);
26026 static inline void vop_cfg_done(struct vop *vop)
26028 - VOP_REG_SET(vop, common, cfg_done, 1);
26029 + VOP_CTRL_SET(vop, cfg_done, 1);
26032 +static bool vop_is_allwin_disabled(struct vop *vop)
26036 + for (i = 0; i < vop->num_wins; i++) {
26037 + struct vop_win *win = &vop->win[i];
26039 + if (VOP_WIN_GET(vop, win, enable) != 0)
26046 +static void vop_win_disable(struct vop *vop, struct vop_win *win)
26049 + * FIXUP: some of the vop scale would be abnormal after windows power
26053 + VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
26054 + VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
26055 + VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
26056 + VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
26059 + VOP_WIN_SET(vop, win, enable, 0);
26061 + VOP_WIN_SET(vop, win, gate, 0);
26064 +static void vop_disable_allwin(struct vop *vop)
26068 + for (i = 0; i < vop->num_wins; i++) {
26069 + struct vop_win *win = &vop->win[i];
26071 + vop_win_disable(vop, win);
26075 +static inline void vop_write_lut(struct vop *vop, uint32_t offset, uint32_t v)
26077 + writel(v, vop->lut_regs + offset);
26080 +static inline uint32_t vop_read_lut(struct vop *vop, uint32_t offset)
26082 + return readl(vop->lut_regs + offset);
26261 -static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
26264 +static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win *win,
26282 + const struct vop_data *vop_data = vop->data;
26289 - DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
26303 VOP_SCL_SET(vop, win, scale_yrgb_x,
26305 @@ -448,45 +921,411 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *…
26309 -static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
26330 + struct vop *vop = to_vop(crtc);
26336 - if (WARN_ON(!vop->is_enabled))
26338 + if (!vop->data->hdr_table)
26352 - spin_lock_irqsave(&vop->irq_lock, flags);
26365 - VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1);
26366 - VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1);
26375 - spin_unlock_irqrestore(&vop->irq_lock, flags);
26395 -static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
26421 - if (WARN_ON(!vop->is_enabled))
26428 - spin_lock_irqsave(&vop->irq_lock, flags);
26435 - VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0);
26441 - spin_unlock_irqrestore(&vop->irq_lock, flags);
26471 +static void vop_disable_all_planes(struct vop *vop)
26476 + vop_disable_allwin(vop);
26477 + vop_cfg_done(vop);
26479 + vop, active, active,
26482 + dev_err(vop->dev, "wait win close timeout\n");
26616 + struct vop *vop = to_vop(crtc);
26619 + const struct vop_csc_table *csc_table = vop->data->csc_table;
26668 + * hdr2sdr on rk3328, vop can't support per-pixel alpha * global
26670 + * gpu output hdr UI, vop will do:
26690 + struct vop *vop = to_vop(crtc);
26696 + VOP_INTR_SET_TYPE(vop, clear, irqs, 1);
26697 + VOP_INTR_SET_TYPE(vop, enable, irqs, 1);
26700 +static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
26704 + if (WARN_ON(!vop->is_enabled))
26707 + spin_lock_irqsave(&vop->irq_lock, flags);
26709 + VOP_INTR_SET_TYPE(vop, clear, DSP_HOLD_VALID_INTR, 1);
26710 + VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 1);
26712 + spin_unlock_irqrestore(&vop->irq_lock, flags);
26715 +static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
26719 + if (WARN_ON(!vop->is_enabled))
26722 + spin_lock_irqsave(&vop->irq_lock, flags);
26724 + VOP_INTR_SET_TYPE(vop, enable, DSP_HOLD_VALID_INTR, 0);
26726 + spin_unlock_irqrestore(&vop->irq_lock, flags);
26742 @@ -567,147 +1406,234 @@ static void vop_core_clks_disable(struct vop *vop)
26743 clk_disable(vop->hclk);
26746 -static void vop_win_disable(struct vop *vop, const struct vop_win *vop_win)
26750 + struct vop *vop = to_vop(crtc);
26754 - VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE);
26755 - VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE);
26756 - VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE);
26757 - VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE);
26758 + if (!vop->is_enabled || !vop->lut || !vop->lut_regs)
26764 + if (!VOP_CTRL_SUPPORT(vop, update_gamma_lut)) {
26765 + spin_lock(&vop->reg_lock);
26766 + VOP_CTRL_SET(vop, dsp_lut_en, 0);
26767 + vop_cfg_done(vop);
26768 + spin_unlock(&vop->reg_lock);
26770 +#define CTRL_GET(name) VOP_CTRL_GET(vop, name)
26777 - VOP_WIN_SET(vop, win, enable, 0);
26778 - vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win));
26779 + for (i = 0; i < vop->lut_len; i++)
26780 + vop_write_lut(vop, i << 2, vop->lut[i]);
26782 + spin_lock(&vop->reg_lock);
26784 + VOP_CTRL_SET(vop, dsp_lut_en, 1);
26785 + VOP_CTRL_SET(vop, update_gamma_lut, 1);
26786 + vop_cfg_done(vop);
26787 + vop->lut_active = true;
26789 + spin_unlock(&vop->reg_lock);
26791 + if (VOP_CTRL_SUPPORT(vop, update_gamma_lut)) {
26798 + VOP_CTRL_SET(vop, update_gamma_lut, 0);
26807 struct vop *vop = to_vop(crtc);
26809 + u32 lut_len = vop->lut_len;
26812 - ret = pm_runtime_get_sync(vop->dev);
26814 - DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
26817 + if (regno >= lut_len || !vop->lut)
26820 - ret = vop_core_clks_enable(vop);
26826 + vop->lut[regno] = r * lut_len * lut_len + g * lut_len + b;
26829 - ret = clk_enable(vop->dclk);
26835 + struct vop *vop = to_vop(crtc);
26836 + u32 lut_len = vop->lut_len;
26840 - * Slave iommu shares power, irq and clock with vop. It was associated
26845 - ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
26847 - DRM_DEV_ERROR(vop->dev,
26851 + if (regno >= lut_len || !vop->lut)
26854 - spin_lock(&vop->reg_lock);
26855 - for (i = 0; i < vop->len; i += 4)
26856 - writel_relaxed(vop->regsbak[i / 4], vop->regs + i);
26857 + r = (vop->lut[regno] / lut_len / lut_len) & (lut_len - 1);
26858 + g = (vop->lut[regno] / lut_len) & (lut_len - 1);
26859 + b = vop->lut[regno] & (lut_len - 1);
26875 - for (i = 0; i < vop->data->win_size; i++) {
26876 - struct vop_win *vop_win = &vop->win[i];
26881 + struct vop *vop = to_vop(crtc);
26882 + int len = min(size, vop->lut_len);
26885 - vop_win_disable(vop, vop_win);
26888 + if (!vop->lut)
26891 - if (vop->data->afbc) {
26894 - * Disable AFBC and forget there was a vop window with AFBC
26896 - VOP_AFBC_SET(vop, enable, 0);
26910 + struct vop *vop = to_vop(crtc);
26911 + struct drm_color_lut *lut = vop->gamma_lut;
26914 + for (i = 0; i < vop->lut_len; i++)
26924 + struct vop *vop = to_vop(crtc);
26927 + ret = clk_prepare_enable(vop->hclk);
26929 + dev_err(vop->dev, "failed to enable hclk - %d\n", ret);
26933 - vop_cfg_done(vop);
26934 + ret = clk_prepare_enable(vop->dclk);
26936 + dev_err(vop->dev, "failed to enable dclk - %d\n", ret);
26940 - spin_unlock(&vop->reg_lock);
26941 + ret = clk_prepare_enable(vop->aclk);
26943 + dev_err(vop->dev, "failed to enable aclk - %d\n", ret);
26948 - * At here, vop clock & iommu is enable, R/W vop regs would be safe.
26950 - vop->is_enabled = true;
26951 + ret = pm_runtime_get_sync(vop->dev);
26953 + dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
26957 - spin_lock(&vop->reg_lock);
26958 + memcpy(vop->regsbak, vop->regs, vop->len);
26960 - VOP_REG_SET(vop, common, standby, 1);
26961 + if (VOP_CTRL_SUPPORT(vop, version)) {
26962 + uint32_t version = VOP_CTRL_GET(vop, version);
26964 - spin_unlock(&vop->reg_lock);
26969 + vop->version = VOP_VERSION(3, 1);
26973 + vop->is_enabled = true;
26979 - clk_disable(vop->dclk);
26981 - vop_core_clks_disable(vop);
26983 - pm_runtime_put_sync(vop->dev);
26985 + clk_disable_unprepare(vop->dclk);
26987 + clk_disable_unprepare(vop->hclk);
26993 - struct vop *vop = to_vop(crtc);
26995 + struct vop *vop = to_vop(crtc);
27000 + VOP_CTRL_SET(vop, global_regdone_en, 1);
27001 + VOP_CTRL_SET(vop, dsp_blank, 0);
27002 + VOP_CTRL_SET(vop, axi_outstanding_max_num, 30);
27003 + VOP_CTRL_SET(vop, axi_max_outstanding_en, 1);
27004 + VOP_CTRL_SET(vop, dither_up_en, 1);
27006 - spin_lock(&vop->reg_lock);
27012 + for (i = 0; i < vop->num_wins; i++) {
27013 + struct vop_win *win = &vop->win[i];
27016 - for (i = 0; i < vop->data->win_size; i++) {
27017 - struct vop_win *vop_win = &vop->win[i];
27019 + VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
27021 + VOP_CTRL_SET(vop, afbdc_en, 0);
27025 - VOP_WIN_SET(vop, win, enable,
27026 - enabled && (vop->win_enabled & BIT(i)));
27028 - vop_cfg_done(vop);
27032 + struct vop *vop = to_vop(crtc);
27034 - spin_unlock(&vop->reg_lock);
27035 + vop_disable_all_planes(vop);
27037 + vop->aclk_rate = clk_get_rate(vop->aclk);
27038 + clk_set_rate(vop->aclk, vop->aclk_rate / 3);
27039 + vop->aclk_rate_reset = true;
27045 struct vop *vop = to_vop(crtc);
27049 WARN_ON(vop->event);
27054 - mutex_lock(&vop->vop_lock);
27060 + vop_lock(vop);
27061 + VOP_CTRL_SET(vop, reg_done_frm, 1);
27062 + VOP_CTRL_SET(vop, dsp_interlace, 0);
27067 + VOP_CTRL_SET(vop, out_mode, ROCKCHIP_OUT_MODE_P888);
27068 + VOP_CTRL_SET(vop, afbdc_en, 0);
27069 + vop_disable_all_planes(vop);
27075 spin_lock(&vop->reg_lock);
27077 - VOP_REG_SET(vop, common, standby, 1);
27078 + VOP_CTRL_SET(vop, standby, 1);
27080 spin_unlock(&vop->reg_lock);
27082 - wait_for_completion(&vop->dsp_hold_completion);
27083 + WARN_ON(!wait_for_completion_timeout(&vop->dsp_hold_completion,
27086 vop_dsp_hold_valid_irq_disable(vop);
27088 vop->is_enabled = false;
27089 + if (vop->is_iommu_enabled) {
27091 + * vop standby complete, so iommu detach is safe.
27093 + VOP_CTRL_SET(vop, dma_stop, 1);
27094 + rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
27095 + vop->is_iommu_enabled = false;
27099 - * vop standby complete, so iommu detach is safe.
27101 - rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
27102 + pm_runtime_put_sync(vop->dev);
27103 + clk_disable_unprepare(vop->dclk);
27104 + clk_disable_unprepare(vop->aclk);
27105 + clk_disable_unprepare(vop->hclk);
27106 + vop_unlock(vop);
27108 - clk_disable(vop->dclk);
27109 - vop_core_clks_disable(vop);
27110 - pm_runtime_put(vop->dev);
27114 - mutex_unlock(&vop->vop_lock);
27165 + struct vop *vop;
27220 + vop = to_vop(crtc);
27221 + vop_data = vop->data;
27255 - struct vop *vop = to_vop(crtc);
27263 - if (!vop->data->afbc) {
27264 - DRM_ERROR("vop does not support AFBC\n");
27303 struct vop *vop = to_vop(old_state->crtc);
27312 spin_lock(&vop->reg_lock);
27314 - vop_win_disable(vop, vop_win);
27315 + vop_win_disable(vop, win);
27319 + * vop will access the freed memory lead to iommu pagefault.
27322 + if (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 5 &&
27324 + VOP_WIN_SET(vop, win, yrgb_mst, 0);
27331 spin_unlock(&vop->reg_lock);
27345 struct vop *vop = to_vop(state->crtc);
27393 * can't update plane when vop is disabled.
27451 spin_lock(&vop->reg_lock);
27456 - VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16);
27457 - VOP_AFBC_SET(vop, hreg_block_split, 0);
27458 - VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win));
27459 - VOP_AFBC_SET(vop, hdr_ptr, dma_addr);
27460 - VOP_AFBC_SET(vop, pic_size, act_info);
27463 - VOP_WIN_SET(vop, win, format, format);
27464 + VOP_WIN_SET(vop, win, format, vop_plane_state->format);
27465 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
27466 - VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
27467 - VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
27468 - VOP_WIN_SET(vop, win, y_mir_en,
27469 + VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
27471 + VOP_WIN_SET(vop, win, ymirror,
27473 - VOP_WIN_SET(vop, win, x_mir_en,
27474 + VOP_WIN_SET(vop, win, xmirror,
27489 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
27490 - VOP_WIN_SET(vop, win, uv_mst, dma_addr);
27493 - VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop,
27498 + VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst);
27500 + VOP_WIN_SET(vop, win, fmt_10, is_yuv_10bit(fb->format->format));
27501 + VOP_WIN_SET(vop, win, fmt_yuyv, is_yuyv_format(fb->format->format));
27504 scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
27509 VOP_WIN_SET(vop, win, act_info, act_info);
27510 VOP_WIN_SET(vop, win, dsp_info, dsp_info);
27511 VOP_WIN_SET(vop, win, dsp_st, dsp_st);
27514 - VOP_WIN_SET(vop, win, rb_swap, rb_swap);
27526 + VOP_MAJOR(vop->version) == 3)
27528 + VOP_WIN_SET(vop, win, rb_swap, rb_swap);
27542 VOP_WIN_SET(vop, win, dst_alpha_ctl,
27553 VOP_WIN_SET(vop, win, src_alpha_ctl, val);
27555 - VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL);
27556 - VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX);
27557 + VOP_WIN_SET(vop, win, alpha_pre_mul,
27559 + VOP_WIN_SET(vop, win, alpha_mode, 1);
27560 VOP_WIN_SET(vop, win, alpha_en, 1);
27562 VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0));
27563 VOP_WIN_SET(vop, win, alpha_en, 0);
27566 + VOP_WIN_SET(vop, win, global_alpha_val, vop_plane_state->global_alpha);
27568 + VOP_WIN_SET(vop, win, csc_mode, vop_plane_state->csc_mode);
27570 + vop_load_csc_table(vop, win->csc->y2r_offset, y2r_table);
27571 + vop_load_csc_table(vop, win->csc->r2r_offset, r2r_table);
27572 + vop_load_csc_table(vop, win->csc->r2y_offset, r2y_table);
27573 + VOP_WIN_SET_EXT(vop, win, csc, y2r_en, vop_plane_state->y2r_en);
27574 + VOP_WIN_SET_EXT(vop, win, csc, r2r_en, vop_plane_state->r2r_en);
27575 + VOP_WIN_SET_EXT(vop, win, csc, r2y_en, vop_plane_state->r2y_en);
27576 + VOP_WIN_SET_EXT(vop, win, csc, csc_mode, vop_plane_state->csc_mode);
27578 VOP_WIN_SET(vop, win, enable, 1);
27579 - vop->win_enabled |= BIT(win_index);
27580 + VOP_WIN_SET(vop, win, gate, 1);
27581 spin_unlock(&vop->reg_lock);
27586 + vop->is_iommu_needed = true;
27604 + list_add_tail(&planlist->entry, &vop->rockchip_crtc.vop_dump_list_head);
27610 + if (vop->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
27611 + vop->rockchip_crtc.vop_dump_times > 0) {
27612 + rockchip_drm_dump_plane_buffer(&planlist->dump_info, vop->rockchip_crtc.frame_count);
27613 + vop->rockchip_crtc.vop_dump_times--;
27771 - struct vop *vop = to_vop(plane->state->crtc);
27798 - if (vop->is_enabled) {
27800 - spin_lock(&vop->reg_lock);
27801 - vop_cfg_done(vop);
27802 - spin_unlock(&vop->reg_lock);
27819 - drm_flip_work_queue(&vop->fb_unref_work, old_fb);
27820 - set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
27882 + DRM_ERROR("failed to set vop plane property id:%d, name:%s\n",
27937 + DRM_ERROR("failed to get vop plane property id:%d, name:%s\n",
27963 struct vop *vop = to_vop(crtc);
27966 - if (WARN_ON(!vop->is_enabled))
27968 + if (WARN_ON(!vop->is_enabled))
27971 + spin_lock_irqsave(&vop->irq_lock, flags);
27973 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7) {
27974 + VOP_INTR_SET_TYPE(vop, clear, FS_FIELD_INTR, 1);
27975 + VOP_INTR_SET_TYPE(vop, enable, FS_FIELD_INTR, 1);
27977 + VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1);
27978 + VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1);
27981 + spin_unlock_irqrestore(&vop->irq_lock, flags);
27988 + struct vop *vop = to_vop(crtc);
27991 + if (WARN_ON(!vop->is_enabled))
27994 + spin_lock_irqsave(&vop->irq_lock, flags);
27996 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7)
27997 + VOP_INTR_SET_TYPE(vop, enable, FS_FIELD_INTR, 0);
27999 + VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0);
28001 + spin_unlock_irqrestore(&vop->irq_lock, flags);
28008 + struct vop *vop = to_vop(crtc);
28013 + e = vop->event;
28015 + vop->event = NULL;
28026 + struct vop *vop = to_vop(crtc);
28030 + if (on == vop->loader_protect)
28034 + if (vop->dclk_source) {
28037 + parent = clk_get_parent(vop->dclk_source);
28040 + vop->pll = &private->default_pll;
28042 + vop->pll = &private->hdmi_pll;
28043 + if (vop->pll)
28044 + vop->pll->use_count++;
28051 + vop->loader_protect = true;
28055 + if (vop->dclk_source && vop->pll) {
28056 + vop->pll->use_count--;
28057 + vop->pll = NULL;
28059 + vop->loader_protect = false;
28140 + struct vop *vop = to_vop(crtc);
28148 + DEBUG_PRINT("VOP [%s]: %s\n", dev_name(vop->dev),
28171 + for (i = 0; i < vop->num_wins; i++) {
28172 + plane = &vop->win[i].base;
28189 + struct vop *vop = to_vop(crtc);
28191 + int dump_len = vop->len > 0x400 ? 0x400 : vop->len;
28199 + vop_readl(vop, i), vop_readl(vop, i + 4),
28200 + vop_readl(vop, i + 8), vop_readl(vop, i + 12));
28207 + struct vop *vop = node->info_ent->data;
28210 + if (!vop->lut || !vop->lut_active || !vop->lut_regs)
28213 + for (i = 0; i < vop->lut_len; i++) {
28216 + DEBUG_PRINT("0x%08x ", vop->lut[i]);
28231 + struct vop *vop = to_vop(crtc);
28234 + vop->debugfs = debugfs_create_dir(dev_name(vop->dev),
28237 + if (!vop->debugfs)
28240 + vop->debugfs_files = kmemdup(vop_debugfs_files,
28243 + if (!vop->debugfs_files) {
28248 + rockchip_drm_add_dump_buffer(crtc, vop->debugfs);
28251 + vop->debugfs_files[i].data = vop;
28253 + drm_debugfs_create_files(vop->debugfs_files, ARRAY_SIZE(vop_debugfs_files),
28254 + vop->debugfs, minor);
28258 + debugfs_remove(vop->debugfs);
28259 + vop->debugfs = NULL;
28266 + struct vop *vop = to_vop(crtc);
28268 + const struct vop_data *vop_data = vop->data;
28276 + VOP_MAJOR(vop->version) == 3 &&
28277 + VOP_MINOR(vop->version) <= 2)
28282 + clock = clk_round_rate(vop->dclk, request_clock * 1000) / 1000;
28314 + struct vop *vop = to_vop(crtc);
28334 + if (vskiplines == 2 && VOP_WIN_SCL_EXT_SUPPORT(vop, win, vsd_yrgb_gt2))
28337 + VOP_WIN_SCL_EXT_SUPPORT(vop, win, vsd_yrgb_gt4))
28382 + struct vop *vop = to_vop(crtc);
28389 + if (!vop->rockchip_crtc.vop_dump_list_init_flag) {
28390 + INIT_LIST_HEAD(&vop->rockchip_crtc.vop_dump_list_head);
28391 + vop->rockchip_crtc.vop_dump_list_init_flag = true;
28393 + list_for_each_entry_safe(pos, n, &vop->rockchip_crtc.vop_dump_list_head, entry) {
28396 + if (vop->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
28397 + vop->rockchip_crtc.vop_dump_times > 0) {
28398 + vop->rockchip_crtc.frame_count++;
28452 + struct vop *vop = NULL;
28456 + vop = to_vop(crtc);
28457 + mutex_lock(&vop->vop_lock);
28458 + if (!vop->is_enabled) {
28459 + mutex_unlock(&vop->vop_lock);
28463 + vop_disable_all_planes(vop);
28464 + mutex_unlock(&vop->vop_lock);
28467 +static u32 vop_mode_done(struct vop *vop)
28469 + return VOP_CTRL_GET(vop, out_mode);
28472 +static void vop_set_out_mode(struct vop *vop, u32 mode)
28477 + VOP_CTRL_SET(vop, out_mode, mode);
28478 + vop_cfg_done(vop);
28479 + ret = readx_poll_timeout(vop_mode_done, vop, val, val == mode,
28482 + dev_err(vop->dev, "wait mode 0x%x timeout\n", mode);
28489 + struct vop *vop = NULL;
28494 + vop = to_vop(crtc);
28501 + vop_set_out_mode(vop, ROCKCHIP_OUT_MODE_P888);
28502 + mutex_lock(&vop->vop_lock);
28503 + if (vop && vop->is_enabled) {
28506 + VOP_CTRL_SET(vop, mcu_rs, 0);
28507 + VOP_CTRL_SET(vop, mcu_rw_bypass_port, value);
28508 + VOP_CTRL_SET(vop, mcu_rs, 1);
28511 + VOP_CTRL_SET(vop, mcu_rs, 1);
28512 + VOP_CTRL_SET(vop, mcu_rw_bypass_port, value);
28515 + VOP_CTRL_SET(vop, mcu_bypass, value ? 1 : 0);
28521 + mutex_unlock(&vop->vop_lock);
28527 + vop_set_out_mode(vop, state->output_mode);
28532 + struct vop *vop = to_vop(crtc);
28536 + if (!vop->is_enabled)
28539 + mutex_lock(&vop->vop_lock);
28541 + if (vop_line_flag_irq_is_enabled(vop)) {
28546 + reinit_completion(&vop->line_flag_completion);
28547 + vop_line_flag_irq_enable(vop);
28549 + jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
28551 + vop_line_flag_irq_disable(vop);
28554 + DRM_DEV_ERROR(vop->dev, "timeout waiting for lineflag IRQ\n");
28560 + mutex_unlock(&vop->vop_lock);
28580 + struct vop *vop = to_vop(crtc);
28581 + const struct vop_data *vop_data = vop->data;
28593 + DIV_ROUND_UP(clk_round_rate(vop->dclk, adj_mode->crtc_clock * 1000),
28603 + struct vop *vop = to_vop(crtc);
28610 + if (vop->mcu_timing.mcu_pix_total)
28615 + VOP_CTRL_SET(vop, dither_down_en, 1);
28616 + VOP_CTRL_SET(vop, dither_down_mode, RGB888_TO_RGB565);
28621 + VOP_CTRL_SET(vop, dither_down_en, 1);
28622 + VOP_CTRL_SET(vop, dither_down_mode, RGB888_TO_RGB666);
28626 + VOP_CTRL_SET(vop, dither_down_en, 0);
28627 + VOP_CTRL_SET(vop, pre_dither_down_en, 1);
28631 + VOP_CTRL_SET(vop, dither_down_en, 0);
28632 + VOP_CTRL_SET(vop, pre_dither_down_en, 0);
28640 + VOP_CTRL_SET(vop, dither_down_en, 0);
28641 + VOP_CTRL_SET(vop, pre_dither_down_en, 0);
28645 + VOP_CTRL_SET(vop, pre_dither_down_en,
28647 + VOP_CTRL_SET(vop, dither_down_sel, DITHER_DOWN_ALLEGRO);
28654 + struct vop *vop = to_vop(crtc);
28658 + !(vop->data->feature & VOP_FEATURE_OUTPUT_10BIT)) ||
28659 + (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) >= 12 &&
28664 + VOP_CTRL_SET(vop, dsp_data_swap, DSP_RB_SWAP);
28666 + VOP_CTRL_SET(vop, dsp_data_swap, 0);
28668 + VOP_CTRL_SET(vop, out_mode, s->output_mode);
28671 + VOP_CTRL_SET(vop, dclk_ddr,
28673 + VOP_CTRL_SET(vop, hdmi_dclk_out_en,
28676 + VOP_CTRL_SET(vop, overlay_mode, s->yuv_overlay);
28677 + VOP_CTRL_SET(vop, dsp_out_yuv, is_yuv_output(s->bus_format));
28680 + * Background color is 10bit depth if vop version >= 3.5
28684 + else if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) == 8 &&
28687 + else if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 5)
28691 + VOP_CTRL_SET(vop, dsp_background, val);
28699 + struct vop *vop = to_vop(crtc);
28721 + if (htotal_sync != VOP_CTRL_GET(vop, htotal_pw) ||
28722 + hactive_st_end != VOP_CTRL_GET(vop, hact_st_end) ||
28723 + vtotal_sync != VOP_CTRL_GET(vop, vtotal_pw) ||
28724 + vactive_st_end != VOP_CTRL_GET(vop, vact_st_end) ||
28725 + crtc_clock != clk_get_rate(vop->dclk))
28733 + struct vop *vop = to_vop(crtc);
28735 + VOP_CTRL_SET(vop, mcu_clk_sel, 1);
28736 + VOP_CTRL_SET(vop, mcu_type, 1);
28738 + VOP_CTRL_SET(vop, mcu_hold_mode, 1);
28739 + VOP_CTRL_SET(vop, mcu_pix_total, vop->mcu_timing.mcu_pix_total);
28740 + VOP_CTRL_SET(vop, mcu_cs_pst, vop->mcu_timing.mcu_cs_pst);
28741 + VOP_CTRL_SET(vop, mcu_cs_pend, vop->mcu_timing.mcu_cs_pend);
28742 + VOP_CTRL_SET(vop, mcu_rw_pst, vop->mcu_timing.mcu_rw_pst);
28743 + VOP_CTRL_SET(vop, mcu_rw_pend, vop->mcu_timing.mcu_rw_pend);
28749 + struct vop *vop = to_vop(crtc);
28772 + if (vop->aclk_rate_reset)
28773 + clk_set_rate(vop->aclk, vop->aclk_rate);
28774 + vop->aclk_rate_reset = false;
28780 + vop_lock(vop);
28781 + DRM_DEV_INFO(vop->dev, "Update mode to %dx%d%s%d, type: %d\n",
28785 + vop_disable_allwin(vop);
28786 + VOP_CTRL_SET(vop, standby, 0);
28789 + vop_disable_all_planes(vop);
28793 + if (vop->lut_active)
28796 + if (vop->mcu_timing.mcu_pix_total)
28801 + VOP_CTRL_SET(vop, dclk_pol, dclk_inv);
28806 + VOP_CTRL_SET(vop, pin_pol, val);
28808 + if (vop->dclk_source && vop->pll && vop->pll->pll) {
28809 + if (clk_set_parent(vop->dclk_source, vop->pll->pll))
28810 + DRM_DEV_ERROR(vop->dev,
28817 + VOP_CTRL_SET(vop, rgb_en, 1);
28818 + VOP_CTRL_SET(vop, rgb_pin_pol, val);
28819 + VOP_CTRL_SET(vop, rgb_dclk_pol, dclk_inv);
28820 + VOP_CTRL_SET(vop, lvds_en, 1);
28821 + VOP_CTRL_SET(vop, lvds_pin_pol, val);
28822 + VOP_CTRL_SET(vop, lvds_dclk_pol, dclk_inv);
28823 + VOP_GRF_SET(vop, grf_dclk_inv, dclk_inv);
28825 + VOP_CTRL_SET(vop, bt1120_en, 1);
28827 + VOP_CTRL_SET(vop, bt1120_yc_swap, yc_swap);
28828 + VOP_CTRL_SET(vop, yuv_clip, 1);
28830 + VOP_CTRL_SET(vop, bt656_en, 1);
28834 + VOP_CTRL_SET(vop, edp_en, 1);
28835 + VOP_CTRL_SET(vop, edp_pin_pol, val);
28836 + VOP_CTRL_SET(vop, edp_dclk_pol, dclk_inv);
28839 + VOP_CTRL_SET(vop, hdmi_en, 1);
28840 + VOP_CTRL_SET(vop, hdmi_pin_pol, val);
28841 + VOP_CTRL_SET(vop, hdmi_dclk_pol, 1);
28844 + VOP_CTRL_SET(vop, mipi_en, 1);
28845 + VOP_CTRL_SET(vop, mipi_pin_pol, val);
28846 + VOP_CTRL_SET(vop, mipi_dclk_pol, dclk_inv);
28847 + VOP_CTRL_SET(vop, mipi_dual_channel_en,
28849 + VOP_CTRL_SET(vop, data01_swap,
28851 + vop->dual_channel_swap);
28854 + VOP_CTRL_SET(vop, dp_dclk_pol, 0);
28855 + VOP_CTRL_SET(vop, dp_pin_pol, val);
28856 + VOP_CTRL_SET(vop, dp_en, 1);
28860 + VOP_CTRL_SET(vop, tve_sw_mode, 1);
28862 + VOP_CTRL_SET(vop, tve_sw_mode, 0);
28864 + VOP_CTRL_SET(vop, tve_dclk_pol, 1);
28865 + VOP_CTRL_SET(vop, tve_dclk_en, 1);
28867 + VOP_CTRL_SET(vop, hdmi_pin_pol, val);
28868 + VOP_CTRL_SET(vop, sw_genlock, 1);
28869 + VOP_CTRL_SET(vop, sw_uv_offset_en, 1);
28870 + VOP_CTRL_SET(vop, dither_up_en, 1);
28876 + VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
28879 + VOP_CTRL_SET(vop, hact_st_end, val);
28880 + VOP_CTRL_SET(vop, hpost_st_end, val);
28884 + VOP_CTRL_SET(vop, vact_st_end, val);
28885 + VOP_CTRL_SET(vop, vpost_st_end, val);
28892 + VOP_CTRL_SET(vop, vact_st_end_f1, val);
28893 + VOP_CTRL_SET(vop, vpost_st_end_f1, val);
28896 + VOP_CTRL_SET(vop, vs_st_end_f1, val);
28897 + VOP_CTRL_SET(vop, dsp_interlace, 1);
28898 + VOP_CTRL_SET(vop, p2i_en, 1);
28902 + VOP_CTRL_SET(vop, dsp_interlace, 0);
28903 + VOP_CTRL_SET(vop, p2i_en, 0);
28907 + if (VOP_MAJOR(vop->version) == 3 &&
28908 + (VOP_MINOR(vop->version) == 2 || VOP_MINOR(vop->version) == 8))
28910 + VOP_INTR_SET(vop, line_flag_num[0], act_end);
28911 + VOP_INTR_SET(vop, line_flag_num[1],
28914 + VOP_CTRL_SET(vop, vtotal_pw, vtotal << 16 | vsync_len);
28916 + VOP_CTRL_SET(vop, core_dclk_div,
28920 + VOP_CTRL_SET(vop, win_csc_mode_sel, 1);
28922 + clk_set_rate(vop->dclk, adjusted_mode->crtc_clock * 1000);
28925 + vop_cfg_done(vop);
28928 + vop_unlock(vop);
28942 + struct vop *vop = to_vop(crtc);
28972 + if (!VOP_CTRL_SUPPORT(vop, afbdc_en)) {
28994 + DRM_ERROR("vop only support one afbc layer\n");
29011 + if (VOP_CTRL_SUPPORT(vop, afbdc_pic_vir_width)) {
29074 + struct vop *vop = to_vop(crtc);
29075 + struct rockchip_dclk_pll *old_pll = vop->pll;
29077 + if (!vop->dclk_source)
29081 + WARN_ON(vop->pll && !vop->pll->use_count);
29082 + if (!vop->pll || vop->pll->use_count > 1 ||
29084 + if (vop->pll)
29085 + vop->pll->use_count--;
29089 + vop->pll = &private->default_pll;
29091 + vop->pll = &private->hdmi_pll;
29093 + vop->pll->use_count++;
29095 + } else if (vop->pll) {
29096 + vop->pll->use_count--;
29097 + vop->pll = NULL;
29099 + if (vop->pll != old_pll)
29108 + struct vop *vop = to_vop(crtc);
29109 + const struct vop_data *vop_data = vop->data;
29122 + if (VOP_CTRL_SUPPORT(vop, overlay_mode))
29136 - spin_lock_irqsave(&vop->irq_lock, flags);
29141 - VOP_INTR_SET_TYPE(vop, clear, FS_INTR, 1);
29142 - VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 1);
29146 - spin_unlock_irqrestore(&vop->irq_lock, flags);
29147 + for (j = 0; j < vop->num_wins; j++) {
29148 + win = &vop->win[j];
29155 + if (WARN_ON(j >= vop->num_wins)) {
29162 - struct vop *vop = to_vop(crtc);
29174 - if (WARN_ON(!vop->is_enabled))
29183 - spin_lock_irqsave(&vop->irq_lock, flags);
29186 - VOP_INTR_SET_TYPE(vop, enable, FS_INTR, 0);
29191 - spin_unlock_irqrestore(&vop->irq_lock, flags);
29200 - struct vop *vop = to_vop(crtc);
29239 - rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
29251 -static bool vop_dsp_lut_is_enabled(struct vop *vop)
29254 - return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en);
29255 + struct vop *vop = to_vop(crtc);
29275 + VOP_CTRL_SET(vop, hpost_st_end, val);
29280 + VOP_CTRL_SET(vop, vpost_st_end, val);
29283 + VOP_CTRL_SET(vop, post_scl_factor, val);
29287 + VOP_CTRL_SET(vop, post_scl_ctrl,
29295 + VOP_CTRL_SET(vop, vpost_st_end_f1, val);
29299 -static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc)
29307 + struct vop *vop = to_vop(crtc);
29312 + if (!vop->data->hdr_table)
29318 - writel(word, vop->lut_regs + i * 4);
29320 + vop_load_hdr2sdr_table(vop);
29325 + VOP_CTRL_SET(vop, hdr2sdr_en_win0_csc, 0);
29327 + VOP_CTRL_SET(vop, hdr2sdr_en, s->hdr.hdr2sdr_en);
29329 + VOP_CTRL_SET(vop, bt1886eotf_pre_conv_en,
29331 + VOP_CTRL_SET(vop, bt1886eotf_post_conv_en,
29334 + VOP_CTRL_SET(vop, rgb2rgb_pre_conv_en,
29336 + VOP_CTRL_SET(vop, rgb2rgb_pre_conv_mode,
29338 + VOP_CTRL_SET(vop, st2084oetf_pre_conv_en,
29341 + VOP_CTRL_SET(vop, rgb2rgb_post_conv_en,
29343 + VOP_CTRL_SET(vop, rgb2rgb_post_conv_mode,
29345 + VOP_CTRL_SET(vop, st2084oetf_post_conv_en,
29350 + vop_load_sdr2hdr_table(vop, sdr2hdr_state->sdr2hdr_func);
29351 + VOP_CTRL_SET(vop, win_csc_mode_sel, 1);
29354 -static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
29367 + struct vop *vop = to_vop(crtc);
29368 + const struct vop_data *vop_data = vop->data;
29370 - if (!vop->lut_regs)
29377 - spin_lock(&vop->reg_lock);
29378 - VOP_REG_SET(vop, common, dsp_lut_en, 0);
29379 - vop_cfg_done(vop);
29380 - spin_unlock(&vop->reg_lock);
29393 - ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
29396 - DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
29398 + &vop->active_tv_state, sizeof(*s->tv_state)) &&
29403 + memcpy(&vop->active_tv_state, s->tv_state, sizeof(*s->tv_state));
29429 + VOP_CTRL_SET(vop, bcsh_r2y_en, s->post_r2y_en);
29430 + VOP_CTRL_SET(vop, bcsh_y2r_en, s->post_y2r_en);
29431 + VOP_CTRL_SET(vop, bcsh_r2y_csc_mode, s->post_csc_mode);
29432 + VOP_CTRL_SET(vop, bcsh_y2r_csc_mode, s->post_csc_mode);
29434 + VOP_CTRL_SET(vop, bcsh_en, s->bcsh_en);
29438 - spin_lock(&vop->reg_lock);
29439 - vop_crtc_write_gamma_lut(vop, crtc);
29440 - VOP_REG_SET(vop, common, dsp_lut_en, 1);
29441 - vop_cfg_done(vop);
29442 - spin_unlock(&vop->reg_lock);
29446 + else if (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 6) /* px30 vopb */
29454 - struct vop *vop = to_vop(crtc);
29455 + if ((VOP_MAJOR(vop->version) == 3) ||
29456 + (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 6)) { /* px30 vopb */
29470 + VOP_CTRL_SET(vop, bcsh_sat_con, saturation * contrast / 0x100);
29478 - vop_crtc_gamma_set(vop, crtc, old_crtc_state);
29493 + VOP_CTRL_SET(vop, bcsh_sat_con, saturation * contrast / 0x80);
29496 + VOP_CTRL_SET(vop, bcsh_brightness, brightness);
29497 + VOP_CTRL_SET(vop, bcsh_contrast, contrast);
29498 + VOP_CTRL_SET(vop, bcsh_sin_hue, sin_hue);
29499 + VOP_CTRL_SET(vop, bcsh_cos_hue, cos_hue);
29500 + VOP_CTRL_SET(vop, bcsh_out_mode, BCSH_OUT_MODE_NORMAL_VIDEO);
29501 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) == 0)
29502 + VOP_CTRL_SET(vop, auto_gate_en, 0);
29503 + VOP_CTRL_SET(vop, bcsh_en, s->bcsh_en);
29513 struct vop *vop = to_vop(crtc);
29514 const struct vop_data *vop_data = vop->data;
29543 - vop_crtc_gamma_set(vop, crtc, old_state);
29545 - mutex_lock(&vop->vop_lock);
29547 - WARN_ON(vop->event);
29548 + spin_lock(&vop->reg_lock);
29552 - mutex_unlock(&vop->vop_lock);
29553 - DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
29560 - VOP_REG_SET(vop, output, pin_pol, pin_pol);
29561 - VOP_REG_SET(vop, output, mipi_dual_channel_en, 0);
29566 - VOP_REG_SET(vop, output, rgb_dclk_pol, 1);
29567 - VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
29568 - VOP_REG_SET(vop, output, rgb_en, 1);
29571 - VOP_REG_SET(vop, output, edp_dclk_pol, 1);
29572 - VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
29573 - VOP_REG_SET(vop, output, edp_en, 1);
29576 - VOP_REG_SET(vop, output, hdmi_dclk_pol, 1);
29577 - VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
29578 - VOP_REG_SET(vop, output, hdmi_en, 1);
29581 - VOP_REG_SET(vop, output, mipi_dclk_pol, 1);
29582 - VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
29583 - VOP_REG_SET(vop, output, mipi_en, 1);
29584 - VOP_REG_SET(vop, output, mipi_dual_channel_en,
29588 - VOP_REG_SET(vop, output, dp_dclk_pol, 0);
29589 - VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
29590 - VOP_REG_SET(vop, output, dp_en, 1);
29593 - DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
29599 - * if vop is not support RGB10 output, need force RGB10 to RGB888.
29608 - VOP_REG_SET(vop, common, pre_dither_down, 1);
29610 - VOP_REG_SET(vop, common, pre_dither_down, 0);
29611 + VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4);
29612 + VOP_CTRL_SET(vop, afbdc_hreg_block_split, 0);
29613 + VOP_CTRL_SET(vop, afbdc_sel, s->afbdc_win_id);
29614 + VOP_CTRL_SET(vop, afbdc_hdr_ptr, s->afbdc_win_ptr);
29617 + VOP_CTRL_SET(vop, afbdc_pic_size, pic_size);
29620 - VOP_REG_SET(vop, common, dither_down_sel, DITHER_DOWN_ALLEGRO);
29621 - VOP_REG_SET(vop, common, dither_down_mode, RGB888_TO_RGB666);
29622 - VOP_REG_SET(vop, common, dither_down_en, 1);
29624 - VOP_REG_SET(vop, common, dither_down_en, 0);
29625 + VOP_CTRL_SET(vop, afbdc_pic_vir_width, s->afbdc_win_vir_width);
29628 + VOP_CTRL_SET(vop, afbdc_pic_offset, pic_offset);
29631 - VOP_REG_SET(vop, common, out_mode, s->output_mode);
29632 + VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
29634 - VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
29637 - VOP_REG_SET(vop, modeset, hact_st_end, val);
29638 - VOP_REG_SET(vop, modeset, hpost_st_end, val);
29640 - VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
29643 - VOP_REG_SET(vop, modeset, vact_st_end, val);
29644 - VOP_REG_SET(vop, modeset, vpost_st_end, val);
29646 - VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
29647 + VOP_CTRL_SET(vop, dsp_layer_sel, s->dsp_layer_sel);
29651 - clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
29653 - VOP_REG_SET(vop, common, standby, 0);
29654 - mutex_unlock(&vop->vop_lock);
29655 + spin_unlock(&vop->reg_lock);
29658 static bool vop_fs_irq_is_pending(struct vop *vop)
29660 - return VOP_INTR_GET_TYPE(vop, status, FS_INTR);
29661 + if (VOP_MAJOR(vop->version) == 3 && VOP_MINOR(vop->version) >= 7)
29662 + return VOP_INTR_GET_TYPE(vop, status, FS_FIELD_INTR);
29664 + return VOP_INTR_GET_TYPE(vop, status, FS_INTR);
29667 static void vop_wait_for_irq_handler(struct vop *vop)
29668 @@ -1413,72 +3857,66 @@ static void vop_wait_for_irq_handler(struct vop *vop)
29669 synchronize_irq(vop->irq);
29679 struct vop *vop = to_vop(crtc);
29689 - if (vop->lut_regs && crtc_state->color_mgmt_changed &&
29701 + if (!vop->is_iommu_enabled && vop->is_iommu_needed) {
29713 + VOP_CTRL_SET(vop, dma_stop, 1);
29717 + ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
29719 + vop->is_iommu_enabled = false;
29720 + vop_disable_all_planes(vop);
29721 + dev_err(vop->dev, "failed to attach dma mapping, %d\n",
29724 + vop->is_iommu_enabled = true;
29725 + VOP_CTRL_SET(vop, dma_stop, 0);
29734 + if (crtc->state->gamma_lut || vop->gamma_lut) {
29736 + vop->gamma_lut = old_crtc_state->gamma_lut->data;
29752 - struct vop *vop = to_vop(crtc);
29757 - if (WARN_ON(!vop->is_enabled))
29760 - spin_lock(&vop->reg_lock);
29764 - VOP_AFBC_SET(vop, enable, s->enable_afbc);
29765 + spin_lock_irqsave(&vop->irq_lock, flags);
29766 + vop->pre_overlay = s->hdr.pre_overlay;
29767 vop_cfg_done(vop);
29773 + if (VOP_MAJOR(vop->version) == 3 &&
29774 + (VOP_MINOR(vop->version) == 7 || VOP_MINOR(vop->version) == 8)) {
29775 + if (!s->mode_update && VOP_CTRL_GET(vop, reg_done_frm))
29776 + VOP_CTRL_SET(vop, reg_done_frm, 0);
29778 + VOP_CTRL_SET(vop, reg_done_frm, 0);
29780 + if (vop->mcu_timing.mcu_pix_total)
29781 + VOP_CTRL_SET(vop, mcu_hold_mode, 0);
29783 - spin_unlock(&vop->reg_lock);
29784 + spin_unlock_irqrestore(&vop->irq_lock, flags);
29869 static struct drm_connector *vop_get_edp_connector(struct vop *vop)
29884 + struct vop *vop = to_vop(crtc);
29908 + *val = clk_get_rate(vop->aclk) / 1000;
29913 + *val = vop->background;
29918 + *val = vop->line_flag;
29922 + DRM_ERROR("failed to get vop crtc property\n");
29935 + struct vop *vop = to_vop(crtc);
29958 + vop->background = val;
29963 + vop->line_flag = val;
29967 + DRM_ERROR("failed to set vop crtc property\n");
29990 struct vop *vop = container_of(work, struct vop, fb_unref_work);
29993 - drm_crtc_vblank_put(&vop->crtc);
29994 + drm_crtc_vblank_put(&vop->rockchip_crtc.crtc);
29998 static void vop_handle_vblank(struct vop *vop)
30000 struct drm_device *drm = vop->drm_dev;
30001 - struct drm_crtc *crtc = &vop->crtc;
30002 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30007 if (vop->event) {
30008 drm_crtc_send_vblank_event(crtc, vop->event);
30010 vop->event = NULL;
30015 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
30016 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
30017 @@ -1669,8 +4215,9 @@ static void vop_handle_vblank(struct vop *vop)
30020 struct vop *vop = data;
30021 - struct drm_crtc *crtc = &vop->crtc;
30022 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30032 - spin_lock(&vop->irq_lock);
30033 + spin_lock_irqsave(&vop->irq_lock, flags);
30035 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK);
30038 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1);
30040 - spin_unlock(&vop->irq_lock);
30041 + spin_unlock_irqrestore(&vop->irq_lock, flags);
30043 /* This is expected for vop iommu irqs, since the irq is shared */
30055 + spin_lock_irqsave(&vop->irq_lock, flags);
30056 + VOP_CTRL_SET(vop, level2_overlay_en, vop->pre_overlay);
30057 + VOP_CTRL_SET(vop, alpha_hard_calc, vop->pre_overlay);
30058 + spin_unlock_irqrestore(&vop->irq_lock, flags);
30060 vop_handle_vblank(vop);
30069 + DRM_DEV_ERROR_RATELIMITED(vop->dev, #x " irq err\n"); \
30085 - DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n",
30090 vop_core_clks_disable(vop);
30097 +static void vop_plane_add_properties(struct vop *vop,
30105 + flags |= (VOP_WIN_SUPPORT(vop, win, xmirror)) ? DRM_MODE_REFLECT_X : 0;
30106 + flags |= (VOP_WIN_SUPPORT(vop, win, ymirror)) ? DRM_MODE_REFLECT_Y : 0;
30113 -static int vop_create_crtc(struct vop *vop)
30114 +static int vop_plane_create_name_property(struct vop *vop, struct vop_win *win)
30116 + struct drm_prop_enum_list *props = vop->plane_name_list;
30120 + prop = drm_property_create_bitmask(vop->drm_dev,
30122 + props, vop->num_wins, bits);
30124 + DRM_DEV_ERROR(vop->dev, "create Name prop for %s failed\n", win->name);
30133 +static int vop_plane_init(struct vop *vop, struct vop_win *win,
30136 + struct rockchip_drm_private *private = vop->drm_dev->dev_private;
30139 + const struct vop_data *vop_data = vop->data;
30143 + ret = drm_universal_plane_init(vop->drm_dev, &win->base, possible_crtcs, &vop_plane_funcs,
30154 + if (VOP_WIN_SUPPORT(vop, win, src_alpha_ctl) ||
30155 + VOP_WIN_SUPPORT(vop, win, alpha_en))
30164 + drm_object_attach_property(&win->base.base, vop->plane_feature_prop,
30169 + if (VOP_WIN_SUPPORT(vop, win, global_alpha_val))
30182 + drm_plane_create_zpos_property(&win->base, win->win_id, 0, vop->num_wins - 1);
30183 + vop_plane_create_name_property(vop, win);
30186 + win->input_width_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30188 + win->input_height_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30191 + win->output_width_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30193 + win->output_height_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30196 + win->scale_prop = drm_property_create_range(vop->drm_dev, DRM_MODE_PROP_IMMUTABLE,
30203 + win->color_key_prop = drm_property_create_range(vop->drm_dev, 0,
30221 +static int vop_of_init_display_lut(struct vop *vop)
30223 + struct device_node *node = vop->dev->of_node;
30225 + u32 lut_len = vop->lut_len;
30230 + if (!vop->lut)
30239 + dev_err(vop->dev, "failed to find gamma_lut\n");
30254 + dev_err(vop->dev, "load gamma-lut failed\n");
30265 + vop->lut[i] = r * lut_len * lut_len + g * lut_len + b;
30271 + vop->lut, vop->lut_len);
30273 + vop->lut_active = true;
30278 +static int vop_crtc_create_plane_mask_property(struct vop *vop, struct drm_crtc *crtc)
30289 + prop = drm_property_create_bitmask(vop->drm_dev,
30294 + DRM_DEV_ERROR(vop->dev, "create plane_mask prop for vp%d failed\n", vop->id);
30298 + vop->plane_mask_prop = prop;
30299 + drm_object_attach_property(&crtc->base, vop->plane_mask_prop, vop->plane_mask);
30304 +static int vop_crtc_create_feature_property(struct vop *vop, struct drm_crtc *crtc)
30306 const struct vop_data *vop_data = vop->data;
30324 + prop = drm_property_create_bitmask(vop->drm_dev,
30329 + DRM_DEV_ERROR(vop->dev, "create FEATURE prop for vop%d failed\n", vop->id);
30333 + vop->feature_prop = prop;
30334 + drm_object_attach_property(&crtc->base, vop->feature_prop, feature);
30339 +static int vop_create_crtc(struct vop *vop)
30341 struct device *dev = vop->dev;
30342 struct drm_device *drm_dev = vop->drm_dev;
30345 - struct drm_crtc *crtc = &vop->crtc;
30346 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30353 @@ -1761,29 +4559,19 @@ static int vop_create_crtc(struct vop *vop)
30358 - struct vop_win *vop_win = &vop->win[i];
30360 + for (i = 0; i < vop->num_wins; i++) {
30361 + struct vop_win *win = &vop->win[i];
30369 - ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
30376 - DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
30378 + if (vop_plane_init(vop, win, 0)) {
30379 + DRM_DEV_ERROR(vop->dev, "failed to init plane\n");
30390 @@ -1796,37 +4584,23 @@ static int vop_create_crtc(struct vop *vop)
30394 - if (vop->lut_regs) {
30404 - struct vop_win *vop_win = &vop->win[i];
30406 + for (i = 0; i < vop->num_wins; i++) {
30407 + struct vop_win *win = &vop->win[i];
30414 - ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
30422 - DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
30424 + if (vop_plane_init(vop, win, possible_crtcs)) {
30425 + DRM_DEV_ERROR(vop->dev, "failed to init overlay\n");
30430 + vop_plane_add_properties(vop, &win->base, win);
30434 @@ -1843,15 +4617,65 @@ static int vop_create_crtc(struct vop *vop)
30435 init_completion(&vop->dsp_hold_completion);
30436 init_completion(&vop->line_flag_completion);
30441 + drm_object_attach_property(&crtc->base, private->soc_id_prop, vop->soc_id);
30442 + drm_object_attach_property(&crtc->base, private->port_id_prop, vop->id);
30455 + vop_crtc_create_plane_mask_property(vop, crtc);
30456 + vop_crtc_create_feature_property(vop, crtc);
30459 DRM_DEV_DEBUG_KMS(vop->dev,
30465 + if (vop->lut_regs) {
30467 + u32 lut_len = vop->lut_len;
30469 + vop->lut = devm_kmalloc_array(dev, lut_len, sizeof(*vop->lut),
30471 + if (!vop->lut)
30474 + if (vop_of_init_display_lut(vop)) {
30480 + vop->lut[i] = r | g | b;
30503 @@ -1863,7 +4687,7 @@ static int vop_create_crtc(struct vop *vop)
30505 static void vop_destroy_crtc(struct vop *vop)
30507 - struct drm_crtc *crtc = &vop->crtc;
30508 + struct drm_crtc *crtc = &vop->rockchip_crtc.crtc;
30509 struct drm_device *drm_dev = vop->drm_dev;
30512 @@ -1891,187 +4715,130 @@ static void vop_destroy_crtc(struct vop *vop)
30513 drm_flip_work_cleanup(&vop->fb_unref_work);
30516 -static int vop_initial(struct vop *vop)
30529 - vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
30530 - if (IS_ERR(vop->hclk)) {
30531 - DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n");
30532 - return PTR_ERR(vop->hclk);
30534 - vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
30535 - if (IS_ERR(vop->aclk)) {
30536 - DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n");
30537 - return PTR_ERR(vop->aclk);
30539 - vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
30540 - if (IS_ERR(vop->dclk)) {
30541 - DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n");
30542 - return PTR_ERR(vop->dclk);
30545 - ret = pm_runtime_get_sync(vop->dev);
30547 - DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
30551 - ret = clk_prepare(vop->dclk);
30553 - DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n");
30557 - /* Enable both the hclk and aclk to setup the vop */
30558 - ret = clk_prepare_enable(vop->hclk);
30560 - DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n");
30564 - ret = clk_prepare_enable(vop->aclk);
30566 - DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n");
30571 - * do hclk_reset, reset all vop registers.
30573 - ahb_rst = devm_reset_control_get(vop->dev, "ahb");
30575 - DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n");
30583 - VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
30584 - VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);
30586 - for (i = 0; i < vop->len; i += sizeof(u32))
30587 - vop->regsbak[i / 4] = readl_relaxed(vop->regs + i);
30589 - VOP_REG_SET(vop, misc, global_regdone_en, 1);
30590 - VOP_REG_SET(vop, common, dsp_blank, 0);
30592 - for (i = 0; i < vop->data->win_size; i++) {
30593 - struct vop_win *vop_win = &vop->win[i];
30597 - VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
30598 - vop_win_disable(vop, vop_win);
30599 - VOP_WIN_SET(vop, win, gate, 1);
30602 - vop_cfg_done(vop);
30607 - vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk");
30608 - if (IS_ERR(vop->dclk_rst)) {
30609 - DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n");
30610 - ret = PTR_ERR(vop->dclk_rst);
30620 - reset_control_assert(vop->dclk_rst);
30622 - reset_control_deassert(vop->dclk_rst);
30624 - clk_disable(vop->hclk);
30625 - clk_disable(vop->aclk);
30627 - vop->is_enabled = false;
30629 - pm_runtime_put_sync(vop->dev);
30634 - clk_disable_unprepare(vop->aclk);
30636 - clk_disable_unprepare(vop->hclk);
30638 - clk_unprepare(vop->dclk);
30640 - pm_runtime_put_sync(vop->dev);
30645 * Initialize the vop->win array elements.
30647 -static void vop_win_init(struct vop *vop)
30648 +static int vop_win_init(struct vop *vop)
30650 const struct vop_data *vop_data = vop->data;
30666 - struct vop_win *vop_win = &vop->win[i];
30667 + struct vop_win *vop_win = &vop->win[num_wins];
30671 - vop_win->vop = vop;
30687 + vop_win->vop = vop;
30691 + snprintf(name, sizeof(name), "VOP%d-win%d-%d", vop->id, vop_win->win_id, vop_win->area_id);
30692 + vop_win->name = devm_kstrdup(vop->dev, name, GFP_KERNEL);
30708 - struct vop *vop = to_vop(crtc);
30713 - if (!crtc || !vop->is_enabled)
30715 + if (!vop->support_multi_area)
30718 - mutex_lock(&vop->vop_lock);
30723 + struct vop_win *vop_area = &vop->win[num_wins];
30733 + vop_area->vop = vop;
30737 + snprintf(name, sizeof(name), "VOP%d-win%d-%d", vop->id, vop_area->win_id, vop_area->area_id);
30738 + vop_area->name = devm_kstrdup(vop->dev, name, GFP_KERNEL);
30741 + vop->plane_mask |= BIT(vop_win->win_id);
30744 - if (vop_line_flag_irq_is_enabled(vop)) {
30747 + vop->num_wins = num_wins;
30749 + vop->plane_feature_prop = drm_property_create_bitmask(vop->drm_dev,
30757 + if (!vop->plane_feature_prop) {
30762 - reinit_completion(&vop->line_flag_completion);
30763 - vop_line_flag_irq_enable(vop);
30764 + plane_name_list = devm_kzalloc(vop->dev,
30765 + vop->num_wins * sizeof(*plane_name_list),
30768 + DRM_DEV_ERROR(vop->dev, "failed to alloc memory for plane_name_list\n");
30772 - jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
30774 - vop_line_flag_irq_disable(vop);
30775 + for (i = 0; i < vop->num_wins; i++) {
30776 + struct vop_win *vop_win = &vop->win[i];
30779 - DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
30787 - mutex_unlock(&vop->vop_lock);
30789 + vop->plane_name_list = plane_name_list;
30799 struct vop *vop;
30818 /* Allocate vop struct and its vop_win array */
30819 - vop = devm_kzalloc(dev, struct_size(vop, win, vop_data->win_size),
30821 + alloc_size = sizeof(*vop) + sizeof(*vop->win) * num_wins;
30822 + vop = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
30823 if (!vop)
30826 vop->dev = dev;
30827 vop->data = vop_data;
30828 vop->drm_dev = drm_dev;
30829 + vop->num_wins = num_wins;
30830 + vop->version = vop_data->version;
30831 + vop->soc_id = vop_data->soc_id;
30832 + vop->id = vop_data->vop_id;
30833 dev_set_drvdata(dev, vop);
30834 + vop->support_multi_area = of_property_read_bool(dev->of_node, "support-multi-area");
30836 - vop_win_init(vop);
30837 + ret = vop_win_init(vop);
30844 + dev_warn(vop->dev, "failed to get vop register byname\n");
30847 vop->regs = devm_ioremap_resource(dev, res);
30848 if (IS_ERR(vop->regs))
30849 return PTR_ERR(vop->regs);
30850 vop->len = resource_size(res);
30853 + vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
30854 + if (!vop->regsbak)
30861 + vop->lut_len = resource_size(res) / sizeof(*vop->lut);
30862 + if (vop->lut_len != 256 && vop->lut_len != 1024) {
30863 + dev_err(vop->dev, "unsupported lut sizes %d\n",
30864 + vop->lut_len);
30868 vop->lut_regs = devm_ioremap_resource(dev, res);
30869 if (IS_ERR(vop->lut_regs))
30870 return PTR_ERR(vop->lut_regs);
30873 - vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
30874 - if (!vop->regsbak)
30877 + vop->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
30879 + if (IS_ERR(vop->grf))
30881 + vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
30882 + if (IS_ERR(vop->hclk)) {
30883 + dev_err(vop->dev, "failed to get hclk source\n");
30884 + return PTR_ERR(vop->hclk);
30886 + vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
30887 + if (IS_ERR(vop->aclk)) {
30888 + dev_err(vop->dev, "failed to get aclk source\n");
30889 + return PTR_ERR(vop->aclk);
30891 + vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
30892 + if (IS_ERR(vop->dclk)) {
30893 + dev_err(vop->dev, "failed to get dclk source\n");
30894 + return PTR_ERR(vop->dclk);
30896 + vop->dclk_source = devm_clk_get(vop->dev, "dclk_source");
30897 + if (PTR_ERR(vop->dclk_source) == -ENOENT) {
30898 + vop->dclk_source = NULL;
30899 + } else if (PTR_ERR(vop->dclk_source) == -EPROBE_DEFER) {
30901 + } else if (IS_ERR(vop->dclk_source)) {
30902 + dev_err(vop->dev, "failed to get dclk source parent\n");
30903 + return PTR_ERR(vop->dclk_source);
30907 DRM_DEV_ERROR(dev, "cannot find irq for vop\n");
30909 spin_lock_init(&vop->irq_lock);
30910 mutex_init(&vop->vop_lock);
30912 + ret = devm_request_irq(dev, vop->irq, vop_isr,
30913 + IRQF_SHARED, dev_name(dev), vop);
30916 ret = vop_create_crtc(vop);
30922 - ret = vop_initial(vop);
30925 - "cannot initial vop dev - err %d\n", ret);
30929 - ret = devm_request_irq(dev, vop->irq, vop_isr,
30930 - IRQF_SHARED, dev_name(dev), vop);
30934 - if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) {
30935 - vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev);
30936 - if (IS_ERR(vop->rgb)) {
30937 - ret = PTR_ERR(vop->rgb);
30948 + vop->mcu_timing.mcu_pix_total = val;
30950 + vop->mcu_timing.mcu_cs_pst = val;
30952 + vop->mcu_timing.mcu_cs_pend = val;
30954 + vop->mcu_timing.mcu_rw_pst = val;
30956 + vop->mcu_timing.mcu_rw_pend = val;
30958 + vop->mcu_timing.mcu_hold_mode = val;
30964 + vop->dual_channel_swap = dual_channel_swap;
30968 - vop_destroy_crtc(vop);
30975 struct vop *vop = dev_get_drvdata(dev);
30977 - if (vop->rgb)
30978 - rockchip_rgb_fini(vop->rgb);
30981 vop_destroy_crtc(vop);
30983 - clk_unprepare(vop->aclk);
30984 - clk_unprepare(vop->hclk);
30985 - clk_unprepare(vop->dclk);
32853 - int vop;
32855 - vop = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder);
32856 - if (vop < 0)
32857 - return vop;
32861 - PX30_LVDS_VOP_SEL(vop));
36087 - * rk3399 vop big windows register layout is same as rk3288, but we
36839 { .compatible = "rockchip,rk3036-vop",
36843 + { .compatible = "rockchip,rk3066-vop",
36847 { .compatible = "rockchip,rk3126-vop",
36849 - { .compatible = "rockchip,px30-vop-big",
36853 { .compatible = "rockchip,px30-vop-lit",
36855 - { .compatible = "rockchip,rk3066-vop",
36857 - { .compatible = "rockchip,rk3188-vop",
36859 - { .compatible = "rockchip,rk3288-vop",
36861 + { .compatible = "rockchip,px30-vop-big",
36865 + { .compatible = "rockchip,rk3308-vop",
36869 + { .compatible = "rockchip,rv1106-vop",
36873 + { .compatible = "rockchip,rv1126-vop",
36877 + { .compatible = "rockchip,rk3288-vop-big",
36879 + { .compatible = "rockchip,rk3288-vop-lit",
36883 { .compatible = "rockchip,rk3368-vop",
36885 { .compatible = "rockchip,rk3366-vop",
36889 { .compatible = "rockchip,rk3399-vop-big",
36891 { .compatible = "rockchip,rk3399-vop-lit",
36895 { .compatible = "rockchip,rk3228-vop",
36899 { .compatible = "rockchip,rk3328-vop",
37181 +/* rk3568 vop registers definition */
39292 + bool skip_read; /* rk3126/rk3128 can't read vop iommu registers */
40129 + if (strstr(dev_name(dev), "vop"))
59584 + [RK3228_PD_VOP] = DOMAIN_RK3036("vop", BIT(5), BIT(5), BIT(21), false),