* 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);
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);
}
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",
#include <media/v4l2-device.h>
#include "ccs.h"
-#include "ccs-limits.h"
#define CCS_ALIGN_DIM(dim, flags) \
((flags) & V4L2_SEL_FLAG_GE \
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);