VIO6 is an older version of the VSP1 used by many of the current
Renesas R-Car/R-Mobile SoCs.
This patch just handles the differences between VSP1 and VIO6,
by adjusting the offset of some registers and the DPR register
operation.

Signed-off-by: Katsuya Matsubara <ma...@igel.co.jp>
---
 drivers/media/platform/vsp1/vsp1.h      |    1 +
 drivers/media/platform/vsp1/vsp1_drv.c  |  226 +++++++++++++++++++++++++++++--
 drivers/media/platform/vsp1/vsp1_regs.h |    8 ++
 drivers/media/platform/vsp1/vsp1_rpf.c  |    5 +
 drivers/media/platform/vsp1/vsp1_wpf.c  |    6 +-
 5 files changed, 230 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h 
b/drivers/media/platform/vsp1/vsp1.h
index 31c24a3..efd8085 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -51,6 +51,7 @@ struct vsp1_device {
 
        struct mutex lock;
        int ref_count;
+       bool is_vio6;
 
        struct vsp1_lif *lif;
        struct vsp1_rwpf *rpf[VPS1_MAX_RPF];
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c 
b/drivers/media/platform/vsp1/vsp1_drv.c
index c24f43f..d685d72 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -241,11 +241,21 @@ static void vsp1_device_init(struct vsp1_device *vsp1)
        u32 status;
        u32 route_unused = vsp1->routes[VI6_DPR_NODE_UNUSED].id;
        u32 val;
-       const u32 fporch_fp[VPS1_MAX_WPF] = {
-               (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
-               (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
-               (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
-               (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
+       const u32 fporch_fp[][VPS1_MAX_WPF] = {
+               {
+                       (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
+                       (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
+                       (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
+                       (VI6_DPR_WPF_FPORCH_FP_WPFN << 8),
+               },
+               {
+                       0,
+                       0,
+                       (VI6_DPR_WPF_FPORCH_FP_WPFN << 16) |
+                       (VI6_DPR_WPF_FPORCH_FP_WPFN <<  8) |
+                       (VI6_DPR_WPF_FPORCH_FP_WPFN <<  0),
+                       VI6_DPR_WPF_FPORCH_FP_WPFN << 24,
+               },
        };
 
        /* Reset any channel that might be running. */
@@ -312,12 +322,17 @@ static void vsp1_device_init(struct vsp1_device *vsp1)
        vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, val);
 
        for (i = 0; i < VPS1_MAX_WPF; ++i)
-               vsp1_write(vsp1, VI6_DPR_WPF_FPORCH0 + i, fporch_fp[i]);
-
-       vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
-                  (route_unused << VI6_DPR_SMPPT_PT_SHIFT));
-       vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
-                  (route_unused << VI6_DPR_SMPPT_PT_SHIFT));
+               vsp1_write(vsp1, VI6_DPR_WPF_FPORCH0 + i,
+                          fporch_fp[vsp1->is_vio6 ? 1 : 0][i]);
+
+       if (!vsp1->is_vio6) {
+               vsp1_write(vsp1, VI6_DPR_HGO_SMPPT,
+                          (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
+                          (route_unused << VI6_DPR_SMPPT_PT_SHIFT));
+               vsp1_write(vsp1, VI6_DPR_HGT_SMPPT,
+                          (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
+                          (route_unused << VI6_DPR_SMPPT_PT_SHIFT));
+       }
 }
 
 /*
@@ -651,7 +666,147 @@ static const struct vsp1_dpr_route vsp1_routes[] = {
        [VI6_DPR_NODE_UNUSED]   = { 63, 0, 0 },
 };
 
-static int vsp1_probe(struct platform_device *pdev)
+static const unsigned int vio6_reg_offs[] = {
+       [VI6_CMD0]              = 0x0000,
+       [VI6_CMD1]              = 0x0000 + 1 * 4,
+       [VI6_CMD2]              = 0x0000 + 2 * 4,
+       [VI6_CMD3]              = 0x0000 + 3 * 4,
+       [VI6_SRESET]            = 0x0018,
+       [VI6_STATUS]            = 0x0020,
+       [VI6_WPF_IRQ_ENB0]      = 0x0030,
+       [VI6_WPF_IRQ_ENB1]      = 0x0030 + 1 * 12,
+       [VI6_WPF_IRQ_ENB2]      = 0x0030 + 2 * 12,
+       [VI6_WPF_IRQ_ENB3]      = 0x0030 + 3 * 12,
+       [VI6_WPF_IRQ_STA0]      = 0x0034,
+       [VI6_WPF_IRQ_STA1]      = 0x0034 + 1 * 12,
+       [VI6_WPF_IRQ_STA2]      = 0x0034 + 2 * 12,
+       [VI6_WPF_IRQ_STA3]      = 0x0034 + 3 * 12,
+
+       [VI6_RPF_SRC_BSIZE]     = 0x0300,
+       [VI6_RPF_SRC_ESIZE]     = 0x0304,
+       [VI6_RPF_INFMT]         = 0x0308,
+       [VI6_RPF_DSWAP]         = 0x030c,
+       [VI6_RPF_LOC]           = 0x0310,
+       [VI6_RPF_ALPH_SEL]      = 0x0314,
+       [VI6_RPF_VRTCOL_SET]    = 0x0318,
+       [VI6_RPF_MSK_CTRL]      = 0x031c,
+       [VI6_RPF_MSK_SET0]      = 0x0320,
+       [VI6_RPF_MSK_SET1]      = 0x0324,
+       [VI6_RPF_CKEY_CTRL]     = 0x0328,
+       [VI6_RPF_CKEY_SET0]     = 0x032c,
+       [VI6_RPF_CKEY_SET1]     = 0x0330,
+       [VI6_RPF_SRCM_PSTRIDE]  = 0x0364,
+       [VI6_RPF_SRCM_ASTRIDE]  = 0x0368,
+       [VI6_RPF_SRCM_ADDR_Y]   = 0x036c,
+       [VI6_RPF_SRCM_ADDR_C0]  = 0x0370,
+       [VI6_RPF_SRCM_ADDR_C1]  = 0x0374,
+       [VI6_RPF_SRCM_ADDR_AI]  = 0x0378,
+       [VI6_RPF_CHPRI_CTRL]    = 0x0380,
+
+       [VI6_WPF_SRCRPF]        = 0x1000,
+       [VI6_WPF_HSZCLIP]       = 0x1004,
+       [VI6_WPF_VSZCLIP]       = 0x1008,
+       [VI6_WPF_OUTFMT]        = 0x100c,
+       [VI6_WPF_DSWAP]         = 0x1010,
+       [VI6_WPF_RNDCTRL]       = 0x1014,
+       [VI6_WPF_DSTM_STRIDE_Y] = 0x104c,
+       [VI6_WPF_DSTM_STRIDE_C] = 0x1050,
+       [VI6_WPF_DSTM_ADDR_Y]   = 0x1054,
+       [VI6_WPF_DSTM_ADDR_C0]  = 0x1058,
+       [VI6_WPF_DSTM_ADDR_C1]  = 0x105c,
+       [VI6_WPF_CHPRI_CTRL]    = 0x1060,
+
+#define VI6_DPR_CTRL(n)                (0x2000 + (n) * 4)
+       [VI6_DPR_RPF_ROUTE0]    = VI6_DPR_CTRL(0),
+       [VI6_DPR_RPF_ROUTE1]    = VI6_DPR_CTRL(0),
+       [VI6_DPR_RPF_ROUTE2]    = VI6_DPR_CTRL(0),
+       [VI6_DPR_RPF_ROUTE3]    = VI6_DPR_CTRL(0),
+       [VI6_DPR_RPF_ROUTE4]    = VI6_DPR_CTRL(1),
+       [VI6_DPR_FXA0]          = 0x2010,
+       [VI6_DPR_FXA1]          = 0x2014,
+       [VI6_DPR_WPF_FPORCH0]   = 0x2018,
+       [VI6_DPR_WPF_FPORCH1]   = 0x2018 + 1 * 4,
+       [VI6_DPR_WPF_FPORCH2]   = 0x2018 + 2 * 4,
+       [VI6_DPR_WPF_FPORCH3]   = 0x2018 + 3 * 4,
+       [VI6_DPR_SRU_ROUTE]     = VI6_DPR_CTRL(1),
+       [VI6_DPR_UDS_ROUTE0]    = VI6_DPR_CTRL(1),
+       [VI6_DPR_UDS_ROUTE1]    = VI6_DPR_CTRL(2),
+       [VI6_DPR_LUT_ROUTE]     = VI6_DPR_CTRL(2),
+       [VI6_DPR_CLU_ROUTE]     = VI6_DPR_CTRL(2),
+       [VI6_DPR_HST_ROUTE]     = VI6_DPR_CTRL(2),
+       [VI6_DPR_HSI_ROUTE]     = VI6_DPR_CTRL(3),
+       [VI6_DPR_BRU_ROUTE]     = VI6_DPR_CTRL(3),
+
+       [VI6_SRU_CTRL0]         = 0x2200,
+       [VI6_SRU_CTRL1]         = 0x2204,
+       [VI6_SRU_CTRL2]         = 0x2208,
+
+       [VI6_UDS_CTRL]          = 0x2300,
+       [VI6_UDS_SCALE]         = 0x2304,
+       [VI6_UDS_ALPTH]         = 0x2308,
+       [VI6_UDS_ALPVAL]        = 0x230c,
+       [VI6_UDS_PASS_BWIDTH]   = 0x2310,
+       [VI6_UDS_CLIP_SIZE]     = 0x2324,
+       [VI6_UDS_FILL_COLOR]    = 0x2328,
+
+       [VI6_LUT_CTRL]          = 0x2600,
+
+       [VI6_CLU_CTRL]          = 0x2700,
+
+       [VI6_HST_CTRL]          = 0x2800,
+
+       [VI6_HSI_CTRL]          = 0x2900,
+
+       [VI6_BRU_INCTRL]        = 0x2a00,
+       [VI6_BRU_VIRRPF_SIZE]   = 0x2a04,
+       [VI6_BRU_VIRRPF_LOC]    = 0x2a08,
+       [VI6_BRU_VIRRPF_COL]    = 0x2a0c,
+       [VI6_BRU_CTRLA]         = 0x2a10,
+       [VI6_BRU_CTRLB]         = 0x2a10 + 1 * 8,
+       [VI6_BRU_CTRLC]         = 0x2a10 + 2 * 8,
+       [VI6_BRU_CTRLD]         = 0x2a10 + 3 * 8,
+       [VI6_BRU_BLDA]          = 0x2a14,
+       [VI6_BRU_BLDB]          = 0x2a14 + 1 * 8,
+       [VI6_BRU_BLDC]          = 0x2a14 + 2 * 8,
+       [VI6_BRU_BLDD]          = 0x2a14 + 3 * 8,
+       [VI6_BRU_ROP]           = 0x2a30,
+
+       [VI6_CLUT_TABLE]        = 0x4800,
+
+       [VI6_LUT_TABLE]         = 0x7000,
+
+       [VI6_CLU_ADDR]          = 0x7400,
+       [VI6_CLU_DATA]          = 0x7404,
+};
+
+static const struct vsp1_dpr_route vio6_routes[] = {
+       [VI6_DPR_NODE_RPF0]     = {  0, VI6_DPR_RPF_ROUTE0, 24 },
+       [VI6_DPR_NODE_RPF1]     = {  1, VI6_DPR_RPF_ROUTE0 + 1, 16 },
+       [VI6_DPR_NODE_RPF2]     = {  2, VI6_DPR_RPF_ROUTE0 + 2, 8 },
+       [VI6_DPR_NODE_RPF3]     = {  3, VI6_DPR_RPF_ROUTE0 + 3, 0 },
+       [VI6_DPR_NODE_RPF4]     = {  4, VI6_DPR_RPF_ROUTE0 + 4, 24 },
+       [VI6_DPR_NODE_SRU]      = {  8, VI6_DPR_SRU_ROUTE, 16 },
+       [VI6_DPR_NODE_UDS0]     = {  9, VI6_DPR_UDS_ROUTE0, 8 },
+       [VI6_DPR_NODE_UDS1]     = { 22, VI6_DPR_UDS_ROUTE0 + 1, 8 },
+       [VI6_DPR_NODE_LUT]      = { 12, VI6_DPR_LUT_ROUTE, 16 },
+       [VI6_DPR_NODE_BRU_IN0]  = { 13, 0, 0 },
+       [VI6_DPR_NODE_BRU_IN1]  = { 14, 0, 0 },
+       [VI6_DPR_NODE_BRU_IN2]  = { 15, 0, 0 },
+       [VI6_DPR_NODE_BRU_IN3]  = { 16, 0, 0 },
+       [VI6_DPR_NODE_BRU_OUT]  = { 17, VI6_DPR_BRU_ROUTE, 16 },
+       [VI6_DPR_NODE_CLU]      = { 19, VI6_DPR_CLU_ROUTE, 8 },
+       [VI6_DPR_NODE_HST]      = { 20, VI6_DPR_HST_ROUTE, 0 },
+       [VI6_DPR_NODE_HSI]      = { 21, VI6_DPR_HSI_ROUTE, 24 },
+       [VI6_DPR_NODE_WPF0]     = { 26, 0, 0 },
+       [VI6_DPR_NODE_WPF1]     = { 27, 0, 0 },
+       [VI6_DPR_NODE_WPF2]     = { 28, 0, 0 },
+       [VI6_DPR_NODE_WPF3]     = { 29, 0, 0 },
+       [VI6_DPR_NODE_UNUSED]   = { 31, 0, 0 },
+};
+
+static int _vsp1_probe(struct platform_device *pdev,
+                      const unsigned int *reg_offs,
+                      const struct vsp1_dpr_route *routes, bool is_vio6)
 {
        struct vsp1_device *vsp1;
        struct resource *irq;
@@ -664,8 +819,9 @@ static int vsp1_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       vsp1->reg_offs = vsp1_reg_offs;
-       vsp1->routes = vsp1_routes;
+       vsp1->reg_offs = reg_offs;
+       vsp1->routes = routes;
+       vsp1->is_vio6 = is_vio6;
 
        vsp1->dev = &pdev->dev;
        mutex_init(&vsp1->lock);
@@ -715,6 +871,17 @@ static int vsp1_probe(struct platform_device *pdev)
        return 0;
 }
 
+static int vsp1_probe(struct platform_device *pdev)
+{
+       return _vsp1_probe(pdev, vsp1_reg_offs, vsp1_routes, false);
+}
+
+static int vio6_probe(struct platform_device *pdev)
+{
+       return _vsp1_probe(pdev, vio6_reg_offs, vio6_routes, true);
+}
+
+
 static int vsp1_remove(struct platform_device *pdev)
 {
        struct vsp1_device *vsp1 = platform_get_drvdata(pdev);
@@ -734,7 +901,36 @@ static struct platform_driver vsp1_platform_driver = {
        },
 };
 
-module_platform_driver(vsp1_platform_driver);
+static struct platform_driver vio6_platform_driver = {
+       .probe          = vio6_probe,
+       .remove         = vsp1_remove,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "vio6",
+               .pm     = &vsp1_pm_ops,
+       },
+};
+
+static int __init vsp1_platform_driver_init(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&vsp1_platform_driver);
+       if (ret)
+               return ret;
+       ret = platform_driver_register(&vio6_platform_driver);
+       if (ret)
+               platform_driver_unregister(&vsp1_platform_driver);
+       return ret;
+}
+module_init(vsp1_platform_driver_init);
+
+static void __exit vsp1_platform_driver_exit(void)
+{
+       platform_driver_unregister(&vio6_platform_driver);
+       platform_driver_unregister(&vsp1_platform_driver);
+}
+module_exit(vsp1_platform_driver_exit);
 
 MODULE_ALIAS("vsp1");
 MODULE_AUTHOR("Laurent Pinchart <laurent.pinch...@ideasonboard.com>");
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h 
b/drivers/media/platform/vsp1/vsp1_regs.h
index bd9f72e..3885aee 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -76,6 +76,7 @@ enum {
        VI6_RPF_SRCM_ADDR_C0,
        VI6_RPF_SRCM_ADDR_C1,
        VI6_RPF_SRCM_ADDR_AI,
+       VI6_RPF_CHPRI_CTRL,     /* for VIO6 */
 
 /* 
-----------------------------------------------------------------------------
  * WPF Control Registers
@@ -93,6 +94,7 @@ enum {
        VI6_WPF_DSTM_ADDR_C0,
        VI6_WPF_DSTM_ADDR_C1,
        VI6_WPF_WRBCK_CTRL,
+       VI6_WPF_CHPRI_CTRL,     /* for VIO6 */
 
 /* 
-----------------------------------------------------------------------------
  * DPR Control Registers
@@ -118,6 +120,8 @@ enum {
        VI6_DPR_BRU_ROUTE,
        VI6_DPR_HGO_SMPPT,
        VI6_DPR_HGT_SMPPT,
+       VI6_DPR_FXA0,           /* for VIO6 */
+       VI6_DPR_FXA1,           /* for VIO6 */
 
 /* 
-----------------------------------------------------------------------------
  * SRU Control Registers
@@ -445,6 +449,8 @@ enum {
 
 #define VI6_RPF_SRCM_PSTRIDE_A_SHIFT   0
 
+#define VI6_RPF_CHPRI_CTRL_ICBP                (1 << 16)       /* for VIO6 */
+
 /* 
-----------------------------------------------------------------------------
  * Macros for WPF Control Registers
  */
@@ -503,6 +509,8 @@ enum {
 
 #define VI6_WPF_WRBCK_CTRL_WBMD                (1 << 0)
 
+#define VI6_WPF_CHPRI_CTRL_ICBP                (1 << 16)       /* for VIO6 */
+
 /* 
-----------------------------------------------------------------------------
  * Macros for DPR Control Registers
  */
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c 
b/drivers/media/platform/vsp1/vsp1_rpf.c
index d469cc8..561ab6a 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -45,6 +45,7 @@ static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, int 
reg, u32 data)
 static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
 {
        struct vsp1_rwpf *rpf = to_rwpf(subdev);
+       struct vsp1_device *vsp1 = rpf->entity.vsp1;
        const struct vsp1_format_info *fmtinfo = rpf->video.fmtinfo;
        const struct v4l2_pix_format_mplane *format = &rpf->video.format;
        u32 pstride;
@@ -97,6 +98,10 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int 
enable)
        vsp1_rpf_write(rpf, VI6_RPF_MSK_CTRL, 0);
        vsp1_rpf_write(rpf, VI6_RPF_CKEY_CTRL, 0);
 
+       if (vsp1->is_vio6)
+               vsp1_rpf_write(rpf, VI6_RPF_CHPRI_CTRL,
+                              VI6_RPF_CHPRI_CTRL_ICBP);
+
        return 0;
 }
 
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c 
b/drivers/media/platform/vsp1/vsp1_wpf.c
index af1f1b8..72dfdea 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -104,7 +104,11 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int 
enable)
 
        vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);
 
-       vsp1_write(vsp1, VI6_WPF_WRBCK_CTRL, 0);
+       if (!vsp1->is_vio6)
+               vsp1_write(vsp1, VI6_WPF_WRBCK_CTRL, 0);
+       else
+               vsp1_wpf_write(wpf, VI6_WPF_CHPRI_CTRL,
+                              VI6_WPF_CHPRI_CTRL_ICBP);
 
        /* Enable interrupts */
        vsp1_write(vsp1, VI6_WPF_IRQ_STA0 + wpf->entity.index, 0);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to