1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2063 lines
77 KiB

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
* Author:Mark Yao <mark.yao@rock-chips.com>
*/
#include <linux/component.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>
#include "rockchip_drm_vop.h"
#include "rockchip_vop_reg.h"
#define VOP_REG_VER_MASK(off, _mask, s, _write_mask, _major, \
_begin_minor, _end_minor) \
{.offset = off, \
.mask = _mask, \
.shift = s, \
.write_mask = _write_mask, \
.major = _major, \
.begin_minor = _begin_minor, \
.end_minor = _end_minor,}
#define VOP_REG(off, _mask, s) \
VOP_REG_VER_MASK(off, _mask, s, false, 0, 0, -1)
#define VOP_REG_MASK(off, _mask, s) \
VOP_REG_VER_MASK(off, _mask, s, true, 0, 0, -1)
#define VOP_REG_VER(off, _mask, s, _major, _begin_minor, _end_minor) \
VOP_REG_VER_MASK(off, _mask, s, false, \
_major, _begin_minor, _end_minor)
static const uint32_t formats_win_full[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
DRM_FORMAT_NV12,
DRM_FORMAT_NV16,
DRM_FORMAT_NV24,
};
static const uint32_t formats_win_full_10bit[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
DRM_FORMAT_NV12,
DRM_FORMAT_NV16,
DRM_FORMAT_NV24,
DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
#ifdef CONFIG_NO_GKI
DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
#endif
};
static const uint32_t formats_win_full_10bit_yuyv[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
#ifdef CONFIG_NO_GKI
DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
#endif
DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode or non-Linear mode */
DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode or non-Linear mode */
DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode or non-Linear mode */
DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode or non-Linear mode */
};
static const uint32_t formats_win_lite[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
};
static const uint64_t format_modifiers[] = {
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID,
};
static const uint64_t format_modifiers_afbc[] = {
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16),
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_SPARSE),
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_YTR),
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_CBR),
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_YTR |
AFBC_FORMAT_MOD_SPARSE),
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_CBR |
AFBC_FORMAT_MOD_SPARSE),
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_YTR |
AFBC_FORMAT_MOD_CBR),
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_YTR |
AFBC_FORMAT_MOD_CBR |
AFBC_FORMAT_MOD_SPARSE),
/* SPLIT mandates SPARSE, RGB modes mandates YTR */
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_YTR |
AFBC_FORMAT_MOD_SPARSE |
AFBC_FORMAT_MOD_SPLIT),
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID,
};
static const struct vop_scl_extension rk3288_win_full_scl_ext = {
.cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
.cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
.cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
.cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
.cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
.yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
.yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
.yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
.yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
.yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
.line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
.cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
.yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
.vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
.vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
.vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
.vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
.bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
.cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
.yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
.lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
};
static const struct vop_scl_regs rk3288_win_full_scl = {
.ext = &rk3288_win_full_scl_ext,
.scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
.scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
.scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
.scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
};
static const struct vop_win_phy rk3288_win01_data = {
.scl = &rk3288_win_full_scl,
.data_formats = formats_win_full_10bit,
.nformats = ARRAY_SIZE(formats_win_full_10bit),
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
.fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 4),
.csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1),
.ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xffff, 0),
.global_alpha_val = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 16),
.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xffffffff, 0),
.channel = VOP_REG_VER(RK3288_WIN0_CTRL2, 0xff, 0, 3, 8, 8),
};
static const struct vop_win_phy rk3288_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
.src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xffff, 0),
.global_alpha_val = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 16),
.dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xffffffff, 0),
};
static const struct vop_win_phy rk3288_area1_data = {
.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 5),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO1, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3288_WIN2_DSP_ST1, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3288_WIN2_MST1, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 16),
};
static const struct vop_win_phy rk3288_area2_data = {
.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 6),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO2, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3288_WIN2_DSP_ST2, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3288_WIN2_MST2, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3288_WIN2_VIR2_3, 0x1fff, 0),
};
static const struct vop_win_phy rk3288_area3_data = {
.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 7),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO3, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3288_WIN2_DSP_ST3, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3288_WIN2_MST3, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3288_WIN2_VIR2_3, 0x1fff, 16),
};
static const struct vop_win_phy *rk3288_area_data[] = {
&rk3288_area1_data,
&rk3288_area2_data,
&rk3288_area3_data
};
static const struct vop_ctrl rk3288_ctrl_data = {
.version = VOP_REG(RK3288_VERSION_INFO, 0xffff, 16),
.standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22),
.dma_stop = VOP_REG(RK3288_SYS_CTRL, 0x1, 21),
.axi_outstanding_max_num = VOP_REG(RK3288_SYS_CTRL1, 0x1f, 13),
.axi_max_outstanding_en = VOP_REG(RK3288_SYS_CTRL1, 0x1, 12),
.reg_done_frm = VOP_REG_VER(RK3288_SYS_CTRL1, 0x1, 24, 3, 5, -1),
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.vact_st_end_f1 = VOP_REG(RK3288_DSP_VACT_ST_END_F1, 0x1fff1fff, 0),
.vs_st_end_f1 = VOP_REG(RK3288_DSP_VS_ST_END_F1, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
.vpost_st_end_f1 = VOP_REG(RK3288_POST_DSP_VACT_INFO_F1, 0x1fff1fff, 0),
.post_scl_factor = VOP_REG(RK3288_POST_SCL_FACTOR_YRGB, 0xffffffff, 0),
.post_scl_ctrl = VOP_REG(RK3288_POST_SCL_CTRL, 0x3, 0),
.dsp_interlace = VOP_REG(RK3288_DSP_CTRL0, 0x1, 10),
.auto_gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
.dsp_layer_sel = VOP_REG(RK3288_DSP_CTRL1, 0xff, 8),
.post_lb_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 18, 3, 2, -1),
.global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
.overlay_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 16, 3, 2, -1),
.core_dclk_div = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 4, 3, 4, -1),
.p2i_en = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 5, 3, 4, -1),
.dclk_ddr = VOP_REG_VER(RK3288_DSP_CTRL0, 0x1, 8, 3, 1, -1),
.dp_en = VOP_REG_VER(RK3399_SYS_CTRL, 0x1, 11, 3, 5, -1),
.hdmi_dclk_out_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 1, 1),
.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
.mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
.data01_swap = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 17, 3, 5, -1),
.dclk_pol = VOP_REG_VER(RK3288_DSP_CTRL0, 0x1, 7, 3, 0, 1),
.pin_pol = VOP_REG_VER(RK3288_DSP_CTRL0, 0x7, 4, 3, 0, 1),
.dp_dclk_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0x1, 19, 3, 5, -1),
.dp_pin_pol = VOP_REG_VER(RK3399_DSP_CTRL1, 0x7, 16, 3, 5, -1),
.rgb_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 19, 3, 2, -1),
.rgb_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 16, 3, 2, -1),
.tve_dclk_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 24),
.tve_dclk_pol = VOP_REG(RK3288_SYS_CTRL, 0x1, 25),
.tve_sw_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 26),
.sw_uv_offset_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 27),
.sw_genlock = VOP_REG(RK3288_SYS_CTRL, 0x1, 28),
.hdmi_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 23, 3, 2, -1),
.hdmi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 20, 3, 2, -1),
.edp_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 27, 3, 2, -1),
.edp_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 24, 3, 2, -1),
.mipi_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 31, 3, 2, -1),
.mipi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 28, 3, 2, -1),
.dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
.dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
.dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
.pre_dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
.dither_up_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
.dsp_out_yuv = VOP_REG_VER(RK3399_POST_SCL_CTRL, 0x1, 2, 3, 5, -1),
.dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12),
.dsp_bg_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1, 12),
.dsp_rb_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1, 13),
.dsp_rg_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1, 14),
.dsp_delta_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1, 15),
.dsp_dummy_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1, 16),
.dsp_ccir656_avg = VOP_REG(RK3288_DSP_CTRL0, 0x1, 20),
.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
.update_gamma_lut = VOP_REG_VER(RK3288_DSP_CTRL1, 0x1, 7, 3, 5, -1),
.lut_buffer_index = VOP_REG_VER(RK3399_DBG_POST_REG1, 0x1, 1, 3, 5, -1),
.dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0),
.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
.afbdc_rstn = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1, 3, 3, 5, -1),
.afbdc_en = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1, 0, 3, 5, -1),
.afbdc_sel = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x3, 1, 3, 5, -1),
.afbdc_format = VOP_REG_VER(RK3399_AFBCD0_CTRL, 0x1f, 16, 3, 5, -1),
.afbdc_hreg_block_split = VOP_REG_VER(RK3399_AFBCD0_CTRL,
0x1, 21, 3, 5, -1),
.afbdc_hdr_ptr = VOP_REG_VER(RK3399_AFBCD0_HDR_PTR, 0xffffffff,
0, 3, 5, -1),
.afbdc_pic_size = VOP_REG_VER(RK3399_AFBCD0_PIC_SIZE, 0xffffffff,
0, 3, 5, -1),
.bcsh_brightness = VOP_REG(RK3288_BCSH_BCS, 0xff, 0),
.bcsh_contrast = VOP_REG(RK3288_BCSH_BCS, 0x1ff, 8),
.bcsh_sat_con = VOP_REG(RK3288_BCSH_BCS, 0x3ff, 20),
.bcsh_out_mode = VOP_REG(RK3288_BCSH_BCS, 0x3, 30),
.bcsh_sin_hue = VOP_REG(RK3288_BCSH_H, 0x1ff, 0),
.bcsh_cos_hue = VOP_REG(RK3288_BCSH_H, 0x1ff, 16),
.bcsh_r2y_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 6, 3, 1, -1),
.bcsh_r2y_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 4, 3, 1, -1),
.bcsh_y2r_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x3, 2, 3, 1, -1),
.bcsh_y2r_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 0, 3, 1, -1),
.bcsh_color_bar = VOP_REG(RK3288_BCSH_COLOR_BAR, 0xffffff, 8),
.bcsh_en = VOP_REG(RK3288_BCSH_COLOR_BAR, 0x1, 0),
.xmirror = VOP_REG(RK3288_DSP_CTRL0, 0x1, 22),
.ymirror = VOP_REG(RK3288_DSP_CTRL0, 0x1, 23),
.dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0),
.cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
};
/*
* Note: rk3288 has a dedicated 'cursor' window, however, that window requires
* special support to get alpha blending working. For now, just use overlay
* window 3 for the drm cursor.
*
*/
static const struct vop_win_data rk3288_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x40, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x00, .phy = &rk3288_win23_data,
.type = DRM_PLANE_TYPE_OVERLAY,
.area = rk3288_area_data,
.area_size = ARRAY_SIZE(rk3288_area_data), },
{ .base = 0x50, .phy = &rk3288_win23_data,
.type = DRM_PLANE_TYPE_CURSOR,
.area = rk3288_area_data,
.area_size = ARRAY_SIZE(rk3288_area_data), },
};
static const int rk3288_vop_intrs[] = {
DSP_HOLD_VALID_INTR,
FS_INTR,
LINE_FLAG_INTR,
BUS_ERROR_INTR,
};
static const struct vop_intr rk3288_vop_intr = {
.intrs = rk3288_vop_intrs,
.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
};
static const struct vop_grf_ctrl rk3288_vop_big_grf_ctrl = {
.grf_dclk_inv = VOP_REG(RK3288_GRF_SOC_CON15, 0x1, 13),
};
static const struct vop_grf_ctrl rk3288_vop_lit_grf_ctrl = {
.grf_dclk_inv = VOP_REG(RK3288_GRF_SOC_CON15, 0x1, 15),
};
static const struct vop_data rk3288_vop_big = {
.soc_id = 0x3288,
.vop_id = 0,
.version = VOP_VERSION(3, 0),
.feature = VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.max_input = {4096, 8192},
.max_output = {3840, 2160},
.intr = &rk3288_vop_intr,
.grf_ctrl = &rk3288_vop_big_grf_ctrl,
.ctrl = &rk3288_ctrl_data,
.win = rk3288_vop_win_data,
.win_size = ARRAY_SIZE(rk3288_vop_win_data),
};
static const struct vop_data rk3288_vop_lit = {
.soc_id = 0x3288,
.vop_id = 1,
.version = VOP_VERSION(3, 0),
.feature = VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.max_input = {4096, 8192},
.max_output = {2560, 1600},
.intr = &rk3288_vop_intr,
.grf_ctrl = &rk3288_vop_lit_grf_ctrl,
.ctrl = &rk3288_ctrl_data,
.win = rk3288_vop_win_data,
.win_size = ARRAY_SIZE(rk3288_vop_win_data),
};
static const int rk3368_vop_intrs[] = {
FS_INTR,
FS_NEW_INTR,
ADDR_SAME_INTR,
LINE_FLAG_INTR,
LINE_FLAG1_INTR,
BUS_ERROR_INTR,
WIN0_EMPTY_INTR,
WIN1_EMPTY_INTR,
WIN2_EMPTY_INTR,
WIN3_EMPTY_INTR,
HWC_EMPTY_INTR,
POST_BUF_EMPTY_INTR,
FS_FIELD_INTR,
DSP_HOLD_VALID_INTR,
};
static const struct vop_intr rk3368_vop_intr = {
.intrs = rk3368_vop_intrs,
.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
.line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
.status = VOP_REG_MASK(RK3368_INTR_STATUS, 0x3fff, 0),
.enable = VOP_REG_MASK(RK3368_INTR_EN, 0x3fff, 0),
.clear = VOP_REG_MASK(RK3368_INTR_CLEAR, 0x3fff, 0),
};
static const struct vop_win_phy rk3368_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
.ymirror = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
.src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xffff, 0),
.global_alpha_val = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 16),
.dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xffffffff, 0),
.color_key = VOP_REG(RK3368_WIN2_COLOR_KEY, 0xffffff, 0),
.color_key_en = VOP_REG(RK3368_WIN2_COLOR_KEY, 0x1, 24),
};
static const struct vop_win_phy rk3368_area1_data = {
.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 8),
.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 9),
.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 23),
.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO1, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST1, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3368_WIN2_MST1, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 16),
};
static const struct vop_win_phy rk3368_area2_data = {
.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 12),
.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 13),
.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 26),
.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO2, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST2, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3368_WIN2_MST2, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3368_WIN2_VIR2_3, 0x1fff, 0),
};
static const struct vop_win_phy rk3368_area3_data = {
.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 16),
.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 17),
.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 29),
.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO3, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST3, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3368_WIN2_MST3, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3368_WIN2_VIR2_3, 0x1fff, 16),
};
static const struct vop_win_phy *rk3368_area_data[] = {
&rk3368_area1_data,
&rk3368_area2_data,
&rk3368_area3_data
};
static const struct vop_win_data rk3368_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x40, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x00, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_OVERLAY,
.area = rk3368_area_data,
.area_size = ARRAY_SIZE(rk3368_area_data), },
{ .base = 0x50, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_CURSOR,
.area = rk3368_area_data,
.area_size = ARRAY_SIZE(rk3368_area_data), },
};
static const struct vop_data rk3368_vop = {
.soc_id = 0x3368,
.vop_id = 0,
.version = VOP_VERSION(3, 2),
.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.max_input = {4096, 8192},
.max_output = {4096, 2160},
.intr = &rk3368_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3368_vop_win_data,
.win_size = ARRAY_SIZE(rk3368_vop_win_data),
};
static const struct vop_intr rk3366_vop_intr = {
.intrs = rk3368_vop_intrs,
.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
.line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
.status = VOP_REG_MASK(RK3366_INTR_STATUS0, 0xffff, 0),
.enable = VOP_REG_MASK(RK3366_INTR_EN0, 0xffff, 0),
.clear = VOP_REG_MASK(RK3366_INTR_CLEAR0, 0xffff, 0),
};
static const struct vop_grf_ctrl rk3368_vop_grf_ctrl = {
.grf_dclk_inv = VOP_REG(RK3368_GRF_SOC_CON6, 0x1, 5),
};
static const struct vop_data rk3366_vop = {
.soc_id = 0x3366,
.vop_id = 0,
.version = VOP_VERSION(3, 4),
.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.max_input = {4096, 8192},
.max_output = {4096, 2160},
.intr = &rk3366_vop_intr,
.grf_ctrl = &rk3368_vop_grf_ctrl,
.ctrl = &rk3288_ctrl_data,
.win = rk3368_vop_win_data,
.win_size = ARRAY_SIZE(rk3368_vop_win_data),
};
static const uint32_t vop_csc_y2r_bt601[] = {
0x00000400, 0x0400059c, 0xfd25fea0, 0x07170400,
0x00000000, 0xfff4cab4, 0x00087932, 0xfff1d4f2,
};
static const uint32_t vop_csc_y2r_bt601_12_235[] = {
0x000004a8, 0x04a80662, 0xfcbffe6f, 0x081204a8,
0x00000000, 0xfff2134e, 0x00087b58, 0xffeeb4b0,
};
static const uint32_t vop_csc_r2y_bt601[] = {
0x02590132, 0xff530075, 0x0200fead, 0xfe530200,
0x0000ffad, 0x00000200, 0x00080200, 0x00080200,
};
static const uint32_t vop_csc_r2y_bt601_12_235[] = {
0x02040107, 0xff680064, 0x01c2fed6, 0xfe8701c2,
0x0000ffb7, 0x00010200, 0x00080200, 0x00080200,
};
static const uint32_t vop_csc_y2r_bt709[] = {
0x000004a8, 0x04a8072c, 0xfddeff26, 0x087304a8,
0x00000000, 0xfff08077, 0x0004cfed, 0xffedf1b8,
};
static const uint32_t vop_csc_r2y_bt709[] = {
0x027500bb, 0xff99003f, 0x01c2fea5, 0xfe6801c2,
0x0000ffd7, 0x00010200, 0x00080200, 0x00080200,
};
static const uint32_t vop_csc_y2r_bt2020[] = {
0x000004a8, 0x04a806b6, 0xfd66ff40, 0x089004a8,
0x00000000, 0xfff16bfc, 0x00058ae9, 0xffedb828,
};
static const uint32_t vop_csc_r2y_bt2020[] = {
0x025300e6, 0xff830034, 0x01c1febd, 0xfe6401c1,
0x0000ffdc, 0x00010200, 0x00080200, 0x00080200,
};
static const uint32_t vop_csc_r2r_bt709_to_bt2020[] = {
0xfda606a4, 0xff80ffb5, 0xfff80488, 0xff99ffed,
0x0000047a, 0x00000200, 0x00000200, 0x00000200,
};
static const uint32_t vop_csc_r2r_bt2020_to_bt709[] = {
0x01510282, 0x0047002c, 0x000c03ae, 0x005a0011,
0x00000394, 0x00000200, 0x00000200, 0x00000200,
};
static const struct vop_csc_table rk3399_csc_table = {
.y2r_bt601 = vop_csc_y2r_bt601,
.y2r_bt601_12_235 = vop_csc_y2r_bt601_12_235,
.r2y_bt601 = vop_csc_r2y_bt601,
.r2y_bt601_12_235 = vop_csc_r2y_bt601_12_235,
.y2r_bt709 = vop_csc_y2r_bt709,
.r2y_bt709 = vop_csc_r2y_bt709,
.y2r_bt2020 = vop_csc_y2r_bt2020,
.r2y_bt2020 = vop_csc_r2y_bt2020,
.r2r_bt709_to_bt2020 = vop_csc_r2r_bt709_to_bt2020,
.r2r_bt2020_to_bt709 = vop_csc_r2r_bt2020_to_bt709,
};
static const struct vop_csc rk3399_win0_csc = {
.r2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 0),
.y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1),
.r2y_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 2),
.y2r_offset = RK3399_WIN0_YUV2YUV_Y2R,
.r2r_offset = RK3399_WIN0_YUV2YUV_3X3,
.r2y_offset = RK3399_WIN0_YUV2YUV_R2Y,
};
static const struct vop_csc rk3399_win1_csc = {
.r2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 8),
.y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9),
.r2y_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 10),
.y2r_offset = RK3399_WIN1_YUV2YUV_Y2R,
.r2r_offset = RK3399_WIN1_YUV2YUV_3X3,
.r2y_offset = RK3399_WIN1_YUV2YUV_R2Y,
};
static const struct vop_csc rk3399_win2_csc = {
.r2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 16),
.r2y_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 18),
.r2r_offset = RK3399_WIN2_YUV2YUV_3X3,
.csc_mode = VOP_REG(RK3399_YUV2YUV_WIN, 0x3, 22),
};
static const struct vop_csc rk3399_win3_csc = {
.r2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 24),
.r2y_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 26),
.r2r_offset = RK3399_WIN3_YUV2YUV_3X3,
.csc_mode = VOP_REG(RK3399_YUV2YUV_WIN, 0x3, 30),
};
static const struct vop_win_phy rk3399_win01_data = {
.scl = &rk3288_win_full_scl,
.data_formats = formats_win_full_10bit_yuyv,
.nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv),
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
.fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 4),
.fmt_yuyv = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 17),
.csc_mode = VOP_REG_VER(RK3288_WIN0_CTRL0, 0x3, 10, 3, 2, -1),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.xmirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 21, 3, 2, -1),
.ymirror = VOP_REG_VER(RK3368_WIN0_CTRL0, 0x1, 22, 3, 2, -1),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xffff, 0),
.global_alpha_val = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 16),
.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xffffffff, 0),
.channel = VOP_REG_VER(RK3288_WIN0_CTRL2, 0xff, 0, 3, 8, 8),
.color_key = VOP_REG(RK3288_WIN0_COLOR_KEY, 0x3fffffff, 0),
.color_key_en = VOP_REG(RK3288_WIN0_COLOR_KEY, 0x1, 31),
};
static const struct vop_win_data rk3399_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3399_win01_data, .csc = &rk3399_win0_csc,
.format_modifiers = format_modifiers_afbc,
.type = DRM_PLANE_TYPE_PRIMARY,
.feature = WIN_FEATURE_AFBDC },
{ .base = 0x40, .phy = &rk3399_win01_data, .csc = &rk3399_win1_csc,
.format_modifiers = format_modifiers_afbc,
.type = DRM_PLANE_TYPE_OVERLAY,
.feature = WIN_FEATURE_AFBDC },
{ .base = 0x00, .phy = &rk3368_win23_data, .csc = &rk3399_win2_csc,
.format_modifiers = format_modifiers_afbc,
.type = DRM_PLANE_TYPE_OVERLAY,
.feature = WIN_FEATURE_AFBDC,
.area = rk3368_area_data,
.area_size = ARRAY_SIZE(rk3368_area_data), },
{ .base = 0x50, .phy = &rk3368_win23_data, .csc = &rk3399_win3_csc,
.format_modifiers = format_modifiers_afbc,
.type = DRM_PLANE_TYPE_CURSOR,
.feature = WIN_FEATURE_AFBDC,
.area = rk3368_area_data,
.area_size = ARRAY_SIZE(rk3368_area_data), },
};
static const struct vop_data rk3399_vop_big = {
.soc_id = 0x3399,
.vop_id = 0,
.version = VOP_VERSION(3, 5),
.csc_table = &rk3399_csc_table,
.feature = VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.max_input = {4096, 8192},
.max_output = {4096, 2160},
.intr = &rk3366_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3399_vop_win_data,
.win_size = ARRAY_SIZE(rk3399_vop_win_data),
};
static const struct vop_win_data rk3399_vop_lit_win_data[] = {
{ .base = 0x00, .phy = &rk3399_win01_data, .csc = &rk3399_win0_csc,
.format_modifiers = format_modifiers,
.type = DRM_PLANE_TYPE_OVERLAY,
.feature = WIN_FEATURE_AFBDC },
{ .phy = NULL },
{ .base = 0x00, .phy = &rk3368_win23_data, .csc = &rk3399_win2_csc,
.format_modifiers = format_modifiers,
.type = DRM_PLANE_TYPE_PRIMARY,
.feature = WIN_FEATURE_AFBDC,
.area = rk3368_area_data,
.area_size = ARRAY_SIZE(rk3368_area_data), },
{ .phy = NULL },
};
static const struct vop_data rk3399_vop_lit = {
.soc_id = 0x3399,
.vop_id = 1,
.version = VOP_VERSION(3, 6),
.feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.csc_table = &rk3399_csc_table,
.max_input = {4096, 8192},
.max_output = {2560, 1600},
.intr = &rk3366_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3399_vop_lit_win_data,
.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
};
static const struct vop_win_data rk322x_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x40, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
static const struct vop_data rk3228_vop = {
.soc_id = 0x3228,
.vop_id = 0,
.version = VOP_VERSION(3, 7),
.feature = VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.max_input = {4096, 8192},
.max_output = {4096, 2160},
.intr = &rk3366_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk322x_vop_win_data,
.win_size = ARRAY_SIZE(rk322x_vop_win_data),
};
static const u32 sdr2hdr_bt1886eotf_yn_for_hlg_hdr[65] = {
0,
1, 7, 17, 35,
60, 92, 134, 184,
244, 315, 396, 487,
591, 706, 833, 915,
1129, 1392, 1717, 2118,
2352, 2612, 2900, 3221,
3577, 3972, 4411, 4899,
5441, 6042, 6710, 7452,
7853, 8276, 8721, 9191,
9685, 10207, 10756, 11335,
11945, 12588, 13266, 13980,
14732, 15525, 16361, 17241,
17699, 18169, 18652, 19147,
19656, 20178, 20714, 21264,
21829, 22408, 23004, 23615,
24242, 24886, 25547, 26214,
};
static const u32 sdr2hdr_bt1886eotf_yn_for_bt2020[65] = {
0,
1820, 3640, 5498, 7674,
10256, 13253, 16678, 20539,
24847, 29609, 34833, 40527,
46699, 53354, 60499, 68141,
76285, 84937, 94103, 103787,
108825, 113995, 119296, 124731,
130299, 136001, 141837, 147808,
153915, 160158, 166538, 173055,
176365, 179709, 183089, 186502,
189951, 193434, 196952, 200505,
204093, 207715, 211373, 215066,
218795, 222558, 226357, 230191,
232121, 234060, 236008, 237965,
239931, 241906, 243889, 245882,
247883, 249894, 251913, 253941,
255978, 258024, 260079, 262143,
};
static u32 sdr2hdr_bt1886eotf_yn_for_hdr[65] = {
/* dst_range 425int */
0,
5, 21, 49, 91,
150, 225, 320, 434,
569, 726, 905, 1108,
1336, 1588, 1866, 2171,
2502, 2862, 3250, 3667,
3887, 4114, 4349, 4591,
4841, 5099, 5364, 5638,
5920, 6209, 6507, 6812,
6968, 7126, 7287, 7449,
7613, 7779, 7948, 8118,
8291, 8466, 8643, 8822,
9003, 9187, 9372, 9560,
9655, 9750, 9846, 9942,
10039, 10136, 10234, 10333,
10432, 10531, 10631, 10732,
10833, 10935, 11038, 11141,
};
static const u32 sdr2hdr_st2084oetf_yn_for_hlg_hdr[65] = {
0,
668, 910, 1217, 1600,
2068, 2384, 2627, 3282,
3710, 4033, 4879, 5416,
5815, 6135, 6401, 6631,
6833, 7176, 7462, 7707,
7921, 8113, 8285, 8442,
8586, 8843, 9068, 9268,
9447, 9760, 10027, 10259,
10465, 10650, 10817, 10971,
11243, 11480, 11689, 11877,
12047, 12202, 12345, 12477,
12601, 12716, 12926, 13115,
13285, 13441, 13583, 13716,
13839, 13953, 14163, 14350,
14519, 14673, 14945, 15180,
15570, 15887, 16153, 16383,
};
static const u32 sdr2hdr_st2084oetf_yn_for_bt2020[65] = {
0,
0, 0, 1, 2,
4, 6, 9, 18,
27, 36, 72, 108,
144, 180, 216, 252,
288, 360, 432, 504,
576, 648, 720, 792,
864, 1008, 1152, 1296,
1444, 1706, 1945, 2166,
2372, 2566, 2750, 2924,
3251, 3553, 3834, 4099,
4350, 4588, 4816, 5035,
5245, 5447, 5832, 6194,
6536, 6862, 7173, 7471,
7758, 8035, 8560, 9055,
9523, 9968, 10800, 11569,
12963, 14210, 15347, 16383,
};
static u32 sdr2hdr_st2084oetf_yn_for_hdr[65] = {
0,
281, 418, 610, 871,
1217, 1464, 1662, 2218,
2599, 2896, 3699, 4228,
4628, 4953, 5227, 5466,
5676, 6038, 6341, 6602,
6833, 7039, 7226, 7396,
7554, 7835, 8082, 8302,
8501, 8848, 9145, 9405,
9635, 9842, 10031, 10204,
10512, 10779, 11017, 11230,
11423, 11599, 11762, 11913,
12054, 12185, 12426, 12641,
12835, 13013, 13177, 13328,
13469, 13600, 13840, 14055,
14248, 14425, 14737, 15006,
15453, 15816, 16121, 16383,
};
static const u32 sdr2hdr_st2084oetf_dxn_pow2[64] = {
0, 0, 1, 2,
3, 3, 3, 5,
5, 5, 7, 7,
7, 7, 7, 7,
7, 8, 8, 8,
8, 8, 8, 8,
8, 9, 9, 9,
9, 10, 10, 10,
10, 10, 10, 10,
11, 11, 11, 11,
11, 11, 11, 11,
11, 11, 12, 12,
12, 12, 12, 12,
12, 12, 13, 13,
13, 13, 14, 14,
15, 15, 15, 15,
};
static const u32 sdr2hdr_st2084oetf_dxn[64] = {
1, 1, 2, 4,
8, 8, 8, 32,
32, 32, 128, 128,
128, 128, 128, 128,
128, 256, 256, 256,
256, 256, 256, 256,
256, 512, 512, 512,
512, 1024, 1024, 1024,
1024, 1024, 1024, 1024,
2048, 2048, 2048, 2048,
2048, 2048, 2048, 2048,
2048, 2048, 4096, 4096,
4096, 4096, 4096, 4096,
4096, 4096, 8192, 8192,
8192, 8192, 16384, 16384,
32768, 32768, 32768, 32768,
};
static const u32 sdr2hdr_st2084oetf_xn[63] = {
1, 2, 4, 8,
16, 24, 32, 64,
96, 128, 256, 384,
512, 640, 768, 896,
1024, 1280, 1536, 1792,
2048, 2304, 2560, 2816,
3072, 3584, 4096, 4608,
5120, 6144, 7168, 8192,
9216, 10240, 11264, 12288,
14336, 16384, 18432, 20480,
22528, 24576, 26624, 28672,
30720, 32768, 36864, 40960,
45056, 49152, 53248, 57344,
61440, 65536, 73728, 81920,
90112, 98304, 114688, 131072,
163840, 196608, 229376,
};
static u32 hdr2sdr_eetf_yn[33] = {
1716,
1880, 2067, 2277, 2508,
2758, 3026, 3310, 3609,
3921, 4246, 4581, 4925,
5279, 5640, 6007, 6380,
6758, 7140, 7526, 7914,
8304, 8694, 9074, 9438,
9779, 10093, 10373, 10615,
10812, 10960, 11053, 11084,
};
static u32 hdr2sdr_bt1886oetf_yn[33] = {
0,
0, 0, 0, 0,
0, 0, 0, 314,
746, 1323, 2093, 2657,
3120, 3519, 3874, 4196,
4492, 5024, 5498, 5928,
6323, 7034, 7666, 8239,
8766, 9716, 10560, 11325,
12029, 13296, 14422, 16383,
};
static const u32 hdr2sdr_sat_yn[9] = {
0,
1792, 3584, 3472, 2778,
2083, 1389, 694, 0,
};
static const struct vop_hdr_table rk3328_hdr_table = {
.hdr2sdr_eetf_oetf_y0_offset = RK3328_HDR2SDR_EETF_OETF_Y0,
.hdr2sdr_eetf_oetf_y1_offset = RK3328_HDR2SDR_EETF_OETF_Y1,
.hdr2sdr_eetf_yn = hdr2sdr_eetf_yn,
.hdr2sdr_bt1886oetf_yn = hdr2sdr_bt1886oetf_yn,
.hdr2sdr_sat_y0_offset = RK3328_HDR2DR_SAT_Y0,
.hdr2sdr_sat_y1_offset = RK3328_HDR2DR_SAT_Y1,
.hdr2sdr_sat_yn = hdr2sdr_sat_yn,
.hdr2sdr_src_range_min = 494,
.hdr2sdr_src_range_max = 12642,
.hdr2sdr_normfaceetf = 1327,
.hdr2sdr_dst_range_min = 4,
.hdr2sdr_dst_range_max = 3276,
.hdr2sdr_normfacgamma = 5120,
.sdr2hdr_eotf_oetf_y0_offset = RK3328_SDR2HDR_EOTF_OETF_Y0,
.sdr2hdr_eotf_oetf_y1_offset = RK3328_SDR2HDR_EOTF_OETF_Y1,
.sdr2hdr_bt1886eotf_yn_for_hlg_hdr = sdr2hdr_bt1886eotf_yn_for_hlg_hdr,
.sdr2hdr_bt1886eotf_yn_for_bt2020 = sdr2hdr_bt1886eotf_yn_for_bt2020,
.sdr2hdr_bt1886eotf_yn_for_hdr = sdr2hdr_bt1886eotf_yn_for_hdr,
.sdr2hdr_st2084oetf_yn_for_hlg_hdr = sdr2hdr_st2084oetf_yn_for_hlg_hdr,
.sdr2hdr_st2084oetf_yn_for_bt2020 = sdr2hdr_st2084oetf_yn_for_bt2020,
.sdr2hdr_st2084oetf_yn_for_hdr = sdr2hdr_st2084oetf_yn_for_hdr,
.sdr2hdr_oetf_dx_dxpow1_offset = RK3328_SDR2HDR_OETF_DX_DXPOW1,
.sdr2hdr_oetf_xn1_offset = RK3328_SDR2HDR_OETF_XN1,
.sdr2hdr_st2084oetf_dxn_pow2 = sdr2hdr_st2084oetf_dxn_pow2,
.sdr2hdr_st2084oetf_dxn = sdr2hdr_st2084oetf_dxn,
.sdr2hdr_st2084oetf_xn = sdr2hdr_st2084oetf_xn,
};
static const struct vop_ctrl rk3328_ctrl_data = {
.standby = VOP_REG(RK3328_SYS_CTRL, 0x1, 22),
.dma_stop = VOP_REG(RK3328_SYS_CTRL, 0x1, 21),
.axi_outstanding_max_num = VOP_REG(RK3328_SYS_CTRL1, 0x1f, 13),
.axi_max_outstanding_en = VOP_REG(RK3328_SYS_CTRL1, 0x1, 12),
.reg_done_frm = VOP_REG(RK3328_SYS_CTRL1, 0x1, 24),
.auto_gate_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 23),
.htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
.vact_st_end_f1 = VOP_REG(RK3328_DSP_VACT_ST_END_F1, 0x1fff1fff, 0),
.vs_st_end_f1 = VOP_REG(RK3328_DSP_VS_ST_END_F1, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
.vpost_st_end_f1 = VOP_REG(RK3328_POST_DSP_VACT_INFO_F1, 0x1fff1fff, 0),
.post_scl_factor = VOP_REG(RK3328_POST_SCL_FACTOR_YRGB, 0xffffffff, 0),
.post_scl_ctrl = VOP_REG(RK3328_POST_SCL_CTRL, 0x3, 0),
.dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2),
.dsp_interlace = VOP_REG(RK3328_DSP_CTRL0, 0x1, 10),
.dsp_layer_sel = VOP_REG(RK3328_DSP_CTRL1, 0xff, 8),
.post_lb_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 18),
.global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
.overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16),
.core_dclk_div = VOP_REG(RK3328_DSP_CTRL0, 0x1, 4),
.dclk_ddr = VOP_REG(RK3328_DSP_CTRL0, 0x1, 8),
.p2i_en = VOP_REG(RK3328_DSP_CTRL0, 0x1, 5),
.rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
.hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
.edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
.mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
.tve_dclk_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 24),
.tve_dclk_pol = VOP_REG(RK3328_SYS_CTRL, 0x1, 25),
.tve_sw_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 26),
.sw_uv_offset_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 27),
.sw_genlock = VOP_REG(RK3328_SYS_CTRL, 0x1, 28),
.sw_dac_sel = VOP_REG(RK3328_SYS_CTRL, 0x1, 29),
.rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16),
.hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20),
.edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24),
.mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28),
.rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19),
.hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23),
.edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27),
.mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31),
.dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
.dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
.dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
.pre_dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
.dither_up_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
.dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12),
.dsp_bg_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1, 12),
.dsp_rb_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1, 13),
.dsp_rg_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1, 14),
.dsp_delta_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1, 15),
.dsp_dummy_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1, 16),
.dsp_ccir656_avg = VOP_REG(RK3328_DSP_CTRL0, 0x1, 20),
.dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
.dsp_lut_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 0),
.out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
.xmirror = VOP_REG(RK3328_DSP_CTRL0, 0x1, 22),
.ymirror = VOP_REG(RK3328_DSP_CTRL0, 0x1, 23),
.dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0),
.alpha_hard_calc = VOP_REG(RK3328_SYS_CTRL1, 0x1, 27),
.level2_overlay_en = VOP_REG(RK3328_SYS_CTRL1, 0x1, 28),
.hdr2sdr_en = VOP_REG(RK3328_HDR2DR_CTRL, 0x1, 0),
.hdr2sdr_en_win0_csc = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 9),
.hdr2sdr_src_min = VOP_REG(RK3328_HDR2DR_SRC_RANGE, 0x3fff, 0),
.hdr2sdr_src_max = VOP_REG(RK3328_HDR2DR_SRC_RANGE, 0x3fff, 16),
.hdr2sdr_normfaceetf = VOP_REG(RK3328_HDR2DR_NORMFACEETF, 0x7ff, 0),
.hdr2sdr_dst_min = VOP_REG(RK3328_HDR2DR_DST_RANGE, 0x3fff, 0),
.hdr2sdr_dst_max = VOP_REG(RK3328_HDR2DR_DST_RANGE, 0x3fff, 16),
.hdr2sdr_normfacgamma = VOP_REG(RK3328_HDR2DR_NORMFACGAMMA, 0xffff, 0),
.bt1886eotf_pre_conv_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 0),
.rgb2rgb_pre_conv_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 1),
.rgb2rgb_pre_conv_mode = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 2),
.st2084oetf_pre_conv_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 3),
.bt1886eotf_post_conv_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 4),
.rgb2rgb_post_conv_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 5),
.rgb2rgb_post_conv_mode = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 6),
.st2084oetf_post_conv_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 7),
.win_csc_mode_sel = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 31),
.bcsh_brightness = VOP_REG(RK3328_BCSH_BCS, 0xff, 0),
.bcsh_contrast = VOP_REG(RK3328_BCSH_BCS, 0x1ff, 8),
.bcsh_sat_con = VOP_REG(RK3328_BCSH_BCS, 0x3ff, 20),
.bcsh_out_mode = VOP_REG(RK3328_BCSH_BCS, 0x3, 30),
.bcsh_sin_hue = VOP_REG(RK3328_BCSH_H, 0x1ff, 0),
.bcsh_cos_hue = VOP_REG(RK3328_BCSH_H, 0x1ff, 16),
.bcsh_r2y_csc_mode = VOP_REG(RK3328_BCSH_CTRL, 0x3, 6),
.bcsh_r2y_en = VOP_REG(RK3328_BCSH_CTRL, 0x1, 4),
.bcsh_y2r_csc_mode = VOP_REG(RK3328_BCSH_CTRL, 0x3, 2),
.bcsh_y2r_en = VOP_REG(RK3328_BCSH_CTRL, 0x1, 0),
.bcsh_color_bar = VOP_REG(RK3328_BCSH_COLOR_BAR, 0xffffff, 8),
.bcsh_en = VOP_REG(RK3328_BCSH_COLOR_BAR, 0x1, 0),
.cfg_done = VOP_REG(RK3328_REG_CFG_DONE, 0x1, 0),
};
static const struct vop_intr rk3328_vop_intr = {
.intrs = rk3368_vop_intrs,
.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
.line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
.status = VOP_REG_MASK(RK3328_INTR_STATUS0, 0xffff, 0),
.enable = VOP_REG_MASK(RK3328_INTR_EN0, 0xffff, 0),
.clear = VOP_REG_MASK(RK3328_INTR_CLEAR0, 0xffff, 0),
};
static const struct vop_csc rk3328_win0_csc = {
.r2y_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 8),
.r2r_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 5),
.y2r_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 9),
};
static const struct vop_csc rk3328_win1_csc = {
.r2y_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 10),
.r2r_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 1),
.y2r_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 11),
};
static const struct vop_csc rk3328_win2_csc = {
.r2y_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 12),
.r2r_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 1),
.y2r_en = VOP_REG(RK3328_SDR2HDR_CTRL, 0x1, 13),
};
static const struct vop_win_data rk3328_vop_win_data[] = {
{ .base = 0xd0, .phy = &rk3288_win01_data, .csc = &rk3328_win0_csc,
.type = DRM_PLANE_TYPE_PRIMARY,
.feature = WIN_FEATURE_HDR2SDR | WIN_FEATURE_SDR2HDR },
{ .base = 0x1d0, .phy = &rk3288_win01_data, .csc = &rk3328_win1_csc,
.type = DRM_PLANE_TYPE_OVERLAY,
.feature = WIN_FEATURE_SDR2HDR | WIN_FEATURE_PRE_OVERLAY },
{ .base = 0x2d0, .phy = &rk3288_win01_data, .csc = &rk3328_win2_csc,
.type = DRM_PLANE_TYPE_CURSOR,
.feature = WIN_FEATURE_SDR2HDR | WIN_FEATURE_PRE_OVERLAY },
};
static const struct vop_data rk3328_vop = {
.soc_id = 0x3328,
.vop_id = 0,
.version = VOP_VERSION(3, 8),
.feature = VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_HDR10 |
VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
.hdr_table = &rk3328_hdr_table,
.max_input = {4096, 8192},
.max_output = {4096, 2160},
.intr = &rk3328_vop_intr,
.ctrl = &rk3328_ctrl_data,
.win = rk3328_vop_win_data,
.win_size = ARRAY_SIZE(rk3328_vop_win_data),
};
static const struct vop_scl_regs rk3036_win0_scl = {
.scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
.scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
.scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
.scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
};
static const struct vop_scl_regs rk3036_win1_scl = {
.scale_yrgb_x = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 0x0),
.scale_yrgb_y = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 16),
};
static const struct vop_win_phy rk3036_win0_data = {
.scl = &rk3036_win0_scl,
.data_formats = formats_win_full,
.nformats = ARRAY_SIZE(formats_win_full),
.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
.act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
.uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
.uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 18),
.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 0),
.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
};
static const struct vop_win_phy rk3036_win1_data = {
.scl = &rk3036_win1_scl,
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
.act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1)
};
static const struct vop_win_data rk3036_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3036_win0_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x00, .phy = &rk3036_win1_data,
.type = DRM_PLANE_TYPE_OVERLAY },
};
static const int rk3036_vop_intrs[] = {
DSP_HOLD_VALID_INTR,
FS_INTR,
LINE_FLAG_INTR,
BUS_ERROR_INTR,
};
static const struct vop_intr rk3036_intr = {
.intrs = rk3036_vop_intrs,
.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
.status = VOP_REG(RK3036_INT_STATUS, 0xf, 0),
.enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4),
.clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8),
};
static const struct vop_ctrl rk3036_ctrl_data = {
.standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30),
.sw_dac_sel = VOP_REG(RK3036_SYS_CTRL, 0x1, 29),
.out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
.dsp_interlace = VOP_REG(RK3036_DSP_CTRL0, 0x1, 12),
.dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
.dsp_background = VOP_REG(RK3036_DSP_CTRL1, 0xffffff, 0),
.dclk_pol = VOP_REG(RK3036_DSP_CTRL0, 0x1, 7),
.pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0x7, 4),
.dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
.tve_sw_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 25),
.dsp_interlace_pol = VOP_REG(RK3036_DSP_CTRL0, 0x1, 13),
.dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
.dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
.dither_up_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 9),
.dsp_layer_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 8),
.htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
.tve_dclk_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 20),
.tve_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 21),
.hdmi_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 22),
.hdmi_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 23),
.core_dclk_div = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 30),
.hdmi_pin_pol = VOP_REG(RK3036_INT_SCALER, 0x7, 4),
.rgb_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 24),
.rgb_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 25),
.lvds_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 26),
.lvds_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 27),
.mipi_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 28),
.mipi_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 29),
.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
.vs_st_end_f1 = VOP_REG(RK3036_DSP_VS_ST_END_F1, 0x1fff1fff, 0),
.vact_st_end_f1 = VOP_REG(RK3036_DSP_VACT_ST_END_F1, 0x1fff1fff, 0),
.cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
};
static const struct vop_data rk3036_vop = {
.soc_id = 0x3036,
.vop_id = 0,
.version = VOP_VERSION(2, 2),
.max_input = {1920, 1080},
.max_output = {1920, 1080},
.ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
.win = rk3036_vop_win_data,
.win_size = ARRAY_SIZE(rk3036_vop_win_data),
};
static const struct vop_scl_regs rk3066_win_scl = {
.scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
.scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
.scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
.scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
};
static const struct vop_win_phy rk3066_win0_data = {
.scl = &rk3066_win_scl,
.data_formats = formats_win_full,
.nformats = ARRAY_SIZE(formats_win_full),
.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4),
.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19),
.act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
.uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
.uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 21),
.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 0)
};
static const struct vop_win_phy rk3066_win1_data = {
.scl = &rk3066_win_scl,
.data_formats = formats_win_full,
.nformats = ARRAY_SIZE(formats_win_full),
.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7),
.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23),
.act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
.uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
.uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 22),
.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 1)
};
static const struct vop_win_phy rk3066_win2_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10),
.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27),
.dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
.alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 23),
.alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 2)
};
static const struct vop_win_data rk3066_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3066_win0_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x00, .phy = &rk3066_win1_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x00, .phy = &rk3066_win2_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
static const int rk3066_vop_intrs[] = {
0,
FS_INTR,
LINE_FLAG_INTR,
BUS_ERROR_INTR,
};
static const struct vop_intr rk3066_intr = {
.intrs = rk3066_vop_intrs,
.nintrs = ARRAY_SIZE(rk3066_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
.status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
.enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
.clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
};
static const struct vop_ctrl rk3066_ctrl_data = {
.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
.dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
.dclk_pol = VOP_REG(RK3066_DSP_CTRL0, 0x1, 7),
.pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
.dsp_layer_sel = VOP_REG(RK3066_DSP_CTRL0, 0x1, 8),
.htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
};
static const struct vop_data rk3066_vop = {
.soc_id = 0x3066,
.vop_id = 0,
.version = VOP_VERSION(2, 1),
.max_input = {1920, 4096},
.max_output = {1920, 1080},
.ctrl = &rk3066_ctrl_data,
.intr = &rk3066_intr,
.win = rk3066_vop_win_data,
.win_size = ARRAY_SIZE(rk3066_vop_win_data),
};
static const int rk3366_vop_lit_intrs[] = {
FS_INTR,
FS_NEW_INTR,
ADDR_SAME_INTR,
LINE_FLAG_INTR,
LINE_FLAG1_INTR,
BUS_ERROR_INTR,
WIN0_EMPTY_INTR,
WIN1_EMPTY_INTR,
DSP_HOLD_VALID_INTR,
DMA_FINISH_INTR,
WIN2_EMPTY_INTR,
POST_BUF_EMPTY_INTR
};
static const struct vop_scl_regs rk3366_lit_win_scl = {
.scale_yrgb_x = VOP_REG(RK3366_LIT_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
.scale_yrgb_y = VOP_REG(RK3366_LIT_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
.scale_cbcr_x = VOP_REG(RK3366_LIT_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
.scale_cbcr_y = VOP_REG(RK3366_LIT_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
};
static const struct vop_win_phy rk3366_lit_win0_data = {
.scl = &rk3366_lit_win_scl,
.data_formats = formats_win_full,
.nformats = ARRAY_SIZE(formats_win_full),
.enable = VOP_REG(RK3366_LIT_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3366_LIT_WIN0_CTRL0, 0x7, 1),
.interlace_read = VOP_REG(RK3366_LIT_WIN0_CTRL0, 0x1, 8),
.rb_swap = VOP_REG(RK3366_LIT_WIN0_CTRL0, 0x1, 12),
.act_info = VOP_REG(RK3366_LIT_WIN0_ACT_INFO, 0xffffffff, 0),
.dsp_info = VOP_REG(RK3366_LIT_WIN0_DSP_INFO, 0xffffffff, 0),
.dsp_st = VOP_REG(RK3366_LIT_WIN0_DSP_ST, 0xffffffff, 0),
.yrgb_mst = VOP_REG(RK3366_LIT_WIN0_YRGB_MST0, 0xffffffff, 0),
.uv_mst = VOP_REG(RK3366_LIT_WIN0_CBR_MST0, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3366_LIT_WIN0_VIR, 0x1fff, 0),
.uv_vir = VOP_REG(RK3366_LIT_WIN0_VIR, 0x1fff, 16),
.alpha_pre_mul = VOP_REG(RK3366_LIT_WIN0_ALPHA_CTRL, 0x1, 2),
.alpha_mode = VOP_REG(RK3366_LIT_WIN0_ALPHA_CTRL, 0x1, 1),
.alpha_en = VOP_REG(RK3366_LIT_WIN0_ALPHA_CTRL, 0x1, 0),
.global_alpha_val = VOP_REG(RK3366_LIT_WIN0_ALPHA_CTRL, 0xff, 4),
.color_key = VOP_REG(RK3366_LIT_WIN0_COLOR_KEY, 0xffffff, 0),
.color_key_en = VOP_REG(RK3366_LIT_WIN0_COLOR_KEY, 0x1, 24),
.channel = VOP_REG(RK3366_LIT_WIN0_CTRL0, 0xff, 12),
};
static const struct vop_win_phy rk3366_lit_win1_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.enable = VOP_REG(RK3366_LIT_WIN1_CTRL0, 0x1, 0),
.format = VOP_REG(RK3366_LIT_WIN1_CTRL0, 0x7, 4),
.interlace_read = VOP_REG(RK3366_LIT_WIN1_CTRL0, 0x1, 8),
.rb_swap = VOP_REG(RK3366_LIT_WIN1_CTRL0, 0x1, 12),
.dsp_info = VOP_REG(RK3366_LIT_WIN1_DSP_INFO, 0xffffffff, 0),
.dsp_st = VOP_REG(RK3366_LIT_WIN1_DSP_ST, 0xffffffff, 0),
.yrgb_mst = VOP_REG(RK3366_LIT_WIN1_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3366_LIT_WIN1_VIR, 0x1fff, 0),
.alpha_pre_mul = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 2),
.alpha_mode = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 1),
.alpha_en = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 0),
.global_alpha_val = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0xff, 4),
.color_key = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0xffffff, 0),
.color_key_en = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0x1, 24),
.channel = VOP_REG(RK3366_LIT_WIN1_CTRL1, 0xf, 8),
};
static const struct vop_win_data rk3366_vop_lit_win_data[] = {
{ .base = 0x00, .phy = &rk3366_lit_win0_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x00, .phy = &rk3366_lit_win1_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
static const struct vop_intr rk3366_lit_intr = {
.intrs = rk3366_vop_lit_intrs,
.nintrs = ARRAY_SIZE(rk3366_vop_lit_intrs),
.line_flag_num[0] = VOP_REG(RK3366_LIT_LINE_FLAG, 0xfff, 0),
.line_flag_num[1] = VOP_REG(RK3366_LIT_LINE_FLAG, 0xfff, 16),
.status = VOP_REG_MASK(RK3366_LIT_INTR_STATUS, 0xffff, 0),
.enable = VOP_REG_MASK(RK3366_LIT_INTR_EN, 0xffff, 0),
.clear = VOP_REG_MASK(RK3366_LIT_INTR_CLEAR, 0xffff, 0),
};
static const struct vop_win_phy rk3126_win1_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
.dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
.alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
.alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1),
.alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
};
static const struct vop_win_data rk3126_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3036_win0_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x00, .phy = &rk3126_win1_data,
.type = DRM_PLANE_TYPE_PRIMARY },
};
static const struct vop_data rk3126_vop = {
.soc_id = 0x3126,
.vop_id = 0,
.version = VOP_VERSION(2, 4),
.max_input = {1920, 8192},
.max_output = {1920, 1080},
.ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
.win = rk3126_vop_win_data,
.win_size = ARRAY_SIZE(rk3126_vop_win_data),
};
/* PX30 VOPB win2 is same with RK3368,
* but RK3368 win2 register offset is 0xb0 and px30 is 0x190,
* so we set the PX30 VOPB win2 base = 0x190 - 0xb0 = 0xe0
*/
static const struct vop_ctrl px30_ctrl_data = {
.standby = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 1),
.axi_outstanding_max_num = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1f, 16),
.axi_max_outstanding_en = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1, 12),
.htotal_pw = VOP_REG(RK3366_LIT_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
.hact_st_end = VOP_REG(RK3366_LIT_DSP_HACT_ST_END, 0x0fff0fff, 0),
.vtotal_pw = VOP_REG(RK3366_LIT_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
.vact_st_end = VOP_REG(RK3366_LIT_DSP_VACT_ST_END, 0x0fff0fff, 0),
.vact_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VACT_ST_END_F1, 0x0fff0fff, 0),
.vs_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VS_ST_END_F1, 0x0fff0fff, 0),
.dsp_interlace = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 0),
.global_regdone_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 13),
.auto_gate_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 0),
.dsp_layer_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0xff, 22),
.overlay_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 4),
.core_dclk_div = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 13),
.dclk_ddr = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 14),
.rgb_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 0),
.rgb_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 2),
.hdmi_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 8),
.hdmi_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 10),
.lvds_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 16),
.lvds_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 18),
.mipi_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 24),
.mipi_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 26),
.mipi_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 25),
.lvds_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 17),
.hdmi_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 9),
.rgb_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 1),
.dither_down_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 8),
.dither_down_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 7),
.dither_down_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 6),
.dither_up_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 2),
.dsp_data_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1f, 9),
.dsp_bg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 9),
.dsp_rb_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 11),
.dsp_rg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 12),
.dsp_ccir656_avg = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 5),
.dsp_black = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 15),
.dsp_blank = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 14),
.dsp_outzero = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 3),
.dsp_lut_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 5),
.out_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0xf, 16),
.dsp_background = VOP_REG(RK3366_LIT_DSP_BG, 0x00ffffff, 0),
.cfg_done = VOP_REG(RK3366_LIT_REG_CFG_DONE, 0x1, 0),
.bcsh_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 0),
.bcsh_r2y_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 1),
.bcsh_out_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 2),
.bcsh_y2r_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 4),
.bcsh_y2r_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 6),
.bcsh_r2y_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 7),
.bcsh_color_bar = VOP_REG(RK3366_LIT_BCSH_COL_BAR, 0xffffff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0xff, 0),
.bcsh_contrast = VOP_REG(RK3366_LIT_BCSH_BCS, 0x1ff, 8),
.bcsh_sat_con = VOP_REG(RK3366_LIT_BCSH_BCS, 0x3ff, 20),
.bcsh_sin_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 0),
.bcsh_cos_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 16),
.afbdc_en = VOP_REG(PX30_AFBCD0_CTRL, 0x1, 0),
.afbdc_format = VOP_REG(PX30_AFBCD0_CTRL, 0x1f, 4),
.afbdc_pic_vir_width = VOP_REG(PX30_AFBCD0_CTRL, 0xffff, 16),
.afbdc_hdr_ptr = VOP_REG(PX30_AFBCD0_HDR_PTR, 0xffffffff, 0),
.afbdc_pic_size = VOP_REG(PX30_AFBCD0_PIC_SIZE, 0xffffffff, 0),
.afbdc_pic_offset = VOP_REG(PX30_AFBCD0_PIC_OFFSET, 0xffffffff, 0),
.afbdc_axi_ctrl = VOP_REG(PX30_AFBCD0_AXI_CTRL, 0xffffffff, 0),
.mcu_pix_total = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 0),
.mcu_cs_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 6),
.mcu_cs_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 10),
.mcu_rw_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 16),
.mcu_rw_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 20),
.mcu_clk_sel = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 26),
.mcu_hold_mode = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 27),
.mcu_frame_st = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 28),
.mcu_rs = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 29),
.mcu_bypass = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 30),
.mcu_type = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 31),
.mcu_rw_bypass_port = VOP_REG(RK3366_LIT_MCU_RW_BYPASS_PORT,
0xffffffff, 0),
};
static const struct vop_win_phy px30_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
.alpha_pre_mul = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0x1, 2),
.alpha_mode = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0x1, 1),
.alpha_en = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0x1, 0),
.global_alpha_val = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 4),
.channel = VOP_REG(RK3368_WIN2_CTRL1, 0xf, 8),
.color_key = VOP_REG(RK3368_WIN2_COLOR_KEY, 0xffffff, 0),
.color_key_en = VOP_REG(RK3368_WIN2_COLOR_KEY, 0x1, 24),
};
static const struct vop_win_data px30_vop_big_win_data[] = {
{ .base = 0x00, .phy = &rk3366_lit_win0_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x00, .phy = &rk3366_lit_win1_data,
.type = DRM_PLANE_TYPE_PRIMARY,
.feature = WIN_FEATURE_AFBDC },
{ .base = 0xe0, .phy = &px30_win23_data,
.type = DRM_PLANE_TYPE_CURSOR,
.area = rk3368_area_data,
.area_size = ARRAY_SIZE(rk3368_area_data), },
};
static const struct vop_win_data px30_vop_lit_win_data[] = {
{ .phy = NULL },
{ .base = 0x00, .phy = &rk3366_lit_win1_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .phy = NULL },
};
static const struct vop_grf_ctrl px30_grf_ctrl = {
.grf_dclk_inv = VOP_REG(PX30_GRF_PD_VO_CON1, 0x1, 4),
};
static const struct vop_data px30_vop_lit = {
.soc_id = 0x3326,
.vop_id = 1,
.version = VOP_VERSION(2, 5),
.max_input = {1920, 8192},
.max_output = {1920, 1080},
.ctrl = &px30_ctrl_data,
.intr = &rk3366_lit_intr,
.grf_ctrl = &px30_grf_ctrl,
.win = px30_vop_lit_win_data,
.win_size = ARRAY_SIZE(px30_vop_lit_win_data),
};
static const struct vop_data px30_vop_big = {
.soc_id = 0x3326,
.vop_id = 0,
.version = VOP_VERSION(2, 6),
.max_input = {1920, 8192},
.max_output = {1920, 1080},
.ctrl = &px30_ctrl_data,
.intr = &rk3366_lit_intr,
.grf_ctrl = &px30_grf_ctrl,
.win = px30_vop_big_win_data,
.win_size = ARRAY_SIZE(px30_vop_big_win_data),
};
static const struct vop_ctrl rk3308_ctrl_data = {
.standby = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 1),
.axi_outstanding_max_num = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1f, 16),
.axi_max_outstanding_en = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1, 12),
.htotal_pw = VOP_REG(RK3366_LIT_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
.hact_st_end = VOP_REG(RK3366_LIT_DSP_HACT_ST_END, 0x0fff0fff, 0),
.vtotal_pw = VOP_REG(RK3366_LIT_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
.vact_st_end = VOP_REG(RK3366_LIT_DSP_VACT_ST_END, 0x0fff0fff, 0),
.vact_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VACT_ST_END_F1, 0x0fff0fff, 0),
.vs_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VS_ST_END_F1, 0x0fff0fff, 0),
.global_regdone_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 13),
.auto_gate_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 0),
.dsp_layer_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 3),
.overlay_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 4),
.dclk_ddr = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 14),
.rgb_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 0),
.rgb_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 2),
.rgb_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 1),
.dither_down_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 8),
.dither_down_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 7),
.dither_down_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 6),
.dither_up_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 2),
.dsp_data_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1f, 9),
.dsp_bg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 9),
.dsp_rb_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 11),
.dsp_rg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 12),
.dsp_ccir656_avg = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 5),
.dsp_black = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 15),
.dsp_blank = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 14),
.dsp_outzero = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 3),
.dsp_lut_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 5),
.out_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0xf, 16),
.dsp_background = VOP_REG(RK3366_LIT_DSP_BG, 0x00ffffff, 0),
.cfg_done = VOP_REG(RK3366_LIT_REG_CFG_DONE, 0x1, 0),
.bcsh_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 0),
.bcsh_r2y_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 1),
.bcsh_out_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 2),
.bcsh_y2r_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 4),
.bcsh_y2r_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 6),
.bcsh_r2y_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 7),
.bcsh_color_bar = VOP_REG(RK3366_LIT_BCSH_COL_BAR, 0xffffff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0x3f, 0),
.bcsh_contrast = VOP_REG(RK3366_LIT_BCSH_BCS, 0xff, 8),
.bcsh_sat_con = VOP_REG(RK3366_LIT_BCSH_BCS, 0x1ff, 16),
.bcsh_sin_hue = VOP_REG(RK3366_LIT_BCSH_H, 0xff, 0),
.bcsh_cos_hue = VOP_REG(RK3366_LIT_BCSH_H, 0xff, 8),
.mcu_pix_total = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 0),
.mcu_cs_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 6),
.mcu_cs_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 10),
.mcu_rw_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 16),
.mcu_rw_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 20),
.mcu_clk_sel = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 26),
.mcu_hold_mode = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 27),
.mcu_frame_st = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 28),
.mcu_rs = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 29),
.mcu_bypass = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 30),
.mcu_type = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 31),
.mcu_rw_bypass_port = VOP_REG(RK3366_LIT_MCU_RW_BYPASS_PORT,
0xffffffff, 0),
};
static const int rk3308_vop_intrs[] = {
FS_INTR,
FS_NEW_INTR,
ADDR_SAME_INTR,
LINE_FLAG_INTR,
LINE_FLAG1_INTR,
BUS_ERROR_INTR,
0,
0,
DSP_HOLD_VALID_INTR,
DMA_FINISH_INTR,
0,
POST_BUF_EMPTY_INTR
};
static const struct vop_intr rk3308_vop_intr = {
.intrs = rk3308_vop_intrs,
.nintrs = ARRAY_SIZE(rk3308_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3366_LIT_LINE_FLAG, 0xfff, 0),
.line_flag_num[1] = VOP_REG(RK3366_LIT_LINE_FLAG, 0xfff, 16),
.status = VOP_REG_MASK(RK3366_LIT_INTR_STATUS, 0xffff, 0),
.enable = VOP_REG_MASK(RK3366_LIT_INTR_EN, 0xffff, 0),
.clear = VOP_REG_MASK(RK3366_LIT_INTR_CLEAR, 0xffff, 0),
};
static const struct vop_data rk3308_vop = {
.soc_id = 0x3308,
.vop_id = 0,
.version = VOP_VERSION(2, 7),
.max_input = {1920, 8192},
.max_output = {1920, 1080},
.ctrl = &rk3308_ctrl_data,
.intr = &rk3308_vop_intr,
.win = rk3366_vop_lit_win_data,
.win_size = ARRAY_SIZE(rk3366_vop_lit_win_data),
};
static const struct vop_ctrl rv1126_ctrl_data = {
.standby = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 1),
.axi_outstanding_max_num = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1f, 16),
.axi_max_outstanding_en = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1, 12),
.htotal_pw = VOP_REG(RK3366_LIT_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
.hact_st_end = VOP_REG(RK3366_LIT_DSP_HACT_ST_END, 0x0fff0fff, 0),
.vtotal_pw = VOP_REG(RK3366_LIT_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
.vact_st_end = VOP_REG(RK3366_LIT_DSP_VACT_ST_END, 0x0fff0fff, 0),
.vact_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VACT_ST_END_F1, 0x0fff0fff, 0),
.vs_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VS_ST_END_F1, 0x0fff0fff, 0),
.dsp_interlace = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 0),
.global_regdone_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 13),
.auto_gate_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 0),
.dsp_layer_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0xff, 22),
.overlay_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 4),
.core_dclk_div = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 13),
.dclk_ddr = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 14),
.rgb_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 0),
.rgb_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 2),
.hdmi_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 8),
.hdmi_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 10),
.lvds_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 16),
.lvds_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 18),
.mipi_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 24),
.mipi_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 26),
.mipi_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 25),
.lvds_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 17),
.hdmi_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 9),
.rgb_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 1),
.dither_down_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 8),
.dither_down_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 7),
.dither_down_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 6),
.dither_up_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 2),
.dsp_data_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1f, 9),
.dsp_bg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 9),
.dsp_rb_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 11),
.dsp_rg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 12),
.yuv_clip = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 4),
.dsp_ccir656_avg = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 5),
.dsp_black = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 15),
.dsp_blank = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 14),
.dsp_outzero = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 3),
.dsp_lut_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 5),
.out_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0xf, 16),
.dsp_background = VOP_REG(RK3366_LIT_DSP_BG, 0x00ffffff, 0),
.cfg_done = VOP_REG(RK3366_LIT_REG_CFG_DONE, 0x1, 0),
.bcsh_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 0),
.bcsh_r2y_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 1),
.bcsh_out_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 2),
.bcsh_y2r_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 4),
.bcsh_y2r_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 6),
.bcsh_r2y_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 7),
.bcsh_color_bar = VOP_REG(RK3366_LIT_BCSH_COL_BAR, 0xffffff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0xff, 0),
.bcsh_contrast = VOP_REG(RK3366_LIT_BCSH_BCS, 0x1ff, 8),
.bcsh_sat_con = VOP_REG(RK3366_LIT_BCSH_BCS, 0x3ff, 20),
.bcsh_sin_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 0),
.bcsh_cos_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 16),
.mcu_pix_total = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 0),
.mcu_cs_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 6),
.mcu_cs_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 10),
.mcu_rw_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 16),
.mcu_rw_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 20),
.mcu_clk_sel = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 26),
.mcu_hold_mode = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 27),
.mcu_frame_st = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 28),
.mcu_rs = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 29),
.mcu_bypass = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 30),
.mcu_type = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 31),
.mcu_rw_bypass_port = VOP_REG(RK3366_LIT_MCU_RW_BYPASS_PORT,
0xffffffff, 0),
.bt1120_yc_swap = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 30),
.bt1120_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 31),
};
static const struct vop_win_data rv1126_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3366_lit_win0_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .phy = NULL },
{ .base = 0xe0, .phy = &px30_win23_data,
.type = DRM_PLANE_TYPE_PRIMARY,
.area = rk3368_area_data,
.area_size = ARRAY_SIZE(rk3368_area_data), },
};
static const struct vop_grf_ctrl rv1126_grf_ctrl = {
.grf_dclk_inv = VOP_REG(RV1126_GRF_IOFUNC_CON3, 0x1, 2),
};
static const struct vop_data rv1126_vop = {
.soc_id = 0x1126,
.vop_id = 0,
.version = VOP_VERSION(2, 0xb),
.max_input = {1920, 1920},
.max_output = {1920, 1080},
.ctrl = &rv1126_ctrl_data,
.intr = &rk3366_lit_intr,
.grf_ctrl = &rv1126_grf_ctrl,
.win = rv1126_vop_win_data,
.win_size = ARRAY_SIZE(rv1126_vop_win_data),
};
static const struct vop_ctrl rv1106_ctrl_data = {
.standby = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 1),
.axi_outstanding_max_num = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1f, 16),
.axi_max_outstanding_en = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1, 12),
.htotal_pw = VOP_REG(RK3366_LIT_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
.hact_st_end = VOP_REG(RK3366_LIT_DSP_HACT_ST_END, 0x0fff0fff, 0),
.vtotal_pw = VOP_REG(RK3366_LIT_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
.vact_st_end = VOP_REG(RK3366_LIT_DSP_VACT_ST_END, 0x0fff0fff, 0),
.vact_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VACT_ST_END_F1, 0x0fff0fff, 0),
.vs_st_end_f1 = VOP_REG(RK3366_LIT_DSP_VS_ST_END_F1, 0x0fff0fff, 0),
.dsp_interlace = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 0),
.auto_gate_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 0),
.overlay_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 4),
.core_dclk_div = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 13),
.dclk_ddr = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 14),
.rgb_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 0),
.rgb_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 1),
.dither_down_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 8),
.dither_down_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 7),
.dither_down_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 6),
.dither_up_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 2),
.dsp_data_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1f, 9),
.dsp_bg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 9),
.dsp_rb_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 11),
.dsp_rg_swap = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 12),
.yuv_clip = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 4),
.dsp_black = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 15),
.dsp_blank = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 14),
.dsp_outzero = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 3),
.out_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0xf, 16),
.dsp_background = VOP_REG(RK3366_LIT_DSP_BG, 0x00ffffff, 0),
.cfg_done = VOP_REG(RK3366_LIT_REG_CFG_DONE, 0x1, 0),
.bcsh_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 0),
.bcsh_r2y_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 1),
.bcsh_out_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 2),
.bcsh_y2r_csc_mode = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x3, 4),
.bcsh_y2r_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 6),
.bcsh_r2y_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 7),
.bcsh_color_bar = VOP_REG(RK3366_LIT_BCSH_COL_BAR, 0xffffff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0xff, 0),
.bcsh_contrast = VOP_REG(RK3366_LIT_BCSH_BCS, 0x1ff, 8),
.bcsh_sat_con = VOP_REG(RK3366_LIT_BCSH_BCS, 0x3ff, 20),
.bcsh_sin_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 0),
.bcsh_cos_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 16),
.mcu_pix_total = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 0),
.mcu_cs_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 6),
.mcu_cs_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 10),
.mcu_rw_pst = VOP_REG(RK3366_LIT_MCU_CTRL, 0xf, 16),
.mcu_rw_pend = VOP_REG(RK3366_LIT_MCU_CTRL, 0x3f, 20),
.mcu_clk_sel = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 26),
.mcu_hold_mode = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 27),
.mcu_frame_st = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 28),
.mcu_rs = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 29),
.mcu_bypass = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 30),
.mcu_type = VOP_REG(RK3366_LIT_MCU_CTRL, 0x1, 31),
.mcu_rw_bypass_port = VOP_REG(RK3366_LIT_MCU_RW_BYPASS_PORT,
0xffffffff, 0),
.bt1120_yc_swap = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 30),
.bt1120_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 31),
.bt656_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 6),
};
static const struct vop_win_data rv1106_vop_win_data[] = {
{ .phy = NULL },
{ .base = 0x00, .phy = &rk3366_lit_win1_data,
.type = DRM_PLANE_TYPE_PRIMARY },
};
static const struct vop_grf_ctrl rv1106_grf_ctrl = {
.grf_dclk_inv = VOP_REG(RV1106_VENC_GRF_VOP_IO_WRAPPER, 0x1, 2),
};
static const struct vop_data rv1106_vop = {
.soc_id = 0x1106,
.vop_id = 0,
.version = VOP_VERSION(2, 0xc),
.max_input = {1280, 1280},
.max_output = {1280, 1280},
.ctrl = &rv1106_ctrl_data,
.intr = &rk3366_lit_intr,
.grf_ctrl = &rv1106_grf_ctrl,
.win = rv1106_vop_win_data,
.win_size = ARRAY_SIZE(rv1106_vop_win_data),
};
static const struct of_device_id vop_driver_dt_match[] = {
#if IS_ENABLED(CONFIG_CPU_RK3036)
{ .compatible = "rockchip,rk3036-vop",
.data = &rk3036_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_RK30XX)
{ .compatible = "rockchip,rk3066-vop",
.data = &rk3066_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_RK312X)
{ .compatible = "rockchip,rk3126-vop",
.data = &rk3126_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_PX30)
{ .compatible = "rockchip,px30-vop-lit",
.data = &px30_vop_lit },
{ .compatible = "rockchip,px30-vop-big",
.data = &px30_vop_big },
#endif
#if IS_ENABLED(CONFIG_CPU_RK3308)
{ .compatible = "rockchip,rk3308-vop",
.data = &rk3308_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_RV1106)
{ .compatible = "rockchip,rv1106-vop",
.data = &rv1106_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_RV1126)
{ .compatible = "rockchip,rv1126-vop",
.data = &rv1126_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_RK3288)
{ .compatible = "rockchip,rk3288-vop-big",
.data = &rk3288_vop_big },
{ .compatible = "rockchip,rk3288-vop-lit",
.data = &rk3288_vop_lit },
#endif
#if IS_ENABLED(CONFIG_CPU_RK3368)
{ .compatible = "rockchip,rk3368-vop",
.data = &rk3368_vop },
{ .compatible = "rockchip,rk3366-vop",
.data = &rk3366_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_RK3399)
{ .compatible = "rockchip,rk3399-vop-big",
.data = &rk3399_vop_big },
{ .compatible = "rockchip,rk3399-vop-lit",
.data = &rk3399_vop_lit },
#endif
#if IS_ENABLED(CONFIG_CPU_RK322X)
{ .compatible = "rockchip,rk3228-vop",
.data = &rk3228_vop },
#endif
#if IS_ENABLED(CONFIG_CPU_RK3328)
{ .compatible = "rockchip,rk3328-vop",
.data = &rk3328_vop },
#endif
{},
};
MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
static int vop_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
if (!dev->of_node) {
DRM_DEV_ERROR(dev, "can't find vop devices\n");
return -ENODEV;
}
return component_add(dev, &vop_component_ops);
}
static int vop_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &vop_component_ops);
return 0;
}
struct platform_driver vop_platform_driver = {
.probe = vop_probe,
.remove = vop_remove,
.driver = {
.name = "rockchip-vop",
.of_match_table = of_match_ptr(vop_driver_dt_match),
},
};