Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * drivers/media/i2c/ccs-pll.c
0004  *
0005  * Generic MIPI CCS/SMIA/SMIA++ PLL calculator
0006  *
0007  * Copyright (C) 2020 Intel Corporation
0008  * Copyright (C) 2011--2012 Nokia Corporation
0009  * Contact: Sakari Ailus <sakari.ailus@linux.intel.com>
0010  */
0011 
0012 #include <linux/device.h>
0013 #include <linux/gcd.h>
0014 #include <linux/lcm.h>
0015 #include <linux/module.h>
0016 
0017 #include "ccs-pll.h"
0018 
0019 /* Return an even number or one. */
0020 static inline u32 clk_div_even(u32 a)
0021 {
0022     return max_t(u32, 1, a & ~1);
0023 }
0024 
0025 /* Return an even number or one. */
0026 static inline u32 clk_div_even_up(u32 a)
0027 {
0028     if (a == 1)
0029         return 1;
0030     return (a + 1) & ~1;
0031 }
0032 
0033 static inline u32 is_one_or_even(u32 a)
0034 {
0035     if (a == 1)
0036         return 1;
0037     if (a & 1)
0038         return 0;
0039 
0040     return 1;
0041 }
0042 
0043 static inline u32 one_or_more(u32 a)
0044 {
0045     return a ?: 1;
0046 }
0047 
0048 static int bounds_check(struct device *dev, u32 val,
0049             u32 min, u32 max, const char *prefix,
0050             char *str)
0051 {
0052     if (val >= min && val <= max)
0053         return 0;
0054 
0055     dev_dbg(dev, "%s_%s out of bounds: %d (%d--%d)\n", prefix,
0056         str, val, min, max);
0057 
0058     return -EINVAL;
0059 }
0060 
0061 #define PLL_OP 1
0062 #define PLL_VT 2
0063 
0064 static const char *pll_string(unsigned int which)
0065 {
0066     switch (which) {
0067     case PLL_OP:
0068         return "op";
0069     case PLL_VT:
0070         return "vt";
0071     }
0072 
0073     return NULL;
0074 }
0075 
0076 #define PLL_FL(f) CCS_PLL_FLAG_##f
0077 
0078 static void print_pll(struct device *dev, struct ccs_pll *pll)
0079 {
0080     const struct {
0081         struct ccs_pll_branch_fr *fr;
0082         struct ccs_pll_branch_bk *bk;
0083         unsigned int which;
0084     } branches[] = {
0085         { &pll->vt_fr, &pll->vt_bk, PLL_VT },
0086         { &pll->op_fr, &pll->op_bk, PLL_OP }
0087     }, *br;
0088     unsigned int i;
0089 
0090     dev_dbg(dev, "ext_clk_freq_hz\t\t%u\n", pll->ext_clk_freq_hz);
0091 
0092     for (i = 0, br = branches; i < ARRAY_SIZE(branches); i++, br++) {
0093         const char *s = pll_string(br->which);
0094 
0095         if (pll->flags & CCS_PLL_FLAG_DUAL_PLL ||
0096             br->which == PLL_VT) {
0097             dev_dbg(dev, "%s_pre_pll_clk_div\t\t%u\n",  s,
0098                 br->fr->pre_pll_clk_div);
0099             dev_dbg(dev, "%s_pll_multiplier\t\t%u\n",  s,
0100                 br->fr->pll_multiplier);
0101 
0102             dev_dbg(dev, "%s_pll_ip_clk_freq_hz\t%u\n", s,
0103                 br->fr->pll_ip_clk_freq_hz);
0104             dev_dbg(dev, "%s_pll_op_clk_freq_hz\t%u\n", s,
0105                 br->fr->pll_op_clk_freq_hz);
0106         }
0107 
0108         if (!(pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) ||
0109             br->which == PLL_VT) {
0110             dev_dbg(dev, "%s_sys_clk_div\t\t%u\n",  s,
0111                 br->bk->sys_clk_div);
0112             dev_dbg(dev, "%s_pix_clk_div\t\t%u\n", s,
0113                 br->bk->pix_clk_div);
0114 
0115             dev_dbg(dev, "%s_sys_clk_freq_hz\t%u\n", s,
0116                 br->bk->sys_clk_freq_hz);
0117             dev_dbg(dev, "%s_pix_clk_freq_hz\t%u\n", s,
0118                 br->bk->pix_clk_freq_hz);
0119         }
0120     }
0121 
0122     dev_dbg(dev, "pixel rate in pixel array:\t%u\n",
0123         pll->pixel_rate_pixel_array);
0124     dev_dbg(dev, "pixel rate on CSI-2 bus:\t%u\n",
0125         pll->pixel_rate_csi);
0126 
0127     dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s\n",
0128         pll->flags & PLL_FL(LANE_SPEED_MODEL) ? " lane-speed" : "",
0129         pll->flags & PLL_FL(LINK_DECOUPLED) ? " link-decoupled" : "",
0130         pll->flags & PLL_FL(EXT_IP_PLL_DIVIDER) ?
0131         " ext-ip-pll-divider" : "",
0132         pll->flags & PLL_FL(FLEXIBLE_OP_PIX_CLK_DIV) ?
0133         " flexible-op-pix-div" : "",
0134         pll->flags & PLL_FL(FIFO_DERATING) ? " fifo-derating" : "",
0135         pll->flags & PLL_FL(FIFO_OVERRATING) ? " fifo-overrating" : "",
0136         pll->flags & PLL_FL(DUAL_PLL) ? " dual-pll" : "",
0137         pll->flags & PLL_FL(OP_SYS_DDR) ? " op-sys-ddr" : "",
0138         pll->flags & PLL_FL(OP_PIX_DDR) ? " op-pix-ddr" : "");
0139 }
0140 
0141 static u32 op_sys_ddr(u32 flags)
0142 {
0143     return flags & CCS_PLL_FLAG_OP_SYS_DDR ? 1 : 0;
0144 }
0145 
0146 static u32 op_pix_ddr(u32 flags)
0147 {
0148     return flags & CCS_PLL_FLAG_OP_PIX_DDR ? 1 : 0;
0149 }
0150 
0151 static int check_fr_bounds(struct device *dev,
0152                const struct ccs_pll_limits *lim,
0153                struct ccs_pll *pll, unsigned int which)
0154 {
0155     const struct ccs_pll_branch_limits_fr *lim_fr;
0156     struct ccs_pll_branch_fr *pll_fr;
0157     const char *s = pll_string(which);
0158     int rval;
0159 
0160     if (which == PLL_OP) {
0161         lim_fr = &lim->op_fr;
0162         pll_fr = &pll->op_fr;
0163     } else {
0164         lim_fr = &lim->vt_fr;
0165         pll_fr = &pll->vt_fr;
0166     }
0167 
0168     rval = bounds_check(dev, pll_fr->pre_pll_clk_div,
0169                 lim_fr->min_pre_pll_clk_div,
0170                 lim_fr->max_pre_pll_clk_div, s, "pre_pll_clk_div");
0171 
0172     if (!rval)
0173         rval = bounds_check(dev, pll_fr->pll_ip_clk_freq_hz,
0174                     lim_fr->min_pll_ip_clk_freq_hz,
0175                     lim_fr->max_pll_ip_clk_freq_hz,
0176                     s, "pll_ip_clk_freq_hz");
0177     if (!rval)
0178         rval = bounds_check(dev, pll_fr->pll_multiplier,
0179                     lim_fr->min_pll_multiplier,
0180                     lim_fr->max_pll_multiplier,
0181                     s, "pll_multiplier");
0182     if (!rval)
0183         rval = bounds_check(dev, pll_fr->pll_op_clk_freq_hz,
0184                     lim_fr->min_pll_op_clk_freq_hz,
0185                     lim_fr->max_pll_op_clk_freq_hz,
0186                     s, "pll_op_clk_freq_hz");
0187 
0188     return rval;
0189 }
0190 
0191 static int check_bk_bounds(struct device *dev,
0192                const struct ccs_pll_limits *lim,
0193                struct ccs_pll *pll, unsigned int which)
0194 {
0195     const struct ccs_pll_branch_limits_bk *lim_bk;
0196     struct ccs_pll_branch_bk *pll_bk;
0197     const char *s = pll_string(which);
0198     int rval;
0199 
0200     if (which == PLL_OP) {
0201         if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)
0202             return 0;
0203 
0204         lim_bk = &lim->op_bk;
0205         pll_bk = &pll->op_bk;
0206     } else {
0207         lim_bk = &lim->vt_bk;
0208         pll_bk = &pll->vt_bk;
0209     }
0210 
0211     rval = bounds_check(dev, pll_bk->sys_clk_div,
0212                 lim_bk->min_sys_clk_div,
0213                 lim_bk->max_sys_clk_div, s, "op_sys_clk_div");
0214     if (!rval)
0215         rval = bounds_check(dev, pll_bk->sys_clk_freq_hz,
0216                     lim_bk->min_sys_clk_freq_hz,
0217                     lim_bk->max_sys_clk_freq_hz,
0218                     s, "sys_clk_freq_hz");
0219     if (!rval)
0220         rval = bounds_check(dev, pll_bk->sys_clk_div,
0221                     lim_bk->min_sys_clk_div,
0222                     lim_bk->max_sys_clk_div,
0223                     s, "sys_clk_div");
0224     if (!rval)
0225         rval = bounds_check(dev, pll_bk->pix_clk_freq_hz,
0226                     lim_bk->min_pix_clk_freq_hz,
0227                     lim_bk->max_pix_clk_freq_hz,
0228                     s, "pix_clk_freq_hz");
0229 
0230     return rval;
0231 }
0232 
0233 static int check_ext_bounds(struct device *dev, struct ccs_pll *pll)
0234 {
0235     if (!(pll->flags & CCS_PLL_FLAG_FIFO_DERATING) &&
0236         pll->pixel_rate_pixel_array > pll->pixel_rate_csi) {
0237         dev_dbg(dev, "device does not support derating\n");
0238         return -EINVAL;
0239     }
0240 
0241     if (!(pll->flags & CCS_PLL_FLAG_FIFO_OVERRATING) &&
0242         pll->pixel_rate_pixel_array < pll->pixel_rate_csi) {
0243         dev_dbg(dev, "device does not support overrating\n");
0244         return -EINVAL;
0245     }
0246 
0247     return 0;
0248 }
0249 
0250 static void
0251 ccs_pll_find_vt_sys_div(struct device *dev, const struct ccs_pll_limits *lim,
0252             struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
0253             u16 min_vt_div, u16 max_vt_div,
0254             u16 *min_sys_div, u16 *max_sys_div)
0255 {
0256     /*
0257      * Find limits for sys_clk_div. Not all values are possible with all
0258      * values of pix_clk_div.
0259      */
0260     *min_sys_div = lim->vt_bk.min_sys_clk_div;
0261     dev_dbg(dev, "min_sys_div: %u\n", *min_sys_div);
0262     *min_sys_div = max_t(u16, *min_sys_div,
0263                  DIV_ROUND_UP(min_vt_div,
0264                       lim->vt_bk.max_pix_clk_div));
0265     dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %u\n", *min_sys_div);
0266     *min_sys_div = max_t(u16, *min_sys_div,
0267                  pll_fr->pll_op_clk_freq_hz
0268                  / lim->vt_bk.max_sys_clk_freq_hz);
0269     dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %u\n", *min_sys_div);
0270     *min_sys_div = clk_div_even_up(*min_sys_div);
0271     dev_dbg(dev, "min_sys_div: one or even: %u\n", *min_sys_div);
0272 
0273     *max_sys_div = lim->vt_bk.max_sys_clk_div;
0274     dev_dbg(dev, "max_sys_div: %u\n", *max_sys_div);
0275     *max_sys_div = min_t(u16, *max_sys_div,
0276                  DIV_ROUND_UP(max_vt_div,
0277                       lim->vt_bk.min_pix_clk_div));
0278     dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %u\n", *max_sys_div);
0279     *max_sys_div = min_t(u16, *max_sys_div,
0280                  DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
0281                       lim->vt_bk.min_pix_clk_freq_hz));
0282     dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %u\n", *max_sys_div);
0283 }
0284 
0285 #define CPHY_CONST      7
0286 #define DPHY_CONST      16
0287 #define PHY_CONST_DIV       16
0288 
0289 static inline int
0290 __ccs_pll_calculate_vt_tree(struct device *dev,
0291                 const struct ccs_pll_limits *lim,
0292                 struct ccs_pll *pll, u32 mul, u32 div)
0293 {
0294     const struct ccs_pll_branch_limits_fr *lim_fr = &lim->vt_fr;
0295     const struct ccs_pll_branch_limits_bk *lim_bk = &lim->vt_bk;
0296     struct ccs_pll_branch_fr *pll_fr = &pll->vt_fr;
0297     struct ccs_pll_branch_bk *pll_bk = &pll->vt_bk;
0298     u32 more_mul;
0299     u16 best_pix_div = SHRT_MAX >> 1, best_div;
0300     u16 vt_div, min_sys_div, max_sys_div, sys_div;
0301 
0302     pll_fr->pll_ip_clk_freq_hz =
0303         pll->ext_clk_freq_hz / pll_fr->pre_pll_clk_div;
0304 
0305     dev_dbg(dev, "vt_pll_ip_clk_freq_hz %u\n", pll_fr->pll_ip_clk_freq_hz);
0306 
0307     more_mul = one_or_more(DIV_ROUND_UP(lim_fr->min_pll_op_clk_freq_hz,
0308                         pll_fr->pll_ip_clk_freq_hz * mul));
0309 
0310     dev_dbg(dev, "more_mul: %u\n", more_mul);
0311     more_mul *= DIV_ROUND_UP(lim_fr->min_pll_multiplier, mul * more_mul);
0312     dev_dbg(dev, "more_mul2: %u\n", more_mul);
0313 
0314     pll_fr->pll_multiplier = mul * more_mul;
0315 
0316     if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz >
0317         lim_fr->max_pll_op_clk_freq_hz)
0318         return -EINVAL;
0319 
0320     pll_fr->pll_op_clk_freq_hz =
0321         pll_fr->pll_ip_clk_freq_hz * pll_fr->pll_multiplier;
0322 
0323     vt_div = div * more_mul;
0324 
0325     ccs_pll_find_vt_sys_div(dev, lim, pll, pll_fr, vt_div, vt_div,
0326                 &min_sys_div, &max_sys_div);
0327 
0328     max_sys_div = (vt_div & 1) ? 1 : max_sys_div;
0329 
0330     dev_dbg(dev, "vt min/max_sys_div: %u,%u\n", min_sys_div, max_sys_div);
0331 
0332     for (sys_div = min_sys_div; sys_div <= max_sys_div;
0333          sys_div += 2 - (sys_div & 1)) {
0334         u16 pix_div;
0335 
0336         if (vt_div % sys_div)
0337             continue;
0338 
0339         pix_div = vt_div / sys_div;
0340 
0341         if (pix_div < lim_bk->min_pix_clk_div ||
0342             pix_div > lim_bk->max_pix_clk_div) {
0343             dev_dbg(dev,
0344                 "pix_div %u too small or too big (%u--%u)\n",
0345                 pix_div,
0346                 lim_bk->min_pix_clk_div,
0347                 lim_bk->max_pix_clk_div);
0348             continue;
0349         }
0350 
0351         dev_dbg(dev, "sys/pix/best_pix: %u,%u,%u\n", sys_div, pix_div,
0352             best_pix_div);
0353 
0354         if (pix_div * sys_div <= best_pix_div) {
0355             best_pix_div = pix_div;
0356             best_div = pix_div * sys_div;
0357         }
0358     }
0359     if (best_pix_div == SHRT_MAX >> 1)
0360         return -EINVAL;
0361 
0362     pll_bk->sys_clk_div = best_div / best_pix_div;
0363     pll_bk->pix_clk_div = best_pix_div;
0364 
0365     pll_bk->sys_clk_freq_hz =
0366         pll_fr->pll_op_clk_freq_hz / pll_bk->sys_clk_div;
0367     pll_bk->pix_clk_freq_hz =
0368         pll_bk->sys_clk_freq_hz / pll_bk->pix_clk_div;
0369 
0370     pll->pixel_rate_pixel_array =
0371         pll_bk->pix_clk_freq_hz * pll->vt_lanes;
0372 
0373     return 0;
0374 }
0375 
0376 static int ccs_pll_calculate_vt_tree(struct device *dev,
0377                      const struct ccs_pll_limits *lim,
0378                      struct ccs_pll *pll)
0379 {
0380     const struct ccs_pll_branch_limits_fr *lim_fr = &lim->vt_fr;
0381     struct ccs_pll_branch_fr *pll_fr = &pll->vt_fr;
0382     u16 min_pre_pll_clk_div = lim_fr->min_pre_pll_clk_div;
0383     u16 max_pre_pll_clk_div = lim_fr->max_pre_pll_clk_div;
0384     u32 pre_mul, pre_div;
0385 
0386     pre_div = gcd(pll->pixel_rate_csi,
0387               pll->ext_clk_freq_hz * pll->vt_lanes);
0388     pre_mul = pll->pixel_rate_csi / pre_div;
0389     pre_div = pll->ext_clk_freq_hz * pll->vt_lanes / pre_div;
0390 
0391     /* Make sure PLL input frequency is within limits */
0392     max_pre_pll_clk_div =
0393         min_t(u16, max_pre_pll_clk_div,
0394               DIV_ROUND_UP(pll->ext_clk_freq_hz,
0395                    lim_fr->min_pll_ip_clk_freq_hz));
0396 
0397     min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div,
0398                     pll->ext_clk_freq_hz /
0399                     lim_fr->max_pll_ip_clk_freq_hz);
0400 
0401     dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
0402         min_pre_pll_clk_div, max_pre_pll_clk_div);
0403 
0404     for (pll_fr->pre_pll_clk_div = min_pre_pll_clk_div;
0405          pll_fr->pre_pll_clk_div <= max_pre_pll_clk_div;
0406          pll_fr->pre_pll_clk_div +=
0407              (pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER) ? 1 :
0408              2 - (pll_fr->pre_pll_clk_div & 1)) {
0409         u32 mul, div;
0410         int rval;
0411 
0412         div = gcd(pre_mul * pll_fr->pre_pll_clk_div, pre_div);
0413         mul = pre_mul * pll_fr->pre_pll_clk_div / div;
0414         div = pre_div / div;
0415 
0416         dev_dbg(dev, "vt pre-div/mul/div: %u,%u,%u\n",
0417             pll_fr->pre_pll_clk_div, mul, div);
0418 
0419         rval = __ccs_pll_calculate_vt_tree(dev, lim, pll,
0420                            mul, div);
0421         if (rval)
0422             continue;
0423 
0424         rval = check_fr_bounds(dev, lim, pll, PLL_VT);
0425         if (rval)
0426             continue;
0427 
0428         rval = check_bk_bounds(dev, lim, pll, PLL_VT);
0429         if (rval)
0430             continue;
0431 
0432         return 0;
0433     }
0434 
0435     return -EINVAL;
0436 }
0437 
0438 static void
0439 ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
0440              const struct ccs_pll_branch_limits_bk *op_lim_bk,
0441              struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
0442              struct ccs_pll_branch_bk *op_pll_bk, bool cphy,
0443              u32 phy_const)
0444 {
0445     u16 sys_div;
0446     u16 best_pix_div = SHRT_MAX >> 1;
0447     u16 vt_op_binning_div;
0448     u16 min_vt_div, max_vt_div, vt_div;
0449     u16 min_sys_div, max_sys_div;
0450 
0451     if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)
0452         goto out_calc_pixel_rate;
0453 
0454     /*
0455      * Find out whether a sensor supports derating. If it does not, VT and
0456      * OP domains are required to run at the same pixel rate.
0457      */
0458     if (!(pll->flags & CCS_PLL_FLAG_FIFO_DERATING)) {
0459         min_vt_div =
0460             op_pll_bk->sys_clk_div * op_pll_bk->pix_clk_div
0461             * pll->vt_lanes * phy_const / pll->op_lanes
0462             / (PHY_CONST_DIV << op_pix_ddr(pll->flags));
0463     } else {
0464         /*
0465          * Some sensors perform analogue binning and some do this
0466          * digitally. The ones doing this digitally can be roughly be
0467          * found out using this formula. The ones doing this digitally
0468          * should run at higher clock rate, so smaller divisor is used
0469          * on video timing side.
0470          */
0471         if (lim->min_line_length_pck_bin > lim->min_line_length_pck
0472             / pll->binning_horizontal)
0473             vt_op_binning_div = pll->binning_horizontal;
0474         else
0475             vt_op_binning_div = 1;
0476         dev_dbg(dev, "vt_op_binning_div: %u\n", vt_op_binning_div);
0477 
0478         /*
0479          * Profile 2 supports vt_pix_clk_div E [4, 10]
0480          *
0481          * Horizontal binning can be used as a base for difference in
0482          * divisors. One must make sure that horizontal blanking is
0483          * enough to accommodate the CSI-2 sync codes.
0484          *
0485          * Take scaling factor and number of VT lanes into account as well.
0486          *
0487          * Find absolute limits for the factor of vt divider.
0488          */
0489         dev_dbg(dev, "scale_m: %u\n", pll->scale_m);
0490         min_vt_div =
0491             DIV_ROUND_UP(pll->bits_per_pixel
0492                      * op_pll_bk->sys_clk_div * pll->scale_n
0493                      * pll->vt_lanes * phy_const,
0494                      (pll->flags &
0495                       CCS_PLL_FLAG_LANE_SPEED_MODEL ?
0496                       pll->csi2.lanes : 1)
0497                      * vt_op_binning_div * pll->scale_m
0498                      * PHY_CONST_DIV << op_pix_ddr(pll->flags));
0499     }
0500 
0501     /* Find smallest and biggest allowed vt divisor. */
0502     dev_dbg(dev, "min_vt_div: %u\n", min_vt_div);
0503     min_vt_div = max_t(u16, min_vt_div,
0504                DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
0505                     lim->vt_bk.max_pix_clk_freq_hz));
0506     dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %u\n",
0507         min_vt_div);
0508     min_vt_div = max_t(u16, min_vt_div, lim->vt_bk.min_pix_clk_div
0509                         * lim->vt_bk.min_sys_clk_div);
0510     dev_dbg(dev, "min_vt_div: min_vt_clk_div: %u\n", min_vt_div);
0511 
0512     max_vt_div = lim->vt_bk.max_sys_clk_div * lim->vt_bk.max_pix_clk_div;
0513     dev_dbg(dev, "max_vt_div: %u\n", max_vt_div);
0514     max_vt_div = min_t(u16, max_vt_div,
0515                DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
0516                       lim->vt_bk.min_pix_clk_freq_hz));
0517     dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %u\n",
0518         max_vt_div);
0519 
0520     ccs_pll_find_vt_sys_div(dev, lim, pll, pll_fr, min_vt_div,
0521                 max_vt_div, &min_sys_div, &max_sys_div);
0522 
0523     /*
0524      * Find pix_div such that a legal pix_div * sys_div results
0525      * into a value which is not smaller than div, the desired
0526      * divisor.
0527      */
0528     for (vt_div = min_vt_div; vt_div <= max_vt_div; vt_div++) {
0529         u16 __max_sys_div = vt_div & 1 ? 1 : max_sys_div;
0530 
0531         for (sys_div = min_sys_div; sys_div <= __max_sys_div;
0532              sys_div += 2 - (sys_div & 1)) {
0533             u16 pix_div;
0534             u16 rounded_div;
0535 
0536             pix_div = DIV_ROUND_UP(vt_div, sys_div);
0537 
0538             if (pix_div < lim->vt_bk.min_pix_clk_div
0539                 || pix_div > lim->vt_bk.max_pix_clk_div) {
0540                 dev_dbg(dev,
0541                     "pix_div %u too small or too big (%u--%u)\n",
0542                     pix_div,
0543                     lim->vt_bk.min_pix_clk_div,
0544                     lim->vt_bk.max_pix_clk_div);
0545                 continue;
0546             }
0547 
0548             rounded_div = roundup(vt_div, best_pix_div);
0549 
0550             /* Check if this one is better. */
0551             if (pix_div * sys_div <= rounded_div)
0552                 best_pix_div = pix_div;
0553 
0554             /* Bail out if we've already found the best value. */
0555             if (vt_div == rounded_div)
0556                 break;
0557         }
0558         if (best_pix_div < SHRT_MAX >> 1)
0559             break;
0560     }
0561 
0562     pll->vt_bk.sys_clk_div = DIV_ROUND_UP(vt_div, best_pix_div);
0563     pll->vt_bk.pix_clk_div = best_pix_div;
0564 
0565     pll->vt_bk.sys_clk_freq_hz =
0566         pll_fr->pll_op_clk_freq_hz / pll->vt_bk.sys_clk_div;
0567     pll->vt_bk.pix_clk_freq_hz =
0568         pll->vt_bk.sys_clk_freq_hz / pll->vt_bk.pix_clk_div;
0569 
0570 out_calc_pixel_rate:
0571     pll->pixel_rate_pixel_array =
0572         pll->vt_bk.pix_clk_freq_hz * pll->vt_lanes;
0573 }
0574 
0575 /*
0576  * Heuristically guess the PLL tree for a given common multiplier and
0577  * divisor. Begin with the operational timing and continue to video
0578  * timing once operational timing has been verified.
0579  *
0580  * @mul is the PLL multiplier and @div is the common divisor
0581  * (pre_pll_clk_div and op_sys_clk_div combined). The final PLL
0582  * multiplier will be a multiple of @mul.
0583  *
0584  * @return Zero on success, error code on error.
0585  */
0586 static int
0587 ccs_pll_calculate_op(struct device *dev, const struct ccs_pll_limits *lim,
0588              const struct ccs_pll_branch_limits_fr *op_lim_fr,
0589              const struct ccs_pll_branch_limits_bk *op_lim_bk,
0590              struct ccs_pll *pll, struct ccs_pll_branch_fr *op_pll_fr,
0591              struct ccs_pll_branch_bk *op_pll_bk, u32 mul,
0592              u32 div, u32 op_sys_clk_freq_hz_sdr, u32 l,
0593              bool cphy, u32 phy_const)
0594 {
0595     /*
0596      * Higher multipliers (and divisors) are often required than
0597      * necessitated by the external clock and the output clocks.
0598      * There are limits for all values in the clock tree. These
0599      * are the minimum and maximum multiplier for mul.
0600      */
0601     u32 more_mul_min, more_mul_max;
0602     u32 more_mul_factor;
0603     u32 i;
0604 
0605     /*
0606      * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be
0607      * too high.
0608      */
0609     dev_dbg(dev, "op_pre_pll_clk_div %u\n", op_pll_fr->pre_pll_clk_div);
0610 
0611     /* Don't go above max pll multiplier. */
0612     more_mul_max = op_lim_fr->max_pll_multiplier / mul;
0613     dev_dbg(dev, "more_mul_max: max_op_pll_multiplier check: %u\n",
0614         more_mul_max);
0615     /* Don't go above max pll op frequency. */
0616     more_mul_max =
0617         min_t(u32,
0618               more_mul_max,
0619               op_lim_fr->max_pll_op_clk_freq_hz
0620               / (pll->ext_clk_freq_hz /
0621              op_pll_fr->pre_pll_clk_div * mul));
0622     dev_dbg(dev, "more_mul_max: max_pll_op_clk_freq_hz check: %u\n",
0623         more_mul_max);
0624     /* Don't go above the division capability of op sys clock divider. */
0625     more_mul_max = min(more_mul_max,
0626                op_lim_bk->max_sys_clk_div * op_pll_fr->pre_pll_clk_div
0627                / div);
0628     dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %u\n",
0629         more_mul_max);
0630     /* Ensure we won't go above max_pll_multiplier. */
0631     more_mul_max = min(more_mul_max, op_lim_fr->max_pll_multiplier / mul);
0632     dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %u\n",
0633         more_mul_max);
0634 
0635     /* Ensure we won't go below min_pll_op_clk_freq_hz. */
0636     more_mul_min = DIV_ROUND_UP(op_lim_fr->min_pll_op_clk_freq_hz,
0637                     pll->ext_clk_freq_hz /
0638                     op_pll_fr->pre_pll_clk_div * mul);
0639     dev_dbg(dev, "more_mul_min: min_op_pll_op_clk_freq_hz check: %u\n",
0640         more_mul_min);
0641     /* Ensure we won't go below min_pll_multiplier. */
0642     more_mul_min = max(more_mul_min,
0643                DIV_ROUND_UP(op_lim_fr->min_pll_multiplier, mul));
0644     dev_dbg(dev, "more_mul_min: min_op_pll_multiplier check: %u\n",
0645         more_mul_min);
0646 
0647     if (more_mul_min > more_mul_max) {
0648         dev_dbg(dev,
0649             "unable to compute more_mul_min and more_mul_max\n");
0650         return -EINVAL;
0651     }
0652 
0653     more_mul_factor = lcm(div, op_pll_fr->pre_pll_clk_div) / div;
0654     dev_dbg(dev, "more_mul_factor: %u\n", more_mul_factor);
0655     more_mul_factor = lcm(more_mul_factor, op_lim_bk->min_sys_clk_div);
0656     dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n",
0657         more_mul_factor);
0658     i = roundup(more_mul_min, more_mul_factor);
0659     if (!is_one_or_even(i))
0660         i <<= 1;
0661 
0662     dev_dbg(dev, "final more_mul: %u\n", i);
0663     if (i > more_mul_max) {
0664         dev_dbg(dev, "final more_mul is bad, max %u\n", more_mul_max);
0665         return -EINVAL;
0666     }
0667 
0668     op_pll_fr->pll_multiplier = mul * i;
0669     op_pll_bk->sys_clk_div = div * i / op_pll_fr->pre_pll_clk_div;
0670     dev_dbg(dev, "op_sys_clk_div: %u\n", op_pll_bk->sys_clk_div);
0671 
0672     op_pll_fr->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz
0673         / op_pll_fr->pre_pll_clk_div;
0674 
0675     op_pll_fr->pll_op_clk_freq_hz = op_pll_fr->pll_ip_clk_freq_hz
0676         * op_pll_fr->pll_multiplier;
0677 
0678     if (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL)
0679         op_pll_bk->pix_clk_div =
0680             (pll->bits_per_pixel
0681              * pll->op_lanes * (phy_const << op_sys_ddr(pll->flags))
0682              / PHY_CONST_DIV / pll->csi2.lanes / l)
0683             >> op_pix_ddr(pll->flags);
0684     else
0685         op_pll_bk->pix_clk_div =
0686             (pll->bits_per_pixel
0687              * (phy_const << op_sys_ddr(pll->flags))
0688              / PHY_CONST_DIV / l) >> op_pix_ddr(pll->flags);
0689 
0690     op_pll_bk->pix_clk_freq_hz =
0691         (op_sys_clk_freq_hz_sdr >> op_pix_ddr(pll->flags))
0692         / op_pll_bk->pix_clk_div;
0693     op_pll_bk->sys_clk_freq_hz =
0694         op_sys_clk_freq_hz_sdr >> op_sys_ddr(pll->flags);
0695 
0696     dev_dbg(dev, "op_pix_clk_div: %u\n", op_pll_bk->pix_clk_div);
0697 
0698     return 0;
0699 }
0700 
0701 int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
0702               struct ccs_pll *pll)
0703 {
0704     const struct ccs_pll_branch_limits_fr *op_lim_fr;
0705     const struct ccs_pll_branch_limits_bk *op_lim_bk;
0706     struct ccs_pll_branch_fr *op_pll_fr;
0707     struct ccs_pll_branch_bk *op_pll_bk;
0708     bool cphy = pll->bus_type == CCS_PLL_BUS_TYPE_CSI2_CPHY;
0709     u32 phy_const = cphy ? CPHY_CONST : DPHY_CONST;
0710     u32 op_sys_clk_freq_hz_sdr;
0711     u16 min_op_pre_pll_clk_div;
0712     u16 max_op_pre_pll_clk_div;
0713     u32 mul, div;
0714     u32 l = (!pll->op_bits_per_lane ||
0715          pll->op_bits_per_lane >= pll->bits_per_pixel) ? 1 : 2;
0716     u32 i;
0717     int rval = -EINVAL;
0718 
0719     if (!(pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL)) {
0720         pll->op_lanes = 1;
0721         pll->vt_lanes = 1;
0722     }
0723 
0724     if (pll->flags & CCS_PLL_FLAG_DUAL_PLL) {
0725         op_lim_fr = &lim->op_fr;
0726         op_lim_bk = &lim->op_bk;
0727         op_pll_fr = &pll->op_fr;
0728         op_pll_bk = &pll->op_bk;
0729     } else if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) {
0730         /*
0731          * If there's no OP PLL at all, use the VT values
0732          * instead. The OP values are ignored for the rest of
0733          * the PLL calculation.
0734          */
0735         op_lim_fr = &lim->vt_fr;
0736         op_lim_bk = &lim->vt_bk;
0737         op_pll_fr = &pll->vt_fr;
0738         op_pll_bk = &pll->vt_bk;
0739     } else {
0740         op_lim_fr = &lim->vt_fr;
0741         op_lim_bk = &lim->op_bk;
0742         op_pll_fr = &pll->vt_fr;
0743         op_pll_bk = &pll->op_bk;
0744     }
0745 
0746     if (!pll->op_lanes || !pll->vt_lanes || !pll->bits_per_pixel ||
0747         !pll->ext_clk_freq_hz || !pll->link_freq || !pll->scale_m ||
0748         !op_lim_fr->min_pll_ip_clk_freq_hz ||
0749         !op_lim_fr->max_pll_ip_clk_freq_hz ||
0750         !op_lim_fr->min_pll_op_clk_freq_hz ||
0751         !op_lim_fr->max_pll_op_clk_freq_hz ||
0752         !op_lim_bk->max_sys_clk_div || !op_lim_fr->max_pll_multiplier)
0753         return -EINVAL;
0754 
0755     /*
0756      * Make sure op_pix_clk_div will be integer --- unless flexible
0757      * op_pix_clk_div is supported
0758      */
0759     if (!(pll->flags & CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV) &&
0760         (pll->bits_per_pixel * pll->op_lanes) %
0761         (pll->csi2.lanes * l << op_pix_ddr(pll->flags))) {
0762         dev_dbg(dev, "op_pix_clk_div not an integer (bpp %u, op lanes %u, lanes %u, l %u)\n",
0763             pll->bits_per_pixel, pll->op_lanes, pll->csi2.lanes, l);
0764         return -EINVAL;
0765     }
0766 
0767     dev_dbg(dev, "vt_lanes: %u\n", pll->vt_lanes);
0768     dev_dbg(dev, "op_lanes: %u\n", pll->op_lanes);
0769 
0770     dev_dbg(dev, "binning: %ux%u\n", pll->binning_horizontal,
0771         pll->binning_vertical);
0772 
0773     switch (pll->bus_type) {
0774     case CCS_PLL_BUS_TYPE_CSI2_DPHY:
0775     case CCS_PLL_BUS_TYPE_CSI2_CPHY:
0776         op_sys_clk_freq_hz_sdr = pll->link_freq * 2
0777             * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
0778                1 : pll->csi2.lanes);
0779         break;
0780     default:
0781         return -EINVAL;
0782     }
0783 
0784     pll->pixel_rate_csi =
0785         div_u64((uint64_t)op_sys_clk_freq_hz_sdr
0786             * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
0787                pll->csi2.lanes : 1) * PHY_CONST_DIV,
0788             phy_const * pll->bits_per_pixel * l);
0789 
0790     /* Figure out limits for OP pre-pll divider based on extclk */
0791     dev_dbg(dev, "min / max op_pre_pll_clk_div: %u / %u\n",
0792         op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
0793     max_op_pre_pll_clk_div =
0794         min_t(u16, op_lim_fr->max_pre_pll_clk_div,
0795               clk_div_even(pll->ext_clk_freq_hz /
0796                    op_lim_fr->min_pll_ip_clk_freq_hz));
0797     min_op_pre_pll_clk_div =
0798         max_t(u16, op_lim_fr->min_pre_pll_clk_div,
0799               clk_div_even_up(
0800                   DIV_ROUND_UP(pll->ext_clk_freq_hz,
0801                        op_lim_fr->max_pll_ip_clk_freq_hz)));
0802     dev_dbg(dev, "pre-pll check: min / max op_pre_pll_clk_div: %u / %u\n",
0803         min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
0804 
0805     i = gcd(op_sys_clk_freq_hz_sdr,
0806         pll->ext_clk_freq_hz << op_pix_ddr(pll->flags));
0807     mul = op_sys_clk_freq_hz_sdr / i;
0808     div = (pll->ext_clk_freq_hz << op_pix_ddr(pll->flags)) / i;
0809     dev_dbg(dev, "mul %u / div %u\n", mul, div);
0810 
0811     min_op_pre_pll_clk_div =
0812         max_t(u16, min_op_pre_pll_clk_div,
0813               clk_div_even_up(
0814                   mul /
0815                   one_or_more(
0816                       DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
0817                            pll->ext_clk_freq_hz))));
0818     dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
0819         min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
0820 
0821     for (op_pll_fr->pre_pll_clk_div = min_op_pre_pll_clk_div;
0822          op_pll_fr->pre_pll_clk_div <= max_op_pre_pll_clk_div;
0823          op_pll_fr->pre_pll_clk_div +=
0824              (pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER) ? 1 :
0825              2 - (op_pll_fr->pre_pll_clk_div & 1)) {
0826         rval = ccs_pll_calculate_op(dev, lim, op_lim_fr, op_lim_bk, pll,
0827                         op_pll_fr, op_pll_bk, mul, div,
0828                         op_sys_clk_freq_hz_sdr, l, cphy,
0829                         phy_const);
0830         if (rval)
0831             continue;
0832 
0833         rval = check_fr_bounds(dev, lim, pll,
0834                        pll->flags & CCS_PLL_FLAG_DUAL_PLL ?
0835                        PLL_OP : PLL_VT);
0836         if (rval)
0837             continue;
0838 
0839         rval = check_bk_bounds(dev, lim, pll, PLL_OP);
0840         if (rval)
0841             continue;
0842 
0843         if (pll->flags & CCS_PLL_FLAG_DUAL_PLL)
0844             break;
0845 
0846         ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr,
0847                      op_pll_bk, cphy, phy_const);
0848 
0849         rval = check_bk_bounds(dev, lim, pll, PLL_VT);
0850         if (rval)
0851             continue;
0852         rval = check_ext_bounds(dev, pll);
0853         if (rval)
0854             continue;
0855 
0856         break;
0857     }
0858 
0859     if (rval) {
0860         dev_dbg(dev, "unable to compute pre_pll divisor\n");
0861 
0862         return rval;
0863     }
0864 
0865     if (pll->flags & CCS_PLL_FLAG_DUAL_PLL) {
0866         rval = ccs_pll_calculate_vt_tree(dev, lim, pll);
0867 
0868         if (rval)
0869             return rval;
0870     }
0871 
0872     print_pll(dev, pll);
0873 
0874     return 0;
0875 }
0876 EXPORT_SYMBOL_GPL(ccs_pll_calculate);
0877 
0878 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
0879 MODULE_DESCRIPTION("Generic MIPI CCS/SMIA/SMIA++ PLL calculator");
0880 MODULE_LICENSE("GPL");