diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/clk-provider.h | 112 | ||||
| -rw-r--r-- | include/linux/clk/analogbits-wrpll-cln28hpc.h | 79 | ||||
| -rw-r--r-- | include/linux/clk/at91_pmc.h | 12 | ||||
| -rw-r--r-- | include/linux/clk/ti.h | 2 | ||||
| -rw-r--r-- | include/linux/device.h | 2 | ||||
| -rw-r--r-- | include/linux/math64.h | 13 |
6 files changed, 151 insertions, 69 deletions
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index b7cf80a71293..491d992d045d 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -24,7 +24,7 @@ #define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ #define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ /* unused */ -#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ + /* unused */ #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ @@ -251,19 +251,40 @@ struct clk_ops { }; /** + * struct clk_parent_data - clk parent information + * @hw: parent clk_hw pointer (used for clk providers with internal clks) + * @fw_name: parent name local to provider registering clk + * @name: globally unique parent name (used as a fallback) + * @index: parent index local to provider registering clk (if @fw_name absent) + */ +struct clk_parent_data { + const struct clk_hw *hw; + const char *fw_name; + const char *name; + int index; +}; + +/** * struct clk_init_data - holds init data that's common to all clocks and is * shared between the clock provider and the common clock framework. * * @name: clock name * @ops: operations this clock supports * @parent_names: array of string names for all possible parents + * @parent_data: array of parent data for all possible parents (when some + * parents are external to the clk controller) + * @parent_hws: array of pointers to all possible parents (when all parents + * are internal to the clk controller) * @num_parents: number of possible parents * @flags: framework-level hints and quirks */ struct clk_init_data { const char *name; const struct clk_ops *ops; + /* Only one of the following three should be assigned */ const char * const *parent_names; + const struct clk_parent_data *parent_data; + const struct clk_hw **parent_hws; u8 num_parents; unsigned long flags; }; @@ -307,7 +328,6 @@ struct clk_fixed_rate { struct clk_hw hw; unsigned long fixed_rate; unsigned long fixed_accuracy; - u8 flags; }; #define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) @@ -349,6 +369,9 @@ void of_fixed_clk_setup(struct device_node *np); * of this register, and mask of gate bits are in higher 16-bit of this * register. While setting the gate bits, higher 16-bit should also be * updated to indicate changing gate bits. + * CLK_GATE_BIG_ENDIAN - by default little endian register accesses are used for + * the gate register. Setting this flag makes the register accesses big + * endian. */ struct clk_gate { struct clk_hw hw; @@ -362,6 +385,7 @@ struct clk_gate { #define CLK_GATE_SET_TO_DISABLE BIT(0) #define CLK_GATE_HIWORD_MASK BIT(1) +#define CLK_GATE_BIG_ENDIAN BIT(2) extern const struct clk_ops clk_gate_ops; struct clk *clk_register_gate(struct device *dev, const char *name, @@ -417,6 +441,9 @@ struct clk_div_table { * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED * except when the value read from the register is zero, the divisor is * 2^width of the field. + * CLK_DIVIDER_BIG_ENDIAN - By default little endian register accesses are used + * for the divider register. Setting this flag makes the register accesses + * big endian. */ struct clk_divider { struct clk_hw hw; @@ -438,6 +465,7 @@ struct clk_divider { #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) #define CLK_DIVIDER_READ_ONLY BIT(5) #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) +#define CLK_DIVIDER_BIG_ENDIAN BIT(7) extern const struct clk_ops clk_divider_ops; extern const struct clk_ops clk_divider_ro_ops; @@ -499,8 +527,13 @@ void clk_hw_unregister_divider(struct clk_hw *hw); * register, and mask of mux bits are in higher 16-bit of this register. * While setting the mux bits, higher 16-bit should also be updated to * indicate changing mux bits. + * CLK_MUX_READ_ONLY - The mux registers can't be written, only read in the + * .get_parent clk_op. * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired * frequency. + * CLK_MUX_BIG_ENDIAN - By default little endian register accesses are used for + * the mux register. Setting this flag makes the register accesses big + * endian. */ struct clk_mux { struct clk_hw hw; @@ -519,6 +552,7 @@ struct clk_mux { #define CLK_MUX_HIWORD_MASK BIT(2) #define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */ #define CLK_MUX_ROUND_CLOSEST BIT(4) +#define CLK_MUX_BIG_ENDIAN BIT(5) extern const struct clk_ops clk_mux_ops; extern const struct clk_ops clk_mux_ro_ops; @@ -602,6 +636,9 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw); * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED * is set then the numerator and denominator are both the value read * plus one. + * CLK_FRAC_DIVIDER_BIG_ENDIAN - By default little endian register accesses are + * used for the divider register. Setting this flag makes the register + * accesses big endian. */ struct clk_fractional_divider { struct clk_hw hw; @@ -622,6 +659,7 @@ struct clk_fractional_divider { #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) #define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0) +#define CLK_FRAC_DIVIDER_BIG_ENDIAN BIT(1) extern const struct clk_ops clk_fractional_divider_ops; struct clk *clk_register_fractional_divider(struct device *dev, @@ -654,6 +692,9 @@ void clk_hw_unregister_fractional_divider(struct clk_hw *hw); * leaving the parent rate unmodified. * CLK_MULTIPLIER_ROUND_CLOSEST - Makes the best calculated divider to be * rounded to the closest integer instead of the down one. + * CLK_MULTIPLIER_BIG_ENDIAN - By default little endian register accesses are + * used for the multiplier register. Setting this flag makes the register + * accesses big endian. */ struct clk_multiplier { struct clk_hw hw; @@ -668,6 +709,7 @@ struct clk_multiplier { #define CLK_MULTIPLIER_ZERO_BYPASS BIT(0) #define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1) +#define CLK_MULTIPLIER_BIG_ENDIAN BIT(2) extern const struct clk_ops clk_multiplier_ops; @@ -712,16 +754,19 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, unsigned long flags); void clk_hw_unregister_composite(struct clk_hw *hw); -/*** - * struct clk_gpio_gate - gpio gated clock +/** + * struct clk_gpio - gpio gated clock * * @hw: handle between common and hardware-specific interfaces * @gpiod: gpio descriptor * - * Clock with a gpio control for enabling and disabling the parent clock. - * Implements .enable, .disable and .is_enabled + * Clock with a gpio control for enabling and disabling the parent clock + * or switching between two parents by asserting or deasserting the gpio. + * + * Implements .enable, .disable and .is_enabled or + * .get_parent, .set_parent and .determine_rate depending on which clk_ops + * is used. */ - struct clk_gpio { struct clk_hw hw; struct gpio_desc *gpiod; @@ -738,16 +783,6 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name, unsigned long flags); void clk_hw_unregister_gpio_gate(struct clk_hw *hw); -/** - * struct clk_gpio_mux - gpio controlled clock multiplexer - * - * @hw: see struct clk_gpio - * @gpiod: gpio descriptor to select the parent of this clock multiplexer - * - * Clock with a gpio control for selecting the parent clock. - * Implements .get_parent, .set_parent and .determine_rate - */ - extern const struct clk_ops clk_gpio_mux_ops; struct clk *clk_register_gpio_mux(struct device *dev, const char *name, const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod, @@ -757,22 +792,12 @@ struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name, unsigned long flags); void clk_hw_unregister_gpio_mux(struct clk_hw *hw); -/** - * clk_register - allocate a new clock, register it and return an opaque cookie - * @dev: device that is registering this clock - * @hw: link to hardware-specific clock data - * - * clk_register is the primary interface for populating the clock tree with new - * clock nodes. It returns a pointer to the newly allocated struct clk which - * cannot be dereferenced by driver code but may be used in conjuction with the - * rest of the clock API. In the event of an error clk_register will return an - * error code; drivers must test for an error code after calling clk_register. - */ struct clk *clk_register(struct device *dev, struct clk_hw *hw); struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw); int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw); +int __must_check of_clk_hw_register(struct device_node *node, struct clk_hw *hw); void clk_unregister(struct clk *clk); void devm_clk_unregister(struct device *dev, struct clk *clk); @@ -993,37 +1018,6 @@ static inline int of_clk_detect_critical(struct device_node *np, int index, } #endif /* CONFIG_OF */ -/* - * wrap access to peripherals in accessor routines - * for improved portability across platforms - */ - -#if IS_ENABLED(CONFIG_PPC) - -static inline u32 clk_readl(u32 __iomem *reg) -{ - return ioread32be(reg); -} - -static inline void clk_writel(u32 val, u32 __iomem *reg) -{ - iowrite32be(val, reg); -} - -#else /* platform dependent I/O accessors */ - -static inline u32 clk_readl(u32 __iomem *reg) -{ - return readl(reg); -} - -static inline void clk_writel(u32 val, u32 __iomem *reg) -{ - writel(val, reg); -} - -#endif /* platform dependent I/O accessors */ - void clk_gate_restore_context(struct clk_hw *hw); #endif /* CONFIG_COMMON_CLK */ diff --git a/include/linux/clk/analogbits-wrpll-cln28hpc.h b/include/linux/clk/analogbits-wrpll-cln28hpc.h new file mode 100644 index 000000000000..03279097e138 --- /dev/null +++ b/include/linux/clk/analogbits-wrpll-cln28hpc.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018-2019 SiFive, Inc. + * Wesley Terpstra + * Paul Walmsley + */ + +#ifndef __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H +#define __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H + +#include <linux/types.h> + +/* DIVQ_VALUES: number of valid DIVQ values */ +#define DIVQ_VALUES 6 + +/* + * Bit definitions for struct wrpll_cfg.flags + * + * WRPLL_FLAGS_BYPASS_FLAG: if set, the PLL is either in bypass, or should be + * programmed to enter bypass + * WRPLL_FLAGS_RESET_FLAG: if set, the PLL is in reset + * WRPLL_FLAGS_INT_FEEDBACK_FLAG: if set, the PLL is configured for internal + * feedback mode + * WRPLL_FLAGS_EXT_FEEDBACK_FLAG: if set, the PLL is configured for external + * feedback mode (not yet supported by this driver) + */ +#define WRPLL_FLAGS_BYPASS_SHIFT 0 +#define WRPLL_FLAGS_BYPASS_MASK BIT(WRPLL_FLAGS_BYPASS_SHIFT) +#define WRPLL_FLAGS_RESET_SHIFT 1 +#define WRPLL_FLAGS_RESET_MASK BIT(WRPLL_FLAGS_RESET_SHIFT) +#define WRPLL_FLAGS_INT_FEEDBACK_SHIFT 2 +#define WRPLL_FLAGS_INT_FEEDBACK_MASK BIT(WRPLL_FLAGS_INT_FEEDBACK_SHIFT) +#define WRPLL_FLAGS_EXT_FEEDBACK_SHIFT 3 +#define WRPLL_FLAGS_EXT_FEEDBACK_MASK BIT(WRPLL_FLAGS_EXT_FEEDBACK_SHIFT) + +/** + * struct wrpll_cfg - WRPLL configuration values + * @divr: reference divider value (6 bits), as presented to the PLL signals + * @divf: feedback divider value (9 bits), as presented to the PLL signals + * @divq: output divider value (3 bits), as presented to the PLL signals + * @flags: PLL configuration flags. See above for more information + * @range: PLL loop filter range. See below for more information + * @output_rate_cache: cached output rates, swept across DIVQ + * @parent_rate: PLL refclk rate for which values are valid + * @max_r: maximum possible R divider value, given @parent_rate + * @init_r: initial R divider value to start the search from + * + * @divr, @divq, @divq, @range represent what the PLL expects to see + * on its input signals. Thus @divr and @divf are the actual divisors + * minus one. @divq is a power-of-two divider; for example, 1 = + * divide-by-2 and 6 = divide-by-64. 0 is an invalid @divq value. + * + * When initially passing a struct wrpll_cfg record, the + * record should be zero-initialized with the exception of the @flags + * field. The only flag bits that need to be set are either + * WRPLL_FLAGS_INT_FEEDBACK or WRPLL_FLAGS_EXT_FEEDBACK. + */ +struct wrpll_cfg { + u8 divr; + u8 divq; + u8 range; + u8 flags; + u16 divf; +/* private: */ + u32 output_rate_cache[DIVQ_VALUES]; + unsigned long parent_rate; + u8 max_r; + u8 init_r; +}; + +int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate, + unsigned long parent_rate); + +unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c); + +unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c, + unsigned long parent_rate); + +#endif /* __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H */ diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index 931ab05f771d..0c53f26ae3d3 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h @@ -74,6 +74,8 @@ #define AT91_PMC_USBDIV_4 (2 << 28) #define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ +#define AT91_PMC_CPU_CKR 0x28 /* CPU Clock Register */ + #define AT91_PMC_MCKR 0x30 /* Master Clock Register */ #define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ #define AT91_PMC_CSS_SLOW (0 << 0) @@ -187,16 +189,8 @@ #define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */ #define AT91_PMC_PCR_PID_MASK 0x3f -#define AT91_PMC_PCR_GCKCSS_OFFSET 8 -#define AT91_PMC_PCR_GCKCSS_MASK (0x7 << AT91_PMC_PCR_GCKCSS_OFFSET) -#define AT91_PMC_PCR_GCKCSS(n) ((n) << AT91_PMC_PCR_GCKCSS_OFFSET) /* GCK Clock Source Selection */ #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ -#define AT91_PMC_PCR_DIV_OFFSET 16 -#define AT91_PMC_PCR_DIV_MASK (0x3 << AT91_PMC_PCR_DIV_OFFSET) -#define AT91_PMC_PCR_DIV(n) ((n) << AT91_PMC_PCR_DIV_OFFSET) /* Divisor Value */ -#define AT91_PMC_PCR_GCKDIV_OFFSET 20 -#define AT91_PMC_PCR_GCKDIV_MASK (0xff << AT91_PMC_PCR_GCKDIV_OFFSET) -#define AT91_PMC_PCR_GCKDIV(n) ((n) << AT91_PMC_PCR_GCKDIV_OFFSET) /* Generated Clock Divisor Value */ +#define AT91_PMC_PCR_GCKDIV_MASK GENMASK(27, 20) #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 78872efc7be0..1e8ef96555ce 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -243,6 +243,7 @@ struct ti_clk_ll_ops { #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) +bool omap2_clk_is_hw_omap(struct clk_hw *hw); int omap2_clk_disable_autoidle_all(void); int omap2_clk_enable_autoidle_all(void); int omap2_clk_allow_idle(struct clk *clk); @@ -293,6 +294,7 @@ struct ti_clk_features { #define TI_CLK_DISABLE_CLKDM_CONTROL BIT(2) #define TI_CLK_ERRATA_I810 BIT(3) #define TI_CLK_CLKCTRL_COMPAT BIT(4) +#define TI_CLK_DEVICE_TYPE_GP BIT(5) void ti_clk_setup_features(struct ti_clk_features *features); const struct ti_clk_features *ti_clk_get_features(void); diff --git a/include/linux/device.h b/include/linux/device.h index 4457e560bc2b..e85264fb6616 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1229,7 +1229,7 @@ static inline void device_lock_assert(struct device *dev) static inline struct device_node *dev_of_node(struct device *dev) { - if (!IS_ENABLED(CONFIG_OF)) + if (!IS_ENABLED(CONFIG_OF) || !dev) return NULL; return dev->of_node; } diff --git a/include/linux/math64.h b/include/linux/math64.h index bb2c84afb80c..65bef21cdddb 100644 --- a/include/linux/math64.h +++ b/include/linux/math64.h @@ -284,4 +284,17 @@ static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 divisor) #define DIV64_U64_ROUND_UP(ll, d) \ ({ u64 _tmp = (d); div64_u64((ll) + _tmp - 1, _tmp); }) +/** + * DIV64_U64_ROUND_CLOSEST - unsigned 64bit divide with 64bit divisor rounded to nearest integer + * @dividend: unsigned 64bit dividend + * @divisor: unsigned 64bit divisor + * + * Divide unsigned 64bit dividend by unsigned 64bit divisor + * and round to closest integer. + * + * Return: dividend / divisor rounded to nearest integer + */ +#define DIV64_U64_ROUND_CLOSEST(dividend, divisor) \ + ({ u64 _tmp = (divisor); div64_u64((dividend) + _tmp / 2, _tmp); }) + #endif /* _LINUX_MATH64_H */ |
