Commit ee81f4ee authored by Chao Xie's avatar Chao Xie Committed by Michael Turquette

clk: mmp: add clock type mix

The clock type mix is a kind of clock combines "div" and "mux".
This kind of clock can not allow to change div first then
mux or change mux first or div.
The reason is
1. Some clock has frequency change bit. Each time want to change
   the frequency, there are some operations based on this bit, and
   these operations are time-cost.
   Seperating div and mux change will make the process longer, and
   waste more time.
2. Seperting the div and mux may generate middle clock that the
   peripharals do not support. It may make the peripharals hang.

There are three kinds of this type of clock in all SOCes.
1. The clock has bit to trigger the frequency change.
2. Same as #1, but the operations for the bit is different
3. Do not have frequency change bit.

So this type of clock has implemented the callbacks
These callbacks can help to change the div and mux together.
Signed-off-by: default avatarChao Xie <>
Acked-by: default avatarHaojian Zhuang <>
Signed-off-by: default avatarMichael Turquette <>
parent 3a2b2f84
......@@ -2,7 +2,7 @@
# Makefile for mmp specific clk
obj-y += clk-apbc.o clk-apmu.o clk-frac.o
obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
This diff is collapsed.
......@@ -37,6 +37,72 @@ extern struct clk *mmp_clk_register_factor(const char *name,
struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
spinlock_t *lock);
/* Clock type "mix" */
#define MMP_CLK_BITS_MASK(width, shift) \
(((1 << (width)) - 1) << (shift))
#define MMP_CLK_BITS_GET_VAL(data, width, shift) \
((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift))
#define MMP_CLK_BITS_SET_VAL(val, width, shift) \
(((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift))
enum {
/* The register layout */
struct mmp_clk_mix_reg_info {
void __iomem *reg_clk_ctrl;
void __iomem *reg_clk_sel;
u8 width_div;
u8 shift_div;
u8 width_mux;
u8 shift_mux;
u8 bit_fc;
/* The suggested clock table from user. */
struct mmp_clk_mix_clk_table {
unsigned long rate;
u8 parent_index;
unsigned int divisor;
unsigned int valid;
struct mmp_clk_mix_config {
struct mmp_clk_mix_reg_info reg_info;
struct mmp_clk_mix_clk_table *table;
unsigned int table_size;
u32 *mux_table;
struct clk_div_table *div_table;
u8 div_flags;
u8 mux_flags;
struct mmp_clk_mix {
struct clk_hw hw;
struct mmp_clk_mix_reg_info reg_info;
struct mmp_clk_mix_clk_table *table;
u32 *mux_table;
struct clk_div_table *div_table;
unsigned int table_size;
u8 div_flags;
u8 mux_flags;
unsigned int type;
spinlock_t *lock;
extern const struct clk_ops mmp_clk_mix_ops;
extern struct clk *mmp_clk_register_mix(struct device *dev,
const char *name,
u8 num_parents,
const char **parent_names,
unsigned long flags,
struct mmp_clk_mix_config *config,
spinlock_t *lock);
extern struct clk *mmp_clk_register_pll2(const char *name,
const char *parent_name, unsigned long flags);
extern struct clk *mmp_clk_register_apbc(const char *name,
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment