ccs-pll.c (10205618052908770451acd33eaeaa7685e97ed2) ccs-pll.c (8a75e8dcd2ef409e2bc7bf3141549cd636b4696b)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * drivers/media/i2c/ccs-pll.c
4 *
5 * Generic MIPI CCS/SMIA/SMIA++ PLL calculator
6 *
7 * Copyright (C) 2020 Intel Corporation
8 * Copyright (C) 2011--2012 Nokia Corporation
9 * Contact: Sakari Ailus <sakari.ailus@linux.intel.com>
10 */
11
12#include <linux/device.h>
13#include <linux/gcd.h>
14#include <linux/lcm.h>
15#include <linux/module.h>
16
17#include "ccs-pll.h"
18
19/* Return an even number or one. */
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * drivers/media/i2c/ccs-pll.c
4 *
5 * Generic MIPI CCS/SMIA/SMIA++ PLL calculator
6 *
7 * Copyright (C) 2020 Intel Corporation
8 * Copyright (C) 2011--2012 Nokia Corporation
9 * Contact: Sakari Ailus <sakari.ailus@linux.intel.com>
10 */
11
12#include <linux/device.h>
13#include <linux/gcd.h>
14#include <linux/lcm.h>
15#include <linux/module.h>
16
17#include "ccs-pll.h"
18
19/* Return an even number or one. */
20static inline uint32_t clk_div_even(uint32_t a)
20static inline u32 clk_div_even(u32 a)
21{
21{
22 return max_t(uint32_t, 1, a & ~1);
22 return max_t(u32, 1, a & ~1);
23}
24
25/* Return an even number or one. */
23}
24
25/* Return an even number or one. */
26static inline uint32_t clk_div_even_up(uint32_t a)
26static inline u32 clk_div_even_up(u32 a)
27{
28 if (a == 1)
29 return 1;
30 return (a + 1) & ~1;
31}
32
27{
28 if (a == 1)
29 return 1;
30 return (a + 1) & ~1;
31}
32
33static inline uint32_t is_one_or_even(uint32_t a)
33static inline u32 is_one_or_even(u32 a)
34{
35 if (a == 1)
36 return 1;
37 if (a & 1)
38 return 0;
39
40 return 1;
41}
42
34{
35 if (a == 1)
36 return 1;
37 if (a & 1)
38 return 0;
39
40 return 1;
41}
42
43static inline uint32_t one_or_more(uint32_t a)
43static inline u32 one_or_more(u32 a)
44{
45 return a ?: 1;
46}
47
44{
45 return a ?: 1;
46}
47
48static int bounds_check(struct device *dev, uint32_t val,
49 uint32_t min, uint32_t max, const char *prefix,
48static int bounds_check(struct device *dev, u32 val,
49 u32 min, u32 max, const char *prefix,
50 char *str)
51{
52 if (val >= min && val <= max)
53 return 0;
54
55 dev_dbg(dev, "%s_%s out of bounds: %d (%d--%d)\n", prefix,
56 str, val, min, max);
57

--- 75 unchanged lines hidden (view full) ---

133 " flexible-op-pix-div" : "",
134 pll->flags & PLL_FL(FIFO_DERATING) ? " fifo-derating" : "",
135 pll->flags & PLL_FL(FIFO_OVERRATING) ? " fifo-overrating" : "",
136 pll->flags & PLL_FL(DUAL_PLL) ? " dual-pll" : "",
137 pll->flags & PLL_FL(OP_SYS_DDR) ? " op-sys-ddr" : "",
138 pll->flags & PLL_FL(OP_PIX_DDR) ? " op-pix-ddr" : "");
139}
140
50 char *str)
51{
52 if (val >= min && val <= max)
53 return 0;
54
55 dev_dbg(dev, "%s_%s out of bounds: %d (%d--%d)\n", prefix,
56 str, val, min, max);
57

--- 75 unchanged lines hidden (view full) ---

133 " flexible-op-pix-div" : "",
134 pll->flags & PLL_FL(FIFO_DERATING) ? " fifo-derating" : "",
135 pll->flags & PLL_FL(FIFO_OVERRATING) ? " fifo-overrating" : "",
136 pll->flags & PLL_FL(DUAL_PLL) ? " dual-pll" : "",
137 pll->flags & PLL_FL(OP_SYS_DDR) ? " op-sys-ddr" : "",
138 pll->flags & PLL_FL(OP_PIX_DDR) ? " op-pix-ddr" : "");
139}
140
141static uint32_t op_sys_ddr(uint32_t flags)
141static u32 op_sys_ddr(u32 flags)
142{
143 return flags & CCS_PLL_FLAG_OP_SYS_DDR ? 1 : 0;
144}
145
142{
143 return flags & CCS_PLL_FLAG_OP_SYS_DDR ? 1 : 0;
144}
145
146static uint32_t op_pix_ddr(uint32_t flags)
146static u32 op_pix_ddr(u32 flags)
147{
148 return flags & CCS_PLL_FLAG_OP_PIX_DDR ? 1 : 0;
149}
150
151static int check_fr_bounds(struct device *dev,
152 const struct ccs_pll_limits *lim,
153 struct ccs_pll *pll, unsigned int which)
154{

--- 90 unchanged lines hidden (view full) ---

245 }
246
247 return 0;
248}
249
250static void
251ccs_pll_find_vt_sys_div(struct device *dev, const struct ccs_pll_limits *lim,
252 struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
147{
148 return flags & CCS_PLL_FLAG_OP_PIX_DDR ? 1 : 0;
149}
150
151static int check_fr_bounds(struct device *dev,
152 const struct ccs_pll_limits *lim,
153 struct ccs_pll *pll, unsigned int which)
154{

--- 90 unchanged lines hidden (view full) ---

245 }
246
247 return 0;
248}
249
250static void
251ccs_pll_find_vt_sys_div(struct device *dev, const struct ccs_pll_limits *lim,
252 struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
253 uint16_t min_vt_div, uint16_t max_vt_div,
254 uint16_t *min_sys_div, uint16_t *max_sys_div)
253 u16 min_vt_div, u16 max_vt_div,
254 u16 *min_sys_div, u16 *max_sys_div)
255{
256 /*
257 * Find limits for sys_clk_div. Not all values are possible with all
258 * values of pix_clk_div.
259 */
260 *min_sys_div = lim->vt_bk.min_sys_clk_div;
261 dev_dbg(dev, "min_sys_div: %u\n", *min_sys_div);
255{
256 /*
257 * Find limits for sys_clk_div. Not all values are possible with all
258 * values of pix_clk_div.
259 */
260 *min_sys_div = lim->vt_bk.min_sys_clk_div;
261 dev_dbg(dev, "min_sys_div: %u\n", *min_sys_div);
262 *min_sys_div = max_t(uint16_t, *min_sys_div,
262 *min_sys_div = max_t(u16, *min_sys_div,
263 DIV_ROUND_UP(min_vt_div,
264 lim->vt_bk.max_pix_clk_div));
265 dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %u\n", *min_sys_div);
263 DIV_ROUND_UP(min_vt_div,
264 lim->vt_bk.max_pix_clk_div));
265 dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %u\n", *min_sys_div);
266 *min_sys_div = max_t(uint16_t, *min_sys_div,
266 *min_sys_div = max_t(u16, *min_sys_div,
267 pll_fr->pll_op_clk_freq_hz
268 / lim->vt_bk.max_sys_clk_freq_hz);
269 dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %u\n", *min_sys_div);
270 *min_sys_div = clk_div_even_up(*min_sys_div);
271 dev_dbg(dev, "min_sys_div: one or even: %u\n", *min_sys_div);
272
273 *max_sys_div = lim->vt_bk.max_sys_clk_div;
274 dev_dbg(dev, "max_sys_div: %u\n", *max_sys_div);
267 pll_fr->pll_op_clk_freq_hz
268 / lim->vt_bk.max_sys_clk_freq_hz);
269 dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %u\n", *min_sys_div);
270 *min_sys_div = clk_div_even_up(*min_sys_div);
271 dev_dbg(dev, "min_sys_div: one or even: %u\n", *min_sys_div);
272
273 *max_sys_div = lim->vt_bk.max_sys_clk_div;
274 dev_dbg(dev, "max_sys_div: %u\n", *max_sys_div);
275 *max_sys_div = min_t(uint16_t, *max_sys_div,
275 *max_sys_div = min_t(u16, *max_sys_div,
276 DIV_ROUND_UP(max_vt_div,
277 lim->vt_bk.min_pix_clk_div));
278 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %u\n", *max_sys_div);
276 DIV_ROUND_UP(max_vt_div,
277 lim->vt_bk.min_pix_clk_div));
278 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %u\n", *max_sys_div);
279 *max_sys_div = min_t(uint16_t, *max_sys_div,
279 *max_sys_div = min_t(u16, *max_sys_div,
280 DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
281 lim->vt_bk.min_pix_clk_freq_hz));
282 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %u\n", *max_sys_div);
283}
284
285#define CPHY_CONST 7
286#define DPHY_CONST 16
287#define PHY_CONST_DIV 16
288
289static inline int
290__ccs_pll_calculate_vt_tree(struct device *dev,
291 const struct ccs_pll_limits *lim,
280 DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
281 lim->vt_bk.min_pix_clk_freq_hz));
282 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %u\n", *max_sys_div);
283}
284
285#define CPHY_CONST 7
286#define DPHY_CONST 16
287#define PHY_CONST_DIV 16
288
289static inline int
290__ccs_pll_calculate_vt_tree(struct device *dev,
291 const struct ccs_pll_limits *lim,
292 struct ccs_pll *pll, uint32_t mul, uint32_t div)
292 struct ccs_pll *pll, u32 mul, u32 div)
293{
294 const struct ccs_pll_branch_limits_fr *lim_fr = &lim->vt_fr;
295 const struct ccs_pll_branch_limits_bk *lim_bk = &lim->vt_bk;
296 struct ccs_pll_branch_fr *pll_fr = &pll->vt_fr;
297 struct ccs_pll_branch_bk *pll_bk = &pll->vt_bk;
293{
294 const struct ccs_pll_branch_limits_fr *lim_fr = &lim->vt_fr;
295 const struct ccs_pll_branch_limits_bk *lim_bk = &lim->vt_bk;
296 struct ccs_pll_branch_fr *pll_fr = &pll->vt_fr;
297 struct ccs_pll_branch_bk *pll_bk = &pll->vt_bk;
298 uint32_t more_mul;
299 uint16_t best_pix_div = SHRT_MAX >> 1, best_div;
300 uint16_t vt_div, min_sys_div, max_sys_div, sys_div;
298 u32 more_mul;
299 u16 best_pix_div = SHRT_MAX >> 1, best_div;
300 u16 vt_div, min_sys_div, max_sys_div, sys_div;
301
302 pll_fr->pll_ip_clk_freq_hz =
303 pll->ext_clk_freq_hz / pll_fr->pre_pll_clk_div;
304
305 dev_dbg(dev, "vt_pll_ip_clk_freq_hz %u\n", pll_fr->pll_ip_clk_freq_hz);
306
307 more_mul = one_or_more(DIV_ROUND_UP(lim_fr->min_pll_op_clk_freq_hz,
308 pll_fr->pll_ip_clk_freq_hz * mul));

--- 17 unchanged lines hidden (view full) ---

326 &min_sys_div, &max_sys_div);
327
328 max_sys_div = (vt_div & 1) ? 1 : max_sys_div;
329
330 dev_dbg(dev, "vt min/max_sys_div: %u,%u\n", min_sys_div, max_sys_div);
331
332 for (sys_div = min_sys_div; sys_div <= max_sys_div;
333 sys_div += 2 - (sys_div & 1)) {
301
302 pll_fr->pll_ip_clk_freq_hz =
303 pll->ext_clk_freq_hz / pll_fr->pre_pll_clk_div;
304
305 dev_dbg(dev, "vt_pll_ip_clk_freq_hz %u\n", pll_fr->pll_ip_clk_freq_hz);
306
307 more_mul = one_or_more(DIV_ROUND_UP(lim_fr->min_pll_op_clk_freq_hz,
308 pll_fr->pll_ip_clk_freq_hz * mul));

--- 17 unchanged lines hidden (view full) ---

326 &min_sys_div, &max_sys_div);
327
328 max_sys_div = (vt_div & 1) ? 1 : max_sys_div;
329
330 dev_dbg(dev, "vt min/max_sys_div: %u,%u\n", min_sys_div, max_sys_div);
331
332 for (sys_div = min_sys_div; sys_div <= max_sys_div;
333 sys_div += 2 - (sys_div & 1)) {
334 uint16_t pix_div;
334 u16 pix_div;
335
336 if (vt_div % sys_div)
337 continue;
338
339 pix_div = vt_div / sys_div;
340
341 if (pix_div < lim_bk->min_pix_clk_div ||
342 pix_div > lim_bk->max_pix_clk_div) {

--- 31 unchanged lines hidden (view full) ---

374}
375
376static int ccs_pll_calculate_vt_tree(struct device *dev,
377 const struct ccs_pll_limits *lim,
378 struct ccs_pll *pll)
379{
380 const struct ccs_pll_branch_limits_fr *lim_fr = &lim->vt_fr;
381 struct ccs_pll_branch_fr *pll_fr = &pll->vt_fr;
335
336 if (vt_div % sys_div)
337 continue;
338
339 pix_div = vt_div / sys_div;
340
341 if (pix_div < lim_bk->min_pix_clk_div ||
342 pix_div > lim_bk->max_pix_clk_div) {

--- 31 unchanged lines hidden (view full) ---

374}
375
376static int ccs_pll_calculate_vt_tree(struct device *dev,
377 const struct ccs_pll_limits *lim,
378 struct ccs_pll *pll)
379{
380 const struct ccs_pll_branch_limits_fr *lim_fr = &lim->vt_fr;
381 struct ccs_pll_branch_fr *pll_fr = &pll->vt_fr;
382 uint16_t min_pre_pll_clk_div = lim_fr->min_pre_pll_clk_div;
383 uint16_t max_pre_pll_clk_div = lim_fr->max_pre_pll_clk_div;
384 uint32_t pre_mul, pre_div;
382 u16 min_pre_pll_clk_div = lim_fr->min_pre_pll_clk_div;
383 u16 max_pre_pll_clk_div = lim_fr->max_pre_pll_clk_div;
384 u32 pre_mul, pre_div;
385
386 pre_div = gcd(pll->pixel_rate_csi,
387 pll->ext_clk_freq_hz * pll->vt_lanes);
388 pre_mul = pll->pixel_rate_csi / pre_div;
389 pre_div = pll->ext_clk_freq_hz * pll->vt_lanes / pre_div;
390
391 /* Make sure PLL input frequency is within limits */
392 max_pre_pll_clk_div =
385
386 pre_div = gcd(pll->pixel_rate_csi,
387 pll->ext_clk_freq_hz * pll->vt_lanes);
388 pre_mul = pll->pixel_rate_csi / pre_div;
389 pre_div = pll->ext_clk_freq_hz * pll->vt_lanes / pre_div;
390
391 /* Make sure PLL input frequency is within limits */
392 max_pre_pll_clk_div =
393 min_t(uint16_t, max_pre_pll_clk_div,
393 min_t(u16, max_pre_pll_clk_div,
394 DIV_ROUND_UP(pll->ext_clk_freq_hz,
395 lim_fr->min_pll_ip_clk_freq_hz));
396
394 DIV_ROUND_UP(pll->ext_clk_freq_hz,
395 lim_fr->min_pll_ip_clk_freq_hz));
396
397 min_pre_pll_clk_div = max_t(uint16_t, min_pre_pll_clk_div,
397 min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div,
398 pll->ext_clk_freq_hz /
399 lim_fr->max_pll_ip_clk_freq_hz);
400
401 dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
402 min_pre_pll_clk_div, max_pre_pll_clk_div);
403
404 for (pll_fr->pre_pll_clk_div = min_pre_pll_clk_div;
405 pll_fr->pre_pll_clk_div <= max_pre_pll_clk_div;
406 pll_fr->pre_pll_clk_div +=
407 (pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER) ? 1 :
408 2 - (pll_fr->pre_pll_clk_div & 1)) {
398 pll->ext_clk_freq_hz /
399 lim_fr->max_pll_ip_clk_freq_hz);
400
401 dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
402 min_pre_pll_clk_div, max_pre_pll_clk_div);
403
404 for (pll_fr->pre_pll_clk_div = min_pre_pll_clk_div;
405 pll_fr->pre_pll_clk_div <= max_pre_pll_clk_div;
406 pll_fr->pre_pll_clk_div +=
407 (pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER) ? 1 :
408 2 - (pll_fr->pre_pll_clk_div & 1)) {
409 uint32_t mul, div;
409 u32 mul, div;
410 int rval;
411
412 div = gcd(pre_mul * pll_fr->pre_pll_clk_div, pre_div);
413 mul = pre_mul * pll_fr->pre_pll_clk_div / div;
414 div = pre_div / div;
415
416 dev_dbg(dev, "vt pre-div/mul/div: %u,%u,%u\n",
417 pll_fr->pre_pll_clk_div, mul, div);

--- 17 unchanged lines hidden (view full) ---

435 return -EINVAL;
436}
437
438static void
439ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
440 const struct ccs_pll_branch_limits_bk *op_lim_bk,
441 struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
442 struct ccs_pll_branch_bk *op_pll_bk, bool cphy,
410 int rval;
411
412 div = gcd(pre_mul * pll_fr->pre_pll_clk_div, pre_div);
413 mul = pre_mul * pll_fr->pre_pll_clk_div / div;
414 div = pre_div / div;
415
416 dev_dbg(dev, "vt pre-div/mul/div: %u,%u,%u\n",
417 pll_fr->pre_pll_clk_div, mul, div);

--- 17 unchanged lines hidden (view full) ---

435 return -EINVAL;
436}
437
438static void
439ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
440 const struct ccs_pll_branch_limits_bk *op_lim_bk,
441 struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
442 struct ccs_pll_branch_bk *op_pll_bk, bool cphy,
443 uint32_t phy_const)
443 u32 phy_const)
444{
444{
445 uint16_t sys_div;
446 uint16_t best_pix_div = SHRT_MAX >> 1;
447 uint16_t vt_op_binning_div;
448 uint16_t min_vt_div, max_vt_div, vt_div;
449 uint16_t min_sys_div, max_sys_div;
445 u16 sys_div;
446 u16 best_pix_div = SHRT_MAX >> 1;
447 u16 vt_op_binning_div;
448 u16 min_vt_div, max_vt_div, vt_div;
449 u16 min_sys_div, max_sys_div;
450
451 if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)
452 goto out_calc_pixel_rate;
453
454 /*
455 * Find out whether a sensor supports derating. If it does not, VT and
456 * OP domains are required to run at the same pixel rate.
457 */

--- 37 unchanged lines hidden (view full) ---

495 CCS_PLL_FLAG_LANE_SPEED_MODEL ?
496 pll->csi2.lanes : 1)
497 * vt_op_binning_div * pll->scale_m
498 * PHY_CONST_DIV << op_pix_ddr(pll->flags));
499 }
500
501 /* Find smallest and biggest allowed vt divisor. */
502 dev_dbg(dev, "min_vt_div: %u\n", min_vt_div);
450
451 if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)
452 goto out_calc_pixel_rate;
453
454 /*
455 * Find out whether a sensor supports derating. If it does not, VT and
456 * OP domains are required to run at the same pixel rate.
457 */

