]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
media: i2c: Fix pixel rate for imx274
authorAditya Tomar <adtomar@nvidia.com>
Mon, 30 Oct 2017 13:16:55 +0000 (18:46 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Wed, 1 Nov 2017 14:30:55 +0000 (07:30 -0700)
Correct pixel rate for 4k mode

Bug 200357182

Change-Id: Iae1a083eb4c2c5d713f19453fd08721272666b75
Reviewed-on: https://git-master.nvidia.com/r/1588442
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Esen Chen <esenc@nvidia.com>
Reviewed-by: Josh Kuo <joshk@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: Aditya Tomar <adtomar@nvidia.com>
Reviewed-by: Shantanu Nath <snath@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
drivers/media/i2c/imx274.c
include/media/imx274.h

index 2e2bb539e1e2e1b4d2e43de524c54cb340cada6a..9b9a9855a774b66384318dbd21cc809a3985b6eb 100644 (file)
@@ -37,7 +37,7 @@
 #define IMX274_MIN_GAIN                (1 << IMX274_GAIN_SHIFT)
 #define IMX274_MAX_GAIN                (23 << IMX274_GAIN_SHIFT)
 #define IMX274_MIN_FRAME_LENGTH        (0x8ED)
-#define IMX274_MAX_FRAME_LENGTH        (0xB292)
+#define IMX274_MAX_FRAME_LENGTH        (0xFFFF)
 #define IMX274_MIN_EXPOSURE_COARSE     (0x0001)
 #define IMX274_MAX_EXPOSURE_COARSE     \
        (IMX274_MAX_FRAME_LENGTH-IMX274_MAX_COARSE_DIFF)
@@ -61,7 +61,7 @@ struct imx274 {
        struct i2c_client               *i2c_client;
        struct v4l2_subdev              *subdev;
        struct media_pad                pad;
-
+       u32                             vmax;
        s32                             group_hold_prev;
        bool                            group_hold_en;
        struct regmap                   *regmap;
@@ -157,9 +157,11 @@ static inline void imx274_get_vmax_regs(imx274_reg *regs,
                                u32 vmax)
 {
        regs->addr = IMX274_VMAX_ADDR_MSB;
-       regs->val = (vmax >> 8) & 0xff;
-       (regs + 1)->addr = IMX274_VMAX_ADDR_LSB;
-       (regs + 1)->val = (vmax) & 0xff;
+       regs->val = (vmax >> 16) & 0x0f;
+       (regs + 1)->addr = IMX274_VMAX_ADDR_MID;
+       (regs + 1)->val = (vmax >> 8) & 0xff;
+       (regs + 2)->addr = IMX274_VMAX_ADDR_LSB;
+       (regs + 2)->val = (vmax) & 0xff;
 }
 
 static inline void imx274_get_shr_regs(imx274_reg *regs,
@@ -597,32 +599,36 @@ fail:
 
 static int imx274_set_frame_length(struct imx274 *priv, s32 val)
 {
-       imx274_reg reg_list[2];
+       struct camera_common_data *s_data = priv->s_data;
+       const struct sensor_mode_properties *mode =
+               &s_data->sensor_props.sensor_modes[s_data->mode];
+       imx274_reg reg_list[3];
        int err;
        u32 frame_length;
        u32 frame_rate;
        int i = 0;
-       u8 svr;
-       u32 vmax;
 
        dev_dbg(&priv->i2c_client->dev,
                 "%s: val: %u\n", __func__, val);
 
        frame_length = (u32)val;
 
-       frame_rate = (u32)(IMX274_PIXEL_CLK_HZ /
-                               (u32)(frame_length * IMX274_LINE_LENGTH));
+       frame_rate = (u32)(mode->signal_properties.pixel_clock.val /
+                       (u32)(frame_length *
+                       mode->image_properties.line_length));
 
-       imx274_read_reg(priv->s_data, IMX274_SVR_ADDR, &svr);
+       /*For 4K mode*/
+       priv->vmax = (u32)(IMX274_SENSOR_INTERNAL_CLK_FREQ /
+                       (frame_rate *
+                       IMX274_4K_MODE_HMAX));
+       if (priv->vmax < IMX274_4K_MODE_MIN_VMAX)
+               priv->vmax = IMX274_4K_MODE_MIN_VMAX;
 
-       vmax = (u32)(72000000 /
-                       (u32)(frame_rate * IMX274_HMAX * (svr + 1))) - 12;
-
-       imx274_get_vmax_regs(reg_list, vmax);
+       imx274_get_vmax_regs(reg_list, priv->vmax);
 
        imx274_set_group_hold(priv);
 
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < 3; i++) {
                err = imx274_write_reg(priv->s_data, reg_list[i].addr,
                         reg_list[i].val);
                if (err)
@@ -630,7 +636,13 @@ static int imx274_set_frame_length(struct imx274 *priv, s32 val)
        }
 
        dev_dbg(&priv->i2c_client->dev,
-               "%s: frame_rate: %d vmax: %u\n", __func__, frame_rate, vmax);
+               "%s: PCLK: %lld, FL: %d, LL: %d, fps: %d, VMAX: %d\n", __func__,
+                       mode->signal_properties.pixel_clock.val,
+                       frame_length,
+                       mode->image_properties.line_length,
+                       frame_rate,
+                       priv->vmax);
+
        return 0;
 
 fail:
@@ -641,36 +653,38 @@ fail:
 
 static int imx274_calculate_shr(struct imx274 *priv, u32 rep)
 {
-       u8 svr;
+       const struct camera_common_data *s_data = priv->s_data;
+       const struct sensor_mode_properties *mode =
+               &s_data->sensor_props.sensor_modes[s_data->mode];
        int shr;
-       int min;
-       int max;
-       u8 vmax_l;
-       u8 vmax_m;
-       u32 vmax;
-
-       imx274_read_reg(priv->s_data, IMX274_SVR_ADDR, &svr);
-
-       imx274_read_reg(priv->s_data, IMX274_VMAX_ADDR_LSB, &vmax_l);
-       imx274_read_reg(priv->s_data, IMX274_VMAX_ADDR_MSB, &vmax_m);
+       int shr_min;
+       int shr_max;
+       u64 et_long;
 
-       vmax = ((vmax_m << 8) + vmax_l);
+       if (priv->vmax < IMX274_4K_MODE_MIN_VMAX)
+               priv->vmax = IMX274_4K_MODE_MIN_VMAX;
 
-       min = IMX274_MODE1_SHR_MIN;
-       max = ((svr + 1) * vmax) - 4;
+       et_long = mode->image_properties.line_length * rep *
+               FIXED_POINT_SCALING_FACTOR /
+               mode->signal_properties.pixel_clock.val;
 
-       shr = vmax * (svr + 1) -
-                       (rep * IMX274_ET_FACTOR - IMX274_MODE1_OFFSET) /
-                       IMX274_HMAX;
+       /*For 4K mode*/
+       shr = priv->vmax -
+               (et_long * IMX274_SENSOR_INTERNAL_CLK_FREQ /
+               FIXED_POINT_SCALING_FACTOR -
+               IMX274_4K_MODE_OFFSET) /
+               IMX274_4K_MODE_HMAX;
 
-       if (shr < min)
-               shr = min;
+       shr_min = 12;
+       shr_max = priv->vmax - 4;
+       if (shr > shr_max)
+               shr = shr_max;
 
-       if (shr > max)
-               shr = max;
+       if (shr < shr_min)
+               shr = shr_min;
 
        dev_dbg(&priv->i2c_client->dev,
-                "%s: shr: %u vmax: %d\n", __func__, shr, vmax);
+                "%s: shr: %u vmax: %d\n", __func__, shr, priv->vmax);
        return shr;
 }
 
index 52c6e87d06d7231f6274ff7e1c80b59a4b7b2b33..499ce3d52535c79de0860a3b76ba6fab833c66ab 100644 (file)
@@ -38,7 +38,8 @@
 #define IMX274_SHR_ADDR_MSB                            0x300D
 
 #define IMX274_VMAX_ADDR_LSB                   0x30F8
-#define IMX274_VMAX_ADDR_MSB                   0x30F9
+#define IMX274_VMAX_ADDR_MID                   0x30F9
+#define IMX274_VMAX_ADDR_MSB                   0x30FA
 
 #define IMX274_GAIN_ADDR_LSB                   0x300A
 #define IMX274_GAIN_ADDR_MSB                   0x300B
 #define IMX274_PIXEL_CLK_HZ                            756000000
 #define IMX274_LINE_LENGTH                             4200
 
-#define IMX274_HMAX                                            263
-#define IMX274_MODE1_OFFSET                            112
-#define IMX274_MODE1_SHR_MIN                   12
-#define IMX274_ET_FACTOR                               400
+#define IMX274_SENSOR_INTERNAL_CLK_FREQ                72000000
+#define IMX274_4K_MODE_HMAX                    263
+#define IMX274_4K_MODE_MIN_VMAX                        4550
+#define IMX274_4K_MODE_OFFSET                  112
 
 struct imx274_mode {
        __u32 xres;