cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ccs-pll.c (25979B)


      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 u32 clk_div_even(u32 a)
     21{
     22	return max_t(u32, 1, a & ~1);
     23}
     24
     25/* Return an even number or one. */
     26static inline u32 clk_div_even_up(u32 a)
     27{
     28	if (a == 1)
     29		return 1;
     30	return (a + 1) & ~1;
     31}
     32
     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
     43static inline u32 one_or_more(u32 a)
     44{
     45	return a ?: 1;
     46}
     47
     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
     58	return -EINVAL;
     59}
     60
     61#define PLL_OP 1
     62#define PLL_VT 2
     63
     64static const char *pll_string(unsigned int which)
     65{
     66	switch (which) {
     67	case PLL_OP:
     68		return "op";
     69	case PLL_VT:
     70		return "vt";
     71	}
     72
     73	return NULL;
     74}
     75
     76#define PLL_FL(f) CCS_PLL_FLAG_##f
     77
     78static void print_pll(struct device *dev, struct ccs_pll *pll)
     79{
     80	const struct {
     81		struct ccs_pll_branch_fr *fr;
     82		struct ccs_pll_branch_bk *bk;
     83		unsigned int which;
     84	} branches[] = {
     85		{ &pll->vt_fr, &pll->vt_bk, PLL_VT },
     86		{ &pll->op_fr, &pll->op_bk, PLL_OP }
     87	}, *br;
     88	unsigned int i;
     89
     90	dev_dbg(dev, "ext_clk_freq_hz\t\t%u\n", pll->ext_clk_freq_hz);
     91
     92	for (i = 0, br = branches; i < ARRAY_SIZE(branches); i++, br++) {
     93		const char *s = pll_string(br->which);
     94
     95		if (pll->flags & CCS_PLL_FLAG_DUAL_PLL ||
     96		    br->which == PLL_VT) {
     97			dev_dbg(dev, "%s_pre_pll_clk_div\t\t%u\n",  s,
     98				br->fr->pre_pll_clk_div);
     99			dev_dbg(dev, "%s_pll_multiplier\t\t%u\n",  s,
    100				br->fr->pll_multiplier);
    101
    102			dev_dbg(dev, "%s_pll_ip_clk_freq_hz\t%u\n", s,
    103				br->fr->pll_ip_clk_freq_hz);
    104			dev_dbg(dev, "%s_pll_op_clk_freq_hz\t%u\n", s,
    105				br->fr->pll_op_clk_freq_hz);
    106		}
    107
    108		if (!(pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) ||
    109		    br->which == PLL_VT) {
    110			dev_dbg(dev, "%s_sys_clk_div\t\t%u\n",  s,
    111				br->bk->sys_clk_div);
    112			dev_dbg(dev, "%s_pix_clk_div\t\t%u\n", s,
    113				br->bk->pix_clk_div);
    114
    115			dev_dbg(dev, "%s_sys_clk_freq_hz\t%u\n", s,
    116				br->bk->sys_clk_freq_hz);
    117			dev_dbg(dev, "%s_pix_clk_freq_hz\t%u\n", s,
    118				br->bk->pix_clk_freq_hz);
    119		}
    120	}
    121
    122	dev_dbg(dev, "pixel rate in pixel array:\t%u\n",
    123		pll->pixel_rate_pixel_array);
    124	dev_dbg(dev, "pixel rate on CSI-2 bus:\t%u\n",
    125		pll->pixel_rate_csi);
    126
    127	dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s\n",
    128		pll->flags & PLL_FL(LANE_SPEED_MODEL) ? " lane-speed" : "",
    129		pll->flags & PLL_FL(LINK_DECOUPLED) ? " link-decoupled" : "",
    130		pll->flags & PLL_FL(EXT_IP_PLL_DIVIDER) ?
    131		" ext-ip-pll-divider" : "",
    132		pll->flags & PLL_FL(FLEXIBLE_OP_PIX_CLK_DIV) ?
    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 u32 op_sys_ddr(u32 flags)
    142{
    143	return flags & CCS_PLL_FLAG_OP_SYS_DDR ? 1 : 0;
    144}
    145
    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{
    155	const struct ccs_pll_branch_limits_fr *lim_fr;
    156	struct ccs_pll_branch_fr *pll_fr;
    157	const char *s = pll_string(which);
    158	int rval;
    159
    160	if (which == PLL_OP) {
    161		lim_fr = &lim->op_fr;
    162		pll_fr = &pll->op_fr;
    163	} else {
    164		lim_fr = &lim->vt_fr;
    165		pll_fr = &pll->vt_fr;
    166	}
    167
    168	rval = bounds_check(dev, pll_fr->pre_pll_clk_div,
    169			    lim_fr->min_pre_pll_clk_div,
    170			    lim_fr->max_pre_pll_clk_div, s, "pre_pll_clk_div");
    171
    172	if (!rval)
    173		rval = bounds_check(dev, pll_fr->pll_ip_clk_freq_hz,
    174				    lim_fr->min_pll_ip_clk_freq_hz,
    175				    lim_fr->max_pll_ip_clk_freq_hz,
    176				    s, "pll_ip_clk_freq_hz");
    177	if (!rval)
    178		rval = bounds_check(dev, pll_fr->pll_multiplier,
    179				    lim_fr->min_pll_multiplier,
    180				    lim_fr->max_pll_multiplier,
    181				    s, "pll_multiplier");
    182	if (!rval)
    183		rval = bounds_check(dev, pll_fr->pll_op_clk_freq_hz,
    184				    lim_fr->min_pll_op_clk_freq_hz,
    185				    lim_fr->max_pll_op_clk_freq_hz,
    186				    s, "pll_op_clk_freq_hz");
    187
    188	return rval;
    189}
    190
    191static int check_bk_bounds(struct device *dev,
    192			   const struct ccs_pll_limits *lim,
    193			   struct ccs_pll *pll, unsigned int which)
    194{
    195	const struct ccs_pll_branch_limits_bk *lim_bk;
    196	struct ccs_pll_branch_bk *pll_bk;
    197	const char *s = pll_string(which);
    198	int rval;
    199
    200	if (which == PLL_OP) {
    201		if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)
    202			return 0;
    203
    204		lim_bk = &lim->op_bk;
    205		pll_bk = &pll->op_bk;
    206	} else {
    207		lim_bk = &lim->vt_bk;
    208		pll_bk = &pll->vt_bk;
    209	}
    210
    211	rval = bounds_check(dev, pll_bk->sys_clk_div,
    212			    lim_bk->min_sys_clk_div,
    213			    lim_bk->max_sys_clk_div, s, "op_sys_clk_div");
    214	if (!rval)
    215		rval = bounds_check(dev, pll_bk->sys_clk_freq_hz,
    216				    lim_bk->min_sys_clk_freq_hz,
    217				    lim_bk->max_sys_clk_freq_hz,
    218				    s, "sys_clk_freq_hz");
    219	if (!rval)
    220		rval = bounds_check(dev, pll_bk->sys_clk_div,
    221				    lim_bk->min_sys_clk_div,
    222				    lim_bk->max_sys_clk_div,
    223				    s, "sys_clk_div");
    224	if (!rval)
    225		rval = bounds_check(dev, pll_bk->pix_clk_freq_hz,
    226				    lim_bk->min_pix_clk_freq_hz,
    227				    lim_bk->max_pix_clk_freq_hz,
    228				    s, "pix_clk_freq_hz");
    229
    230	return rval;
    231}
    232
    233static int check_ext_bounds(struct device *dev, struct ccs_pll *pll)
    234{
    235	if (!(pll->flags & CCS_PLL_FLAG_FIFO_DERATING) &&
    236	    pll->pixel_rate_pixel_array > pll->pixel_rate_csi) {
    237		dev_dbg(dev, "device does not support derating\n");
    238		return -EINVAL;
    239	}
    240
    241	if (!(pll->flags & CCS_PLL_FLAG_FIFO_OVERRATING) &&
    242	    pll->pixel_rate_pixel_array < pll->pixel_rate_csi) {
    243		dev_dbg(dev, "device does not support overrating\n");
    244		return -EINVAL;
    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			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);
    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);
    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);
    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);
    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,
    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;
    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));
    309
    310	dev_dbg(dev, "more_mul: %u\n", more_mul);
    311	more_mul *= DIV_ROUND_UP(lim_fr->min_pll_multiplier, mul * more_mul);
    312	dev_dbg(dev, "more_mul2: %u\n", more_mul);
    313
    314	pll_fr->pll_multiplier = mul * more_mul;
    315
    316	if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz >
    317	    lim_fr->max_pll_op_clk_freq_hz)
    318		return -EINVAL;
    319
    320	pll_fr->pll_op_clk_freq_hz =
    321		pll_fr->pll_ip_clk_freq_hz * pll_fr->pll_multiplier;
    322
    323	vt_div = div * more_mul;
    324
    325	ccs_pll_find_vt_sys_div(dev, lim, pll, pll_fr, vt_div, vt_div,
    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		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) {
    343			dev_dbg(dev,
    344				"pix_div %u too small or too big (%u--%u)\n",
    345				pix_div,
    346				lim_bk->min_pix_clk_div,
    347				lim_bk->max_pix_clk_div);
    348			continue;
    349		}
    350
    351		dev_dbg(dev, "sys/pix/best_pix: %u,%u,%u\n", sys_div, pix_div,
    352			best_pix_div);
    353
    354		if (pix_div * sys_div <= best_pix_div) {
    355			best_pix_div = pix_div;
    356			best_div = pix_div * sys_div;
    357		}
    358	}
    359	if (best_pix_div == SHRT_MAX >> 1)
    360		return -EINVAL;
    361
    362	pll_bk->sys_clk_div = best_div / best_pix_div;
    363	pll_bk->pix_clk_div = best_pix_div;
    364
    365	pll_bk->sys_clk_freq_hz =
    366		pll_fr->pll_op_clk_freq_hz / pll_bk->sys_clk_div;
    367	pll_bk->pix_clk_freq_hz =
    368		pll_bk->sys_clk_freq_hz / pll_bk->pix_clk_div;
    369
    370	pll->pixel_rate_pixel_array =
    371		pll_bk->pix_clk_freq_hz * pll->vt_lanes;
    372
    373	return 0;
    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	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 =
    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
    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)) {
    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);
    418
    419		rval = __ccs_pll_calculate_vt_tree(dev, lim, pll,
    420						   mul, div);
    421		if (rval)
    422			continue;
    423
    424		rval = check_fr_bounds(dev, lim, pll, PLL_VT);
    425		if (rval)
    426			continue;
    427
    428		rval = check_bk_bounds(dev, lim, pll, PLL_VT);
    429		if (rval)
    430			continue;
    431
    432		return 0;
    433	}
    434
    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		     u32 phy_const)
    444{
    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	 */
    458	if (!(pll->flags & CCS_PLL_FLAG_FIFO_DERATING)) {
    459		min_vt_div =
    460			op_pll_bk->sys_clk_div * op_pll_bk->pix_clk_div
    461			* pll->vt_lanes * phy_const / pll->op_lanes
    462			/ (PHY_CONST_DIV << op_pix_ddr(pll->flags));
    463	} else {
    464		/*
    465		 * Some sensors perform analogue binning and some do this
    466		 * digitally. The ones doing this digitally can be roughly be
    467		 * found out using this formula. The ones doing this digitally
    468		 * should run at higher clock rate, so smaller divisor is used
    469		 * on video timing side.
    470		 */
    471		if (lim->min_line_length_pck_bin > lim->min_line_length_pck
    472		    / pll->binning_horizontal)
    473			vt_op_binning_div = pll->binning_horizontal;
    474		else
    475			vt_op_binning_div = 1;
    476		dev_dbg(dev, "vt_op_binning_div: %u\n", vt_op_binning_div);
    477
    478		/*
    479		 * Profile 2 supports vt_pix_clk_div E [4, 10]
    480		 *
    481		 * Horizontal binning can be used as a base for difference in
    482		 * divisors. One must make sure that horizontal blanking is
    483		 * enough to accommodate the CSI-2 sync codes.
    484		 *
    485		 * Take scaling factor and number of VT lanes into account as well.
    486		 *
    487		 * Find absolute limits for the factor of vt divider.
    488		 */
    489		dev_dbg(dev, "scale_m: %u\n", pll->scale_m);
    490		min_vt_div =
    491			DIV_ROUND_UP(pll->bits_per_pixel
    492				     * op_pll_bk->sys_clk_div * pll->scale_n
    493				     * pll->vt_lanes * phy_const,
    494				     (pll->flags &
    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(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);
    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);
    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++) {
    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)) {
    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,
    543					lim->vt_bk.min_pix_clk_div,
    544					lim->vt_bk.max_pix_clk_div);
    545				continue;
    546			}
    547
    548			rounded_div = roundup(vt_div, best_pix_div);
    549
    550			/* Check if this one is better. */
    551			if (pix_div * sys_div <= rounded_div)
    552				best_pix_div = pix_div;
    553
    554			/* Bail out if we've already found the best value. */
    555			if (vt_div == rounded_div)
    556				break;
    557		}
    558		if (best_pix_div < SHRT_MAX >> 1)
    559			break;
    560	}
    561
    562	pll->vt_bk.sys_clk_div = DIV_ROUND_UP(vt_div, best_pix_div);
    563	pll->vt_bk.pix_clk_div = best_pix_div;
    564
    565	pll->vt_bk.sys_clk_freq_hz =
    566		pll_fr->pll_op_clk_freq_hz / pll->vt_bk.sys_clk_div;
    567	pll->vt_bk.pix_clk_freq_hz =
    568		pll->vt_bk.sys_clk_freq_hz / pll->vt_bk.pix_clk_div;
    569
    570out_calc_pixel_rate:
    571	pll->pixel_rate_pixel_array =
    572		pll->vt_bk.pix_clk_freq_hz * pll->vt_lanes;
    573}
    574
    575/*
    576 * Heuristically guess the PLL tree for a given common multiplier and
    577 * divisor. Begin with the operational timing and continue to video
    578 * timing once operational timing has been verified.
    579 *
    580 * @mul is the PLL multiplier and @div is the common divisor
    581 * (pre_pll_clk_div and op_sys_clk_div combined). The final PLL
    582 * multiplier will be a multiple of @mul.
    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, 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	 */
    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 =
    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,
    626			   op_lim_bk->max_sys_clk_div * op_pll_fr->pre_pll_clk_div
    627			   / div);
    628	dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %u\n",
    629		more_mul_max);
    630	/* Ensure we won't go above max_pll_multiplier. */
    631	more_mul_max = min(more_mul_max, op_lim_fr->max_pll_multiplier / mul);
    632	dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %u\n",
    633		more_mul_max);
    634
    635	/* Ensure we won't go below min_pll_op_clk_freq_hz. */
    636	more_mul_min = DIV_ROUND_UP(op_lim_fr->min_pll_op_clk_freq_hz,
    637				    pll->ext_clk_freq_hz /
    638				    op_pll_fr->pre_pll_clk_div * mul);
    639	dev_dbg(dev, "more_mul_min: min_op_pll_op_clk_freq_hz check: %u\n",
    640		more_mul_min);
    641	/* Ensure we won't go below min_pll_multiplier. */
    642	more_mul_min = max(more_mul_min,
    643			   DIV_ROUND_UP(op_lim_fr->min_pll_multiplier, mul));
    644	dev_dbg(dev, "more_mul_min: min_op_pll_multiplier check: %u\n",
    645		more_mul_min);
    646
    647	if (more_mul_min > more_mul_max) {
    648		dev_dbg(dev,
    649			"unable to compute more_mul_min and more_mul_max\n");
    650		return -EINVAL;
    651	}
    652
    653	more_mul_factor = lcm(div, op_pll_fr->pre_pll_clk_div) / div;
    654	dev_dbg(dev, "more_mul_factor: %u\n", more_mul_factor);
    655	more_mul_factor = lcm(more_mul_factor, op_lim_bk->min_sys_clk_div);
    656	dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n",
    657		more_mul_factor);
    658	i = roundup(more_mul_min, more_mul_factor);
    659	if (!is_one_or_even(i))
    660		i <<= 1;
    661
    662	dev_dbg(dev, "final more_mul: %u\n", i);
    663	if (i > more_mul_max) {
    664		dev_dbg(dev, "final more_mul is bad, max %u\n", more_mul_max);
    665		return -EINVAL;
    666	}
    667
    668	op_pll_fr->pll_multiplier = mul * i;
    669	op_pll_bk->sys_clk_div = div * i / op_pll_fr->pre_pll_clk_div;
    670	dev_dbg(dev, "op_sys_clk_div: %u\n", op_pll_bk->sys_clk_div);
    671
    672	op_pll_fr->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz
    673		/ op_pll_fr->pre_pll_clk_div;
    674
    675	op_pll_fr->pll_op_clk_freq_hz = op_pll_fr->pll_ip_clk_freq_hz
    676		* op_pll_fr->pll_multiplier;
    677
    678	if (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL)
    679		op_pll_bk->pix_clk_div =
    680			(pll->bits_per_pixel
    681			 * pll->op_lanes * (phy_const << op_sys_ddr(pll->flags))
    682			 / PHY_CONST_DIV / pll->csi2.lanes / l)
    683			>> op_pix_ddr(pll->flags);
    684	else
    685		op_pll_bk->pix_clk_div =
    686			(pll->bits_per_pixel
    687			 * (phy_const << op_sys_ddr(pll->flags))
    688			 / PHY_CONST_DIV / l) >> op_pix_ddr(pll->flags);
    689
    690	op_pll_bk->pix_clk_freq_hz =
    691		(op_sys_clk_freq_hz_sdr >> op_pix_ddr(pll->flags))
    692		/ op_pll_bk->pix_clk_div;
    693	op_pll_bk->sys_clk_freq_hz =
    694		op_sys_clk_freq_hz_sdr >> op_sys_ddr(pll->flags);
    695
    696	dev_dbg(dev, "op_pix_clk_div: %u\n", op_pll_bk->pix_clk_div);
    697
    698	return 0;
    699}
    700
    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	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) {
    725		op_lim_fr = &lim->op_fr;
    726		op_lim_bk = &lim->op_bk;
    727		op_pll_fr = &pll->op_fr;
    728		op_pll_bk = &pll->op_bk;
    729	} else if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) {
    730		/*
    731		 * If there's no OP PLL at all, use the VT values
    732		 * instead. The OP values are ignored for the rest of
    733		 * the PLL calculation.
    734		 */
    735		op_lim_fr = &lim->vt_fr;
    736		op_lim_bk = &lim->vt_bk;
    737		op_pll_fr = &pll->vt_fr;
    738		op_pll_bk = &pll->vt_bk;
    739	} else {
    740		op_lim_fr = &lim->vt_fr;
    741		op_lim_bk = &lim->op_bk;
    742		op_pll_fr = &pll->vt_fr;
    743		op_pll_bk = &pll->op_bk;
    744	}
    745
    746	if (!pll->op_lanes || !pll->vt_lanes || !pll->bits_per_pixel ||
    747	    !pll->ext_clk_freq_hz || !pll->link_freq || !pll->scale_m ||
    748	    !op_lim_fr->min_pll_ip_clk_freq_hz ||
    749	    !op_lim_fr->max_pll_ip_clk_freq_hz ||
    750	    !op_lim_fr->min_pll_op_clk_freq_hz ||
    751	    !op_lim_fr->max_pll_op_clk_freq_hz ||
    752	    !op_lim_bk->max_sys_clk_div || !op_lim_fr->max_pll_multiplier)
    753		return -EINVAL;
    754
    755	/*
    756	 * Make sure op_pix_clk_div will be integer --- unless flexible
    757	 * op_pix_clk_div is supported
    758	 */
    759	if (!(pll->flags & CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV) &&
    760	    (pll->bits_per_pixel * pll->op_lanes) %
    761	    (pll->csi2.lanes * l << op_pix_ddr(pll->flags))) {
    762		dev_dbg(dev, "op_pix_clk_div not an integer (bpp %u, op lanes %u, lanes %u, l %u)\n",
    763			pll->bits_per_pixel, pll->op_lanes, pll->csi2.lanes, l);
    764		return -EINVAL;
    765	}
    766
    767	dev_dbg(dev, "vt_lanes: %u\n", pll->vt_lanes);
    768	dev_dbg(dev, "op_lanes: %u\n", pll->op_lanes);
    769
    770	dev_dbg(dev, "binning: %ux%u\n", pll->binning_horizontal,
    771		pll->binning_vertical);
    772
    773	switch (pll->bus_type) {
    774	case CCS_PLL_BUS_TYPE_CSI2_DPHY:
    775	case CCS_PLL_BUS_TYPE_CSI2_CPHY:
    776		op_sys_clk_freq_hz_sdr = pll->link_freq * 2
    777			* (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
    778			   1 : pll->csi2.lanes);
    779		break;
    780	default:
    781		return -EINVAL;
    782	}
    783
    784	pll->pixel_rate_csi =
    785		div_u64((uint64_t)op_sys_clk_freq_hz_sdr
    786			* (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
    787			   pll->csi2.lanes : 1) * PHY_CONST_DIV,
    788			phy_const * pll->bits_per_pixel * l);
    789
    790	/* Figure out limits for OP pre-pll divider based on extclk */
    791	dev_dbg(dev, "min / max op_pre_pll_clk_div: %u / %u\n",
    792		op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
    793	max_op_pre_pll_clk_div =
    794		min_t(u16, op_lim_fr->max_pre_pll_clk_div,
    795		      clk_div_even(pll->ext_clk_freq_hz /
    796				   op_lim_fr->min_pll_ip_clk_freq_hz));
    797	min_op_pre_pll_clk_div =
    798		max_t(u16, op_lim_fr->min_pre_pll_clk_div,
    799		      clk_div_even_up(
    800			      DIV_ROUND_UP(pll->ext_clk_freq_hz,
    801					   op_lim_fr->max_pll_ip_clk_freq_hz)));
    802	dev_dbg(dev, "pre-pll check: min / max op_pre_pll_clk_div: %u / %u\n",
    803		min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
    804
    805	i = gcd(op_sys_clk_freq_hz_sdr,
    806		pll->ext_clk_freq_hz << op_pix_ddr(pll->flags));
    807	mul = op_sys_clk_freq_hz_sdr / i;
    808	div = (pll->ext_clk_freq_hz << op_pix_ddr(pll->flags)) / i;
    809	dev_dbg(dev, "mul %u / div %u\n", mul, div);
    810
    811	min_op_pre_pll_clk_div =
    812		max_t(u16, min_op_pre_pll_clk_div,
    813		      clk_div_even_up(
    814			      mul /
    815			      one_or_more(
    816				      DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
    817						   pll->ext_clk_freq_hz))));
    818	dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
    819		min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
    820
    821	for (op_pll_fr->pre_pll_clk_div = min_op_pre_pll_clk_div;
    822	     op_pll_fr->pre_pll_clk_div <= max_op_pre_pll_clk_div;
    823	     op_pll_fr->pre_pll_clk_div +=
    824		     (pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER) ? 1 :
    825		     2 - (op_pll_fr->pre_pll_clk_div & 1)) {
    826		rval = ccs_pll_calculate_op(dev, lim, op_lim_fr, op_lim_bk, pll,
    827					    op_pll_fr, op_pll_bk, mul, div,
    828					    op_sys_clk_freq_hz_sdr, l, cphy,
    829					    phy_const);
    830		if (rval)
    831			continue;
    832
    833		rval = check_fr_bounds(dev, lim, pll,
    834				       pll->flags & CCS_PLL_FLAG_DUAL_PLL ?
    835				       PLL_OP : PLL_VT);
    836		if (rval)
    837			continue;
    838
    839		rval = check_bk_bounds(dev, lim, pll, PLL_OP);
    840		if (rval)
    841			continue;
    842
    843		if (pll->flags & CCS_PLL_FLAG_DUAL_PLL)
    844			break;
    845
    846		ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr,
    847				     op_pll_bk, cphy, phy_const);
    848
    849		rval = check_bk_bounds(dev, lim, pll, PLL_VT);
    850		if (rval)
    851			continue;
    852		rval = check_ext_bounds(dev, pll);
    853		if (rval)
    854			continue;
    855
    856		break;
    857	}
    858
    859	if (rval) {
    860		dev_dbg(dev, "unable to compute pre_pll divisor\n");
    861
    862		return rval;
    863	}
    864
    865	if (pll->flags & CCS_PLL_FLAG_DUAL_PLL) {
    866		rval = ccs_pll_calculate_vt_tree(dev, lim, pll);
    867
    868		if (rval)
    869			return rval;
    870	}
    871
    872	print_pll(dev, pll);
    873
    874	return 0;
    875}
    876EXPORT_SYMBOL_GPL(ccs_pll_calculate);
    877
    878MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
    879MODULE_DESCRIPTION("Generic MIPI CCS/SMIA/SMIA++ PLL calculator");
    880MODULE_LICENSE("GPL");