Commit 5a9b1258 authored by Michael Tretter's avatar Michael Tretter Committed by Stephen Boyd
Browse files

soc: xilinx: vcu: remove calculation of PLL configuration



As the consumers are now responsible for setting the clock rate via
clock framework, the clock rate is now calculated using round_rate and
the driver does not need to calculate the clock rate beforehand.

Remove the code that calculates the PLL configuration.

Signed-off-by: default avatarMichael Tretter <m.tretter@pengutronix.de>
Acked-by: default avatarMichal Simek <michal.simek@xilinx.com>
Link: https://lore.kernel.org/r/20210121071659.1226489-12-m.tretter@pengutronix.de


Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 58ee6baf
Loading
Loading
Loading
Loading
+0 −117
Original line number Diff line number Diff line
@@ -59,10 +59,6 @@
#define MHZ				1000000
#define FVCO_MIN			(1500U * MHZ)
#define FVCO_MAX			(3000U * MHZ)
#define DIVISOR_MIN			0
#define DIVISOR_MAX			63
#define FRAC				100
#define LIMIT				(10 * MHZ)

/**
 * struct xvcu_device - Xilinx VCU init device structure
@@ -482,111 +478,6 @@ static struct clk_hw *xvcu_register_pll(struct device *dev,
	return hw;
}

/**
 * xvcu_set_vcu_pll_info - Set the VCU PLL info
 * @xvcu:	Pointer to the xvcu_device structure
 *
 * Programming the VCU PLL based on the user configuration
 * (ref clock freq, core clock freq, mcu clock freq).
 * Core clock frequency has higher priority than mcu clock frequency
 * Errors in following cases
 *    - When mcu or clock clock get from logicoreIP is 0
 *    - When VCU PLL DIV related bits value other than 1
 *    - When proper data not found for given data
 *    - When sis570_1 clocksource related operation failed
 *
 * Return:	Returns status, either success or error+reason
 */
static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
{
	u32 refclk, coreclk, mcuclk, inte, deci;
	u32 divisor_mcu, divisor_core, fvco;
	u32 pll_clk;
	u32 mod;
	int i;
	const struct xvcu_pll_cfg *found = NULL;

	regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK, &inte);
	regmap_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC, &deci);
	regmap_read(xvcu->logicore_reg_ba, VCU_CORE_CLK, &coreclk);
	coreclk *= MHZ;
	regmap_read(xvcu->logicore_reg_ba, VCU_MCU_CLK, &mcuclk);
	mcuclk *= MHZ;
	if (!mcuclk || !coreclk) {
		dev_err(xvcu->dev, "Invalid mcu and core clock data\n");
		return -EINVAL;
	}

	refclk = (inte * MHZ) + (deci * (MHZ / FRAC));
	dev_dbg(xvcu->dev, "Ref clock from logicoreIP is %uHz\n", refclk);
	dev_dbg(xvcu->dev, "Core clock from logicoreIP is %uHz\n", coreclk);
	dev_dbg(xvcu->dev, "Mcu clock from logicoreIP is %uHz\n", mcuclk);

	for (i = ARRAY_SIZE(xvcu_pll_cfg) - 1; i >= 0; i--) {
		const struct xvcu_pll_cfg *cfg = &xvcu_pll_cfg[i];

		fvco = cfg->fbdiv * refclk;
		if (fvco >= FVCO_MIN && fvco <= FVCO_MAX) {
			pll_clk = fvco / VCU_PLL_DIV2;
			if (fvco % VCU_PLL_DIV2 != 0)
				pll_clk++;
			mod = pll_clk % coreclk;
			if (mod < LIMIT) {
				divisor_core = pll_clk / coreclk;
			} else if (coreclk - mod < LIMIT) {
				divisor_core = pll_clk / coreclk;
				divisor_core++;
			} else {
				continue;
			}
			if (divisor_core >= DIVISOR_MIN &&
			    divisor_core <= DIVISOR_MAX) {
				found = cfg;
				divisor_mcu = pll_clk / mcuclk;
				mod = pll_clk % mcuclk;
				if (mcuclk - mod < LIMIT)
					divisor_mcu++;
				break;
			}
		}
	}

	if (!found) {
		dev_err(xvcu->dev, "Invalid clock combination.\n");
		return -EINVAL;
	}

	coreclk = pll_clk / divisor_core;
	mcuclk = pll_clk / divisor_mcu;
	dev_dbg(xvcu->dev, "Actual Ref clock freq is %uHz\n", refclk);
	dev_dbg(xvcu->dev, "Actual Core clock freq is %uHz\n", coreclk);
	dev_dbg(xvcu->dev, "Actual Mcu clock freq is %uHz\n", mcuclk);

	return 0;
}

/**
 * xvcu_set_pll - PLL init sequence
 * @xvcu:	Pointer to the xvcu_device structure
 *
 * Call the api to set the PLL info and once that is done then
 * init the PLL sequence to make the PLL stable.
 *
 * Return:	Returns status, either success or error+reason
 */
static int xvcu_set_pll(struct xvcu_device *xvcu)
{
	int ret;

	ret = xvcu_set_vcu_pll_info(xvcu);
	if (ret) {
		dev_err(xvcu->dev, "failed to set pll info\n");
		return ret;
	}

	return 0;
}

static struct clk_hw *xvcu_clk_hw_register_leaf(struct device *dev,
						const char *name,
						const struct clk_parent_data *parent_data,
@@ -834,13 +725,6 @@ static int xvcu_probe(struct platform_device *pdev)
	 */
	regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE);

	/* Do the PLL Settings based on the ref clk,core and mcu clk freq */
	ret = xvcu_set_pll(xvcu);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set the pll\n");
		goto error_pll_ref;
	}

	ret = xvcu_register_clock_provider(xvcu);
	if (ret) {
		dev_err(&pdev->dev, "failed to register clock provider\n");
@@ -853,7 +737,6 @@ static int xvcu_probe(struct platform_device *pdev)

error_clk_provider:
	xvcu_unregister_clock_provider(xvcu);
error_pll_ref:
	clk_disable_unprepare(xvcu->aclk);
	return ret;
}