@@ -335,6 +335,10 @@ static int __smiapp_pll_calculate(struct device *dev,
pll->pixel_rate_csi =
pll->op_pix_clk_freq_hz * lane_op_clock_ratio;
pll->pixel_rate_pixel_array = pll->vt_pix_clk_freq_hz;
+ if (pll->flags & SMIAPP_PLL_FLAG_PIX_CLOCK_DOUBLE) {
+ pll->pixel_rate_csi *= 2;
+ pll->pixel_rate_pixel_array *= 2;
+ }
rval = bounds_check(dev, pll->pll_ip_clk_freq_hz,
limits->min_pll_ip_freq_hz,
@@ -426,6 +430,12 @@ int smiapp_pll_calculate(struct device *dev,
*/
if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_DIV_HALF)
pll->pll_op_clk_freq_hz /= 2;
+ /*
+ * If it'll be multiplied by two in the end divide it now to
+ * avoid achieving double the desired clock.
+ */
+ if (pll->flags & SMIAPP_PLL_FLAG_PIX_CLOCK_DOUBLE)
+ pll->pll_op_clk_freq_hz /= 2;
/* Figure out limits for pre-pll divider based on extclk */
dev_dbg(dev, "min / max pre_pll_clk_div: %u / %u\n",
@@ -38,6 +38,12 @@
#define SMIAPP_PLL_FLAG_ALLOW_ODD_PRE_PLL_CLK_DIV (1 << 2)
/* op pix div value is half of the bits-per-pixel value */
#define SMIAPP_PLL_FLAG_OP_PIX_DIV_HALF (1 << 3)
+/*
+ * The effective vt and op pix clocks are twice as high as the
+ * calculated value. The limits are still against the regular limit
+ * values.
+ */
+#define SMIAPP_PLL_FLAG_PIX_CLOCK_DOUBLE (1 << 4)
struct smiapp_pll {
/* input values */
Some sensors have effectively the double pixel (and other clocks) compared to calculations. The frequency of the bus is also affected similarly so take this into account when calculating pll_op_clock frequency. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> --- drivers/media/i2c/smiapp-pll.c | 10 ++++++++++ drivers/media/i2c/smiapp-pll.h | 6 ++++++ 2 files changed, 16 insertions(+)