clk: Add a basic multiplier clock

Some clocks are using a multiplier component, however, unlike their mux,
gate or divider counterpart, these factors don't have a basic clock
implementation.

This leads to code duplication across platforms that want to use that kind
of clocks, and the impossibility to use the composite clocks with such a
clock without defining your own rate operations.

Create such a driver in order to remove these issues, and hopefully factor
the implementations, reducing code size across platforms and consolidating
the various implementations.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
This commit is contained in:
Maxime Ripard 2015-05-19 22:19:33 +02:00
parent 7d6ddad659
commit f2e0a53271
3 changed files with 224 additions and 0 deletions

View file

@ -518,6 +518,48 @@ struct clk *clk_register_fractional_divider(struct device *dev,
void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
u8 clk_divider_flags, spinlock_t *lock);
/**
* struct clk_multiplier - adjustable multiplier clock
*
* @hw: handle between common and hardware-specific interfaces
* @reg: register containing the multiplier
* @shift: shift to the multiplier bit field
* @width: width of the multiplier bit field
* @lock: register lock
*
* Clock with an adjustable multiplier affecting its output frequency.
* Implements .recalc_rate, .set_rate and .round_rate
*
* Flags:
* CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read
* from the register, with 0 being a valid value effectively
* zeroing the output clock rate. If CLK_MULTIPLIER_ZERO_BYPASS is
* set, then a null multiplier will be considered as a bypass,
* 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.
*/
struct clk_multiplier {
struct clk_hw hw;
void __iomem *reg;
u8 shift;
u8 width;
u8 flags;
spinlock_t *lock;
};
#define CLK_MULTIPLIER_ZERO_BYPASS BIT(0)
#define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1)
extern const struct clk_ops clk_multiplier_ops;
struct clk *clk_register_multiplier(struct device *dev, const char *name,
const char *parent_name,
unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mult_flags, spinlock_t *lock);
void clk_unregister_multiplier(struct clk *clk);
/***
* struct clk_composite - aggregate clock of mux, divider and gate clocks
*