// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) Rockchip Electronics Co., Ltd. * Author:Mark Yao */ #include #include #include #include #include #include #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_NV21, DRM_FORMAT_NV16, DRM_FORMAT_NV61, DRM_FORMAT_NV24, DRM_FORMAT_NV42, }; 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_NV21, DRM_FORMAT_NV16, DRM_FORMAT_NV61, DRM_FORMAT_NV24, DRM_FORMAT_NV42, DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ }; 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_NV21, /* yuv420_8bit linear mode, 2 plane */ DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */ DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */ DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 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 uint32_t formats_win_ebc[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB888, DRM_FORMAT_RGB565, }; 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, 0x1, 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 = &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 = &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 = &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, 0x1, 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 }, { .phy = NULL }, { .base = 0x00, .phy = &rk3368_win23_data, .csc = &rk3399_win2_csc, .format_modifiers = format_modifiers, .type = DRM_PLANE_TYPE_PRIMARY, .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), .csc_mode = VOP_REG(RK3366_LIT_WIN0_CTRL0, 0x3, 10), .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), .csc_mode = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 2), .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, .format_modifiers = format_modifiers_afbc, .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 = &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 = &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 = &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 = &rv1106_grf_ctrl, .win = rv1106_vop_win_data, .win_size = ARRAY_SIZE(rv1106_vop_win_data), }; static const struct vop_ctrl rk3506_ctrl_data = { .cfg_done = VOP_REG(RK3366_LIT_REG_CFG_DONE, 0x1, 0), .dsp_background = VOP_REG(RK3366_LIT_DSP_BG, 0x00ffffff, 0), .axi_outstanding_max_num = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1f, 16), .axi_max_outstanding_en = VOP_REG(RK3366_LIT_SYS_CTRL1, 0x1, 12), .auto_gate_en = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 0), .standby = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 1), .dsp_outzero = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 3), .yuv_clip = VOP_REG(RK3366_LIT_SYS_CTRL2, 0x1, 4), .rgb_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 0), .rgb_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 2), .bt1120_uv_swap = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 5), .bt656_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 6), .core_dclk_div = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 13), .mipi_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 24), .mipi_dclk_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 25), .mipi_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 26), .bt1120_yc_swap = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 30), .bt1120_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 31), .dsp_interlace = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 0), .dsp_interlace_pol = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 1), .dither_up_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 2), .overlay_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 4), .dsp_lut_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 5), .dither_down_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 6), .dither_down_sel = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 7), .dither_down_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 8), .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_blank = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 14), .dsp_black = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 15), .out_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0xf, 16), .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), .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), }; static const struct vop_win_phy rk3506_lit_win1_data = { .data_formats = formats_win_lite, .nformats = ARRAY_SIZE(formats_win_lite), .enable = VOP_REG(RK3366_LIT_WIN1_CTRL0, 0x1, 0), .csc_mode = VOP_REG(RK3366_LIT_WIN1_CTRL0, 0x1, 2), .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), .channel = VOP_REG(RK3366_LIT_WIN1_CTRL1, 0xf, 8), .yrgb_vir = VOP_REG(RK3366_LIT_WIN1_VIR, 0x1fff, 0), .yrgb_mst = VOP_REG(RK3366_LIT_WIN1_MST, 0xffffffff, 0), .dsp_info = VOP_REG(RK3366_LIT_WIN1_DSP_INFO, 0xffffffff, 0), .dsp_st = VOP_REG(RK3366_LIT_WIN1_DSP_ST, 0xffffffff, 0), .color_key = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0xffffff, 0), .color_key_en = VOP_REG(RK3366_LIT_WIN1_COLOR_KEY, 0x1, 24), .alpha_en = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 0), .alpha_mode = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 1), .alpha_pre_mul = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0x1, 2), .global_alpha_val = VOP_REG(RK3366_LIT_WIN1_ALPHA_CTRL, 0xff, 4), }; static const struct vop_win_data rk3506_vop_win_data[] = { { .phy = NULL }, { .base = 0x00, .phy = &rk3506_lit_win1_data, .type = DRM_PLANE_TYPE_PRIMARY }, }; static const struct vop_grf_ctrl rk3506_grf_ctrl = { .grf_dclk_inv = VOP_REG(RK3506_GRF_SOC_CON2, 0x1, 0), }; static const struct vop_mcu_bypass_cfg rk3506_mcu_bypass_cfg = { .timing = { .mcu_pix_total = 26, .mcu_cs_pst = 3, .mcu_cs_pend = 24, .mcu_rw_pst = 6, .mcu_rw_pend = 15, }, .dclk_rate = 120000000, }; static const struct vop_data rk3506_vop = { .soc_id = 0x3506, .vop_id = 0, .version = VOP_VERSION(2, 0xe), .max_input = {1280, 1280}, .max_output = {1280, 1280}, .ctrl = &rk3506_ctrl_data, .intr = &rk3366_lit_intr, .grf = &rk3506_grf_ctrl, .win = rk3506_vop_win_data, .win_size = ARRAY_SIZE(rk3506_vop_win_data), .mcu_bypass_cfg = &rk3506_mcu_bypass_cfg, }; static const struct vop_ctrl rk3576_lit_ctrl_data = { .cfg_done = VOP_REG(EBC_CONFIG_DONE, 0x1, 0), .enable = VOP_REG(EBC_VOP_SYS_CTRL, 0x1, 0), .bcsh_r2y_en = VOP_REG(EBC_VOP_SYS_CTRL, 0x1, 1), .bcsh_r2y_csc_mode = VOP_REG(EBC_VOP_SYS_CTRL, 0x1, 2), .bt1120_yc_swap = VOP_REG(EBC_VOP_SYS_CTRL, 0x1, 6), .bt1120_uv_swap = VOP_REG(EBC_VOP_SYS_CTRL, 0x1, 7), .inf_out_en = VOP_REG(EBC_VOP_SYS_CTRL, 0x1, 8), .rgb_en = VOP_REG(EBC_VOP_DSP_CTRL0, 0x1, 0), .bt1120_en = VOP_REG(EBC_VOP_DSP_CTRL0, 0x1, 1), .bt656_en = VOP_REG(EBC_VOP_DSP_CTRL0, 0x1, 2), .core_dclk_div = VOP_REG(EBC_VOP_DSP_CTRL0, 0x1, 3), .dclk_pol = VOP_REG(EBC_VOP_DSP_CTRL0, 0x1, 4), .rgb_pin_pol = VOP_REG(EBC_VOP_DSP_CTRL0, 0x7, 5), .standby = VOP_REG(EBC_VOP_DSP_CTRL0, 0x1, 15), .out_dresetn = VOP_REG(EBC_VOP_DSP_CTRL0, 0x1, 31), .dsp_interlace = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 0), .dsp_interlace_pol = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 1), .dither_up_en = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 4), .dither_down_en = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 5), .dither_down_mode = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 6), .dither_down_sel = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 7), .dsp_data_swap = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1f, 8), .dsp_bg_swap = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 8), .dsp_rb_swap = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 9), .dsp_rg_swap = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 10), .dsp_delta_swap = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 11), .dsp_dummy_swap = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 12), .dsp_black = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 14), .dsp_blank = VOP_REG(EBC_VOP_DSP_CTRL1, 0x1, 15), .out_mode = VOP_REG(EBC_VOP_DSP_CTRL1, 0xf, 16), .mcu_pix_total = VOP_REG(EBC_VOP_MCU_CTRL, 0x3f, 0), .mcu_cs_pst = VOP_REG(EBC_VOP_MCU_CTRL, 0xf, 6), .mcu_cs_pend = VOP_REG(EBC_VOP_MCU_CTRL, 0x3f, 10), .mcu_rw_pst = VOP_REG(EBC_VOP_MCU_CTRL, 0xf, 16), .mcu_rw_pend = VOP_REG(EBC_VOP_MCU_CTRL, 0x3f, 20), .mcu_hold_mode = VOP_REG(EBC_VOP_MCU_CTRL, 0x1, 27), .mcu_frame_st = VOP_REG(EBC_VOP_MCU_CTRL, 0x1, 28), .mcu_rs = VOP_REG(EBC_VOP_MCU_CTRL, 0x1, 29), .mcu_bypass = VOP_REG(EBC_VOP_MCU_CTRL, 0x1, 30), .mcu_type = VOP_REG(EBC_VOP_MCU_CTRL, 0x1, 31), .mcu_rw_bypass_port = VOP_REG(EBC_MCU_RW_BYPASS_PORT, 0xffffffff, 0), .htotal_pw = VOP_REG(EBC_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), .hact_st_end = VOP_REG(EBC_DSP_HACT_ST_END, 0x0fff0fff, 0), .vtotal_pw = VOP_REG(EBC_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), .vact_st_end = VOP_REG(EBC_DSP_VACT_ST_END, 0x0fff0fff, 0), .vs_st_end_f1 = VOP_REG(EBC_DSP_VS_ST_END_F1, 0x0fff0fff, 0), .vact_st_end_f1 = VOP_REG(EBC_DSP_VACT_ST_END_F1, 0x0fff0fff, 0), .dsp_background = VOP_REG(EBC_DSP_BG, 0xffffffff, 0), }; static const int rk3576_vop_lit_intrs[] = { FS_INTR, DMA_FINISH_INTR, LINE_FLAG_INTR, LINE_FLAG1_INTR, BUS_ERROR_INTR, DSP_HOLD_VALID_INTR, }; static const struct vop_intr rk3576_lit_intr = { .intrs = rk3576_vop_lit_intrs, .nintrs = ARRAY_SIZE(rk3576_vop_lit_intrs), .line_flag_num[0] = VOP_REG(EBC_LINE_FLAG, 0xfff, 0), .line_flag_num[1] = VOP_REG(EBC_LINE_FLAG, 0xfff, 16), .status = VOP_REG_MASK(EBC_VOP_INT_STATUS, 0xffff, 0), .enable = VOP_REG_MASK(EBC_VOP_INT_EN, 0xffff, 0), .clear = VOP_REG_MASK(EBC_VOP_INT_CLR, 0xffff, 0), }; static const struct vop_win_phy rk3576_lit_win2_data = { .data_formats = formats_win_ebc, .nformats = ARRAY_SIZE(formats_win_ebc), .dsp_info = VOP_REG(EBC_VOP_WIN_DSP_INFO, 0xffffffff, 0), .dsp_st = VOP_REG(EBC_VOP_WIN_DSP_ST, 0xffffffff, 0), .yrgb_mst = VOP_REG(EBC_WIN_MST2, 0xffffffff, 0), .enable = VOP_REG(EBC_WIN2_CTRL, 0x1, 0), .interlace_read = VOP_REG(EBC_VOP_SYS_CTRL, 0x1, 3), .format = VOP_REG(EBC_VOP_SYS_CTRL, 0x3, 4), .yrgb_vir = VOP_REG(EBC_VOP_WIN_VIR, 0x1fff, 0), }; static const struct vop_win_data rk3576_lit_win_data[] = { { .phy = NULL }, { .phy = NULL }, { .base = 0x00, .phy = &rk3576_lit_win2_data, .type = DRM_PLANE_TYPE_PRIMARY }, }; static const struct vop_grf_ctrl rk3576_lit_vo0_grf_ctrl = { .grf_edp_ch_sel = VOP_REG(RK3576_VO0_GRF_SOC_CON9, 0x1, 10), .grf_hdmi_ch_sel = VOP_REG(RK3576_VO0_GRF_SOC_CON9, 0x1, 9), .grf_mipi_ch_sel = VOP_REG(RK3576_VO0_GRF_SOC_CON9, 0x1, 8), .grf_hdmi_pin_pol = VOP_REG(RK3576_VO0_GRF_SOC_CON13, 0x3, 5), .grf_hdmi_1to4_en = VOP_REG(RK3576_VO0_GRF_SOC_CON13, 0x1, 4), .grf_mipi_mode = VOP_REG(RK3576_VO0_GRF_SOC_CON13, 0x1, 3), .grf_mipi_pin_pol = VOP_REG(RK3576_VO0_GRF_SOC_CON13, 0x3, 1), .grf_mipi_1to4_en = VOP_REG(RK3576_VO0_GRF_SOC_CON13, 0x1, 0), }; static const struct vop_grf_ctrl rk3576_lit_grf_ctrl = { .grf_dclk_inv = VOP_REG(RK3576_IOC_GRF_MISC_CON8, 0x1, 9), .grf_vopl_sel = VOP_REG(RK3576_IOC_GRF_MISC_CON8, 0x1, 11), }; static const struct vop_mcu_bypass_cfg rk3576_lit_mcu_bypass_cfg = { .timing = { .mcu_pix_total = 53, .mcu_cs_pst = 6, .mcu_cs_pend = 48, .mcu_rw_pst = 12, .mcu_rw_pend = 30, }, .dclk_rate = 150000000, }; static const struct vop_data rk3576_vop_lit = { .soc_id = 0x3576, .vop_id = 0, .version = VOP_VERSION(2, 0xd), .max_input = {1920, 1920}, .max_output = {1920, 1920}, .ctrl = &rk3576_lit_ctrl_data, .intr = &rk3576_lit_intr, .vo0_grf = &rk3576_lit_vo0_grf_ctrl, .grf = &rk3576_lit_grf_ctrl, .win = rk3576_lit_win_data, .win_size = ARRAY_SIZE(rk3576_lit_win_data), .mcu_bypass_cfg = &rk3576_lit_mcu_bypass_cfg, }; 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 #if IS_ENABLED(CONFIG_CPU_RK3506) { .compatible = "rockchip,rk3506-vop", .data = &rk3506_vop }, #endif #if IS_ENABLED(CONFIG_CPU_RK3576) { .compatible = "rockchip,rk3576-vop-lit", .data = &rk3576_vop_lit }, #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), }, };