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: Michael Tretter <m.tretter@pengutronix.de> Acked-by: Michal Simek <michal.simek@xilinx.com> Link: https://lore.kernel.org/r/20210121071659.1226489-12-m.tretter@pengutronix.de Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
parent
58ee6baf39
commit
5a9b125817
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user