Merge remote-tracking branch 'lightnvm/for-next'
[deliverable/linux.git] / drivers / gpu / drm / rockchip / rockchip_vop_reg.c
index 919992cdc97e32f190b285f874c8c3944dd93ea3..35c51f3402f2973f0ea1305cd27073db950cc356 100644 (file)
 #define VOP_REG(off, _mask, s) \
                {.offset = off, \
                 .mask = _mask, \
-                .shift = s,}
+                .shift = s, \
+                .write_mask = false,}
+
+#define VOP_REG_MASK(off, _mask, s) \
+               {.offset = off, \
+                .mask = _mask, \
+                .shift = s, \
+                .write_mask = true,}
 
 static const uint32_t formats_win_full[] = {
        DRM_FORMAT_XRGB8888,
@@ -50,6 +57,89 @@ static const uint32_t formats_win_lite[] = {
        DRM_FORMAT_BGR565,
 };
 
+static const struct vop_scl_regs rk3036_win_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_win_phy rk3036_win0_data = {
+       .scl = &rk3036_win_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),
+};
+
+static const struct vop_win_phy rk3036_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),
+       .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),
+};
+
+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_CURSOR },
+};
+
+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),
+       .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),
+       .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
+       .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
+       .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
+       .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
+       .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
+       .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
+       .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
+       .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
+};
+
+static const struct vop_reg_data rk3036_vop_init_reg_table[] = {
+       {RK3036_DSP_CTRL1, 0x00000000},
+};
+
+static const struct vop_data rk3036_vop = {
+       .init_table = rk3036_vop_init_reg_table,
+       .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
+       .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_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),
@@ -133,6 +223,7 @@ static const struct vop_ctrl rk3288_ctrl_data = {
        .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 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),
+       .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
        .cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
 };
 
@@ -190,93 +281,104 @@ static const struct vop_data rk3288_vop = {
        .win_size = ARRAY_SIZE(rk3288_vop_win_data),
 };
 
-static const struct vop_scl_regs rk3036_win_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_win_phy rk3036_win0_data = {
-       .scl = &rk3036_win_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),
+static const struct vop_ctrl rk3399_ctrl_data = {
+       .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22),
+       .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
+       .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12),
+       .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13),
+       .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14),
+       .mipi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 15),
+       .dither_down = VOP_REG(RK3399_DSP_CTRL1, 0xf, 1),
+       .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
+       .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
+       .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
+       .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
+       .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20),
+       .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24),
+       .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28),
+       .htotal_pw = VOP_REG(RK3399_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
+       .hact_st_end = VOP_REG(RK3399_DSP_HACT_ST_END, 0x1fff1fff, 0),
+       .vtotal_pw = VOP_REG(RK3399_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
+       .vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
+       .hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
+       .vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
+       .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 0),
+       .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 16),
+       .cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
 };
 
-static const struct vop_win_phy rk3036_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),
-       .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),
-};
-
-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_CURSOR },
-};
-
-static const int rk3036_vop_intrs[] = {
-       DSP_HOLD_VALID_INTR,
+static const int rk3399_vop_intrs[] = {
        FS_INTR,
+       0, 0,
        LINE_FLAG_INTR,
+       0,
        BUS_ERROR_INTR,
+       0, 0, 0, 0, 0, 0, 0,
+       DSP_HOLD_VALID_INTR,
 };
 
-static const struct vop_intr rk3036_intr = {
-       .intrs = rk3036_vop_intrs,
-       .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
-       .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_intr rk3399_vop_intr = {
+       .intrs = rk3399_vop_intrs,
+       .nintrs = ARRAY_SIZE(rk3399_vop_intrs),
+       .status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0xffff, 0),
+       .enable = VOP_REG_MASK(RK3399_INTR_EN0, 0xffff, 0),
+       .clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0xffff, 0),
 };
 
-static const struct vop_ctrl rk3036_ctrl_data = {
-       .standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30),
-       .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
-       .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
-       .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
-       .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
-       .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
-       .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
-       .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
+static const struct vop_reg_data rk3399_init_reg_table[] = {
+       {RK3399_SYS_CTRL, 0x2000f800},
+       {RK3399_DSP_CTRL0, 0x00000000},
+       {RK3399_WIN0_CTRL0, 0x00000080},
+       {RK3399_WIN1_CTRL0, 0x00000080},
+       /* TODO: Win2/3 support multiple area function, but we haven't found
+        * a suitable way to use it yet, so let's just use them as other windows
+        * with only area 0 enabled.
+        */
+       {RK3399_WIN2_CTRL0, 0x00000010},
+       {RK3399_WIN3_CTRL0, 0x00000010},
 };
 
-static const struct vop_reg_data rk3036_vop_init_reg_table[] = {
-       {RK3036_DSP_CTRL1, 0x00000000},
+static const struct vop_data rk3399_vop_big = {
+       .init_table = rk3399_init_reg_table,
+       .table_size = ARRAY_SIZE(rk3399_init_reg_table),
+       .intr = &rk3399_vop_intr,
+       .ctrl = &rk3399_ctrl_data,
+       /*
+        * rk3399 vop big windows register layout is same as rk3288.
+        */
+       .win = rk3288_vop_win_data,
+       .win_size = ARRAY_SIZE(rk3288_vop_win_data),
 };
 
-static const struct vop_data rk3036_vop = {
-       .init_table = rk3036_vop_init_reg_table,
-       .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
-       .ctrl = &rk3036_ctrl_data,
-       .intr = &rk3036_intr,
-       .win = rk3036_vop_win_data,
-       .win_size = ARRAY_SIZE(rk3036_vop_win_data),
+static const struct vop_win_data rk3399_vop_lit_win_data[] = {
+       { .base = 0x00, .phy = &rk3288_win01_data,
+         .type = DRM_PLANE_TYPE_PRIMARY },
+       { .base = 0x00, .phy = &rk3288_win23_data,
+         .type = DRM_PLANE_TYPE_CURSOR},
+};
+
+static const struct vop_data rk3399_vop_lit = {
+       .init_table = rk3399_init_reg_table,
+       .table_size = ARRAY_SIZE(rk3399_init_reg_table),
+       .intr = &rk3399_vop_intr,
+       .ctrl = &rk3399_ctrl_data,
+       /*
+        * rk3399 vop lit windows register layout is same as rk3288,
+        * but cut off the win1 and win3 windows.
+        */
+       .win = rk3399_vop_lit_win_data,
+       .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
 };
 
 static const struct of_device_id vop_driver_dt_match[] = {
-       { .compatible = "rockchip,rk3288-vop",
-         .data = &rk3288_vop },
        { .compatible = "rockchip,rk3036-vop",
          .data = &rk3036_vop },
+       { .compatible = "rockchip,rk3288-vop",
+         .data = &rk3288_vop },
+       { .compatible = "rockchip,rk3399-vop-big",
+         .data = &rk3399_vop_big },
+       { .compatible = "rockchip,rk3399-vop-lit",
+         .data = &rk3399_vop_lit },
        {},
 };
 MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
@@ -305,7 +407,6 @@ static struct platform_driver vop_platform_driver = {
        .remove = vop_remove,
        .driver = {
                .name = "rockchip-vop",
-               .owner = THIS_MODULE,
                .of_match_table = of_match_ptr(vop_driver_dt_match),
        },
 };
This page took 0.030796 seconds and 5 git commands to generate.