19c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2a67719d1SMark Yao /* 3a67719d1SMark Yao * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 4a67719d1SMark Yao * Author:Mark Yao <mark.yao@rock-chips.com> 5a67719d1SMark Yao */ 6a67719d1SMark Yao 7a67719d1SMark Yao #include <linux/component.h> 8c2156ccdSSam Ravnborg #include <linux/mod_devicetable.h> 9c2156ccdSSam Ravnborg #include <linux/module.h> 10c2156ccdSSam Ravnborg #include <linux/of.h> 11c2156ccdSSam Ravnborg #include <linux/platform_device.h> 12c2156ccdSSam Ravnborg 13c2156ccdSSam Ravnborg #include <drm/drm_fourcc.h> 14c2156ccdSSam Ravnborg #include <drm/drm_plane.h> 15c2156ccdSSam Ravnborg #include <drm/drm_print.h> 16a67719d1SMark Yao 17a67719d1SMark Yao #include "rockchip_drm_vop.h" 18a67719d1SMark Yao #include "rockchip_vop_reg.h" 19b02516b6SBen Dooks #include "rockchip_drm_drv.h" 20a67719d1SMark Yao 219548e1b4SMark yao #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \ 229548e1b4SMark yao { \ 239548e1b4SMark yao .offset = off, \ 24a67719d1SMark Yao .mask = _mask, \ 259548e1b4SMark yao .shift = _shift, \ 269548e1b4SMark yao .write_mask = _write_mask, \ 279548e1b4SMark yao .relaxed = _relaxed, \ 289548e1b4SMark yao } 29d49463ecSMark Yao 309548e1b4SMark yao #define VOP_REG(off, _mask, _shift) \ 319548e1b4SMark yao _VOP_REG(off, _mask, _shift, false, true) 329548e1b4SMark yao 339548e1b4SMark yao #define VOP_REG_SYNC(off, _mask, _shift) \ 349548e1b4SMark yao _VOP_REG(off, _mask, _shift, false, false) 359548e1b4SMark yao 369548e1b4SMark yao #define VOP_REG_MASK_SYNC(off, _mask, _shift) \ 379548e1b4SMark yao _VOP_REG(off, _mask, _shift, true, false) 38a67719d1SMark Yao 39f7673453SMark Yao static const uint32_t formats_win_full[] = { 40a67719d1SMark Yao DRM_FORMAT_XRGB8888, 41a67719d1SMark Yao DRM_FORMAT_ARGB8888, 42a67719d1SMark Yao DRM_FORMAT_XBGR8888, 43a67719d1SMark Yao DRM_FORMAT_ABGR8888, 44a67719d1SMark Yao DRM_FORMAT_RGB888, 45a67719d1SMark Yao DRM_FORMAT_BGR888, 46a67719d1SMark Yao DRM_FORMAT_RGB565, 47a67719d1SMark Yao DRM_FORMAT_BGR565, 48a67719d1SMark Yao DRM_FORMAT_NV12, 49a67719d1SMark Yao DRM_FORMAT_NV16, 50a67719d1SMark Yao DRM_FORMAT_NV24, 51a67719d1SMark Yao }; 52a67719d1SMark Yao 53f7673453SMark Yao static const uint32_t formats_win_lite[] = { 54a67719d1SMark Yao DRM_FORMAT_XRGB8888, 55a67719d1SMark Yao DRM_FORMAT_ARGB8888, 56a67719d1SMark Yao DRM_FORMAT_XBGR8888, 57a67719d1SMark Yao DRM_FORMAT_ABGR8888, 58a67719d1SMark Yao DRM_FORMAT_RGB888, 59a67719d1SMark Yao DRM_FORMAT_BGR888, 60a67719d1SMark Yao DRM_FORMAT_RGB565, 61a67719d1SMark Yao DRM_FORMAT_BGR565, 62a67719d1SMark Yao }; 63a67719d1SMark Yao 64b51502adSMark Yao static const struct vop_scl_regs rk3036_win_scl = { 65b51502adSMark Yao .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), 66b51502adSMark Yao .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), 67b51502adSMark Yao .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), 68b51502adSMark Yao .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16), 69b51502adSMark Yao }; 70b51502adSMark Yao 71b51502adSMark Yao static const struct vop_win_phy rk3036_win0_data = { 72b51502adSMark Yao .scl = &rk3036_win_scl, 73b51502adSMark Yao .data_formats = formats_win_full, 74b51502adSMark Yao .nformats = ARRAY_SIZE(formats_win_full), 75b51502adSMark Yao .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0), 76b51502adSMark Yao .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3), 77b51502adSMark Yao .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15), 78b51502adSMark Yao .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0), 79b51502adSMark Yao .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0), 80b51502adSMark Yao .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0), 81b51502adSMark Yao .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0), 82b51502adSMark Yao .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0), 83b51502adSMark Yao .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0), 84b51502adSMark Yao .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16), 85b51502adSMark Yao }; 86b51502adSMark Yao 87b51502adSMark Yao static const struct vop_win_phy rk3036_win1_data = { 88b51502adSMark Yao .data_formats = formats_win_lite, 89b51502adSMark Yao .nformats = ARRAY_SIZE(formats_win_lite), 90b51502adSMark Yao .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), 91b51502adSMark Yao .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), 92b51502adSMark Yao .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), 93b51502adSMark Yao .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0), 94b51502adSMark Yao .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0), 95b51502adSMark Yao .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0), 96b51502adSMark Yao .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0), 97b51502adSMark Yao .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0), 98b51502adSMark Yao }; 99b51502adSMark Yao 100b51502adSMark Yao static const struct vop_win_data rk3036_vop_win_data[] = { 101b51502adSMark Yao { .base = 0x00, .phy = &rk3036_win0_data, 102b51502adSMark Yao .type = DRM_PLANE_TYPE_PRIMARY }, 103b51502adSMark Yao { .base = 0x00, .phy = &rk3036_win1_data, 104b51502adSMark Yao .type = DRM_PLANE_TYPE_CURSOR }, 105b51502adSMark Yao }; 106b51502adSMark Yao 107b51502adSMark Yao static const int rk3036_vop_intrs[] = { 108b51502adSMark Yao DSP_HOLD_VALID_INTR, 109b51502adSMark Yao FS_INTR, 110b51502adSMark Yao LINE_FLAG_INTR, 111b51502adSMark Yao BUS_ERROR_INTR, 112b51502adSMark Yao }; 113b51502adSMark Yao 114b51502adSMark Yao static const struct vop_intr rk3036_intr = { 115b51502adSMark Yao .intrs = rk3036_vop_intrs, 116b51502adSMark Yao .nintrs = ARRAY_SIZE(rk3036_vop_intrs), 117ac6560dfSMark yao .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12), 1189a61c54bSMark yao .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0), 1199a61c54bSMark yao .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4), 1209a61c54bSMark yao .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8), 121b51502adSMark Yao }; 122b51502adSMark Yao 1239a61c54bSMark yao static const struct vop_modeset rk3036_modeset = { 124b51502adSMark Yao .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), 125b51502adSMark Yao .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0), 126b51502adSMark Yao .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), 127b51502adSMark Yao .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0), 1289a61c54bSMark yao }; 1299a61c54bSMark yao 1309a61c54bSMark yao static const struct vop_output rk3036_output = { 1319a61c54bSMark yao .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4), 1329a61c54bSMark yao }; 1339a61c54bSMark yao 1349a61c54bSMark yao static const struct vop_common rk3036_common = { 1359a61c54bSMark yao .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30), 1369a61c54bSMark yao .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0), 1379a61c54bSMark yao .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24), 138a5c0fa44SUrja Rannikko .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27), 139a5c0fa44SUrja Rannikko .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11), 140a5c0fa44SUrja Rannikko .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10), 1419548e1b4SMark yao .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0), 142b51502adSMark Yao }; 143b51502adSMark Yao 144b51502adSMark Yao static const struct vop_data rk3036_vop = { 145b51502adSMark Yao .intr = &rk3036_intr, 1469a61c54bSMark yao .common = &rk3036_common, 1479a61c54bSMark yao .modeset = &rk3036_modeset, 1489a61c54bSMark yao .output = &rk3036_output, 149b51502adSMark Yao .win = rk3036_vop_win_data, 150b51502adSMark Yao .win_size = ARRAY_SIZE(rk3036_vop_win_data), 151b51502adSMark Yao }; 152b51502adSMark Yao 153460c3b00SSandy Huang static const struct vop_win_phy rk3126_win1_data = { 154460c3b00SSandy Huang .data_formats = formats_win_lite, 155460c3b00SSandy Huang .nformats = ARRAY_SIZE(formats_win_lite), 156460c3b00SSandy Huang .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), 157460c3b00SSandy Huang .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), 158460c3b00SSandy Huang .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), 159460c3b00SSandy Huang .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0), 160460c3b00SSandy Huang .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0), 161460c3b00SSandy Huang .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0), 162460c3b00SSandy Huang .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0), 163460c3b00SSandy Huang }; 164460c3b00SSandy Huang 165460c3b00SSandy Huang static const struct vop_win_data rk3126_vop_win_data[] = { 166460c3b00SSandy Huang { .base = 0x00, .phy = &rk3036_win0_data, 167460c3b00SSandy Huang .type = DRM_PLANE_TYPE_PRIMARY }, 168460c3b00SSandy Huang { .base = 0x00, .phy = &rk3126_win1_data, 169460c3b00SSandy Huang .type = DRM_PLANE_TYPE_CURSOR }, 170460c3b00SSandy Huang }; 171460c3b00SSandy Huang 172460c3b00SSandy Huang static const struct vop_data rk3126_vop = { 173460c3b00SSandy Huang .intr = &rk3036_intr, 174460c3b00SSandy Huang .common = &rk3036_common, 175460c3b00SSandy Huang .modeset = &rk3036_modeset, 176460c3b00SSandy Huang .output = &rk3036_output, 177460c3b00SSandy Huang .win = rk3126_vop_win_data, 178460c3b00SSandy Huang .win_size = ARRAY_SIZE(rk3126_vop_win_data), 179460c3b00SSandy Huang }; 180460c3b00SSandy Huang 181570913e0SSandy Huang static const int px30_vop_intrs[] = { 182570913e0SSandy Huang FS_INTR, 183570913e0SSandy Huang 0, 0, 184570913e0SSandy Huang LINE_FLAG_INTR, 185570913e0SSandy Huang 0, 186570913e0SSandy Huang BUS_ERROR_INTR, 187570913e0SSandy Huang 0, 0, 188570913e0SSandy Huang DSP_HOLD_VALID_INTR, 189570913e0SSandy Huang }; 190570913e0SSandy Huang 191570913e0SSandy Huang static const struct vop_intr px30_intr = { 192570913e0SSandy Huang .intrs = px30_vop_intrs, 193570913e0SSandy Huang .nintrs = ARRAY_SIZE(px30_vop_intrs), 194a6edf839SSandy Huang .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0), 195a6edf839SSandy Huang .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0), 196a6edf839SSandy Huang .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0), 197a6edf839SSandy Huang .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0), 198570913e0SSandy Huang }; 199570913e0SSandy Huang 200570913e0SSandy Huang static const struct vop_common px30_common = { 201570913e0SSandy Huang .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1), 202570913e0SSandy Huang .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16), 203570913e0SSandy Huang .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14), 204a5c0fa44SUrja Rannikko .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8), 205a5c0fa44SUrja Rannikko .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7), 206a5c0fa44SUrja Rannikko .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6), 207570913e0SSandy Huang .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0), 208570913e0SSandy Huang }; 209570913e0SSandy Huang 210570913e0SSandy Huang static const struct vop_modeset px30_modeset = { 211570913e0SSandy Huang .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), 212570913e0SSandy Huang .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0), 213570913e0SSandy Huang .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), 214570913e0SSandy Huang .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0), 215570913e0SSandy Huang }; 216570913e0SSandy Huang 217570913e0SSandy Huang static const struct vop_output px30_output = { 218570913e0SSandy Huang .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 1), 219570913e0SSandy Huang .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 25), 220570913e0SSandy Huang .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0), 221570913e0SSandy Huang .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24), 222570913e0SSandy Huang }; 223570913e0SSandy Huang 224570913e0SSandy Huang static const struct vop_scl_regs px30_win_scl = { 225570913e0SSandy Huang .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), 226570913e0SSandy Huang .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), 227570913e0SSandy Huang .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), 228570913e0SSandy Huang .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16), 229570913e0SSandy Huang }; 230570913e0SSandy Huang 231570913e0SSandy Huang static const struct vop_win_phy px30_win0_data = { 232570913e0SSandy Huang .scl = &px30_win_scl, 233570913e0SSandy Huang .data_formats = formats_win_full, 234570913e0SSandy Huang .nformats = ARRAY_SIZE(formats_win_full), 235570913e0SSandy Huang .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0), 236570913e0SSandy Huang .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1), 237570913e0SSandy Huang .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12), 238570913e0SSandy Huang .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0), 239570913e0SSandy Huang .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0), 240570913e0SSandy Huang .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0), 241570913e0SSandy Huang .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0), 242570913e0SSandy Huang .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0), 243570913e0SSandy Huang .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0), 244570913e0SSandy Huang .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16), 245570913e0SSandy Huang }; 246570913e0SSandy Huang 247570913e0SSandy Huang static const struct vop_win_phy px30_win1_data = { 248570913e0SSandy Huang .data_formats = formats_win_lite, 249570913e0SSandy Huang .nformats = ARRAY_SIZE(formats_win_lite), 250570913e0SSandy Huang .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0), 251570913e0SSandy Huang .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4), 252570913e0SSandy Huang .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12), 253570913e0SSandy Huang .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0), 254570913e0SSandy Huang .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0), 255570913e0SSandy Huang .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0), 256570913e0SSandy Huang .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0), 257570913e0SSandy Huang }; 258570913e0SSandy Huang 259570913e0SSandy Huang static const struct vop_win_phy px30_win2_data = { 260570913e0SSandy Huang .data_formats = formats_win_lite, 261570913e0SSandy Huang .nformats = ARRAY_SIZE(formats_win_lite), 262a6edf839SSandy Huang .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4), 263a6edf839SSandy Huang .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0), 264570913e0SSandy Huang .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5), 265570913e0SSandy Huang .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20), 266570913e0SSandy Huang .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0), 267570913e0SSandy Huang .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0), 268570913e0SSandy Huang .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0), 269570913e0SSandy Huang .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0), 270570913e0SSandy Huang }; 271570913e0SSandy Huang 272570913e0SSandy Huang static const struct vop_win_data px30_vop_big_win_data[] = { 273570913e0SSandy Huang { .base = 0x00, .phy = &px30_win0_data, 274570913e0SSandy Huang .type = DRM_PLANE_TYPE_PRIMARY }, 275570913e0SSandy Huang { .base = 0x00, .phy = &px30_win1_data, 276570913e0SSandy Huang .type = DRM_PLANE_TYPE_OVERLAY }, 277570913e0SSandy Huang { .base = 0x00, .phy = &px30_win2_data, 278570913e0SSandy Huang .type = DRM_PLANE_TYPE_CURSOR }, 279570913e0SSandy Huang }; 280570913e0SSandy Huang 281570913e0SSandy Huang static const struct vop_data px30_vop_big = { 282570913e0SSandy Huang .intr = &px30_intr, 2838d544233SSandy Huang .feature = VOP_FEATURE_INTERNAL_RGB, 284570913e0SSandy Huang .common = &px30_common, 285570913e0SSandy Huang .modeset = &px30_modeset, 286570913e0SSandy Huang .output = &px30_output, 287570913e0SSandy Huang .win = px30_vop_big_win_data, 288570913e0SSandy Huang .win_size = ARRAY_SIZE(px30_vop_big_win_data), 289570913e0SSandy Huang }; 290570913e0SSandy Huang 291570913e0SSandy Huang static const struct vop_win_data px30_vop_lit_win_data[] = { 292570913e0SSandy Huang { .base = 0x00, .phy = &px30_win1_data, 293570913e0SSandy Huang .type = DRM_PLANE_TYPE_PRIMARY }, 294570913e0SSandy Huang }; 295570913e0SSandy Huang 296570913e0SSandy Huang static const struct vop_data px30_vop_lit = { 297570913e0SSandy Huang .intr = &px30_intr, 2988d544233SSandy Huang .feature = VOP_FEATURE_INTERNAL_RGB, 299570913e0SSandy Huang .common = &px30_common, 300570913e0SSandy Huang .modeset = &px30_modeset, 301570913e0SSandy Huang .output = &px30_output, 302570913e0SSandy Huang .win = px30_vop_lit_win_data, 303570913e0SSandy Huang .win_size = ARRAY_SIZE(px30_vop_lit_win_data), 304570913e0SSandy Huang }; 305570913e0SSandy Huang 306f4a6de85SMark Yao static const struct vop_scl_regs rk3066_win_scl = { 307f4a6de85SMark Yao .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), 308f4a6de85SMark Yao .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), 309f4a6de85SMark Yao .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), 310f4a6de85SMark Yao .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16), 311f4a6de85SMark Yao }; 312f4a6de85SMark Yao 313f4a6de85SMark Yao static const struct vop_win_phy rk3066_win0_data = { 314f4a6de85SMark Yao .scl = &rk3066_win_scl, 315f4a6de85SMark Yao .data_formats = formats_win_full, 316f4a6de85SMark Yao .nformats = ARRAY_SIZE(formats_win_full), 317f4a6de85SMark Yao .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0), 318f4a6de85SMark Yao .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4), 319f4a6de85SMark Yao .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19), 320f4a6de85SMark Yao .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0), 321f4a6de85SMark Yao .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0), 322f4a6de85SMark Yao .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0), 323f4a6de85SMark Yao .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0), 324f4a6de85SMark Yao .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0), 325f4a6de85SMark Yao .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0), 326f4a6de85SMark Yao .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16), 327f4a6de85SMark Yao }; 328f4a6de85SMark Yao 329f4a6de85SMark Yao static const struct vop_win_phy rk3066_win1_data = { 330f4a6de85SMark Yao .scl = &rk3066_win_scl, 331f4a6de85SMark Yao .data_formats = formats_win_full, 332f4a6de85SMark Yao .nformats = ARRAY_SIZE(formats_win_full), 333f4a6de85SMark Yao .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1), 334f4a6de85SMark Yao .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7), 335f4a6de85SMark Yao .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23), 336f4a6de85SMark Yao .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0), 337f4a6de85SMark Yao .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0), 338f4a6de85SMark Yao .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0), 339f4a6de85SMark Yao .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0), 340f4a6de85SMark Yao .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0), 341f4a6de85SMark Yao .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0), 342f4a6de85SMark Yao .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16), 343f4a6de85SMark Yao }; 344f4a6de85SMark Yao 345f4a6de85SMark Yao static const struct vop_win_phy rk3066_win2_data = { 346f4a6de85SMark Yao .data_formats = formats_win_lite, 347f4a6de85SMark Yao .nformats = ARRAY_SIZE(formats_win_lite), 348f4a6de85SMark Yao .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2), 349f4a6de85SMark Yao .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10), 350f4a6de85SMark Yao .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27), 351f4a6de85SMark Yao .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0), 352f4a6de85SMark Yao .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0), 353f4a6de85SMark Yao .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0), 354f4a6de85SMark Yao .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0), 355f4a6de85SMark Yao }; 356f4a6de85SMark Yao 357f4a6de85SMark Yao static const struct vop_modeset rk3066_modeset = { 358f4a6de85SMark Yao .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), 359f4a6de85SMark Yao .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0), 360f4a6de85SMark Yao .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), 361f4a6de85SMark Yao .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0), 362f4a6de85SMark Yao }; 363f4a6de85SMark Yao 364f4a6de85SMark Yao static const struct vop_output rk3066_output = { 365f4a6de85SMark Yao .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4), 366f4a6de85SMark Yao }; 367f4a6de85SMark Yao 368f4a6de85SMark Yao static const struct vop_common rk3066_common = { 369f4a6de85SMark Yao .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1), 370f4a6de85SMark Yao .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0), 371f4a6de85SMark Yao .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0), 372a5c0fa44SUrja Rannikko .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11), 373a5c0fa44SUrja Rannikko .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10), 374f4a6de85SMark Yao .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24), 375f4a6de85SMark Yao }; 376f4a6de85SMark Yao 377f4a6de85SMark Yao static const struct vop_win_data rk3066_vop_win_data[] = { 378f4a6de85SMark Yao { .base = 0x00, .phy = &rk3066_win0_data, 379f4a6de85SMark Yao .type = DRM_PLANE_TYPE_PRIMARY }, 380f4a6de85SMark Yao { .base = 0x00, .phy = &rk3066_win1_data, 381f4a6de85SMark Yao .type = DRM_PLANE_TYPE_OVERLAY }, 382f4a6de85SMark Yao { .base = 0x00, .phy = &rk3066_win2_data, 383f4a6de85SMark Yao .type = DRM_PLANE_TYPE_CURSOR }, 384f4a6de85SMark Yao }; 385f4a6de85SMark Yao 386f4a6de85SMark Yao static const int rk3066_vop_intrs[] = { 387f4a6de85SMark Yao /* 388f4a6de85SMark Yao * hs_start interrupt fires at frame-start, so serves 389f4a6de85SMark Yao * the same purpose as dsp_hold in the driver. 390f4a6de85SMark Yao */ 391f4a6de85SMark Yao DSP_HOLD_VALID_INTR, 392f4a6de85SMark Yao FS_INTR, 393f4a6de85SMark Yao LINE_FLAG_INTR, 394f4a6de85SMark Yao BUS_ERROR_INTR, 395f4a6de85SMark Yao }; 396f4a6de85SMark Yao 397f4a6de85SMark Yao static const struct vop_intr rk3066_intr = { 398f4a6de85SMark Yao .intrs = rk3066_vop_intrs, 399f4a6de85SMark Yao .nintrs = ARRAY_SIZE(rk3066_vop_intrs), 400f4a6de85SMark Yao .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12), 401f4a6de85SMark Yao .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0), 402f4a6de85SMark Yao .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4), 403f4a6de85SMark Yao .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8), 404f4a6de85SMark Yao }; 405f4a6de85SMark Yao 406f4a6de85SMark Yao static const struct vop_data rk3066_vop = { 407f4a6de85SMark Yao .version = VOP_VERSION(2, 1), 408f4a6de85SMark Yao .intr = &rk3066_intr, 409f4a6de85SMark Yao .common = &rk3066_common, 410f4a6de85SMark Yao .modeset = &rk3066_modeset, 411f4a6de85SMark Yao .output = &rk3066_output, 412f4a6de85SMark Yao .win = rk3066_vop_win_data, 413f4a6de85SMark Yao .win_size = ARRAY_SIZE(rk3066_vop_win_data), 414f4a6de85SMark Yao }; 415f4a6de85SMark Yao 416428e15ccSHeiko Stuebner static const struct vop_scl_regs rk3188_win_scl = { 417428e15ccSHeiko Stuebner .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), 418428e15ccSHeiko Stuebner .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), 419428e15ccSHeiko Stuebner .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), 420428e15ccSHeiko Stuebner .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16), 421428e15ccSHeiko Stuebner }; 422428e15ccSHeiko Stuebner 423428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win0_data = { 424428e15ccSHeiko Stuebner .scl = &rk3188_win_scl, 425428e15ccSHeiko Stuebner .data_formats = formats_win_full, 426428e15ccSHeiko Stuebner .nformats = ARRAY_SIZE(formats_win_full), 427428e15ccSHeiko Stuebner .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0), 428428e15ccSHeiko Stuebner .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3), 429428e15ccSHeiko Stuebner .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15), 430428e15ccSHeiko Stuebner .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0), 431428e15ccSHeiko Stuebner .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0), 432428e15ccSHeiko Stuebner .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0), 433428e15ccSHeiko Stuebner .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0), 434428e15ccSHeiko Stuebner .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0), 435428e15ccSHeiko Stuebner .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0), 436428e15ccSHeiko Stuebner }; 437428e15ccSHeiko Stuebner 438428e15ccSHeiko Stuebner static const struct vop_win_phy rk3188_win1_data = { 439428e15ccSHeiko Stuebner .data_formats = formats_win_lite, 440428e15ccSHeiko Stuebner .nformats = ARRAY_SIZE(formats_win_lite), 441428e15ccSHeiko Stuebner .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1), 442428e15ccSHeiko Stuebner .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6), 443428e15ccSHeiko Stuebner .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19), 444428e15ccSHeiko Stuebner /* no act_info on window1 */ 445428e15ccSHeiko Stuebner .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0), 446428e15ccSHeiko Stuebner .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0), 447428e15ccSHeiko Stuebner .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0), 448428e15ccSHeiko Stuebner .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16), 449428e15ccSHeiko Stuebner }; 450428e15ccSHeiko Stuebner 451428e15ccSHeiko Stuebner static const struct vop_modeset rk3188_modeset = { 452428e15ccSHeiko Stuebner .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), 453428e15ccSHeiko Stuebner .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0), 454428e15ccSHeiko Stuebner .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), 455428e15ccSHeiko Stuebner .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0), 456428e15ccSHeiko Stuebner }; 457428e15ccSHeiko Stuebner 458428e15ccSHeiko Stuebner static const struct vop_output rk3188_output = { 459428e15ccSHeiko Stuebner .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4), 460428e15ccSHeiko Stuebner }; 461428e15ccSHeiko Stuebner 462428e15ccSHeiko Stuebner static const struct vop_common rk3188_common = { 463428e15ccSHeiko Stuebner .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31), 464428e15ccSHeiko Stuebner .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30), 465428e15ccSHeiko Stuebner .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0), 466428e15ccSHeiko Stuebner .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0), 467a5c0fa44SUrja Rannikko .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27), 468a5c0fa44SUrja Rannikko .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11), 469a5c0fa44SUrja Rannikko .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10), 470428e15ccSHeiko Stuebner .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24), 471428e15ccSHeiko Stuebner }; 472428e15ccSHeiko Stuebner 473428e15ccSHeiko Stuebner static const struct vop_win_data rk3188_vop_win_data[] = { 474428e15ccSHeiko Stuebner { .base = 0x00, .phy = &rk3188_win0_data, 475428e15ccSHeiko Stuebner .type = DRM_PLANE_TYPE_PRIMARY }, 476428e15ccSHeiko Stuebner { .base = 0x00, .phy = &rk3188_win1_data, 477428e15ccSHeiko Stuebner .type = DRM_PLANE_TYPE_CURSOR }, 478428e15ccSHeiko Stuebner }; 479428e15ccSHeiko Stuebner 480428e15ccSHeiko Stuebner static const int rk3188_vop_intrs[] = { 4814f297df8SHeiko Stuebner /* 4824f297df8SHeiko Stuebner * hs_start interrupt fires at frame-start, so serves 4834f297df8SHeiko Stuebner * the same purpose as dsp_hold in the driver. 4844f297df8SHeiko Stuebner */ 4854f297df8SHeiko Stuebner DSP_HOLD_VALID_INTR, 486428e15ccSHeiko Stuebner FS_INTR, 487428e15ccSHeiko Stuebner LINE_FLAG_INTR, 488428e15ccSHeiko Stuebner BUS_ERROR_INTR, 489428e15ccSHeiko Stuebner }; 490428e15ccSHeiko Stuebner 491428e15ccSHeiko Stuebner static const struct vop_intr rk3188_vop_intr = { 492428e15ccSHeiko Stuebner .intrs = rk3188_vop_intrs, 493428e15ccSHeiko Stuebner .nintrs = ARRAY_SIZE(rk3188_vop_intrs), 494428e15ccSHeiko Stuebner .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12), 495428e15ccSHeiko Stuebner .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0), 496428e15ccSHeiko Stuebner .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4), 497428e15ccSHeiko Stuebner .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8), 498428e15ccSHeiko Stuebner }; 499428e15ccSHeiko Stuebner 500428e15ccSHeiko Stuebner static const struct vop_data rk3188_vop = { 501428e15ccSHeiko Stuebner .intr = &rk3188_vop_intr, 502428e15ccSHeiko Stuebner .common = &rk3188_common, 503428e15ccSHeiko Stuebner .modeset = &rk3188_modeset, 504428e15ccSHeiko Stuebner .output = &rk3188_output, 505428e15ccSHeiko Stuebner .win = rk3188_vop_win_data, 506428e15ccSHeiko Stuebner .win_size = ARRAY_SIZE(rk3188_vop_win_data), 507428e15ccSHeiko Stuebner .feature = VOP_FEATURE_INTERNAL_RGB, 508428e15ccSHeiko Stuebner }; 509428e15ccSHeiko Stuebner 510f7673453SMark Yao static const struct vop_scl_extension rk3288_win_full_scl_ext = { 511f7673453SMark Yao .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), 512f7673453SMark Yao .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), 513f7673453SMark Yao .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28), 514f7673453SMark Yao .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26), 515f7673453SMark Yao .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24), 516f7673453SMark Yao .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23), 517f7673453SMark Yao .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22), 518f7673453SMark Yao .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20), 519f7673453SMark Yao .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18), 520f7673453SMark Yao .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16), 521f7673453SMark Yao .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15), 522f7673453SMark Yao .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12), 523f7673453SMark Yao .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8), 524f7673453SMark Yao .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7), 525f7673453SMark Yao .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6), 526f7673453SMark Yao .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5), 527f7673453SMark Yao .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4), 528f7673453SMark Yao .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2), 529f7673453SMark Yao .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1), 530f7673453SMark Yao .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0), 531f7673453SMark Yao .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5), 5321194fffbSMark Yao }; 5331194fffbSMark Yao 534f7673453SMark Yao static const struct vop_scl_regs rk3288_win_full_scl = { 535f7673453SMark Yao .ext = &rk3288_win_full_scl_ext, 536f7673453SMark Yao .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), 537f7673453SMark Yao .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), 538f7673453SMark Yao .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), 539f7673453SMark Yao .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16), 540a67719d1SMark Yao }; 541a67719d1SMark Yao 542f7673453SMark Yao static const struct vop_win_phy rk3288_win01_data = { 543f7673453SMark Yao .scl = &rk3288_win_full_scl, 544f7673453SMark Yao .data_formats = formats_win_full, 545f7673453SMark Yao .nformats = ARRAY_SIZE(formats_win_full), 546f7673453SMark Yao .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), 547f7673453SMark Yao .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), 548f7673453SMark Yao .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), 549f7673453SMark Yao .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), 550f7673453SMark Yao .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), 551f7673453SMark Yao .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), 552f7673453SMark Yao .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), 553f7673453SMark Yao .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), 554f7673453SMark Yao .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), 555f7673453SMark Yao .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), 556f7673453SMark Yao .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), 557f7673453SMark Yao .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), 5589dd2aca4SMark yao .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), 559a67719d1SMark Yao }; 560a67719d1SMark Yao 561f7673453SMark Yao static const struct vop_win_phy rk3288_win23_data = { 562f7673453SMark Yao .data_formats = formats_win_lite, 563f7673453SMark Yao .nformats = ARRAY_SIZE(formats_win_lite), 56460b7ae7fSMark yao .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4), 56560b7ae7fSMark yao .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0), 566f7673453SMark Yao .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1), 567f7673453SMark Yao .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12), 568f7673453SMark Yao .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0), 569f7673453SMark Yao .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0), 570f7673453SMark Yao .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0), 571f7673453SMark Yao .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0), 572f7673453SMark Yao .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0), 573f7673453SMark Yao .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0), 574a67719d1SMark Yao }; 575a67719d1SMark Yao 5769a61c54bSMark yao static const struct vop_modeset rk3288_modeset = { 577f7673453SMark Yao .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), 578f7673453SMark Yao .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0), 579f7673453SMark Yao .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), 580f7673453SMark Yao .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0), 581f7673453SMark Yao .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0), 582f7673453SMark Yao .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0), 5839a61c54bSMark yao }; 5849a61c54bSMark yao 5859a61c54bSMark yao static const struct vop_output rk3288_output = { 5869a61c54bSMark yao .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4), 5879a61c54bSMark yao .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), 5889a61c54bSMark yao .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), 5899a61c54bSMark yao .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), 5909a61c54bSMark yao .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), 5919a61c54bSMark yao }; 5929a61c54bSMark yao 5939a61c54bSMark yao static const struct vop_common rk3288_common = { 5949a61c54bSMark yao .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22), 5959a61c54bSMark yao .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23), 5969a61c54bSMark yao .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20), 597a5c0fa44SUrja Rannikko .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4), 598a5c0fa44SUrja Rannikko .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3), 599a5c0fa44SUrja Rannikko .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2), 6006bda8112SMark Yao .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1), 6019a61c54bSMark yao .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6), 602b23ab6acSEzequiel Garcia .dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0), 6039a61c54bSMark yao .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19), 6049a61c54bSMark yao .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), 6059a61c54bSMark yao .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0), 6069548e1b4SMark yao .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), 607a67719d1SMark Yao }; 608a67719d1SMark Yao 609a67719d1SMark Yao /* 610a67719d1SMark Yao * Note: rk3288 has a dedicated 'cursor' window, however, that window requires 611a67719d1SMark Yao * special support to get alpha blending working. For now, just use overlay 612a67719d1SMark Yao * window 3 for the drm cursor. 613a67719d1SMark Yao * 614a67719d1SMark Yao */ 615a67719d1SMark Yao static const struct vop_win_data rk3288_vop_win_data[] = { 616f7673453SMark Yao { .base = 0x00, .phy = &rk3288_win01_data, 617f7673453SMark Yao .type = DRM_PLANE_TYPE_PRIMARY }, 618f7673453SMark Yao { .base = 0x40, .phy = &rk3288_win01_data, 619f7673453SMark Yao .type = DRM_PLANE_TYPE_OVERLAY }, 620f7673453SMark Yao { .base = 0x00, .phy = &rk3288_win23_data, 621f7673453SMark Yao .type = DRM_PLANE_TYPE_OVERLAY }, 622f7673453SMark Yao { .base = 0x50, .phy = &rk3288_win23_data, 623f7673453SMark Yao .type = DRM_PLANE_TYPE_CURSOR }, 624a67719d1SMark Yao }; 625a67719d1SMark Yao 626a67719d1SMark Yao static const int rk3288_vop_intrs[] = { 627a67719d1SMark Yao DSP_HOLD_VALID_INTR, 628a67719d1SMark Yao FS_INTR, 629a67719d1SMark Yao LINE_FLAG_INTR, 630a67719d1SMark Yao BUS_ERROR_INTR, 631a67719d1SMark Yao }; 632a67719d1SMark Yao 633a67719d1SMark Yao static const struct vop_intr rk3288_vop_intr = { 634a67719d1SMark Yao .intrs = rk3288_vop_intrs, 635a67719d1SMark Yao .nintrs = ARRAY_SIZE(rk3288_vop_intrs), 636ac6560dfSMark yao .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12), 637f7673453SMark Yao .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0), 638f7673453SMark Yao .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4), 639f7673453SMark Yao .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8), 640a67719d1SMark Yao }; 641a67719d1SMark Yao 642a67719d1SMark Yao static const struct vop_data rk3288_vop = { 643eb5cb6aaSMark yao .version = VOP_VERSION(3, 1), 644efd11cc8SMark yao .feature = VOP_FEATURE_OUTPUT_RGB10, 645a67719d1SMark Yao .intr = &rk3288_vop_intr, 6469a61c54bSMark yao .common = &rk3288_common, 6479a61c54bSMark yao .modeset = &rk3288_modeset, 6489a61c54bSMark yao .output = &rk3288_output, 649a67719d1SMark Yao .win = rk3288_vop_win_data, 650a67719d1SMark Yao .win_size = ARRAY_SIZE(rk3288_vop_win_data), 651b23ab6acSEzequiel Garcia .lut_size = 1024, 652a67719d1SMark Yao }; 653a67719d1SMark Yao 654eb5cb6aaSMark yao static const int rk3368_vop_intrs[] = { 6550a63bfd0SMark Yao FS_INTR, 6560a63bfd0SMark Yao 0, 0, 6570a63bfd0SMark Yao LINE_FLAG_INTR, 6580a63bfd0SMark Yao 0, 6590a63bfd0SMark Yao BUS_ERROR_INTR, 6600a63bfd0SMark Yao 0, 0, 0, 0, 0, 0, 0, 6610a63bfd0SMark Yao DSP_HOLD_VALID_INTR, 662f7673453SMark Yao }; 663f7673453SMark Yao 664eb5cb6aaSMark yao static const struct vop_intr rk3368_vop_intr = { 665eb5cb6aaSMark yao .intrs = rk3368_vop_intrs, 666eb5cb6aaSMark yao .nintrs = ARRAY_SIZE(rk3368_vop_intrs), 667eb5cb6aaSMark yao .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0), 668eb5cb6aaSMark yao .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16), 669eb5cb6aaSMark yao .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0), 670eb5cb6aaSMark yao .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0), 671eb5cb6aaSMark yao .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0), 672eb5cb6aaSMark yao }; 673eb5cb6aaSMark yao 674fbb1c738SEzequiel Garcia static const struct vop_win_phy rk3368_win01_data = { 675fbb1c738SEzequiel Garcia .scl = &rk3288_win_full_scl, 676fbb1c738SEzequiel Garcia .data_formats = formats_win_full, 677fbb1c738SEzequiel Garcia .nformats = ARRAY_SIZE(formats_win_full), 678fbb1c738SEzequiel Garcia .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0), 679fbb1c738SEzequiel Garcia .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1), 680fbb1c738SEzequiel Garcia .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12), 681677e8bbcSDaniele Castagna .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21), 682677e8bbcSDaniele Castagna .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22), 683fbb1c738SEzequiel Garcia .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0), 684fbb1c738SEzequiel Garcia .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0), 685fbb1c738SEzequiel Garcia .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0), 686fbb1c738SEzequiel Garcia .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0), 687fbb1c738SEzequiel Garcia .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0), 688fbb1c738SEzequiel Garcia .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0), 689fbb1c738SEzequiel Garcia .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16), 690fbb1c738SEzequiel Garcia .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0), 691fbb1c738SEzequiel Garcia .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0), 692fbb1c738SEzequiel Garcia .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0), 693fbb1c738SEzequiel Garcia }; 694fbb1c738SEzequiel Garcia 695eb5cb6aaSMark yao static const struct vop_win_phy rk3368_win23_data = { 696eb5cb6aaSMark yao .data_formats = formats_win_lite, 697eb5cb6aaSMark yao .nformats = ARRAY_SIZE(formats_win_lite), 698eb5cb6aaSMark yao .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0), 699eb5cb6aaSMark yao .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4), 700eb5cb6aaSMark yao .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5), 701eb5cb6aaSMark yao .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20), 702677e8bbcSDaniele Castagna .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15), 703eb5cb6aaSMark yao .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0), 704eb5cb6aaSMark yao .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0), 705eb5cb6aaSMark yao .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0), 706eb5cb6aaSMark yao .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0), 707eb5cb6aaSMark yao .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0), 708eb5cb6aaSMark yao .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0), 709eb5cb6aaSMark yao }; 710eb5cb6aaSMark yao 711eb5cb6aaSMark yao static const struct vop_win_data rk3368_vop_win_data[] = { 712fbb1c738SEzequiel Garcia { .base = 0x00, .phy = &rk3368_win01_data, 713eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_PRIMARY }, 714fbb1c738SEzequiel Garcia { .base = 0x40, .phy = &rk3368_win01_data, 715eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_OVERLAY }, 716eb5cb6aaSMark yao { .base = 0x00, .phy = &rk3368_win23_data, 717eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_OVERLAY }, 718eb5cb6aaSMark yao { .base = 0x50, .phy = &rk3368_win23_data, 719eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_CURSOR }, 720eb5cb6aaSMark yao }; 721eb5cb6aaSMark yao 722eb5cb6aaSMark yao static const struct vop_output rk3368_output = { 723eb5cb6aaSMark yao .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16), 724eb5cb6aaSMark yao .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20), 725eb5cb6aaSMark yao .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24), 726eb5cb6aaSMark yao .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28), 727eb5cb6aaSMark yao .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), 728eb5cb6aaSMark yao .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), 729eb5cb6aaSMark yao .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), 730eb5cb6aaSMark yao .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), 731eb5cb6aaSMark yao }; 732eb5cb6aaSMark yao 733eb5cb6aaSMark yao static const struct vop_misc rk3368_misc = { 734eb5cb6aaSMark yao .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11), 735eb5cb6aaSMark yao }; 736eb5cb6aaSMark yao 737eb5cb6aaSMark yao static const struct vop_data rk3368_vop = { 738eb5cb6aaSMark yao .version = VOP_VERSION(3, 2), 739eb5cb6aaSMark yao .intr = &rk3368_vop_intr, 740eb5cb6aaSMark yao .common = &rk3288_common, 741eb5cb6aaSMark yao .modeset = &rk3288_modeset, 742eb5cb6aaSMark yao .output = &rk3368_output, 743eb5cb6aaSMark yao .misc = &rk3368_misc, 744eb5cb6aaSMark yao .win = rk3368_vop_win_data, 745eb5cb6aaSMark yao .win_size = ARRAY_SIZE(rk3368_vop_win_data), 746eb5cb6aaSMark yao }; 747eb5cb6aaSMark yao 748eb5cb6aaSMark yao static const struct vop_intr rk3366_vop_intr = { 749eb5cb6aaSMark yao .intrs = rk3368_vop_intrs, 750eb5cb6aaSMark yao .nintrs = ARRAY_SIZE(rk3368_vop_intrs), 751eb5cb6aaSMark yao .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0), 752eb5cb6aaSMark yao .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16), 753eb5cb6aaSMark yao .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0), 754eb5cb6aaSMark yao .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0), 755eb5cb6aaSMark yao .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0), 756eb5cb6aaSMark yao }; 757eb5cb6aaSMark yao 758eb5cb6aaSMark yao static const struct vop_data rk3366_vop = { 759eb5cb6aaSMark yao .version = VOP_VERSION(3, 4), 760eb5cb6aaSMark yao .intr = &rk3366_vop_intr, 761eb5cb6aaSMark yao .common = &rk3288_common, 762eb5cb6aaSMark yao .modeset = &rk3288_modeset, 763eb5cb6aaSMark yao .output = &rk3368_output, 764eb5cb6aaSMark yao .misc = &rk3368_misc, 765eb5cb6aaSMark yao .win = rk3368_vop_win_data, 766eb5cb6aaSMark yao .win_size = ARRAY_SIZE(rk3368_vop_win_data), 767f7673453SMark Yao }; 768f7673453SMark Yao 7699a61c54bSMark yao static const struct vop_output rk3399_output = { 7709a61c54bSMark yao .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16), 771eb5cb6aaSMark yao .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16), 772eb5cb6aaSMark yao .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20), 773eb5cb6aaSMark yao .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24), 774eb5cb6aaSMark yao .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28), 7759a61c54bSMark yao .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11), 7769a61c54bSMark yao .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), 7779a61c54bSMark yao .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), 7789a61c54bSMark yao .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), 7799a61c54bSMark yao .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), 780cf6d100dSHeiko Stuebner .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3), 7819a61c54bSMark yao }; 7829a61c54bSMark yao 7831c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = { 7841c21aa8fSDaniele Castagna .y2r_coefficients = { 7851c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0), 7861c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16), 7871c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0), 7881c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16), 7891c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0), 7901c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16), 7911c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0), 7921c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16), 7931c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0), 7941c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0), 7951c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0), 7961c21aa8fSDaniele Castagna VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0), 7971c21aa8fSDaniele Castagna }, 7981c21aa8fSDaniele Castagna }; 7991c21aa8fSDaniele Castagna 8001c21aa8fSDaniele Castagna static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { }; 8011c21aa8fSDaniele Castagna 8021c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = { 8031c21aa8fSDaniele Castagna { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data, 8041c21aa8fSDaniele Castagna .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) }, 8051c21aa8fSDaniele Castagna { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data, 8061c21aa8fSDaniele Castagna .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) }, 8071c21aa8fSDaniele Castagna { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data }, 8081c21aa8fSDaniele Castagna { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data }, 8091c21aa8fSDaniele Castagna }; 8101c21aa8fSDaniele Castagna 8110a63bfd0SMark Yao static const struct vop_data rk3399_vop_big = { 812eb5cb6aaSMark yao .version = VOP_VERSION(3, 5), 813efd11cc8SMark yao .feature = VOP_FEATURE_OUTPUT_RGB10, 814eb5cb6aaSMark yao .intr = &rk3366_vop_intr, 8159a61c54bSMark yao .common = &rk3288_common, 8169a61c54bSMark yao .modeset = &rk3288_modeset, 8179a61c54bSMark yao .output = &rk3399_output, 818eb5cb6aaSMark yao .misc = &rk3368_misc, 819eb5cb6aaSMark yao .win = rk3368_vop_win_data, 820eb5cb6aaSMark yao .win_size = ARRAY_SIZE(rk3368_vop_win_data), 8211c21aa8fSDaniele Castagna .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data, 8220a63bfd0SMark Yao }; 8230a63bfd0SMark Yao 8240a63bfd0SMark Yao static const struct vop_win_data rk3399_vop_lit_win_data[] = { 825fbb1c738SEzequiel Garcia { .base = 0x00, .phy = &rk3368_win01_data, 826f7673453SMark Yao .type = DRM_PLANE_TYPE_PRIMARY }, 827eb5cb6aaSMark yao { .base = 0x00, .phy = &rk3368_win23_data, 828f7673453SMark Yao .type = DRM_PLANE_TYPE_CURSOR}, 829f7673453SMark Yao }; 830f7673453SMark Yao 8311c21aa8fSDaniele Castagna static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = { 8321c21aa8fSDaniele Castagna { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data, 8331c21aa8fSDaniele Castagna .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)}, 8341c21aa8fSDaniele Castagna { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data }, 8351c21aa8fSDaniele Castagna }; 8361c21aa8fSDaniele Castagna 8370a63bfd0SMark Yao static const struct vop_data rk3399_vop_lit = { 838eb5cb6aaSMark yao .version = VOP_VERSION(3, 6), 839eb5cb6aaSMark yao .intr = &rk3366_vop_intr, 8409a61c54bSMark yao .common = &rk3288_common, 8419a61c54bSMark yao .modeset = &rk3288_modeset, 8429a61c54bSMark yao .output = &rk3399_output, 843eb5cb6aaSMark yao .misc = &rk3368_misc, 8440a63bfd0SMark Yao .win = rk3399_vop_lit_win_data, 8450a63bfd0SMark Yao .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data), 8461c21aa8fSDaniele Castagna .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data, 847f7673453SMark Yao }; 848f7673453SMark Yao 849eb5cb6aaSMark yao static const struct vop_win_data rk3228_vop_win_data[] = { 850eb5cb6aaSMark yao { .base = 0x00, .phy = &rk3288_win01_data, 851eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_PRIMARY }, 852eb5cb6aaSMark yao { .base = 0x40, .phy = &rk3288_win01_data, 853eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_CURSOR }, 854eb5cb6aaSMark yao }; 855eb5cb6aaSMark yao 856eb5cb6aaSMark yao static const struct vop_data rk3228_vop = { 857eb5cb6aaSMark yao .version = VOP_VERSION(3, 7), 858eb5cb6aaSMark yao .feature = VOP_FEATURE_OUTPUT_RGB10, 859eb5cb6aaSMark yao .intr = &rk3366_vop_intr, 860eb5cb6aaSMark yao .common = &rk3288_common, 861eb5cb6aaSMark yao .modeset = &rk3288_modeset, 862eb5cb6aaSMark yao .output = &rk3399_output, 863eb5cb6aaSMark yao .misc = &rk3368_misc, 864eb5cb6aaSMark yao .win = rk3228_vop_win_data, 865eb5cb6aaSMark yao .win_size = ARRAY_SIZE(rk3228_vop_win_data), 866eb5cb6aaSMark yao }; 867eb5cb6aaSMark yao 868eb5cb6aaSMark yao static const struct vop_modeset rk3328_modeset = { 869eb5cb6aaSMark yao .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), 870eb5cb6aaSMark yao .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0), 871eb5cb6aaSMark yao .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), 872eb5cb6aaSMark yao .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0), 873eb5cb6aaSMark yao .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0), 874eb5cb6aaSMark yao .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0), 875eb5cb6aaSMark yao }; 876eb5cb6aaSMark yao 877eb5cb6aaSMark yao static const struct vop_output rk3328_output = { 878eb5cb6aaSMark yao .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12), 879eb5cb6aaSMark yao .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13), 880eb5cb6aaSMark yao .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14), 881eb5cb6aaSMark yao .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15), 882eb5cb6aaSMark yao .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16), 883eb5cb6aaSMark yao .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20), 884eb5cb6aaSMark yao .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24), 885eb5cb6aaSMark yao .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28), 886eb5cb6aaSMark yao }; 887eb5cb6aaSMark yao 888eb5cb6aaSMark yao static const struct vop_misc rk3328_misc = { 889eb5cb6aaSMark yao .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11), 890eb5cb6aaSMark yao }; 891eb5cb6aaSMark yao 892eb5cb6aaSMark yao static const struct vop_common rk3328_common = { 893eb5cb6aaSMark yao .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22), 894a5c0fa44SUrja Rannikko .dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4), 895a5c0fa44SUrja Rannikko .dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3), 896a5c0fa44SUrja Rannikko .dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2), 897a5c0fa44SUrja Rannikko .pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1), 898eb5cb6aaSMark yao .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6), 899eb5cb6aaSMark yao .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18), 900eb5cb6aaSMark yao .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), 901eb5cb6aaSMark yao .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), 902eb5cb6aaSMark yao }; 903eb5cb6aaSMark yao 904eb5cb6aaSMark yao static const struct vop_intr rk3328_vop_intr = { 905eb5cb6aaSMark yao .intrs = rk3368_vop_intrs, 906eb5cb6aaSMark yao .nintrs = ARRAY_SIZE(rk3368_vop_intrs), 907eb5cb6aaSMark yao .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0), 908eb5cb6aaSMark yao .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16), 909eb5cb6aaSMark yao .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0), 910eb5cb6aaSMark yao .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0), 911eb5cb6aaSMark yao .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0), 912eb5cb6aaSMark yao }; 913eb5cb6aaSMark yao 914eb5cb6aaSMark yao static const struct vop_win_data rk3328_vop_win_data[] = { 915fbb1c738SEzequiel Garcia { .base = 0xd0, .phy = &rk3368_win01_data, 916eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_PRIMARY }, 917fbb1c738SEzequiel Garcia { .base = 0x1d0, .phy = &rk3368_win01_data, 918eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_OVERLAY }, 919fbb1c738SEzequiel Garcia { .base = 0x2d0, .phy = &rk3368_win01_data, 920eb5cb6aaSMark yao .type = DRM_PLANE_TYPE_CURSOR }, 921eb5cb6aaSMark yao }; 922eb5cb6aaSMark yao 923eb5cb6aaSMark yao static const struct vop_data rk3328_vop = { 924eb5cb6aaSMark yao .version = VOP_VERSION(3, 8), 925eb5cb6aaSMark yao .feature = VOP_FEATURE_OUTPUT_RGB10, 926eb5cb6aaSMark yao .intr = &rk3328_vop_intr, 927eb5cb6aaSMark yao .common = &rk3328_common, 928eb5cb6aaSMark yao .modeset = &rk3328_modeset, 929eb5cb6aaSMark yao .output = &rk3328_output, 930eb5cb6aaSMark yao .misc = &rk3328_misc, 931eb5cb6aaSMark yao .win = rk3328_vop_win_data, 932eb5cb6aaSMark yao .win_size = ARRAY_SIZE(rk3328_vop_win_data), 933eb5cb6aaSMark yao }; 934eb5cb6aaSMark yao 935a67719d1SMark Yao static const struct of_device_id vop_driver_dt_match[] = { 936f7673453SMark Yao { .compatible = "rockchip,rk3036-vop", 937f7673453SMark Yao .data = &rk3036_vop }, 938460c3b00SSandy Huang { .compatible = "rockchip,rk3126-vop", 939460c3b00SSandy Huang .data = &rk3126_vop }, 940570913e0SSandy Huang { .compatible = "rockchip,px30-vop-big", 941570913e0SSandy Huang .data = &px30_vop_big }, 942570913e0SSandy Huang { .compatible = "rockchip,px30-vop-lit", 943570913e0SSandy Huang .data = &px30_vop_lit }, 944f4a6de85SMark Yao { .compatible = "rockchip,rk3066-vop", 945f4a6de85SMark Yao .data = &rk3066_vop }, 946428e15ccSHeiko Stuebner { .compatible = "rockchip,rk3188-vop", 947428e15ccSHeiko Stuebner .data = &rk3188_vop }, 948b51502adSMark Yao { .compatible = "rockchip,rk3288-vop", 949b51502adSMark Yao .data = &rk3288_vop }, 950eb5cb6aaSMark yao { .compatible = "rockchip,rk3368-vop", 951eb5cb6aaSMark yao .data = &rk3368_vop }, 952eb5cb6aaSMark yao { .compatible = "rockchip,rk3366-vop", 953eb5cb6aaSMark yao .data = &rk3366_vop }, 9540a63bfd0SMark Yao { .compatible = "rockchip,rk3399-vop-big", 9550a63bfd0SMark Yao .data = &rk3399_vop_big }, 9560a63bfd0SMark Yao { .compatible = "rockchip,rk3399-vop-lit", 9570a63bfd0SMark Yao .data = &rk3399_vop_lit }, 958eb5cb6aaSMark yao { .compatible = "rockchip,rk3228-vop", 959eb5cb6aaSMark yao .data = &rk3228_vop }, 960eb5cb6aaSMark yao { .compatible = "rockchip,rk3328-vop", 961eb5cb6aaSMark yao .data = &rk3328_vop }, 962a67719d1SMark Yao {}, 963a67719d1SMark Yao }; 964a67719d1SMark Yao MODULE_DEVICE_TABLE(of, vop_driver_dt_match); 965a67719d1SMark Yao 966a67719d1SMark Yao static int vop_probe(struct platform_device *pdev) 967a67719d1SMark Yao { 968a67719d1SMark Yao struct device *dev = &pdev->dev; 969a67719d1SMark Yao 970a67719d1SMark Yao if (!dev->of_node) { 971d8dd6804SHaneen Mohammed DRM_DEV_ERROR(dev, "can't find vop devices\n"); 972a67719d1SMark Yao return -ENODEV; 973a67719d1SMark Yao } 974a67719d1SMark Yao 975a67719d1SMark Yao return component_add(dev, &vop_component_ops); 976a67719d1SMark Yao } 977a67719d1SMark Yao 978a67719d1SMark Yao static int vop_remove(struct platform_device *pdev) 979a67719d1SMark Yao { 980a67719d1SMark Yao component_del(&pdev->dev, &vop_component_ops); 981a67719d1SMark Yao 982a67719d1SMark Yao return 0; 983a67719d1SMark Yao } 984a67719d1SMark Yao 9858820b68bSJeffy Chen struct platform_driver vop_platform_driver = { 986a67719d1SMark Yao .probe = vop_probe, 987a67719d1SMark Yao .remove = vop_remove, 988a67719d1SMark Yao .driver = { 989a67719d1SMark Yao .name = "rockchip-vop", 990a67719d1SMark Yao .of_match_table = of_match_ptr(vop_driver_dt_match), 991a67719d1SMark Yao }, 992a67719d1SMark Yao }; 993