This is an automatic generated email to let you know that the following patch 
were queued:

Subject: media: ccs-pll: Add support flexible OP PLL pixel clock divider
Author:  Sakari Ailus <[email protected]>
Date:    Fri Aug 7 11:07:14 2020 +0200

Flexible OP PLL pixel clock divider allows a higher OP pixel clock than
what the bus can transfer. This generally makes it easier to select pixel
clock dividers.

This changes how the pixel rate on the bus and minimum VT divisor are
calculated, as the pixel rate is no longer directly determined by the
OP pixel clock and the number of the lanes.

Also add a sanity check for sensors that do not support flexible OP PLL
pixel clock divider. This could have caused the PLL calculator to come up
with an invalid configuration for those devices.

Signed-off-by: Sakari Ailus <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>

 drivers/media/i2c/ccs-pll.c      | 26 +++++++++++++++++++-------
 drivers/media/i2c/ccs-pll.h      |  1 +
 drivers/media/i2c/ccs/ccs-core.c |  4 +++-
 3 files changed, 23 insertions(+), 8 deletions(-)

---

diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c
index 60ab0c043c7a..e3a6493fd601 100644
--- a/drivers/media/i2c/ccs-pll.c
+++ b/drivers/media/i2c/ccs-pll.c
@@ -294,11 +294,11 @@ __ccs_pll_calculate(struct device *dev, const struct 
ccs_pll_limits *lim,
         * Find absolute limits for the factor of vt divider.
         */
        dev_dbg(dev, "scale_m: %u\n", pll->scale_m);
-       min_vt_div = DIV_ROUND_UP(op_pll_bk->pix_clk_div
-                                 * op_pll_bk->sys_clk_div * pll->scale_n
-                                 * pll->vt_lanes * l,
-                                 pll->op_lanes * vt_op_binning_div
-                                 * pll->scale_m);
+       min_vt_div = DIV_ROUND_UP(pll->bits_per_pixel * op_pll_bk->sys_clk_div
+                                 * pll->scale_n * pll->vt_lanes,
+                                 (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
+                                  pll->csi2.lanes : 1)
+                                 * vt_op_binning_div * pll->scale_m);
 
        /* Find smallest and biggest allowed vt divisor. */
        dev_dbg(dev, "min_vt_div: %u\n", min_vt_div);
@@ -420,6 +420,18 @@ int ccs_pll_calculate(struct device *dev, const struct 
ccs_pll_limits *lim,
                pll->op_lanes = 1;
                pll->vt_lanes = 1;
        }
+
+       /*
+        * Make sure op_pix_clk_div will be integer --- unless flexible
+        * op_pix_clk_div is supported
+        */
+       if (!(pll->flags & CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV) &&
+           (pll->bits_per_pixel * pll->op_lanes) % (pll->csi2.lanes * l)) {
+               dev_dbg(dev, "op_pix_clk_div not an integer (bpp %u, op lanes 
%u, lanes %u, l %u)\n",
+                       pll->bits_per_pixel, pll->op_lanes, pll->csi2.lanes, l);
+               return -EINVAL;
+       }
+
        dev_dbg(dev, "vt_lanes: %u\n", pll->vt_lanes);
        dev_dbg(dev, "op_lanes: %u\n", pll->op_lanes);
 
@@ -449,9 +461,9 @@ int ccs_pll_calculate(struct device *dev, const struct 
ccs_pll_limits *lim,
        }
 
        pll->pixel_rate_csi =
-               op_pll_bk->pix_clk_freq_hz
+               op_pll_bk->sys_clk_freq_hz
                * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
-                  pll->csi2.lanes : 1) / l;
+                  pll->csi2.lanes : 1) / pll->bits_per_pixel / l;
 
        /* Figure out limits for OP pre-pll divider based on extclk */
        dev_dbg(dev, "min / max op_pre_pll_clk_div: %u / %u\n",
diff --git a/drivers/media/i2c/ccs-pll.h b/drivers/media/i2c/ccs-pll.h
index 207822cf2324..1b5c20736fe8 100644
--- a/drivers/media/i2c/ccs-pll.h
+++ b/drivers/media/i2c/ccs-pll.h
@@ -26,6 +26,7 @@
 #define CCS_PLL_FLAG_LANE_SPEED_MODEL                          BIT(2)
 #define CCS_PLL_FLAG_LINK_DECOUPLED                            BIT(3)
 #define CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER                                BIT(4)
+#define CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV                   BIT(5)
 
 /**
  * struct ccs_pll_branch_fr - CCS PLL configuration (front)
diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c
index d39da0f31d90..21158e6d0159 100644
--- a/drivers/media/i2c/ccs/ccs-core.c
+++ b/drivers/media/i2c/ccs/ccs-core.c
@@ -30,7 +30,6 @@
 #include <media/v4l2-device.h>
 
 #include "ccs.h"
-#include "ccs-limits.h"
 
 #define CCS_ALIGN_DIM(dim, flags)      \
        ((flags) & V4L2_SEL_FLAG_GE     \
@@ -3222,6 +3221,9 @@ static int ccs_probe(struct i2c_client *client)
        if (CCS_LIM(sensor, CLOCK_TREE_PLL_CAPABILITY) &
            CCS_CLOCK_TREE_PLL_CAPABILITY_EXT_DIVIDER)
                sensor->pll.flags |= CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER;
+       if (CCS_LIM(sensor, CLOCK_TREE_PLL_CAPABILITY) &
+           CCS_CLOCK_TREE_PLL_CAPABILITY_FLEXIBLE_OP_PIX_CLK_DIV)
+               sensor->pll.flags |= CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV;
        sensor->pll.op_bits_per_lane = CCS_LIM(sensor, OP_BITS_PER_LANE);
        sensor->pll.ext_clk_freq_hz = sensor->hwcfg.ext_clk;
        sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN);

_______________________________________________
linuxtv-commits mailing list
[email protected]
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to