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