266 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef __MACH_MMP_CLK_H3#define __MACH_MMP_CLK_H4 5#include <linux/clk-provider.h>6#include <linux/pm_domain.h>7#include <linux/clkdev.h>8 9#define APBC_NO_BUS_CTRL BIT(0)10#define APBC_POWER_CTRL BIT(1)11 12 13/* Clock type "factor" */14struct mmp_clk_factor_masks {15 unsigned int factor;16 unsigned int num_mask;17 unsigned int den_mask;18 unsigned int num_shift;19 unsigned int den_shift;20 unsigned int enable_mask;21};22 23struct mmp_clk_factor_tbl {24 unsigned int num;25 unsigned int den;26};27 28struct mmp_clk_factor {29 struct clk_hw hw;30 void __iomem *base;31 struct mmp_clk_factor_masks *masks;32 struct mmp_clk_factor_tbl *ftbl;33 unsigned int ftbl_cnt;34 spinlock_t *lock;35};36 37extern struct clk *mmp_clk_register_factor(const char *name,38 const char *parent_name, unsigned long flags,39 void __iomem *base, struct mmp_clk_factor_masks *masks,40 struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,41 spinlock_t *lock);42 43/* Clock type "mix" */44#define MMP_CLK_BITS_MASK(width, shift) \45 (((1 << (width)) - 1) << (shift))46#define MMP_CLK_BITS_GET_VAL(data, width, shift) \47 ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift))48#define MMP_CLK_BITS_SET_VAL(val, width, shift) \49 (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift))50 51enum {52 MMP_CLK_MIX_TYPE_V1,53 MMP_CLK_MIX_TYPE_V2,54 MMP_CLK_MIX_TYPE_V3,55};56 57/* The register layout */58struct mmp_clk_mix_reg_info {59 void __iomem *reg_clk_ctrl;60 void __iomem *reg_clk_sel;61 u8 width_div;62 u8 shift_div;63 u8 width_mux;64 u8 shift_mux;65 u8 bit_fc;66};67 68/* The suggested clock table from user. */69struct mmp_clk_mix_clk_table {70 unsigned long rate;71 u8 parent_index;72 unsigned int divisor;73 unsigned int valid;74};75 76struct mmp_clk_mix_config {77 struct mmp_clk_mix_reg_info reg_info;78 struct mmp_clk_mix_clk_table *table;79 unsigned int table_size;80 u32 *mux_table;81 struct clk_div_table *div_table;82 u8 div_flags;83 u8 mux_flags;84};85 86struct mmp_clk_mix {87 struct clk_hw hw;88 struct mmp_clk_mix_reg_info reg_info;89 struct mmp_clk_mix_clk_table *table;90 u32 *mux_table;91 struct clk_div_table *div_table;92 unsigned int table_size;93 u8 div_flags;94 u8 mux_flags;95 unsigned int type;96 spinlock_t *lock;97};98 99extern const struct clk_ops mmp_clk_mix_ops;100extern struct clk *mmp_clk_register_mix(struct device *dev,101 const char *name,102 const char * const *parent_names,103 u8 num_parents,104 unsigned long flags,105 struct mmp_clk_mix_config *config,106 spinlock_t *lock);107 108 109/* Clock type "gate". MMP private gate */110#define MMP_CLK_GATE_NEED_DELAY BIT(0)111 112struct mmp_clk_gate {113 struct clk_hw hw;114 void __iomem *reg;115 u32 mask;116 u32 val_enable;117 u32 val_disable;118 unsigned int flags;119 spinlock_t *lock;120};121 122extern const struct clk_ops mmp_clk_gate_ops;123extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,124 const char *parent_name, unsigned long flags,125 void __iomem *reg, u32 mask, u32 val_enable,126 u32 val_disable, unsigned int gate_flags,127 spinlock_t *lock);128 129extern struct clk *mmp_clk_register_apbc(const char *name,130 const char *parent_name, void __iomem *base,131 unsigned int delay, unsigned int apbc_flags, spinlock_t *lock);132extern struct clk *mmp_clk_register_apmu(const char *name,133 const char *parent_name, void __iomem *base, u32 enable_mask,134 spinlock_t *lock);135 136struct mmp_clk_unit {137 unsigned int nr_clks;138 struct clk **clk_table;139 struct clk_onecell_data clk_data;140};141 142struct mmp_param_fixed_rate_clk {143 unsigned int id;144 char *name;145 const char *parent_name;146 unsigned long flags;147 unsigned long fixed_rate;148};149void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,150 struct mmp_param_fixed_rate_clk *clks,151 int size);152 153struct mmp_param_fixed_factor_clk {154 unsigned int id;155 char *name;156 const char *parent_name;157 unsigned long mult;158 unsigned long div;159 unsigned long flags;160};161void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,162 struct mmp_param_fixed_factor_clk *clks,163 int size);164 165struct mmp_param_general_gate_clk {166 unsigned int id;167 const char *name;168 const char *parent_name;169 unsigned long flags;170 unsigned long offset;171 u8 bit_idx;172 u8 gate_flags;173 spinlock_t *lock;174};175void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,176 struct mmp_param_general_gate_clk *clks,177 void __iomem *base, int size);178 179struct mmp_param_gate_clk {180 unsigned int id;181 char *name;182 const char *parent_name;183 unsigned long flags;184 unsigned long offset;185 u32 mask;186 u32 val_enable;187 u32 val_disable;188 unsigned int gate_flags;189 spinlock_t *lock;190};191void mmp_register_gate_clks(struct mmp_clk_unit *unit,192 struct mmp_param_gate_clk *clks,193 void __iomem *base, int size);194 195struct mmp_param_mux_clk {196 unsigned int id;197 char *name;198 const char * const *parent_name;199 u8 num_parents;200 unsigned long flags;201 unsigned long offset;202 u8 shift;203 u8 width;204 u8 mux_flags;205 spinlock_t *lock;206};207void mmp_register_mux_clks(struct mmp_clk_unit *unit,208 struct mmp_param_mux_clk *clks,209 void __iomem *base, int size);210 211struct mmp_param_div_clk {212 unsigned int id;213 char *name;214 const char *parent_name;215 unsigned long flags;216 unsigned long offset;217 u8 shift;218 u8 width;219 u8 div_flags;220 spinlock_t *lock;221};222void mmp_register_div_clks(struct mmp_clk_unit *unit,223 struct mmp_param_div_clk *clks,224 void __iomem *base, int size);225 226struct mmp_param_pll_clk {227 unsigned int id;228 char *name;229 unsigned long default_rate;230 unsigned long enable_offset;231 u32 enable;232 unsigned long offset;233 u8 shift;234 /* MMP3 specific: */235 unsigned long input_rate;236 unsigned long postdiv_offset;237 unsigned long postdiv_shift;238};239void mmp_register_pll_clks(struct mmp_clk_unit *unit,240 struct mmp_param_pll_clk *clks,241 void __iomem *base, int size);242 243#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \244{ \245 .width_div = (w_d), \246 .shift_div = (s_d), \247 .width_mux = (w_m), \248 .shift_mux = (s_m), \249 .bit_fc = (fc), \250}251 252void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,253 int nr_clks);254void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,255 struct clk *clk);256 257/* Power islands */258#define MMP_PM_DOMAIN_NO_DISABLE BIT(0)259 260struct generic_pm_domain *mmp_pm_domain_register(const char *name,261 void __iomem *reg,262 u32 power_on, u32 reset, u32 clock_enable,263 unsigned int flags, spinlock_t *lock);264 265#endif266