[PATCH 1/9] drivers: clk: dm: Add clock driver for Diamond Mesa

Sean Anderson seanga2 at gmail.com
Wed Sep 28 19:14:14 CEST 2022


On 9/18/22 08:17, Jit Loon Lim wrote:
> From: Siew Chin Lim <elly.siew.chin.lim at intel.com>
> 
> Add clock manager driver for Diamond Mesa. Provides clock
> initialization and get_rate functions.

It appears that you are doing a static configuration of the
clocks (with no provision for later modifying clocks). Can
you add some comments to the commit message regarding rates
for the major clocks and why you chose them?

> Signed-off-by: Siew Chin Lim <elly.siew.chin.lim at intel.com>
> Signed-off-by: Jit Loon Lim <jit.loon.lim at intel.com>
> ---
>   drivers/clk/altera/clk-dm.c          | 504 +++++++++++++++++++++++++++
>   drivers/clk/altera/clk-dm.h          | 217 ++++++++++++
>   include/dt-bindings/clock/dm-clock.h |  71 ++++
>   3 files changed, 792 insertions(+)
>   create mode 100644 drivers/clk/altera/clk-dm.c
>   create mode 100644 drivers/clk/altera/clk-dm.h
>   create mode 100644 include/dt-bindings/clock/dm-clock.h

Please reconsider the prefix "DM" as it typically means "Driver
Model" in the rest of U-Boot. diamond_? dmesa_? diamesa_?

This commit also needs to add clk-dm.o to drivers/clk/altera/Makefile.

> 
> diff --git a/drivers/clk/altera/clk-dm.c b/drivers/clk/altera/clk-dm.c
> new file mode 100644
> index 0000000000..1076240b41
> --- /dev/null
> +++ b/drivers/clk/altera/clk-dm.c
> @@ -0,0 +1,504 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Intel Corporation <www.intel.com>

Is this accurate?

> + */
> +
> +#include <common.h>
> +#include <asm/arch/clock_manager.h>
> +#include <asm/io.h>
> +#include <clk-uclass.h>

This should come after common.h.

> +#include <dm.h>
> +#include <dm/lists.h>
> +#include <dm/util.h>
> +#include <dt-bindings/clock/dm-clock.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct socfpga_clk_plat {
> +	void __iomem *regs;
> +};
> +
> +/*
> + * function to write the bypass register which requires a poll of the
> + * busy bit
> + */
> +static void clk_write_bypass_mainpll(struct socfpga_clk_plat *plat, u32 val)
> +{
> +	CM_REG_WRITEL(plat, val, CLKMGR_MAINPLL_BYPASS);
> +	cm_wait_for_fsm();
> +}
> +
> +static void clk_write_bypass_perpll(struct socfpga_clk_plat *plat, u32 val)
> +{
> +	CM_REG_WRITEL(plat, val, CLKMGR_PERPLL_BYPASS);
> +	cm_wait_for_fsm();
> +}
> +
> +#ifndef CONFIG_TARGET_SOCFPGA_DM
> +/* function to write the ctrl register which requires a poll of the busy bit */
> +static void clk_write_ctrl(struct socfpga_clk_plat *plat, u32 val)
> +{
> +	CM_REG_WRITEL(plat, val, CLKMGR_CTRL);
> +	cm_wait_for_fsm();
> +}
> +#endif

You can define this unconditionally...

> +
> +/*
> + * Setup clocks while making no assumptions about previous state of the clocks.
> + */
> +static void clk_basic_init(struct udevice *dev,
> +			   const struct cm_config * const cfg)
> +{
> +	struct socfpga_clk_plat *plat = dev_get_plat(dev);
> +
> +	if (!cfg)
> +		return;
> +
> +#ifndef CONFIG_TARGET_SOCFPGA_DM
> +#ifdef CONFIG_SPL_BUILD
> +	/* Always force clock manager into boot mode before any configuration */
> +	clk_write_ctrl(plat,
> +		       CM_REG_READL(plat, CLKMGR_CTRL) | CLKMGR_CTRL_BOOTMODE);
> +#else
> +	/* Skip clock configuration in SSBL if it's not in boot mode */
> +	if (!(CM_REG_READL(plat, CLKMGR_CTRL) & CLKMGR_CTRL_BOOTMODE))
> +		return;
> +#endif
> +#endif

...and then use regular ifs here. e.g.

if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_DM)) {
	if (spl_phase() == PHASE_SPL)
		...
	else
		...
}

