]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/media/platform/rcar-vin/rcar-csi2.c
media: rcar-csi2: Handle per-SoC number of channels
[linux.git] / drivers / media / platform / rcar-vin / rcar-csi2.c
index b0044a08e71ed017a3c95c0a2d8d59234f22b865..80ad906d1136c50177231b638cb0df9987fda557 100644 (file)
@@ -152,37 +152,37 @@ static const struct rcsi2_mbps_reg phtw_mbps_h3_v3h_m3n[] = {
 };
 
 static const struct rcsi2_mbps_reg phtw_mbps_v3m_e3[] = {
-       { .mbps =   80, .reg = 0x00 },
-       { .mbps =   90, .reg = 0x20 },
-       { .mbps =  100, .reg = 0x40 },
-       { .mbps =  110, .reg = 0x02 },
-       { .mbps =  130, .reg = 0x22 },
-       { .mbps =  140, .reg = 0x42 },
-       { .mbps =  150, .reg = 0x04 },
-       { .mbps =  170, .reg = 0x24 },
-       { .mbps =  180, .reg = 0x44 },
-       { .mbps =  200, .reg = 0x06 },
-       { .mbps =  220, .reg = 0x26 },
-       { .mbps =  240, .reg = 0x46 },
-       { .mbps =  250, .reg = 0x08 },
-       { .mbps =  270, .reg = 0x28 },
-       { .mbps =  300, .reg = 0x0a },
-       { .mbps =  330, .reg = 0x2a },
-       { .mbps =  360, .reg = 0x4a },
-       { .mbps =  400, .reg = 0x0c },
-       { .mbps =  450, .reg = 0x2c },
-       { .mbps =  500, .reg = 0x0e },
-       { .mbps =  550, .reg = 0x2e },
-       { .mbps =  600, .reg = 0x10 },
-       { .mbps =  650, .reg = 0x30 },
-       { .mbps =  700, .reg = 0x12 },
-       { .mbps =  750, .reg = 0x32 },
-       { .mbps =  800, .reg = 0x52 },
-       { .mbps =  850, .reg = 0x72 },
-       { .mbps =  900, .reg = 0x14 },
-       { .mbps =  950, .reg = 0x34 },
-       { .mbps = 1000, .reg = 0x54 },
-       { .mbps = 1050, .reg = 0x74 },
+       { .mbps =   89, .reg = 0x00 },
+       { .mbps =   99, .reg = 0x20 },
+       { .mbps =  109, .reg = 0x40 },
+       { .mbps =  129, .reg = 0x02 },
+       { .mbps =  139, .reg = 0x22 },
+       { .mbps =  149, .reg = 0x42 },
+       { .mbps =  169, .reg = 0x04 },
+       { .mbps =  179, .reg = 0x24 },
+       { .mbps =  199, .reg = 0x44 },
+       { .mbps =  219, .reg = 0x06 },
+       { .mbps =  239, .reg = 0x26 },
+       { .mbps =  249, .reg = 0x46 },
+       { .mbps =  269, .reg = 0x08 },
+       { .mbps =  299, .reg = 0x28 },
+       { .mbps =  329, .reg = 0x0a },
+       { .mbps =  359, .reg = 0x2a },
+       { .mbps =  399, .reg = 0x4a },
+       { .mbps =  449, .reg = 0x0c },
+       { .mbps =  499, .reg = 0x2c },
+       { .mbps =  549, .reg = 0x0e },
+       { .mbps =  599, .reg = 0x2e },
+       { .mbps =  649, .reg = 0x10 },
+       { .mbps =  699, .reg = 0x30 },
+       { .mbps =  749, .reg = 0x12 },
+       { .mbps =  799, .reg = 0x32 },
+       { .mbps =  849, .reg = 0x52 },
+       { .mbps =  899, .reg = 0x72 },
+       { .mbps =  949, .reg = 0x14 },
+       { .mbps =  999, .reg = 0x34 },
+       { .mbps = 1049, .reg = 0x54 },
+       { .mbps = 1099, .reg = 0x74 },
        { .mbps = 1125, .reg = 0x16 },
        { /* sentinel */ },
 };
@@ -342,6 +342,7 @@ struct rcar_csi2_info {
        int (*confirm_start)(struct rcar_csi2 *priv);
        const struct rcsi2_mbps_reg *hsfreqrange;
        unsigned int csi0clkfreqrange;
+       unsigned int num_channels;
        bool clear_ulps;
 };
 
@@ -476,13 +477,14 @@ static int rcsi2_start(struct rcar_csi2 *priv)
        format = rcsi2_code_to_fmt(priv->mf.code);
 
        /*
-        * Enable all Virtual Channels.
+        * Enable all supported CSI-2 channels with virtual channel and
+        * data type matching.
         *
         * NOTE: It's not possible to get individual datatype for each
         *       source virtual channel. Once this is possible in V4L2
         *       it should be used here.
         */
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < priv->info->num_channels; i++) {
                u32 vcdt_part;
 
                vcdt_part = VCDT_SEL_VC(i) | VCDT_VCDTN_EN | VCDT_SEL_DTN_ON |
@@ -511,7 +513,8 @@ static int rcsi2_start(struct rcar_csi2 *priv)
        rcsi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 |
                    FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN);
        rcsi2_write(priv, VCDT_REG, vcdt);
-       rcsi2_write(priv, VCDT2_REG, vcdt2);
+       if (vcdt2)
+               rcsi2_write(priv, VCDT2_REG, vcdt2);
        /* Lanes are zero indexed. */
        rcsi2_write(priv, LSWAP_REG,
                    LSWAP_L0SEL(priv->lane_swap[0] - 1) |
@@ -940,27 +943,38 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = {
        .init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
        .hsfreqrange = hsfreqrange_h3_v3h_m3n,
        .csi0clkfreqrange = 0x20,
+       .num_channels = 4,
        .clear_ulps = true,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a7795es1 = {
        .hsfreqrange = hsfreqrange_m3w_h3es1,
+       .num_channels = 4,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = {
        .hsfreqrange = hsfreqrange_m3w_h3es1,
+       .num_channels = 4,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = {
        .init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
        .hsfreqrange = hsfreqrange_h3_v3h_m3n,
        .csi0clkfreqrange = 0x20,
+       .num_channels = 4,
        .clear_ulps = true,
 };
 
 static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = {
        .init_phtw = rcsi2_init_phtw_v3m_e3,
        .confirm_start = rcsi2_confirm_start_v3m_e3,
+       .num_channels = 4,
+};
+
+static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {
+       .init_phtw = rcsi2_init_phtw_v3m_e3,
+       .confirm_start = rcsi2_confirm_start_v3m_e3,
+       .num_channels = 2,
 };
 
 static const struct of_device_id rcar_csi2_of_table[] = {
@@ -980,6 +994,10 @@ static const struct of_device_id rcar_csi2_of_table[] = {
                .compatible = "renesas,r8a77970-csi2",
                .data = &rcar_csi2_info_r8a77970,
        },
+       {
+               .compatible = "renesas,r8a77990-csi2",
+               .data = &rcar_csi2_info_r8a77990,
+       },
        { /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);