--- 37 unchanged lines hidden (view full) ---

495 CCS_PLL_FLAG_LANE_SPEED_MODEL ?
496 pll->csi2.lanes : 1)
497 * vt_op_binning_div * pll->scale_m
498 * PHY_CONST_DIV << op_pix_ddr(pll->flags));
499 }
500
501 /* Find smallest and biggest allowed vt divisor. */
502 dev_dbg(dev, "min_vt_div: %u\n", min_vt_div);
503 min_vt_div = max_t(uint16_t, min_vt_div,
503 min_vt_div = max_t(u16, min_vt_div,
504 DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
505 lim->vt_bk.max_pix_clk_freq_hz));
506 dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %u\n",
507 min_vt_div);
504 DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
505 lim->vt_bk.max_pix_clk_freq_hz));
506 dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %u\n",
507 min_vt_div);
508 min_vt_div = max_t(uint16_t, min_vt_div, lim->vt_bk.min_pix_clk_div
509 * lim->vt_bk.min_sys_clk_div);
508 min_vt_div = max_t(u16, min_vt_div, lim->vt_bk.min_pix_clk_div
509 * lim->vt_bk.min_sys_clk_div);
510 dev_dbg(dev, "min_vt_div: min_vt_clk_div: %u\n", min_vt_div);
511
512 max_vt_div = lim->vt_bk.max_sys_clk_div * lim->vt_bk.max_pix_clk_div;
513 dev_dbg(dev, "max_vt_div: %u\n", max_vt_div);
510 dev_dbg(dev, "min_vt_div: min_vt_clk_div: %u\n", min_vt_div);
511
512 max_vt_div = lim->vt_bk.max_sys_clk_div * lim->vt_bk.max_pix_clk_div;
513 dev_dbg(dev, "max_vt_div: %u\n", max_vt_div);
514 max_vt_div = min_t(uint16_t, max_vt_div,
514 max_vt_div = min_t(u16, max_vt_div,
515 DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
516 lim->vt_bk.min_pix_clk_freq_hz));
517 dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %u\n",
518 max_vt_div);
519
520 ccs_pll_find_vt_sys_div(dev, lim, pll, pll_fr, min_vt_div,
521 max_vt_div, &min_sys_div, &max_sys_div);
522
523 /*
524 * Find pix_div such that a legal pix_div * sys_div results
525 * into a value which is not smaller than div, the desired
526 * divisor.
527 */
528 for (vt_div = min_vt_div; vt_div <= max_vt_div; vt_div++) {
515 DIV_ROUND_UP(pll_fr->pll_op_clk_freq_hz,
516 lim->vt_bk.min_pix_clk_freq_hz));
517 dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %u\n",
518 max_vt_div);
519
520 ccs_pll_find_vt_sys_div(dev, lim, pll, pll_fr, min_vt_div,
521 max_vt_div, &min_sys_div, &max_sys_div);
522
523 /*
524 * Find pix_div such that a legal pix_div * sys_div results
525 * into a value which is not smaller than div, the desired
526 * divisor.
527 */
528 for (vt_div = min_vt_div; vt_div <= max_vt_div; vt_div++) {
529 uint16_t __max_sys_div = vt_div & 1 ? 1 : max_sys_div;
529 u16 __max_sys_div = vt_div & 1 ? 1 : max_sys_div;
530
531 for (sys_div = min_sys_div; sys_div <= __max_sys_div;
532 sys_div += 2 - (sys_div & 1)) {
530
531 for (sys_div = min_sys_div; sys_div <= __max_sys_div;
532 sys_div += 2 - (sys_div & 1)) {
533 uint16_t pix_div;
534 uint16_t rounded_div;
533 u16 pix_div;
534 u16 rounded_div;
535
536 pix_div = DIV_ROUND_UP(vt_div, sys_div);
537
538 if (pix_div < lim->vt_bk.min_pix_clk_div
539 || pix_div > lim->vt_bk.max_pix_clk_div) {
540 dev_dbg(dev,
541 "pix_div %u too small or too big (%u--%u)\n",
542 pix_div,

--- 40 unchanged lines hidden (view full) ---

583 *
584 * @return Zero on success, error code on error.
585 */
586static int
587ccs_pll_calculate_op(struct device *dev, const struct ccs_pll_limits *lim,
588 const struct ccs_pll_branch_limits_fr *op_lim_fr,
589 const struct ccs_pll_branch_limits_bk *op_lim_bk,
590 struct ccs_pll *pll, struct ccs_pll_branch_fr *op_pll_fr,
535
536 pix_div = DIV_ROUND_UP(vt_div, sys_div);
537
538 if (pix_div < lim->vt_bk.min_pix_clk_div
539 || pix_div > lim->vt_bk.max_pix_clk_div) {
540 dev_dbg(dev,
541 "pix_div %u too small or too big (%u--%u)\n",
542 pix_div,

--- 40 unchanged lines hidden (view full) ---

583 *
584 * @return Zero on success, error code on error.
585 */
586static int
587ccs_pll_calculate_op(struct device *dev, const struct ccs_pll_limits *lim,
588 const struct ccs_pll_branch_limits_fr *op_lim_fr,
589 const struct ccs_pll_branch_limits_bk *op_lim_bk,
590 struct ccs_pll *pll, struct ccs_pll_branch_fr *op_pll_fr,
591 struct ccs_pll_branch_bk *op_pll_bk, uint32_t mul,
592 uint32_t div, uint32_t op_sys_clk_freq_hz_sdr, uint32_t l,
593 bool cphy, uint32_t phy_const)
591 struct ccs_pll_branch_bk *op_pll_bk, u32 mul,
592 u32 div, u32 op_sys_clk_freq_hz_sdr, u32 l,
593 bool cphy, u32 phy_const)
594{
595 /*
596 * Higher multipliers (and divisors) are often required than
597 * necessitated by the external clock and the output clocks.
598 * There are limits for all values in the clock tree. These
599 * are the minimum and maximum multiplier for mul.
600 */
594{
595 /*
596 * Higher multipliers (and divisors) are often required than
597 * necessitated by the external clock and the output clocks.
598 * There are limits for all values in the clock tree. These
599 * are the minimum and maximum multiplier for mul.
600 */
601 uint32_t more_mul_min, more_mul_max;
602 uint32_t more_mul_factor;
603 uint32_t i;
601 u32 more_mul_min, more_mul_max;
602 u32 more_mul_factor;
603 u32 i;
604
605 /*
606 * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be
607 * too high.
608 */
609 dev_dbg(dev, "op_pre_pll_clk_div %u\n", op_pll_fr->pre_pll_clk_div);
610
611 /* Don't go above max pll multiplier. */
612 more_mul_max = op_lim_fr->max_pll_multiplier / mul;
613 dev_dbg(dev, "more_mul_max: max_op_pll_multiplier check: %u\n",
614 more_mul_max);
615 /* Don't go above max pll op frequency. */
616 more_mul_max =
604
605 /*
606 * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be
607 * too high.
608 */
609 dev_dbg(dev, "op_pre_pll_clk_div %u\n", op_pll_fr->pre_pll_clk_div);
610
611 /* Don't go above max pll multiplier. */
612 more_mul_max = op_lim_fr->max_pll_multiplier / mul;
613 dev_dbg(dev, "more_mul_max: max_op_pll_multiplier check: %u\n",
614 more_mul_max);
615 /* Don't go above max pll op frequency. */
616 more_mul_max =
617 min_t(uint32_t,
617 min_t(u32,
618 more_mul_max,
619 op_lim_fr->max_pll_op_clk_freq_hz
620 / (pll->ext_clk_freq_hz /
621 op_pll_fr->pre_pll_clk_div * mul));
622 dev_dbg(dev, "more_mul_max: max_pll_op_clk_freq_hz check: %u\n",
623 more_mul_max);
624 /* Don't go above the division capability of op sys clock divider. */
625 more_mul_max = min(more_mul_max,

--- 75 unchanged lines hidden (view full) ---

701int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
702 struct ccs_pll *pll)
703{
704 const struct ccs_pll_branch_limits_fr *op_lim_fr;
705 const struct ccs_pll_branch_limits_bk *op_lim_bk;
706 struct ccs_pll_branch_fr *op_pll_fr;
707 struct ccs_pll_branch_bk *op_pll_bk;
708 bool cphy = pll->bus_type == CCS_PLL_BUS_TYPE_CSI2_CPHY;
618 more_mul_max,
619 op_lim_fr->max_pll_op_clk_freq_hz
620 / (pll->ext_clk_freq_hz /
621 op_pll_fr->pre_pll_clk_div * mul));
622 dev_dbg(dev, "more_mul_max: max_pll_op_clk_freq_hz check: %u\n",
623 more_mul_max);
624 /* Don't go above the division capability of op sys clock divider. */
625 more_mul_max = min(more_mul_max,

--- 75 unchanged lines hidden (view full) ---

701int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
702 struct ccs_pll *pll)
703{
704 const struct ccs_pll_branch_limits_fr *op_lim_fr;
705 const struct ccs_pll_branch_limits_bk *op_lim_bk;
706 struct ccs_pll_branch_fr *op_pll_fr;
707 struct ccs_pll_branch_bk *op_pll_bk;
708 bool cphy = pll->bus_type == CCS_PLL_BUS_TYPE_CSI2_CPHY;
709 uint32_t phy_const = cphy ? CPHY_CONST : DPHY_CONST;
710 uint32_t op_sys_clk_freq_hz_sdr;
711 uint16_t min_op_pre_pll_clk_div;
712 uint16_t max_op_pre_pll_clk_div;
713 uint32_t mul, div;
714 uint32_t l = (!pll->op_bits_per_lane ||
715 pll->op_bits_per_lane >= pll->bits_per_pixel) ? 1 : 2;
716 uint32_t i;
709 u32 phy_const = cphy ? CPHY_CONST : DPHY_CONST;
710 u32 op_sys_clk_freq_hz_sdr;
711 u16 min_op_pre_pll_clk_div;
712 u16 max_op_pre_pll_clk_div;
713 u32 mul, div;
714 u32 l = (!pll->op_bits_per_lane ||
715 pll->op_bits_per_lane >= pll->bits_per_pixel) ? 1 : 2;
716 u32 i;
717 int rval = -EINVAL;
718
719 if (!(pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL)) {
720 pll->op_lanes = 1;
721 pll->vt_lanes = 1;
722 }
723
724 if (pll->flags & CCS_PLL_FLAG_DUAL_PLL) {

--- 67 unchanged lines hidden (view full) ---

792 * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
793 pll->csi2.lanes : 1) * PHY_CONST_DIV,
794 phy_const * pll->bits_per_pixel * l);
795
796 /* Figure out limits for OP pre-pll divider based on extclk */
797 dev_dbg(dev, "min / max op_pre_pll_clk_div: %u / %u\n",
798 op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
799 max_op_pre_pll_clk_div =
717 int rval = -EINVAL;
718
719 if (!(pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL)) {
720 pll->op_lanes = 1;
721 pll->vt_lanes = 1;
722 }
723
724 if (pll->flags & CCS_PLL_FLAG_DUAL_PLL) {

--- 67 unchanged lines hidden (view full) ---

792 * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
793 pll->csi2.lanes : 1) * PHY_CONST_DIV,
794 phy_const * pll->bits_per_pixel * l);
795
796 /* Figure out limits for OP pre-pll divider based on extclk */
797 dev_dbg(dev, "min / max op_pre_pll_clk_div: %u / %u\n",
798 op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
799 max_op_pre_pll_clk_div =
800 min_t(uint16_t, op_lim_fr->max_pre_pll_clk_div,
800 min_t(u16, op_lim_fr->max_pre_pll_clk_div,
801 clk_div_even(pll->ext_clk_freq_hz /
802 op_lim_fr->min_pll_ip_clk_freq_hz));
803 min_op_pre_pll_clk_div =
801 clk_div_even(pll->ext_clk_freq_hz /
802 op_lim_fr->min_pll_ip_clk_freq_hz));
803 min_op_pre_pll_clk_div =
804 max_t(uint16_t, op_lim_fr->min_pre_pll_clk_div,
804 max_t(u16, op_lim_fr->min_pre_pll_clk_div,
805 clk_div_even_up(
806 DIV_ROUND_UP(pll->ext_clk_freq_hz,
807 op_lim_fr->max_pll_ip_clk_freq_hz)));
808 dev_dbg(dev, "pre-pll check: min / max op_pre_pll_clk_div: %u / %u\n",
809 min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
810
811 i = gcd(op_sys_clk_freq_hz_sdr,
812 pll->ext_clk_freq_hz << op_pix_ddr(pll->flags));
813 mul = op_sys_clk_freq_hz_sdr / i;
814 div = (pll->ext_clk_freq_hz << op_pix_ddr(pll->flags)) / i;
815 dev_dbg(dev, "mul %u / div %u\n", mul, div);
816
817 min_op_pre_pll_clk_div =
805 clk_div_even_up(
806 DIV_ROUND_UP(pll->ext_clk_freq_hz,
807 op_lim_fr->max_pll_ip_clk_freq_hz)));
808 dev_dbg(dev, "pre-pll check: min / max op_pre_pll_clk_div: %u / %u\n",
809 min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
810
811 i = gcd(op_sys_clk_freq_hz_sdr,
812 pll->ext_clk_freq_hz << op_pix_ddr(pll->flags));
813 mul = op_sys_clk_freq_hz_sdr / i;
814 div = (pll->ext_clk_freq_hz << op_pix_ddr(pll->flags)) / i;
815 dev_dbg(dev, "mul %u / div %u\n", mul, div);
816
817 min_op_pre_pll_clk_div =
818 max_t(uint16_t, min_op_pre_pll_clk_div,
818 max_t(u16, min_op_pre_pll_clk_div,
819 clk_div_even_up(
820 mul /
821 one_or_more(
822 DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
823 pll->ext_clk_freq_hz))));
824 dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
825 min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
826

--- 60 unchanged lines hidden ---
819 clk_div_even_up(
820 mul /
821 one_or_more(
822 DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
823 pll->ext_clk_freq_hz))));
824 dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
825 min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
826

--- 60 unchanged lines hidden ---