> +
> +	/* Put both PLLs in bypass */
> +	clk_write_bypass_mainpll(plat, CLKMGR_BYPASS_MAINPLL_ALL);
> +	clk_write_bypass_perpll(plat, CLKMGR_BYPASS_PERPLL_ALL);
> +
> +	/* Put both PLLs in Reset */
> +	CM_REG_SETBITS(plat, CLKMGR_MAINPLL_PLLCTRL,
> +		       CLKMGR_PLLCTRL_BYPASS_MASK);
> +	CM_REG_SETBITS(plat, CLKMGR_PERPLL_PLLCTRL,
> +		       CLKMGR_PLLCTRL_BYPASS_MASK);
> +
> +#ifndef CONFIG_TARGET_SOCFPGA_DM
> +	/* setup main PLL */
> +	CM_REG_WRITEL(plat, cfg->main_pll_pllglob, CLKMGR_MAINPLL_PLLGLOB);
> +	CM_REG_WRITEL(plat, cfg->main_pll_plldiv, CLKMGR_MAINPLL_PLLDIV);
> +	CM_REG_WRITEL(plat, cfg->main_pll_plloutdiv, CLKMGR_MAINPLL_PLLOUTDIV);
> +	CM_REG_WRITEL(plat, cfg->main_pll_mpuclk, CLKMGR_MAINPLL_MPUCLK);
> +	CM_REG_WRITEL(plat, cfg->main_pll_nocclk, CLKMGR_MAINPLL_NOCCLK);
> +	CM_REG_WRITEL(plat, cfg->main_pll_nocdiv, CLKMGR_MAINPLL_NOCDIV);
> +
> +	/* setup peripheral */
> +	CM_REG_WRITEL(plat, cfg->per_pll_pllglob, CLKMGR_PERPLL_PLLGLOB);
> +	CM_REG_WRITEL(plat, cfg->per_pll_plldiv, CLKMGR_PERPLL_PLLDIV);
> +	CM_REG_WRITEL(plat, cfg->per_pll_plloutdiv, CLKMGR_PERPLL_PLLOUTDIV);
> +	CM_REG_WRITEL(plat, cfg->per_pll_emacctl, CLKMGR_PERPLL_EMACCTL);
> +	CM_REG_WRITEL(plat, cfg->per_pll_gpiodiv, CLKMGR_PERPLL_GPIODIV);
> +#endif

I think you can do the same kind of thing here.

That said, what other target are you planning to support? Can you document
it in the commit message or somewhere in the code?

> +
> +	/* Take both PLL out of reset and power up */
> +	CM_REG_CLRBITS(plat, CLKMGR_MAINPLL_PLLCTRL,
> +		       CLKMGR_PLLCTRL_BYPASS_MASK);
> +	CM_REG_CLRBITS(plat, CLKMGR_PERPLL_PLLCTRL,
> +		       CLKMGR_PLLCTRL_BYPASS_MASK);
> +
> +	cm_wait_for_lock(CLKMGR_STAT_ALLPLL_LOCKED_MASK);
> +
> +#ifndef CONFIG_TARGET_SOCFPGA_DM
> +	CM_REG_WRITEL(plat, cfg->alt_emacactr, CLKMGR_ALTR_EMACACTR);
> +	CM_REG_WRITEL(plat, cfg->alt_emacbctr, CLKMGR_ALTR_EMACBCTR);
> +	CM_REG_WRITEL(plat, cfg->alt_emacptpctr, CLKMGR_ALTR_EMACPTPCTR);
> +	CM_REG_WRITEL(plat, cfg->alt_gpiodbctr, CLKMGR_ALTR_GPIODBCTR);
> +	CM_REG_WRITEL(plat, cfg->alt_sdmmcctr, CLKMGR_ALTR_SDMMCCTR);
> +	CM_REG_WRITEL(plat, cfg->alt_s2fuser0ctr, CLKMGR_ALTR_S2FUSER0CTR);
> +	CM_REG_WRITEL(plat, cfg->alt_s2fuser1ctr, CLKMGR_ALTR_S2FUSER1CTR);
> +	CM_REG_WRITEL(plat, cfg->alt_psirefctr, CLKMGR_ALTR_PSIREFCTR);
> +#endif
> +
> +	/* Configure ping pong counters in altera group */
> +	CM_REG_WRITEL(plat, CLKMGR_LOSTLOCK_SET_MASK, CLKMGR_MAINPLL_LOSTLOCK);
> +	CM_REG_WRITEL(plat, CLKMGR_LOSTLOCK_SET_MASK, CLKMGR_PERPLL_LOSTLOCK);
> +
> +	CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_MAINPLL_PLLGLOB) |
> +			CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK,
> +			CLKMGR_MAINPLL_PLLGLOB);
> +	CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLGLOB) |
> +			CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK,
> +			CLKMGR_PERPLL_PLLGLOB);
> +
> +	/* Take all PLLs out of bypass */
> +	clk_write_bypass_mainpll(plat, 0);
> +	clk_write_bypass_perpll(plat, 0);
> +
> +	/* Clear the loss of lock bits (write 1 to clear) */
> +	CM_REG_CLRBITS(plat, CLKMGR_INTRCLR,
> +		       CLKMGR_INTER_PERPLLLOST_MASK |
> +		       CLKMGR_INTER_MAINPLLLOST_MASK);
> +
> +	/* Take all ping pong counters out of reset */
> +	CM_REG_CLRBITS(plat, CLKMGR_ALTR_EXTCNTRST,
> +		       CLKMGR_ALT_EXTCNTRST_ALLCNTRST_MASK);
> +
> +#ifndef CONFIG_TARGET_SOCFPGA_DM
> +	/* Out of boot mode */
> +	clk_write_ctrl(plat,
> +		       CM_REG_READL(plat, CLKMGR_CTRL) & ~CLKMGR_CTRL_BOOTMODE);
> +#endif
> +}
> +
> +static u32 clk_get_5_1_clk_src(struct socfpga_clk_plat *plat, u32 reg)
> +{
> +	u32 clksrc = CM_REG_READL(plat, reg);
> +
> +	return (clksrc & CLKMGR_CLKSRC_MASK) >> CLKMGR_CLKSRC_OFFSET;
> +}
> +
> +static u64 clk_get_pll_output_hz(struct socfpga_clk_plat *plat,
> +				 u32 pllglob_reg, u32 plldiv_reg)


As a general note, I would expect this to be named something like

dm_pll_get_rate()

(using your existing dm_ prefix), since it is implicit that all rates are in Hz.

> +{
> +	u64 clock = 0;
> +	u32 clklsrc, divf, divr, divq, power = 1;
> +
> +	/* Get input clock frequency */
> +	clklsrc = (CM_REG_READL(plat, pllglob_reg) &
> +		   CLKMGR_PLLGLOB_VCO_PSRC_MASK) >>
> +		   CLKMGR_PLLGLOB_VCO_PSRC_OFFSET;
> +
> +	switch (clklsrc) {
> +	case CLKMGR_VCO_PSRC_EOSC1:
> +		clock = cm_get_osc_clk_hz();
> +		break;
> +	case CLKMGR_VCO_PSRC_INTOSC:
> +		clock = cm_get_intosc_clk_hz();
> +		break;
> +	case CLKMGR_VCO_PSRC_F2S:
> +		clock = cm_get_fpga_clk_hz();
> +		break;
> +	}
> +
> +	/* Calculate pll out clock frequency */
> +	divf = (CM_REG_READL(plat, plldiv_reg) &
> +		CLKMGR_PLLDIV_FDIV_MASK) >>
> +		CLKMGR_PLLDIV_FDIV_OFFSET;
> +
> +	divr = (CM_REG_READL(plat, plldiv_reg) &
> +		CLKMGR_PLLDIV_REFCLKDIV_MASK) >>
> +		CLKMGR_PLLDIV_REFCLKDIV_OFFSET;
> +
> +	divq = (CM_REG_READL(plat, plldiv_reg) &
> +		CLKMGR_PLLDIV_OUTDIV_QDIV_MASK) >>
> +		CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET;
> +
> +	while (divq) {
> +		power *= 2;
> +		divq--;
> +	}
> +
> +	return ((clock * 2 * (divf + 1)) / ((divr + 1) * power));
> +}
> +
> +static u64 clk_get_clksrc_hz(struct socfpga_clk_plat *plat, u32 clksrc_reg,

> +			     u32 main_div, u32 per_div)
> +{
> +	u64 clock = 0;
> +	u32 clklsrc = clk_get_5_1_clk_src(plat, clksrc_reg);
> +
> +	switch (clklsrc) {
> +	case CLKMGR_CLKSRC_MAIN:
> +		clock = clk_get_pll_output_hz(plat,
> +					      CLKMGR_MAINPLL_PLLGLOB,
> +					      CLKMGR_MAINPLL_PLLDIV);
> +		clock /= 1 + main_div;
> +		break;
> +
> +	case CLKMGR_CLKSRC_PER:
> +		clock = clk_get_pll_output_hz(plat,
> +					      CLKMGR_PERPLL_PLLGLOB,
> +					      CLKMGR_PERPLL_PLLDIV);
> +		clock /= 1 + per_div;
> +		break;
> +
> +	case CLKMGR_CLKSRC_OSC1:
> +		clock = cm_get_osc_clk_hz();
> +		break;
> +
> +	case CLKMGR_CLKSRC_INTOSC:
> +		clock = cm_get_intosc_clk_hz();
> +		break;
> +
> +	case CLKMGR_CLKSRC_FPGA:
> +		clock = cm_get_fpga_clk_hz();
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	return clock;
> +}
> +
> +static u64 clk_get_mpu_clk_hz(struct socfpga_clk_plat *plat)
> +{
> +	u32 mainpll_c0cnt = (CM_REG_READL(plat, CLKMGR_MAINPLL_PLLOUTDIV) &
> +			     CLKMGR_PLLOUTDIV_C0CNT_MASK) >>
> +			     CLKMGR_PLLOUTDIV_C0CNT_OFFSET;
> +
> +	u32 perpll_c0cnt = (CM_REG_READL(plat, CLKMGR_PERPLL_PLLOUTDIV) &
> +			    CLKMGR_PLLOUTDIV_C0CNT_MASK) >>
> +			    CLKMGR_PLLOUTDIV_C0CNT_OFFSET;
> +
> +	u64 clock = clk_get_clksrc_hz(plat, CLKMGR_MAINPLL_MPUCLK,
> +				      mainpll_c0cnt, perpll_c0cnt);
> +
> +	clock /= 1 + (CM_REG_READL(plat, CLKMGR_MAINPLL_MPUCLK) &
> +		      CLKMGR_CLKCNT_MSK);
> +
> +	return clock;
> +}
> +
> +static u32 clk_get_l3_main_clk_hz(struct socfpga_clk_plat *plat)
> +{
> +	u32 mainpll_c1cnt = (CM_REG_READL(plat, CLKMGR_MAINPLL_PLLOUTDIV) &
> +			     CLKMGR_PLLOUTDIV_C1CNT_MASK) >>
> +			     CLKMGR_PLLOUTDIV_C1CNT_OFFSET;
> +
> +	u32 perpll_c1cnt = (CM_REG_READL(plat, CLKMGR_PERPLL_PLLOUTDIV) &
> +			    CLKMGR_PLLOUTDIV_C1CNT_MASK) >>
> +			    CLKMGR_PLLOUTDIV_C1CNT_OFFSET;
> +
> +	return clk_get_clksrc_hz(plat, CLKMGR_MAINPLL_NOCCLK,
> +				 mainpll_c1cnt, perpll_c1cnt);
> +}
> +
> +static u32 clk_get_l4_main_clk_hz(struct socfpga_clk_plat *plat)
> +{
> +	u64 clock = clk_get_l3_main_clk_hz(plat);
> +
> +	clock /= BIT((CM_REG_READL(plat, CLKMGR_MAINPLL_NOCDIV) >>
> +		      CLKMGR_NOCDIV_L4MAIN_OFFSET) &
> +		      CLKMGR_NOCDIV_DIVIDER_MASK);
> +
> +	return clock;
> +}
> +
> +static u32 clk_get_sdmmc_clk_hz(struct socfpga_clk_plat *plat)
> +{
> +	u32 mainpll_c3cnt = (CM_REG_READL(plat, CLKMGR_MAINPLL_PLLOUTDIV) &
> +			     CLKMGR_PLLOUTDIV_C3CNT_MASK) >>
> +			     CLKMGR_PLLOUTDIV_C3CNT_OFFSET;
> +
> +	u32 perpll_c3cnt = (CM_REG_READL(plat, CLKMGR_PERPLL_PLLOUTDIV) &
> +			    CLKMGR_PLLOUTDIV_C3CNT_MASK) >>
> +			    CLKMGR_PLLOUTDIV_C3CNT_OFFSET;
> +
> +	u64 clock = clk_get_clksrc_hz(plat, CLKMGR_ALTR_SDMMCCTR,
> +				      mainpll_c3cnt, perpll_c3cnt);
> +
> +	clock /= 1 + (CM_REG_READL(plat, CLKMGR_ALTR_SDMMCCTR) &
> +		      CLKMGR_CLKCNT_MSK);
> +
> +	return clock / 4;
> +}
> +
> +#ifndef CONFIG_TARGET_SOCFPGA_DM
> +static u32 clk_get_l4_sp_clk_hz(struct socfpga_clk_plat *plat)
> +{
> +	u64 clock = clk_get_l3_main_clk_hz(plat);
> +
> +	clock /= BIT((CM_REG_READL(plat, CLKMGR_MAINPLL_NOCDIV) >>
> +		      CLKMGR_NOCDIV_L4SPCLK_OFFSET) &
> +		      CLKMGR_NOCDIV_DIVIDER_MASK);
> +
> +	return clock;
> +}
> +#endif
> +
> +static u32 clk_get_l4_mp_clk_hz(struct socfpga_clk_plat *plat)
> +{
> +	u64 clock = clk_get_l3_main_clk_hz(plat);
> +
> +	clock /= BIT((CM_REG_READL(plat, CLKMGR_MAINPLL_NOCDIV) >>
> +		      CLKMGR_NOCDIV_L4MPCLK_OFFSET) &
> +		      CLKMGR_NOCDIV_DIVIDER_MASK);
> +
> +	return clock;
> +}
> +
> +static u32 clk_get_l4_sys_free_clk_hz(struct socfpga_clk_plat *plat)
> +{
> +	if (CM_REG_READL(plat, CLKMGR_STAT) & CLKMGR_STAT_BOOTMODE)
> +		return clk_get_l3_main_clk_hz(plat) / 2;
> +
> +	return clk_get_l3_main_clk_hz(plat) / 4;
> +}
> +
> +static u32 clk_get_emac_clk_hz(struct socfpga_clk_plat *plat, u32 emac_id)
> +{
> +	bool emacsel_a;
> +	u32 ctl;
> +	u32 ctr_reg;
> +	u32 clock;
> +	u32 div;
> +	u32 reg;
> +
> +	/* Get EMAC clock source */
> +	ctl = CM_REG_READL(plat, CLKMGR_PERPLL_EMACCTL);
> +	if (emac_id == DM_EMAC0_CLK)
> +		ctl = (ctl >> CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_OFFSET) &
> +		       CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_MASK;
> +	else if (emac_id == DM_EMAC1_CLK)
> +		ctl = (ctl >> CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_OFFSET) &
> +		       CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_MASK;
> +	else if (emac_id == DM_EMAC2_CLK)
> +		ctl = (ctl >> CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_OFFSET) &
> +		       CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_MASK;
> +	else
> +		return 0;
> +
> +	if (ctl) {
> +		/* EMAC B source */
> +		emacsel_a = false;
> +		ctr_reg = CLKMGR_ALTR_EMACBCTR;
> +	} else {
> +		/* EMAC A source */
> +		emacsel_a = true;
> +		ctr_reg = CLKMGR_ALTR_EMACACTR;
> +	}
> +
> +	reg = CM_REG_READL(plat, ctr_reg);
> +	clock = (reg & CLKMGR_ALT_EMACCTR_SRC_MASK)
> +		 >> CLKMGR_ALT_EMACCTR_SRC_OFFSET;
> +	div = (reg & CLKMGR_ALT_EMACCTR_CNT_MASK)
> +	       >> CLKMGR_ALT_EMACCTR_CNT_OFFSET;
> +
> +	switch (clock) {
> +	case CLKMGR_CLKSRC_MAIN:
> +		clock = clk_get_pll_output_hz(plat,
> +					      CLKMGR_MAINPLL_PLLGLOB,
> +					      CLKMGR_MAINPLL_PLLDIV);
> +
> +		if (emacsel_a) {
> +			clock /= 1 + ((CM_REG_READL(plat,
> +				       CLKMGR_MAINPLL_PLLOUTDIV) &
> +				       CLKMGR_PLLOUTDIV_C2CNT_MASK) >>
> +				       CLKMGR_PLLOUTDIV_C2CNT_OFFSET);
> +		} else {
> +			clock /= 1 + ((CM_REG_READL(plat,
> +				       CLKMGR_MAINPLL_PLLOUTDIV) &
> +				       CLKMGR_PLLOUTDIV_C3CNT_MASK) >>
> +				       CLKMGR_PLLOUTDIV_C3CNT_OFFSET);
> +		}
> +		break;
> +
> +	case CLKMGR_CLKSRC_PER:
> +		clock = clk_get_pll_output_hz(plat,
> +					      CLKMGR_PERPLL_PLLGLOB,
> +					      CLKMGR_PERPLL_PLLDIV);
> +		if (emacsel_a) {
> +			clock /= 1 + ((CM_REG_READL(plat,
> +				       CLKMGR_PERPLL_PLLOUTDIV) &
> +				       CLKMGR_PLLOUTDIV_C2CNT_MASK) >>
> +				       CLKMGR_PLLOUTDIV_C2CNT_OFFSET);
> +		} else {
> +			clock /= 1 + ((CM_REG_READL(plat,
> +				       CLKMGR_PERPLL_PLLOUTDIV) &
> +				       CLKMGR_PLLOUTDIV_C3CNT_MASK >>
> +				       CLKMGR_PLLOUTDIV_C3CNT_OFFSET));
> +		}
> +		break;
> +
> +	case CLKMGR_CLKSRC_OSC1:
> +		clock = cm_get_osc_clk_hz();
> +		break;
> +
> +	case CLKMGR_CLKSRC_INTOSC:
> +		clock = cm_get_intosc_clk_hz();
> +		break;
> +
> +	case CLKMGR_CLKSRC_FPGA:
> +		clock = cm_get_fpga_clk_hz();
> +		break;
> +	}
> +
> +	clock /= 1 + div;
> +
> +	return clock;
> +}
> +
> +static ulong socfpga_clk_get_rate(struct clk *clk)
> +{
> +	struct socfpga_clk_plat *plat = dev_get_plat(clk->dev);
> +
> +	switch (clk->id) {
> +	case DM_MPU_CLK:
> +		return clk_get_mpu_clk_hz(plat);
> +	case DM_L4_MAIN_CLK:
> +		return clk_get_l4_main_clk_hz(plat);
> +	case DM_L4_SYS_FREE_CLK:
> +		return clk_get_l4_sys_free_clk_hz(plat);
> +	case DM_L4_MP_CLK:
> +		return clk_get_l4_mp_clk_hz(plat);
> +	case DM_L4_SP_CLK:
> +#ifndef CONFIG_TARGET_SOCFPGA_DM
> +		return clk_get_l4_sp_clk_hz(plat);
> +#else
> +		return 76800;
> +#endif
> +	case DM_SDMMC_CLK:
> +		return clk_get_sdmmc_clk_hz(plat);
> +	case DM_EMAC0_CLK:
> +	case DM_EMAC1_CLK:
> +	case DM_EMAC2_CLK:
> +		return clk_get_emac_clk_hz(plat, clk->id);
> +	case DM_USB_CLK:
> +	case DM_NAND_X_CLK:
> +		return clk_get_l4_mp_clk_hz(plat);
> +	case DM_NAND_CLK:
> +		return clk_get_l4_mp_clk_hz(plat) / 4;
> +	default:
> +		return -ENXIO;

ENOENT please

> +	}
> +}
> +
> +static int socfpga_clk_enable(struct clk *clk)
> +{
> +	return 0;
> +}
> +
> +static int socfpga_clk_probe(struct udevice *dev)
> +{
> +	const struct cm_config *cm_default_cfg = cm_get_default_config();
> +
> +	clk_basic_init(dev, cm_default_cfg);
> +
> +	return 0;
> +}
> +
> +static int socfpga_clk_of_to_plat(struct udevice *dev)
> +{
> +	struct socfpga_clk_plat *plat = dev_get_plat(dev);
> +	fdt_addr_t addr;
> +
> +	addr = devfdt_get_addr(dev);
> +	if (addr == FDT_ADDR_T_NONE)
> +		return -EINVAL;
> +	plat->regs = (void __iomem *)addr;
> +
> +	return 0;
> +}
> +
> +static struct clk_ops socfpga_clk_ops = {
> +	.enable		= socfpga_clk_enable,
> +	.get_rate	= socfpga_clk_get_rate,
> +};
> +
> +static const struct udevice_id socfpga_clk_match[] = {
> +	{ .compatible = "intel,dm-clkmgr" },
> +	{}
> +};
> +
> +U_BOOT_DRIVER(socfpga_dm_clk) = {
> +	.name		= "clk-dm",
> +	.id		= UCLASS_CLK,
> +	.of_match	= socfpga_clk_match,
> +	.ops		= &socfpga_clk_ops,
> +	.probe		= socfpga_clk_probe,
> +	.of_to_plat	= socfpga_clk_of_to_plat,
> +	.plat_auto	= sizeof(struct socfpga_clk_plat),
> +};
> diff --git a/drivers/clk/altera/clk-dm.h b/drivers/clk/altera/clk-dm.h
> new file mode 100644
> index 0000000000..89d3a92a34
> --- /dev/null
> +++ b/drivers/clk/altera/clk-dm.h
> @@ -0,0 +1,217 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2020 Intel Corporation <www.intel.com>
> + */
> +
> +#ifndef	_CLK_DM_
> +#define	_CLK_DM_
> +
> +#ifndef __ASSEMBLY__
> +#include <linux/bitops.h>
> +#endif
> +
> +#define CM_REG_READL(plat, reg)				\
> +	readl((plat)->regs + (reg))
> +
> +#define CM_REG_WRITEL(plat, data, reg)			\
> +	writel(data, (plat)->regs + (reg))
> +
> +#define CM_REG_CLRBITS(plat, reg, clear)		\
> +	clrbits_le32((plat)->regs + (reg), (clear))
> +
> +#define CM_REG_SETBITS(plat, reg, set)			\
> +	setbits_le32((plat)->regs + (reg), (set))

Can you use inline functions here instead?

> +struct cm_config {
> +	/* main group */
> +	u32 main_pll_mpuclk;
> +	u32 main_pll_nocclk;
> +	u32 main_pll_nocdiv;
> +	u32 main_pll_pllglob;
> +	u32 main_pll_plldiv;
> +	u32 main_pll_plloutdiv;
> +	u32 spare_1[4];

Are these reserved fields? If so, please name them as such.

> +
> +	/* peripheral group */
> +	u32 per_pll_emacctl;
> +	u32 per_pll_gpiodiv;
> +	u32 per_pll_pllglob;
> +	u32 per_pll_plldiv;
> +	u32 per_pll_plloutdiv;
> +	u32 spare_2[4];
> +
> +	/* altera group */
> +	u32 alt_emacactr;
> +	u32 alt_emacbctr;
> +	u32 alt_emacptpctr;
> +	u32 alt_gpiodbctr;
> +	u32 alt_sdmmcctr;
> +	u32 alt_s2fuser0ctr;
> +	u32 alt_s2fuser1ctr;
> +	u32 alt_psirefctr;
> +
> +	/* incoming clock */
> +	u32 hps_osc_clk_hz;
> +	u32 fpga_clk_hz;
> +	u32 spare_3[3];
> +
> +	/* memory clock group */
> +	u32 mem_memdiv;
> +	u32 mem_pllglob;
> +	u32 mem_plldiv;
> +	u32 mem_plloutdiv;
> +	u32 spare_4[4];
> +};
> +
> +/* Clock Manager registers */
> +#define CLKMGR_CTRL					0
> +#define CLKMGR_STAT					4
> +#define CLKMGR_TESTIOCTRL				8
> +#define CLKMGR_INTRGEN					0x0c
> +#define CLKMGR_INTRMSK					0x10
> +#define CLKMGR_INTRCLR					0x14
> +#define CLKMGR_INTRSTS					0x18
> +#define CLKMGR_INTRSTK					0x1c
> +#define CLKMGR_INTRRAW					0x20
> +
> +/* Clock Manager Main PPL group registers */
> +#define CLKMGR_MAINPLL_EN				0x24
> +#define CLKMGR_MAINPLL_ENS				0x28
> +#define CLKMGR_MAINPLL_ENR				0x2c
> +#define CLKMGR_MAINPLL_BYPASS				0x30
> +#define CLKMGR_MAINPLL_BYPASSS				0x34
> +#define CLKMGR_MAINPLL_BYPASSR				0x38
> +#define CLKMGR_MAINPLL_MPUCLK				0x3c
> +#define CLKMGR_MAINPLL_NOCCLK				0x40
> +#define CLKMGR_MAINPLL_NOCDIV				0x44
> +#define CLKMGR_MAINPLL_PLLGLOB				0x48
> +#define CLKMGR_MAINPLL_PLLCTRL				0x4c
> +#define CLKMGR_MAINPLL_PLLDIV				0x50
> +#define CLKMGR_MAINPLL_PLLOUTDIV			0x54
> +#define CLKMGR_MAINPLL_LOSTLOCK				0x58
> +
> +/* Clock Manager Peripheral PPL group registers */
> +#define CLKMGR_PERPLL_EN				0x7c
> +#define CLKMGR_PERPLL_ENS				0x80
> +#define CLKMGR_PERPLL_ENR				0x84
> +#define CLKMGR_PERPLL_BYPASS				0x88
> +#define CLKMGR_PERPLL_BYPASSS				0x8c
> +#define CLKMGR_PERPLL_BYPASSR				0x90
> +#define CLKMGR_PERPLL_EMACCTL				0x94
> +#define CLKMGR_PERPLL_GPIODIV				0x98
> +#define CLKMGR_PERPLL_PLLGLOB				0x9c
> +#define CLKMGR_PERPLL_PLLCTRL				0xa0
> +#define CLKMGR_PERPLL_PLLDIV				0xa4
> +#define CLKMGR_PERPLL_PLLOUTDIV				0xa8
> +#define CLKMGR_PERPLL_LOSTLOCK				0xac
> +
> +/* Clock Manager Altera group registers */
> +#define CLKMGR_ALTR_EMACACTR				0xd4
> +#define CLKMGR_ALTR_EMACBCTR				0xd8
> +#define CLKMGR_ALTR_EMACPTPCTR				0xdc
> +#define CLKMGR_ALTR_GPIODBCTR				0xe0
> +#define CLKMGR_ALTR_SDMMCCTR				0xe4
> +#define CLKMGR_ALTR_S2FUSER0CTR				0xe8
> +#define CLKMGR_ALTR_S2FUSER1CTR				0xec
> +#define CLKMGR_ALTR_PSIREFCTR				0xf0
> +#define CLKMGR_ALTR_EXTCNTRST				0xf4
> +
> +#define CLKMGR_CTRL_BOOTMODE				BIT(0)
> +
> +#define CLKMGR_STAT_BUSY				BIT(0)
> +#define CLKMGR_STAT_MAINPLL_LOCKED			BIT(8)
> +#define CLKMGR_STAT_MAIN_TRANS				BIT(9)
> +#define CLKMGR_STAT_PERPLL_LOCKED			BIT(16)
> +#define CLKMGR_STAT_PERF_TRANS				BIT(17)
> +#define CLKMGR_STAT_BOOTMODE				BIT(24)
> +#define CLKMGR_STAT_BOOTCLKSRC				BIT(25)
> +
> +#define CLKMGR_STAT_ALLPLL_LOCKED_MASK			\
> +	(CLKMGR_STAT_MAINPLL_LOCKED | CLKMGR_STAT_PERPLL_LOCKED)
> +
> +#define CLKMGR_INTER_MAINPLLLOCKED_MASK			0x00000001
> +#define CLKMGR_INTER_PERPLLLOCKED_MASK			0x00000002
> +#define CLKMGR_INTER_MAINPLLLOST_MASK			0x00000004
> +#define CLKMGR_INTER_PERPLLLOST_MASK			0x00000008

BIT()?

> +#define CLKMGR_CLKSRC_MASK				GENMASK(18, 16)
> +#define CLKMGR_CLKSRC_OFFSET				16
> +#define CLKMGR_CLKSRC_MAIN				0
> +#define CLKMGR_CLKSRC_PER				1
> +#define CLKMGR_CLKSRC_OSC1				2
> +#define CLKMGR_CLKSRC_INTOSC				3
> +#define CLKMGR_CLKSRC_FPGA				4
> +#define CLKMGR_CLKCNT_MSK				GENMASK(10, 0)
> +
> +#define CLKMGR_BYPASS_MAINPLL_ALL			0x7
> +#define CLKMGR_BYPASS_PERPLL_ALL			0x7f

GENMASK()?

> +#define CLKMGR_NOCDIV_L4MAIN_OFFSET			0
> +#define CLKMGR_NOCDIV_L4MPCLK_OFFSET			8
> +#define CLKMGR_NOCDIV_L4SPCLK_OFFSET			16
> +#define CLKMGR_NOCDIV_CSATCLK_OFFSET			24
> +#define CLKMGR_NOCDIV_CSTRACECLK_OFFSET			26
> +#define CLKMGR_NOCDIV_CSPDBGCLK_OFFSET			28
> +#define CLKMGR_NOCDIV_DIVIDER_MASK			0x3
> +
> +#define CLKMGR_PLLGLOB_VCO_PSRC_MASK			GENMASK(17, 16)
> +#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET			16
> +#define CLKMGR_PLLGLOB_LOSTLOCK_BYPASS_EN_MASK		BIT(28)
> +#define CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK		BIT(29)
> +
> +#define CLKMGR_VCO_PSRC_EOSC1				0
> +#define CLKMGR_VCO_PSRC_INTOSC				1
> +#define CLKMGR_VCO_PSRC_F2S				2
> +
> +#define CLKMGR_PLLCTRL_BYPASS_MASK			BIT(0)
> +#define CLKMGR_PLLCTRL_RST_N_MASK			BIT(1)
> +
> +#define CLKMGR_PLLDIV_REFCLKDIV_MASK			GENMASK(5, 0)
> +#define CLKMGR_PLLDIV_FDIV_MASK				GENMASK(16, 8)
> +#define CLKMGR_PLLDIV_OUTDIV_QDIV_MASK			GENMASK(26, 24)
> +#define CLKMGR_PLLDIV_RANGE_MASK			GENMASK(30, 28)
> +
> +#define CLKMGR_PLLDIV_REFCLKDIV_OFFSET			0
> +#define CLKMGR_PLLDIV_FDIV_OFFSET			8
> +#define CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET		24
> +#define CLKMGR_PLLDIV_RANGE_OFFSET			28
> +
> +#define CLKMGR_PLLOUTDIV_C0CNT_MASK			GENMASK(4, 0)
> +#define CLKMGR_PLLOUTDIV_C1CNT_MASK			GENMASK(12, 8)
> +#define CLKMGR_PLLOUTDIV_C2CNT_MASK			GENMASK(20, 16)
> +#define CLKMGR_PLLOUTDIV_C3CNT_MASK			GENMASK(28, 24)
> +
> +#define CLKMGR_PLLOUTDIV_C0CNT_OFFSET			0
> +#define CLKMGR_PLLOUTDIV_C1CNT_OFFSET			8
> +#define CLKMGR_PLLOUTDIV_C2CNT_OFFSET			16
> +#define CLKMGR_PLLOUTDIV_C3CNT_OFFSET			24
> +
> +#define CLKMGR_PLLCX_EN_SET_MSK				BIT(27)
> +#define CLKMGR_PLLCX_MUTE_SET_MSK			BIT(28)
> +
> +#define CLKMGR_VCOCALIB_MSCNT_MASK			GENMASK(23, 16)
> +#define CLKMGR_VCOCALIB_MSCNT_OFFSET			16
> +#define CLKMGR_VCOCALIB_HSCNT_MASK			GENMASK(9, 0)
> +#define CLKMGR_VCOCALIB_MSCNT_CONST			100
> +#define CLKMGR_VCOCALIB_HSCNT_CONST			4
> +
> +#define CLKMGR_PLLM_MDIV_MASK				GENMASK(9, 0)
> +
> +#define CLKMGR_LOSTLOCK_SET_MASK			BIT(0)
> +
> +#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK		BIT(5)
> +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_OFFSET	26
> +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_MASK		BIT(26)
> +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_OFFSET	27
> +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_MASK		BIT(27)
> +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_OFFSET	28
> +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_MASK		BIT(28)
> +
> +#define CLKMGR_ALT_EMACCTR_SRC_OFFSET			16
> +#define CLKMGR_ALT_EMACCTR_SRC_MASK			GENMASK(18, 16)
> +#define CLKMGR_ALT_EMACCTR_CNT_OFFSET			0
> +#define CLKMGR_ALT_EMACCTR_CNT_MASK			GENMASK(10, 0)
> +
> +#define CLKMGR_ALT_EXTCNTRST_ALLCNTRST_MASK		GENMASK(15, 0)
> +
> +#endif /* _CLK_DM_ */
> diff --git a/include/dt-bindings/clock/dm-clock.h b/include/dt-bindings/clock/dm-clock.h
> new file mode 100644
> index 0000000000..d624ac723c
> --- /dev/null
> +++ b/include/dt-bindings/clock/dm-clock.h
> @@ -0,0 +1,71 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2020, Intel Corporation
> + */
> +
> +#ifndef __DM_CLOCK_H
> +#define __DM_CLOCK_H
> +
> +/* fixed rate clocks */
> +#define DM_OSC1					0
> +#define DM_CB_INTOSC_HS_DIV2_CLK		1
> +#define DM_CB_INTOSC_LS_CLK			2
> +#define DM_L4_SYS_FREE_CLK			3
> +#define DM_F2S_FREE_CLK				4
> +
> +/* PLL clocks */
> +#define DM_MAIN_PLL_CLK				5
> +#define DM_MAIN_PLL_C0_CLK			6
> +#define DM_MAIN_PLL_C1_CLK			7
> +#define DM_MAIN_PLL_C2_CLK			8
> +#define DM_MAIN_PLL_C3_CLK			9
> +#define DM_PERIPH_PLL_CLK			10
> +#define DM_PERIPH_PLL_C0_CLK			11
> +#define DM_PERIPH_PLL_C1_CLK			12
> +#define DM_PERIPH_PLL_C2_CLK			13
> +#define DM_PERIPH_PLL_C3_CLK			14
> +#define DM_MPU_FREE_CLK				15
> +#define DM_MPU_CCU_CLK				16
> +#define DM_BOOT_CLK				17
> +
> +/* fixed factor clocks */
> +#define DM_L3_MAIN_FREE_CLK			18
> +#define DM_NOC_FREE_CLK				19
> +#define DM_S2F_USR0_CLK				20
> +#define DM_NOC_CLK				21
> +#define DM_EMAC_A_FREE_CLK			22
> +#define DM_EMAC_B_FREE_CLK			23
> +#define DM_EMAC_PTP_FREE_CLK			24
> +#define DM_GPIO_DB_FREE_CLK			25
> +#define DM_SDMMC_FREE_CLK			26
> +#define DM_S2F_USER0_FREE_CLK			27
> +#define DM_S2F_USER1_FREE_CLK			28
> +#define DM_PSI_REF_FREE_CLK			29
> +
> +/* Gate clocks */
> +#define DM_MPU_CLK				30
> +#define DM_MPU_PERIPH_CLK			31
> +#define DM_L4_MAIN_CLK				32
> +#define DM_L4_MP_CLK				33
> +#define DM_L4_SP_CLK				34
> +#define DM_CS_AT_CLK				35
> +#define DM_CS_TRACE_CLK				36
> +#define DM_CS_PDBG_CLK				37
> +#define DM_CS_TIMER_CLK				38
> +#define DM_S2F_USER0_CLK			39
> +#define DM_EMAC0_CLK				40
> +#define DM_EMAC1_CLK				41
> +#define DM_EMAC2_CLK				42
> +#define DM_EMAC_PTP_CLK				43
> +#define DM_GPIO_DB_CLK				44
> +#define DM_NAND_CLK				45
> +#define DM_PSI_REF_CLK				46
> +#define DM_S2F_USER1_CLK			47
> +#define DM_SDMMC_CLK				48
> +#define DM_SPI_M_CLK				49
> +#define DM_USB_CLK				50
> +#define DM_NAND_X_CLK				51
> +#define DM_NAND_ECC_CLK				52
> +#define DM_NUM_CLKS				53
> +
> +#endif	/* __DM_CLOCK_H */



More information about the U-Boot mailing list