1*9e05bbacSSakari Ailus // SPDX-License-Identifier: GPL-2.0-only 2*9e05bbacSSakari Ailus /* 3*9e05bbacSSakari Ailus * drivers/media/i2c/ccs-pll.c 4*9e05bbacSSakari Ailus * 5*9e05bbacSSakari Ailus * Generic MIPI CCS/SMIA/SMIA++ PLL calculator 6*9e05bbacSSakari Ailus * 7*9e05bbacSSakari Ailus * Copyright (C) 2020 Intel Corporation 8*9e05bbacSSakari Ailus * Copyright (C) 2011--2012 Nokia Corporation 9*9e05bbacSSakari Ailus * Contact: Sakari Ailus <sakari.ailus@iki.fi> 10*9e05bbacSSakari Ailus */ 11*9e05bbacSSakari Ailus 12*9e05bbacSSakari Ailus #include <linux/device.h> 13*9e05bbacSSakari Ailus #include <linux/gcd.h> 14*9e05bbacSSakari Ailus #include <linux/lcm.h> 15*9e05bbacSSakari Ailus #include <linux/module.h> 16*9e05bbacSSakari Ailus 17*9e05bbacSSakari Ailus #include "ccs-pll.h" 18*9e05bbacSSakari Ailus 19*9e05bbacSSakari Ailus /* Return an even number or one. */ 20*9e05bbacSSakari Ailus static inline uint32_t clk_div_even(uint32_t a) 21*9e05bbacSSakari Ailus { 22*9e05bbacSSakari Ailus return max_t(uint32_t, 1, a & ~1); 23*9e05bbacSSakari Ailus } 24*9e05bbacSSakari Ailus 25*9e05bbacSSakari Ailus /* Return an even number or one. */ 26*9e05bbacSSakari Ailus static inline uint32_t clk_div_even_up(uint32_t a) 27*9e05bbacSSakari Ailus { 28*9e05bbacSSakari Ailus if (a == 1) 29*9e05bbacSSakari Ailus return 1; 30*9e05bbacSSakari Ailus return (a + 1) & ~1; 31*9e05bbacSSakari Ailus } 32*9e05bbacSSakari Ailus 33*9e05bbacSSakari Ailus static inline uint32_t is_one_or_even(uint32_t a) 34*9e05bbacSSakari Ailus { 35*9e05bbacSSakari Ailus if (a == 1) 36*9e05bbacSSakari Ailus return 1; 37*9e05bbacSSakari Ailus if (a & 1) 38*9e05bbacSSakari Ailus return 0; 39*9e05bbacSSakari Ailus 40*9e05bbacSSakari Ailus return 1; 41*9e05bbacSSakari Ailus } 42*9e05bbacSSakari Ailus 43*9e05bbacSSakari Ailus static int bounds_check(struct device *dev, uint32_t val, 44*9e05bbacSSakari Ailus uint32_t min, uint32_t max, char *str) 45*9e05bbacSSakari Ailus { 46*9e05bbacSSakari Ailus if (val >= min && val <= max) 47*9e05bbacSSakari Ailus return 0; 48*9e05bbacSSakari Ailus 49*9e05bbacSSakari Ailus dev_dbg(dev, "%s out of bounds: %d (%d--%d)\n", str, val, min, max); 50*9e05bbacSSakari Ailus 51*9e05bbacSSakari Ailus return -EINVAL; 52*9e05bbacSSakari Ailus } 53*9e05bbacSSakari Ailus 54*9e05bbacSSakari Ailus static void print_pll(struct device *dev, struct ccs_pll *pll) 55*9e05bbacSSakari Ailus { 56*9e05bbacSSakari Ailus dev_dbg(dev, "pre_pll_clk_div\t%u\n", pll->pre_pll_clk_div); 57*9e05bbacSSakari Ailus dev_dbg(dev, "pll_multiplier \t%u\n", pll->pll_multiplier); 58*9e05bbacSSakari Ailus if (!(pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)) { 59*9e05bbacSSakari Ailus dev_dbg(dev, "op_sys_clk_div \t%u\n", pll->op.sys_clk_div); 60*9e05bbacSSakari Ailus dev_dbg(dev, "op_pix_clk_div \t%u\n", pll->op.pix_clk_div); 61*9e05bbacSSakari Ailus } 62*9e05bbacSSakari Ailus dev_dbg(dev, "vt_sys_clk_div \t%u\n", pll->vt.sys_clk_div); 63*9e05bbacSSakari Ailus dev_dbg(dev, "vt_pix_clk_div \t%u\n", pll->vt.pix_clk_div); 64*9e05bbacSSakari Ailus 65*9e05bbacSSakari Ailus dev_dbg(dev, "ext_clk_freq_hz \t%u\n", pll->ext_clk_freq_hz); 66*9e05bbacSSakari Ailus dev_dbg(dev, "pll_ip_clk_freq_hz \t%u\n", pll->pll_ip_clk_freq_hz); 67*9e05bbacSSakari Ailus dev_dbg(dev, "pll_op_clk_freq_hz \t%u\n", pll->pll_op_clk_freq_hz); 68*9e05bbacSSakari Ailus if (!(pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)) { 69*9e05bbacSSakari Ailus dev_dbg(dev, "op_sys_clk_freq_hz \t%u\n", 70*9e05bbacSSakari Ailus pll->op.sys_clk_freq_hz); 71*9e05bbacSSakari Ailus dev_dbg(dev, "op_pix_clk_freq_hz \t%u\n", 72*9e05bbacSSakari Ailus pll->op.pix_clk_freq_hz); 73*9e05bbacSSakari Ailus } 74*9e05bbacSSakari Ailus dev_dbg(dev, "vt_sys_clk_freq_hz \t%u\n", pll->vt.sys_clk_freq_hz); 75*9e05bbacSSakari Ailus dev_dbg(dev, "vt_pix_clk_freq_hz \t%u\n", pll->vt.pix_clk_freq_hz); 76*9e05bbacSSakari Ailus } 77*9e05bbacSSakari Ailus 78*9e05bbacSSakari Ailus static int check_all_bounds(struct device *dev, 79*9e05bbacSSakari Ailus const struct ccs_pll_limits *limits, 80*9e05bbacSSakari Ailus const struct ccs_pll_branch_limits *op_limits, 81*9e05bbacSSakari Ailus struct ccs_pll *pll, struct ccs_pll_branch *op_pll) 82*9e05bbacSSakari Ailus { 83*9e05bbacSSakari Ailus int rval; 84*9e05bbacSSakari Ailus 85*9e05bbacSSakari Ailus rval = bounds_check(dev, pll->pll_ip_clk_freq_hz, 86*9e05bbacSSakari Ailus limits->min_pll_ip_freq_hz, 87*9e05bbacSSakari Ailus limits->max_pll_ip_freq_hz, 88*9e05bbacSSakari Ailus "pll_ip_clk_freq_hz"); 89*9e05bbacSSakari Ailus if (!rval) 90*9e05bbacSSakari Ailus rval = bounds_check( 91*9e05bbacSSakari Ailus dev, pll->pll_multiplier, 92*9e05bbacSSakari Ailus limits->min_pll_multiplier, limits->max_pll_multiplier, 93*9e05bbacSSakari Ailus "pll_multiplier"); 94*9e05bbacSSakari Ailus if (!rval) 95*9e05bbacSSakari Ailus rval = bounds_check( 96*9e05bbacSSakari Ailus dev, pll->pll_op_clk_freq_hz, 97*9e05bbacSSakari Ailus limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz, 98*9e05bbacSSakari Ailus "pll_op_clk_freq_hz"); 99*9e05bbacSSakari Ailus if (!rval) 100*9e05bbacSSakari Ailus rval = bounds_check( 101*9e05bbacSSakari Ailus dev, op_pll->sys_clk_div, 102*9e05bbacSSakari Ailus op_limits->min_sys_clk_div, op_limits->max_sys_clk_div, 103*9e05bbacSSakari Ailus "op_sys_clk_div"); 104*9e05bbacSSakari Ailus if (!rval) 105*9e05bbacSSakari Ailus rval = bounds_check( 106*9e05bbacSSakari Ailus dev, op_pll->sys_clk_freq_hz, 107*9e05bbacSSakari Ailus op_limits->min_sys_clk_freq_hz, 108*9e05bbacSSakari Ailus op_limits->max_sys_clk_freq_hz, 109*9e05bbacSSakari Ailus "op_sys_clk_freq_hz"); 110*9e05bbacSSakari Ailus if (!rval) 111*9e05bbacSSakari Ailus rval = bounds_check( 112*9e05bbacSSakari Ailus dev, op_pll->pix_clk_freq_hz, 113*9e05bbacSSakari Ailus op_limits->min_pix_clk_freq_hz, 114*9e05bbacSSakari Ailus op_limits->max_pix_clk_freq_hz, 115*9e05bbacSSakari Ailus "op_pix_clk_freq_hz"); 116*9e05bbacSSakari Ailus 117*9e05bbacSSakari Ailus /* 118*9e05bbacSSakari Ailus * If there are no OP clocks, the VT clocks are contained in 119*9e05bbacSSakari Ailus * the OP clock struct. 120*9e05bbacSSakari Ailus */ 121*9e05bbacSSakari Ailus if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) 122*9e05bbacSSakari Ailus return rval; 123*9e05bbacSSakari Ailus 124*9e05bbacSSakari Ailus if (!rval) 125*9e05bbacSSakari Ailus rval = bounds_check( 126*9e05bbacSSakari Ailus dev, pll->vt.sys_clk_freq_hz, 127*9e05bbacSSakari Ailus limits->vt.min_sys_clk_freq_hz, 128*9e05bbacSSakari Ailus limits->vt.max_sys_clk_freq_hz, 129*9e05bbacSSakari Ailus "vt_sys_clk_freq_hz"); 130*9e05bbacSSakari Ailus if (!rval) 131*9e05bbacSSakari Ailus rval = bounds_check( 132*9e05bbacSSakari Ailus dev, pll->vt.pix_clk_freq_hz, 133*9e05bbacSSakari Ailus limits->vt.min_pix_clk_freq_hz, 134*9e05bbacSSakari Ailus limits->vt.max_pix_clk_freq_hz, 135*9e05bbacSSakari Ailus "vt_pix_clk_freq_hz"); 136*9e05bbacSSakari Ailus 137*9e05bbacSSakari Ailus return rval; 138*9e05bbacSSakari Ailus } 139*9e05bbacSSakari Ailus 140*9e05bbacSSakari Ailus /* 141*9e05bbacSSakari Ailus * Heuristically guess the PLL tree for a given common multiplier and 142*9e05bbacSSakari Ailus * divisor. Begin with the operational timing and continue to video 143*9e05bbacSSakari Ailus * timing once operational timing has been verified. 144*9e05bbacSSakari Ailus * 145*9e05bbacSSakari Ailus * @mul is the PLL multiplier and @div is the common divisor 146*9e05bbacSSakari Ailus * (pre_pll_clk_div and op_sys_clk_div combined). The final PLL 147*9e05bbacSSakari Ailus * multiplier will be a multiple of @mul. 148*9e05bbacSSakari Ailus * 149*9e05bbacSSakari Ailus * @return Zero on success, error code on error. 150*9e05bbacSSakari Ailus */ 151*9e05bbacSSakari Ailus static int 152*9e05bbacSSakari Ailus __ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits, 153*9e05bbacSSakari Ailus const struct ccs_pll_branch_limits *op_limits, 154*9e05bbacSSakari Ailus struct ccs_pll *pll, struct ccs_pll_branch *op_pll, 155*9e05bbacSSakari Ailus uint32_t mul, uint32_t div, uint32_t lane_op_clock_ratio) 156*9e05bbacSSakari Ailus { 157*9e05bbacSSakari Ailus uint32_t sys_div; 158*9e05bbacSSakari Ailus uint32_t best_pix_div = INT_MAX >> 1; 159*9e05bbacSSakari Ailus uint32_t vt_op_binning_div; 160*9e05bbacSSakari Ailus /* 161*9e05bbacSSakari Ailus * Higher multipliers (and divisors) are often required than 162*9e05bbacSSakari Ailus * necessitated by the external clock and the output clocks. 163*9e05bbacSSakari Ailus * There are limits for all values in the clock tree. These 164*9e05bbacSSakari Ailus * are the minimum and maximum multiplier for mul. 165*9e05bbacSSakari Ailus */ 166*9e05bbacSSakari Ailus uint32_t more_mul_min, more_mul_max; 167*9e05bbacSSakari Ailus uint32_t more_mul_factor; 168*9e05bbacSSakari Ailus uint32_t min_vt_div, max_vt_div, vt_div; 169*9e05bbacSSakari Ailus uint32_t min_sys_div, max_sys_div; 170*9e05bbacSSakari Ailus unsigned int i; 171*9e05bbacSSakari Ailus 172*9e05bbacSSakari Ailus /* 173*9e05bbacSSakari Ailus * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be 174*9e05bbacSSakari Ailus * too high. 175*9e05bbacSSakari Ailus */ 176*9e05bbacSSakari Ailus dev_dbg(dev, "pre_pll_clk_div %u\n", pll->pre_pll_clk_div); 177*9e05bbacSSakari Ailus 178*9e05bbacSSakari Ailus /* Don't go above max pll multiplier. */ 179*9e05bbacSSakari Ailus more_mul_max = limits->max_pll_multiplier / mul; 180*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_max: max_pll_multiplier check: %u\n", 181*9e05bbacSSakari Ailus more_mul_max); 182*9e05bbacSSakari Ailus /* Don't go above max pll op frequency. */ 183*9e05bbacSSakari Ailus more_mul_max = 184*9e05bbacSSakari Ailus min_t(uint32_t, 185*9e05bbacSSakari Ailus more_mul_max, 186*9e05bbacSSakari Ailus limits->max_pll_op_freq_hz 187*9e05bbacSSakari Ailus / (pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul)); 188*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_max: max_pll_op_freq_hz check: %u\n", 189*9e05bbacSSakari Ailus more_mul_max); 190*9e05bbacSSakari Ailus /* Don't go above the division capability of op sys clock divider. */ 191*9e05bbacSSakari Ailus more_mul_max = min(more_mul_max, 192*9e05bbacSSakari Ailus op_limits->max_sys_clk_div * pll->pre_pll_clk_div 193*9e05bbacSSakari Ailus / div); 194*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %u\n", 195*9e05bbacSSakari Ailus more_mul_max); 196*9e05bbacSSakari Ailus /* Ensure we won't go above min_pll_multiplier. */ 197*9e05bbacSSakari Ailus more_mul_max = min(more_mul_max, 198*9e05bbacSSakari Ailus DIV_ROUND_UP(limits->max_pll_multiplier, mul)); 199*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %u\n", 200*9e05bbacSSakari Ailus more_mul_max); 201*9e05bbacSSakari Ailus 202*9e05bbacSSakari Ailus /* Ensure we won't go below min_pll_op_freq_hz. */ 203*9e05bbacSSakari Ailus more_mul_min = DIV_ROUND_UP(limits->min_pll_op_freq_hz, 204*9e05bbacSSakari Ailus pll->ext_clk_freq_hz / pll->pre_pll_clk_div 205*9e05bbacSSakari Ailus * mul); 206*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_min: min_pll_op_freq_hz check: %u\n", 207*9e05bbacSSakari Ailus more_mul_min); 208*9e05bbacSSakari Ailus /* Ensure we won't go below min_pll_multiplier. */ 209*9e05bbacSSakari Ailus more_mul_min = max(more_mul_min, 210*9e05bbacSSakari Ailus DIV_ROUND_UP(limits->min_pll_multiplier, mul)); 211*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_min: min_pll_multiplier check: %u\n", 212*9e05bbacSSakari Ailus more_mul_min); 213*9e05bbacSSakari Ailus 214*9e05bbacSSakari Ailus if (more_mul_min > more_mul_max) { 215*9e05bbacSSakari Ailus dev_dbg(dev, 216*9e05bbacSSakari Ailus "unable to compute more_mul_min and more_mul_max\n"); 217*9e05bbacSSakari Ailus return -EINVAL; 218*9e05bbacSSakari Ailus } 219*9e05bbacSSakari Ailus 220*9e05bbacSSakari Ailus more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div; 221*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_factor: %u\n", more_mul_factor); 222*9e05bbacSSakari Ailus more_mul_factor = lcm(more_mul_factor, op_limits->min_sys_clk_div); 223*9e05bbacSSakari Ailus dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n", 224*9e05bbacSSakari Ailus more_mul_factor); 225*9e05bbacSSakari Ailus i = roundup(more_mul_min, more_mul_factor); 226*9e05bbacSSakari Ailus if (!is_one_or_even(i)) 227*9e05bbacSSakari Ailus i <<= 1; 228*9e05bbacSSakari Ailus 229*9e05bbacSSakari Ailus dev_dbg(dev, "final more_mul: %u\n", i); 230*9e05bbacSSakari Ailus if (i > more_mul_max) { 231*9e05bbacSSakari Ailus dev_dbg(dev, "final more_mul is bad, max %u\n", more_mul_max); 232*9e05bbacSSakari Ailus return -EINVAL; 233*9e05bbacSSakari Ailus } 234*9e05bbacSSakari Ailus 235*9e05bbacSSakari Ailus pll->pll_multiplier = mul * i; 236*9e05bbacSSakari Ailus op_pll->sys_clk_div = div * i / pll->pre_pll_clk_div; 237*9e05bbacSSakari Ailus dev_dbg(dev, "op_sys_clk_div: %u\n", op_pll->sys_clk_div); 238*9e05bbacSSakari Ailus 239*9e05bbacSSakari Ailus pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz 240*9e05bbacSSakari Ailus / pll->pre_pll_clk_div; 241*9e05bbacSSakari Ailus 242*9e05bbacSSakari Ailus pll->pll_op_clk_freq_hz = pll->pll_ip_clk_freq_hz 243*9e05bbacSSakari Ailus * pll->pll_multiplier; 244*9e05bbacSSakari Ailus 245*9e05bbacSSakari Ailus /* Derive pll_op_clk_freq_hz. */ 246*9e05bbacSSakari Ailus op_pll->sys_clk_freq_hz = 247*9e05bbacSSakari Ailus pll->pll_op_clk_freq_hz / op_pll->sys_clk_div; 248*9e05bbacSSakari Ailus 249*9e05bbacSSakari Ailus op_pll->pix_clk_div = pll->bits_per_pixel; 250*9e05bbacSSakari Ailus dev_dbg(dev, "op_pix_clk_div: %u\n", op_pll->pix_clk_div); 251*9e05bbacSSakari Ailus 252*9e05bbacSSakari Ailus op_pll->pix_clk_freq_hz = 253*9e05bbacSSakari Ailus op_pll->sys_clk_freq_hz / op_pll->pix_clk_div; 254*9e05bbacSSakari Ailus 255*9e05bbacSSakari Ailus if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) { 256*9e05bbacSSakari Ailus /* No OP clocks --- VT clocks are used instead. */ 257*9e05bbacSSakari Ailus goto out_skip_vt_calc; 258*9e05bbacSSakari Ailus } 259*9e05bbacSSakari Ailus 260*9e05bbacSSakari Ailus /* 261*9e05bbacSSakari Ailus * Some sensors perform analogue binning and some do this 262*9e05bbacSSakari Ailus * digitally. The ones doing this digitally can be roughly be 263*9e05bbacSSakari Ailus * found out using this formula. The ones doing this digitally 264*9e05bbacSSakari Ailus * should run at higher clock rate, so smaller divisor is used 265*9e05bbacSSakari Ailus * on video timing side. 266*9e05bbacSSakari Ailus */ 267*9e05bbacSSakari Ailus if (limits->min_line_length_pck_bin > limits->min_line_length_pck 268*9e05bbacSSakari Ailus / pll->binning_horizontal) 269*9e05bbacSSakari Ailus vt_op_binning_div = pll->binning_horizontal; 270*9e05bbacSSakari Ailus else 271*9e05bbacSSakari Ailus vt_op_binning_div = 1; 272*9e05bbacSSakari Ailus dev_dbg(dev, "vt_op_binning_div: %u\n", vt_op_binning_div); 273*9e05bbacSSakari Ailus 274*9e05bbacSSakari Ailus /* 275*9e05bbacSSakari Ailus * Profile 2 supports vt_pix_clk_div E [4, 10] 276*9e05bbacSSakari Ailus * 277*9e05bbacSSakari Ailus * Horizontal binning can be used as a base for difference in 278*9e05bbacSSakari Ailus * divisors. One must make sure that horizontal blanking is 279*9e05bbacSSakari Ailus * enough to accommodate the CSI-2 sync codes. 280*9e05bbacSSakari Ailus * 281*9e05bbacSSakari Ailus * Take scaling factor into account as well. 282*9e05bbacSSakari Ailus * 283*9e05bbacSSakari Ailus * Find absolute limits for the factor of vt divider. 284*9e05bbacSSakari Ailus */ 285*9e05bbacSSakari Ailus dev_dbg(dev, "scale_m: %u\n", pll->scale_m); 286*9e05bbacSSakari Ailus min_vt_div = DIV_ROUND_UP(op_pll->pix_clk_div * op_pll->sys_clk_div 287*9e05bbacSSakari Ailus * pll->scale_n, 288*9e05bbacSSakari Ailus lane_op_clock_ratio * vt_op_binning_div 289*9e05bbacSSakari Ailus * pll->scale_m); 290*9e05bbacSSakari Ailus 291*9e05bbacSSakari Ailus /* Find smallest and biggest allowed vt divisor. */ 292*9e05bbacSSakari Ailus dev_dbg(dev, "min_vt_div: %u\n", min_vt_div); 293*9e05bbacSSakari Ailus min_vt_div = max(min_vt_div, 294*9e05bbacSSakari Ailus DIV_ROUND_UP(pll->pll_op_clk_freq_hz, 295*9e05bbacSSakari Ailus limits->vt.max_pix_clk_freq_hz)); 296*9e05bbacSSakari Ailus dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %u\n", 297*9e05bbacSSakari Ailus min_vt_div); 298*9e05bbacSSakari Ailus min_vt_div = max_t(uint32_t, min_vt_div, 299*9e05bbacSSakari Ailus limits->vt.min_pix_clk_div 300*9e05bbacSSakari Ailus * limits->vt.min_sys_clk_div); 301*9e05bbacSSakari Ailus dev_dbg(dev, "min_vt_div: min_vt_clk_div: %u\n", min_vt_div); 302*9e05bbacSSakari Ailus 303*9e05bbacSSakari Ailus max_vt_div = limits->vt.max_sys_clk_div * limits->vt.max_pix_clk_div; 304*9e05bbacSSakari Ailus dev_dbg(dev, "max_vt_div: %u\n", max_vt_div); 305*9e05bbacSSakari Ailus max_vt_div = min(max_vt_div, 306*9e05bbacSSakari Ailus DIV_ROUND_UP(pll->pll_op_clk_freq_hz, 307*9e05bbacSSakari Ailus limits->vt.min_pix_clk_freq_hz)); 308*9e05bbacSSakari Ailus dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %u\n", 309*9e05bbacSSakari Ailus max_vt_div); 310*9e05bbacSSakari Ailus 311*9e05bbacSSakari Ailus /* 312*9e05bbacSSakari Ailus * Find limitsits for sys_clk_div. Not all values are possible 313*9e05bbacSSakari Ailus * with all values of pix_clk_div. 314*9e05bbacSSakari Ailus */ 315*9e05bbacSSakari Ailus min_sys_div = limits->vt.min_sys_clk_div; 316*9e05bbacSSakari Ailus dev_dbg(dev, "min_sys_div: %u\n", min_sys_div); 317*9e05bbacSSakari Ailus min_sys_div = max(min_sys_div, 318*9e05bbacSSakari Ailus DIV_ROUND_UP(min_vt_div, 319*9e05bbacSSakari Ailus limits->vt.max_pix_clk_div)); 320*9e05bbacSSakari Ailus dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %u\n", min_sys_div); 321*9e05bbacSSakari Ailus min_sys_div = max(min_sys_div, 322*9e05bbacSSakari Ailus pll->pll_op_clk_freq_hz 323*9e05bbacSSakari Ailus / limits->vt.max_sys_clk_freq_hz); 324*9e05bbacSSakari Ailus dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %u\n", min_sys_div); 325*9e05bbacSSakari Ailus min_sys_div = clk_div_even_up(min_sys_div); 326*9e05bbacSSakari Ailus dev_dbg(dev, "min_sys_div: one or even: %u\n", min_sys_div); 327*9e05bbacSSakari Ailus 328*9e05bbacSSakari Ailus max_sys_div = limits->vt.max_sys_clk_div; 329*9e05bbacSSakari Ailus dev_dbg(dev, "max_sys_div: %u\n", max_sys_div); 330*9e05bbacSSakari Ailus max_sys_div = min(max_sys_div, 331*9e05bbacSSakari Ailus DIV_ROUND_UP(max_vt_div, 332*9e05bbacSSakari Ailus limits->vt.min_pix_clk_div)); 333*9e05bbacSSakari Ailus dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %u\n", max_sys_div); 334*9e05bbacSSakari Ailus max_sys_div = min(max_sys_div, 335*9e05bbacSSakari Ailus DIV_ROUND_UP(pll->pll_op_clk_freq_hz, 336*9e05bbacSSakari Ailus limits->vt.min_pix_clk_freq_hz)); 337*9e05bbacSSakari Ailus dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %u\n", max_sys_div); 338*9e05bbacSSakari Ailus 339*9e05bbacSSakari Ailus /* 340*9e05bbacSSakari Ailus * Find pix_div such that a legal pix_div * sys_div results 341*9e05bbacSSakari Ailus * into a value which is not smaller than div, the desired 342*9e05bbacSSakari Ailus * divisor. 343*9e05bbacSSakari Ailus */ 344*9e05bbacSSakari Ailus for (vt_div = min_vt_div; vt_div <= max_vt_div; 345*9e05bbacSSakari Ailus vt_div += 2 - (vt_div & 1)) { 346*9e05bbacSSakari Ailus for (sys_div = min_sys_div; 347*9e05bbacSSakari Ailus sys_div <= max_sys_div; 348*9e05bbacSSakari Ailus sys_div += 2 - (sys_div & 1)) { 349*9e05bbacSSakari Ailus uint16_t pix_div = DIV_ROUND_UP(vt_div, sys_div); 350*9e05bbacSSakari Ailus 351*9e05bbacSSakari Ailus if (pix_div < limits->vt.min_pix_clk_div 352*9e05bbacSSakari Ailus || pix_div > limits->vt.max_pix_clk_div) { 353*9e05bbacSSakari Ailus dev_dbg(dev, 354*9e05bbacSSakari Ailus "pix_div %u too small or too big (%u--%u)\n", 355*9e05bbacSSakari Ailus pix_div, 356*9e05bbacSSakari Ailus limits->vt.min_pix_clk_div, 357*9e05bbacSSakari Ailus limits->vt.max_pix_clk_div); 358*9e05bbacSSakari Ailus continue; 359*9e05bbacSSakari Ailus } 360*9e05bbacSSakari Ailus 361*9e05bbacSSakari Ailus /* Check if this one is better. */ 362*9e05bbacSSakari Ailus if (pix_div * sys_div 363*9e05bbacSSakari Ailus <= roundup(min_vt_div, best_pix_div)) 364*9e05bbacSSakari Ailus best_pix_div = pix_div; 365*9e05bbacSSakari Ailus } 366*9e05bbacSSakari Ailus if (best_pix_div < INT_MAX >> 1) 367*9e05bbacSSakari Ailus break; 368*9e05bbacSSakari Ailus } 369*9e05bbacSSakari Ailus 370*9e05bbacSSakari Ailus pll->vt.sys_clk_div = DIV_ROUND_UP(min_vt_div, best_pix_div); 371*9e05bbacSSakari Ailus pll->vt.pix_clk_div = best_pix_div; 372*9e05bbacSSakari Ailus 373*9e05bbacSSakari Ailus pll->vt.sys_clk_freq_hz = 374*9e05bbacSSakari Ailus pll->pll_op_clk_freq_hz / pll->vt.sys_clk_div; 375*9e05bbacSSakari Ailus pll->vt.pix_clk_freq_hz = 376*9e05bbacSSakari Ailus pll->vt.sys_clk_freq_hz / pll->vt.pix_clk_div; 377*9e05bbacSSakari Ailus 378*9e05bbacSSakari Ailus out_skip_vt_calc: 379*9e05bbacSSakari Ailus pll->pixel_rate_csi = 380*9e05bbacSSakari Ailus op_pll->pix_clk_freq_hz * lane_op_clock_ratio; 381*9e05bbacSSakari Ailus pll->pixel_rate_pixel_array = pll->vt.pix_clk_freq_hz; 382*9e05bbacSSakari Ailus 383*9e05bbacSSakari Ailus return check_all_bounds(dev, limits, op_limits, pll, op_pll); 384*9e05bbacSSakari Ailus } 385*9e05bbacSSakari Ailus 386*9e05bbacSSakari Ailus int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits, 387*9e05bbacSSakari Ailus struct ccs_pll *pll) 388*9e05bbacSSakari Ailus { 389*9e05bbacSSakari Ailus const struct ccs_pll_branch_limits *op_limits = &limits->op; 390*9e05bbacSSakari Ailus struct ccs_pll_branch *op_pll = &pll->op; 391*9e05bbacSSakari Ailus uint16_t min_pre_pll_clk_div; 392*9e05bbacSSakari Ailus uint16_t max_pre_pll_clk_div; 393*9e05bbacSSakari Ailus uint32_t lane_op_clock_ratio; 394*9e05bbacSSakari Ailus uint32_t mul, div; 395*9e05bbacSSakari Ailus unsigned int i; 396*9e05bbacSSakari Ailus int rval = -EINVAL; 397*9e05bbacSSakari Ailus 398*9e05bbacSSakari Ailus if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) { 399*9e05bbacSSakari Ailus /* 400*9e05bbacSSakari Ailus * If there's no OP PLL at all, use the VT values 401*9e05bbacSSakari Ailus * instead. The OP values are ignored for the rest of 402*9e05bbacSSakari Ailus * the PLL calculation. 403*9e05bbacSSakari Ailus */ 404*9e05bbacSSakari Ailus op_limits = &limits->vt; 405*9e05bbacSSakari Ailus op_pll = &pll->vt; 406*9e05bbacSSakari Ailus } 407*9e05bbacSSakari Ailus 408*9e05bbacSSakari Ailus if (pll->flags & CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE) 409*9e05bbacSSakari Ailus lane_op_clock_ratio = pll->csi2.lanes; 410*9e05bbacSSakari Ailus else 411*9e05bbacSSakari Ailus lane_op_clock_ratio = 1; 412*9e05bbacSSakari Ailus dev_dbg(dev, "lane_op_clock_ratio: %u\n", lane_op_clock_ratio); 413*9e05bbacSSakari Ailus 414*9e05bbacSSakari Ailus dev_dbg(dev, "binning: %ux%u\n", pll->binning_horizontal, 415*9e05bbacSSakari Ailus pll->binning_vertical); 416*9e05bbacSSakari Ailus 417*9e05bbacSSakari Ailus switch (pll->bus_type) { 418*9e05bbacSSakari Ailus case CCS_PLL_BUS_TYPE_CSI2: 419*9e05bbacSSakari Ailus /* CSI transfers 2 bits per clock per lane; thus times 2 */ 420*9e05bbacSSakari Ailus pll->pll_op_clk_freq_hz = pll->link_freq * 2 421*9e05bbacSSakari Ailus * (pll->csi2.lanes / lane_op_clock_ratio); 422*9e05bbacSSakari Ailus break; 423*9e05bbacSSakari Ailus case CCS_PLL_BUS_TYPE_PARALLEL: 424*9e05bbacSSakari Ailus pll->pll_op_clk_freq_hz = pll->link_freq * pll->bits_per_pixel 425*9e05bbacSSakari Ailus / DIV_ROUND_UP(pll->bits_per_pixel, 426*9e05bbacSSakari Ailus pll->parallel.bus_width); 427*9e05bbacSSakari Ailus break; 428*9e05bbacSSakari Ailus default: 429*9e05bbacSSakari Ailus return -EINVAL; 430*9e05bbacSSakari Ailus } 431*9e05bbacSSakari Ailus 432*9e05bbacSSakari Ailus /* Figure out limits for pre-pll divider based on extclk */ 433*9e05bbacSSakari Ailus dev_dbg(dev, "min / max pre_pll_clk_div: %u / %u\n", 434*9e05bbacSSakari Ailus limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div); 435*9e05bbacSSakari Ailus max_pre_pll_clk_div = 436*9e05bbacSSakari Ailus min_t(uint16_t, limits->max_pre_pll_clk_div, 437*9e05bbacSSakari Ailus clk_div_even(pll->ext_clk_freq_hz / 438*9e05bbacSSakari Ailus limits->min_pll_ip_freq_hz)); 439*9e05bbacSSakari Ailus min_pre_pll_clk_div = 440*9e05bbacSSakari Ailus max_t(uint16_t, limits->min_pre_pll_clk_div, 441*9e05bbacSSakari Ailus clk_div_even_up( 442*9e05bbacSSakari Ailus DIV_ROUND_UP(pll->ext_clk_freq_hz, 443*9e05bbacSSakari Ailus limits->max_pll_ip_freq_hz))); 444*9e05bbacSSakari Ailus dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %u / %u\n", 445*9e05bbacSSakari Ailus min_pre_pll_clk_div, max_pre_pll_clk_div); 446*9e05bbacSSakari Ailus 447*9e05bbacSSakari Ailus i = gcd(pll->pll_op_clk_freq_hz, pll->ext_clk_freq_hz); 448*9e05bbacSSakari Ailus mul = div_u64(pll->pll_op_clk_freq_hz, i); 449*9e05bbacSSakari Ailus div = pll->ext_clk_freq_hz / i; 450*9e05bbacSSakari Ailus dev_dbg(dev, "mul %u / div %u\n", mul, div); 451*9e05bbacSSakari Ailus 452*9e05bbacSSakari Ailus min_pre_pll_clk_div = 453*9e05bbacSSakari Ailus max_t(uint16_t, min_pre_pll_clk_div, 454*9e05bbacSSakari Ailus clk_div_even_up( 455*9e05bbacSSakari Ailus DIV_ROUND_UP(mul * pll->ext_clk_freq_hz, 456*9e05bbacSSakari Ailus limits->max_pll_op_freq_hz))); 457*9e05bbacSSakari Ailus dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %u / %u\n", 458*9e05bbacSSakari Ailus min_pre_pll_clk_div, max_pre_pll_clk_div); 459*9e05bbacSSakari Ailus 460*9e05bbacSSakari Ailus for (pll->pre_pll_clk_div = min_pre_pll_clk_div; 461*9e05bbacSSakari Ailus pll->pre_pll_clk_div <= max_pre_pll_clk_div; 462*9e05bbacSSakari Ailus pll->pre_pll_clk_div += 2 - (pll->pre_pll_clk_div & 1)) { 463*9e05bbacSSakari Ailus rval = __ccs_pll_calculate(dev, limits, op_limits, pll, op_pll, 464*9e05bbacSSakari Ailus mul, div, lane_op_clock_ratio); 465*9e05bbacSSakari Ailus if (rval) 466*9e05bbacSSakari Ailus continue; 467*9e05bbacSSakari Ailus 468*9e05bbacSSakari Ailus print_pll(dev, pll); 469*9e05bbacSSakari Ailus return 0; 470*9e05bbacSSakari Ailus } 471*9e05bbacSSakari Ailus 472*9e05bbacSSakari Ailus dev_dbg(dev, "unable to compute pre_pll divisor\n"); 473*9e05bbacSSakari Ailus 474*9e05bbacSSakari Ailus return rval; 475*9e05bbacSSakari Ailus } 476*9e05bbacSSakari Ailus EXPORT_SYMBOL_GPL(ccs_pll_calculate); 477*9e05bbacSSakari Ailus 478*9e05bbacSSakari Ailus MODULE_AUTHOR("Sakari Ailus <sakari.ailus@iki.fi>"); 479*9e05bbacSSakari Ailus MODULE_DESCRIPTION("Generic MIPI CCS/SMIA/SMIA++ PLL calculator"); 480*9e05bbacSSakari Ailus MODULE_LICENSE("GPL"); 481