media: ccs-pll: Add support for extended input PLL clock divider
authorSakari Ailus <sakari.ailus@linux.intel.com>
Tue, 23 Jun 2020 11:40:32 +0000 (13:40 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 7 Dec 2020 14:56:17 +0000 (15:56 +0100)
CCS allows odd PLL dividers other than 1, granted that the corresponding
capability bit is set. Support this both in the PLL calculator and the CCS
driver.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/i2c/ccs-pll.c
drivers/media/i2c/ccs-pll.h
drivers/media/i2c/ccs/ccs-core.c

index cb19a36e54df5b6851b466d0e0dbd3671f88ae0f..62939ca5b8e2ab4f0b44f95ddf3c538076ae03a4 100644 (file)
@@ -478,7 +478,9 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
 
        for (op_pll_fr->pre_pll_clk_div = min_op_pre_pll_clk_div;
             op_pll_fr->pre_pll_clk_div <= max_op_pre_pll_clk_div;
-            op_pll_fr->pre_pll_clk_div += 2 - (op_pll_fr->pre_pll_clk_div & 1)) {
+            op_pll_fr->pre_pll_clk_div +=
+                    (pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER) ? 1 :
+                    2 - (op_pll_fr->pre_pll_clk_div & 1)) {
                rval = __ccs_pll_calculate(dev, lim, op_lim_fr, op_lim_bk, pll,
                                           op_pll_fr, op_pll_bk, mul, div);
                if (rval)
index fe20af11a068d8dfa834a54170012c08e4acfa02..807ae7250aa2376b2ac5f7c1f058da08e3994887 100644 (file)
@@ -25,6 +25,7 @@
 /* CCS PLL flags */
 #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)
 
 /**
  * struct ccs_pll_branch_fr - CCS PLL configuration (front)
index 855e51675864d049c24696c8c32e347bebdcaae7..6c2b8a4259fde3407e5c6054b6ed739d1969b61c 100644 (file)
@@ -3219,6 +3219,9 @@ static int ccs_probe(struct i2c_client *client)
                        sensor->pll.op_lanes = sensor->pll.csi2.lanes;
                }
        }
+       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;
        sensor->pll.ext_clk_freq_hz = sensor->hwcfg.ext_clk;
        sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN);