On 15/03/2023 08:28, Jacky Huang wrote: > From: Jacky Huang <ychuang3@xxxxxxxxxxx> > > The clock controller generates clocks for the whole chip, including > system clocks and all peripheral clocks. This driver support ma35d1 > clock gating, divider, and individual PLL configuration. > > There are 6 PLLs in ma35d1 SoC: > - CA-PLL for the two Cortex-A35 CPU clock > - SYS-PLL for system bus, which comes from the companion MCU > and cannot be programmed by clock controller. > - DDR-PLL for DDR > - EPLL for GMAC and GFX, Display, and VDEC IPs. > - VPLL for video output pixel clock > - APLL for SDHC, I2S audio, and other IPs. > CA-PLL has only one operation mode. > DDR-PLL, EPLL, VPLL, and APLL are advanced PLLs which have 3 > operation modes: integer mode, fraction mode, and spread specturm mode. > > Signed-off-by: Jacky Huang <ychuang3@xxxxxxxxxxx> > --- > drivers/clk/Makefile | 1 + > drivers/clk/nuvoton/Makefile | 4 + > drivers/clk/nuvoton/clk-ma35d1-divider.c | 144 ++++ > drivers/clk/nuvoton/clk-ma35d1-pll.c | 534 +++++++++++++ > drivers/clk/nuvoton/clk-ma35d1.c | 970 +++++++++++++++++++++++ > drivers/clk/nuvoton/clk-ma35d1.h | 198 +++++ > 6 files changed, 1851 insertions(+) > create mode 100644 drivers/clk/nuvoton/Makefile > create mode 100644 drivers/clk/nuvoton/clk-ma35d1-divider.c > create mode 100644 drivers/clk/nuvoton/clk-ma35d1-pll.c > create mode 100644 drivers/clk/nuvoton/clk-ma35d1.c > create mode 100644 drivers/clk/nuvoton/clk-ma35d1.h > > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile > index e3ca0d058a25..2e7916d269e1 100644 > --- a/drivers/clk/Makefile > +++ b/drivers/clk/Makefile > @@ -103,6 +103,7 @@ endif > obj-y += mstar/ > obj-y += mvebu/ > obj-$(CONFIG_ARCH_MXS) += mxs/ > +obj-$(CONFIG_ARCH_NUVOTON) += nuvoton/ Missing compile test. (...) > + > +MODULE_AUTHOR("Chi-Fang Li<cfli0@xxxxxxxxxxx>"); > +MODULE_DESCRIPTION("NUVOTON MA35D1 Clock Driver"); > +MODULE_LICENSE("GPL v2"); > diff --git a/drivers/clk/nuvoton/clk-ma35d1.h b/drivers/clk/nuvoton/clk-ma35d1.h > new file mode 100644 > index 000000000000..faae5a17e425 > --- /dev/null > +++ b/drivers/clk/nuvoton/clk-ma35d1.h > @@ -0,0 +1,198 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (C) 2023 Nuvoton Technology Corp. > + * Author: Chi-Fang Li <cfli0@xxxxxxxxxxx> > + */ > + > +#ifndef __DRV_CLK_NUVOTON_MA35D1_H > +#define __DRV_CLK_NUVOTON_MA35D1_H > + > +#include <linux/clk.h> > +#include <linux/clkdev.h> > +#include <linux/clk-provider.h> > +#include <linux/spinlock.h> > +#include <linux/regmap.h> > +#include <linux/mfd/syscon.h> > +#include <linux/mfd/ma35d1-sys.h> > + > +enum ma35d1_pll_type { > + MA35D1_CAPLL, > + MA35D1_DDRPLL, > + MA35D1_APLL, > + MA35D1_EPLL, > + MA35D1_VPLL, > +}; > + > +enum ma35d1_pll_mode { > + VSIPLL_INTEGER_MODE, > + VSIPLL_FRACTIONAL_MODE, > + VSIPLL_SS_MODE, > +}; > + > +/* VSI-PLL CTL0~2 */ > +#define VSIPLL_CTL0 0x0 > +#define VSIPLL_CTL1 0x4 > +#define VSIPLL_CTL2 0x8 > + > +/* VSI-PLL Specification limits */ > +#define VSIPLL_FREF_MAX_FREQ 200000000UL > +#define VSIPLL_FREF_MIN_FREQ 1000000UL > +#define VSIPLL_FREFDIVM_MAX_FREQ 40000000UL > +#define VSIPLL_FREFDIVM_MIN_FREQ0 1000000UL > +#define VSIPLL_FREFDIVM_MIN_FREQ1 10000000UL > +#define VSIPLL_FCLK_MAX_FREQ 2400000000UL > +#define VSIPLL_FCLK_MIN_FREQ 600000000UL > +#define VSIPLL_FCLKO_MAX_FREQ 2400000000UL > +#define VSIPLL_FCLKO_MIN_FREQ 85700000UL > +#define VSIPLL_SPREAD_RANGE 194 > +#define VSIPLL_MODULATION_FREQ 50000 > + > +/* Clock Control Registers Offset */ > +#define REG_CLK_PWRCTL (0x00) > +#define REG_CLK_SYSCLK0 (0x04) > +#define REG_CLK_SYSCLK1 (0x08) > +#define REG_CLK_APBCLK0 (0x0C) > +#define REG_CLK_APBCLK1 (0x10) > +#define REG_CLK_APBCLK2 (0x14) > +#define REG_CLK_CLKSEL0 (0x18) > +#define REG_CLK_CLKSEL1 (0x1C) > +#define REG_CLK_CLKSEL2 (0x20) > +#define REG_CLK_CLKSEL3 (0x24) > +#define REG_CLK_CLKSEL4 (0x28) > +#define REG_CLK_CLKDIV0 (0x2C) > +#define REG_CLK_CLKDIV1 (0x30) > +#define REG_CLK_CLKDIV2 (0x34) > +#define REG_CLK_CLKDIV3 (0x38) > +#define REG_CLK_CLKDIV4 (0x3C) > +#define REG_CLK_CLKOCTL (0x40) > +#define REG_CLK_STATUS (0x50) > +#define REG_CLK_PLL0CTL0 (0x60) > +#define REG_CLK_PLL2CTL0 (0x80) > +#define REG_CLK_PLL2CTL1 (0x84) > +#define REG_CLK_PLL2CTL2 (0x88) > +#define REG_CLK_PLL3CTL0 (0x90) > +#define REG_CLK_PLL3CTL1 (0x94) > +#define REG_CLK_PLL3CTL2 (0x98) > +#define REG_CLK_PLL4CTL0 (0xA0) > +#define REG_CLK_PLL4CTL1 (0xA4) > +#define REG_CLK_PLL4CTL2 (0xA8) > +#define REG_CLK_PLL5CTL0 (0xB0) > +#define REG_CLK_PLL5CTL1 (0xB4) > +#define REG_CLK_PLL5CTL2 (0xB8) > +#define REG_CLK_CLKDCTL (0xC0) > +#define REG_CLK_CLKDSTS (0xC4) > +#define REG_CLK_CDUPB (0xC8) > +#define REG_CLK_CDLOWB (0xCC) > +#define REG_CLK_CKFLTRCTL (0xD0) > +#define REG_CLK_TESTCLK (0xF0) > +#define REG_CLK_PLLCTL (0x40) > + > +/* Constant Definitions for Clock Controller */ > +#define SMICPLLCTL0_FBDIV_POS (0) > +#define SMICPLLCTL0_FBDIV_MSK (0xfful << SMICPLLCTL0_FBDIV_POS) > +#define SMICPLLCTL0_INDIV_POS (8) > +#define SMICPLLCTL0_INDIV_MSK (0xful << SMICPLLCTL0_INDIV_POS) > +#define SMICPLLCTL0_OUTDIV_POS (12) > +#define SMICPLLCTL0_OUTDIV_MSK (0x3ul << SMICPLLCTL0_OUTDIV_POS) > +#define SMICPLLCTL0_PD_POS (16) > +#define SMICPLLCTL0_PD_MSK (0x1ul << SMICPLLCTL0_PD_POS) > +#define SMICPLLCTL0_BP_POS (17) > +#define SMICPLLCTL0_BP_MSK (0x1ul << SMICPLLCTL0_BP_POS) > +#define VSIPLLCTL0_FBDIV_POS (0) > +#define VSIPLLCTL0_FBDIV_MSK (0x7fful << VSIPLLCTL0_FBDIV_POS) > +#define VSIPLLCTL0_INDIV_POS (12) > +#define VSIPLLCTL0_INDIV_MSK (0x3ful << VSIPLLCTL0_INDIV_POS) > +#define VSIPLLCTL0_MODE_POS (18) > +#define VSIPLLCTL0_MODE_MSK (0x3ul << VSIPLLCTL0_MODE_POS) > +#define VSIPLLCTL0_SSRATE_POS (20) > +#define VSIPLLCTL0_SSRATE_MSK (0x7fful << VSIPLLCTL0_SSRATE_POS) > +#define VSIPLLCTL1_PD_POS (0) > +#define VSIPLLCTL1_PD_MSK (0x1ul << VSIPLLCTL1_PD_POS) > +#define VSIPLLCTL1_BP_POS (1) > +#define VSIPLLCTL1_BP_MSK (0x1ul << VSIPLLCTL1_BP_POS) > +#define VSIPLLCTL1_OUTDIV_POS (4) > +#define VSIPLLCTL1_OUTDIV_MSK (0x7ul << VSIPLLCTL1_OUTDIV_POS) > +#define VSIPLLCTL1_FRAC_POS (8) > +#define VSIPLLCTL1_FRAC_MSK (0xfffffful << VSIPLLCTL1_FRAC_POS) > +#define VSIPLLCTL2_SLOPE_POS (0) > +#define VSIPLLCTL2_SLOPE_MSK (0xfffffful << VSIPLLCTL2_SLOPE_POS) > + > +struct clk_hw *ma35d1_reg_clk_pll(enum ma35d1_pll_type type, u8 u8mode, > + const char *name, const char *parent, > + unsigned long targetFreq, > + void __iomem *base, > + struct regmap *regmap); > + > +struct clk_hw *ma35d1_reg_adc_clkdiv(struct device *dev, > + const char *name, > + const char *parent_name, > + unsigned long flags, > + void __iomem *reg, u8 shift, > + u8 width, u32 mask_bit); > + > +extern spinlock_t ma35d1_lock; Why this is here? > + > +static inline struct clk_hw *ma35d1_clk_fixed(const char *name, int rate) > +{ > + return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); > +} > + Why all these are here? > + > +#endif /* __DRV_CLK_NUVOTON_MA35D1_H */ Best regards, Krzysztof