1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Hisilicon Hi3620 clock gate driver 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (c) 2012-2013 Hisilicon Limited. 6*4882a593Smuzhiyun * Copyright (c) 2012-2013 Linaro Limited. 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Author: Haojian Zhuang <haojian.zhuang@linaro.org> 9*4882a593Smuzhiyun * Xin Li <li.xin@linaro.org> 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #ifndef __HISI_CLK_H 13*4882a593Smuzhiyun #define __HISI_CLK_H 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #include <linux/clk-provider.h> 16*4882a593Smuzhiyun #include <linux/io.h> 17*4882a593Smuzhiyun #include <linux/spinlock.h> 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun struct platform_device; 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun struct hisi_clock_data { 22*4882a593Smuzhiyun struct clk_onecell_data clk_data; 23*4882a593Smuzhiyun void __iomem *base; 24*4882a593Smuzhiyun }; 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun struct hisi_fixed_rate_clock { 27*4882a593Smuzhiyun unsigned int id; 28*4882a593Smuzhiyun char *name; 29*4882a593Smuzhiyun const char *parent_name; 30*4882a593Smuzhiyun unsigned long flags; 31*4882a593Smuzhiyun unsigned long fixed_rate; 32*4882a593Smuzhiyun }; 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun struct hisi_fixed_factor_clock { 35*4882a593Smuzhiyun unsigned int id; 36*4882a593Smuzhiyun char *name; 37*4882a593Smuzhiyun const char *parent_name; 38*4882a593Smuzhiyun unsigned long mult; 39*4882a593Smuzhiyun unsigned long div; 40*4882a593Smuzhiyun unsigned long flags; 41*4882a593Smuzhiyun }; 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun struct hisi_mux_clock { 44*4882a593Smuzhiyun unsigned int id; 45*4882a593Smuzhiyun const char *name; 46*4882a593Smuzhiyun const char *const *parent_names; 47*4882a593Smuzhiyun u8 num_parents; 48*4882a593Smuzhiyun unsigned long flags; 49*4882a593Smuzhiyun unsigned long offset; 50*4882a593Smuzhiyun u8 shift; 51*4882a593Smuzhiyun u8 width; 52*4882a593Smuzhiyun u8 mux_flags; 53*4882a593Smuzhiyun u32 *table; 54*4882a593Smuzhiyun const char *alias; 55*4882a593Smuzhiyun }; 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun struct hisi_phase_clock { 58*4882a593Smuzhiyun unsigned int id; 59*4882a593Smuzhiyun const char *name; 60*4882a593Smuzhiyun const char *parent_names; 61*4882a593Smuzhiyun unsigned long flags; 62*4882a593Smuzhiyun unsigned long offset; 63*4882a593Smuzhiyun u8 shift; 64*4882a593Smuzhiyun u8 width; 65*4882a593Smuzhiyun u32 *phase_degrees; 66*4882a593Smuzhiyun u32 *phase_regvals; 67*4882a593Smuzhiyun u8 phase_num; 68*4882a593Smuzhiyun }; 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun struct hisi_divider_clock { 71*4882a593Smuzhiyun unsigned int id; 72*4882a593Smuzhiyun const char *name; 73*4882a593Smuzhiyun const char *parent_name; 74*4882a593Smuzhiyun unsigned long flags; 75*4882a593Smuzhiyun unsigned long offset; 76*4882a593Smuzhiyun u8 shift; 77*4882a593Smuzhiyun u8 width; 78*4882a593Smuzhiyun u8 div_flags; 79*4882a593Smuzhiyun struct clk_div_table *table; 80*4882a593Smuzhiyun const char *alias; 81*4882a593Smuzhiyun }; 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun struct hi6220_divider_clock { 84*4882a593Smuzhiyun unsigned int id; 85*4882a593Smuzhiyun const char *name; 86*4882a593Smuzhiyun const char *parent_name; 87*4882a593Smuzhiyun unsigned long flags; 88*4882a593Smuzhiyun unsigned long offset; 89*4882a593Smuzhiyun u8 shift; 90*4882a593Smuzhiyun u8 width; 91*4882a593Smuzhiyun u32 mask_bit; 92*4882a593Smuzhiyun const char *alias; 93*4882a593Smuzhiyun }; 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun struct hisi_gate_clock { 96*4882a593Smuzhiyun unsigned int id; 97*4882a593Smuzhiyun const char *name; 98*4882a593Smuzhiyun const char *parent_name; 99*4882a593Smuzhiyun unsigned long flags; 100*4882a593Smuzhiyun unsigned long offset; 101*4882a593Smuzhiyun u8 bit_idx; 102*4882a593Smuzhiyun u8 gate_flags; 103*4882a593Smuzhiyun const char *alias; 104*4882a593Smuzhiyun }; 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun struct clk *hisi_register_clkgate_sep(struct device *, const char *, 107*4882a593Smuzhiyun const char *, unsigned long, 108*4882a593Smuzhiyun void __iomem *, u8, 109*4882a593Smuzhiyun u8, spinlock_t *); 110*4882a593Smuzhiyun struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, 111*4882a593Smuzhiyun const char *parent_name, unsigned long flags, void __iomem *reg, 112*4882a593Smuzhiyun u8 shift, u8 width, u32 mask_bit, spinlock_t *lock); 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun struct hisi_clock_data *hisi_clk_alloc(struct platform_device *, int); 115*4882a593Smuzhiyun struct hisi_clock_data *hisi_clk_init(struct device_node *, int); 116*4882a593Smuzhiyun int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *, 117*4882a593Smuzhiyun int, struct hisi_clock_data *); 118*4882a593Smuzhiyun int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *, 119*4882a593Smuzhiyun int, struct hisi_clock_data *); 120*4882a593Smuzhiyun int hisi_clk_register_mux(const struct hisi_mux_clock *, int, 121*4882a593Smuzhiyun struct hisi_clock_data *); 122*4882a593Smuzhiyun struct clk *clk_register_hisi_phase(struct device *dev, 123*4882a593Smuzhiyun const struct hisi_phase_clock *clks, 124*4882a593Smuzhiyun void __iomem *base, spinlock_t *lock); 125*4882a593Smuzhiyun int hisi_clk_register_phase(struct device *dev, 126*4882a593Smuzhiyun const struct hisi_phase_clock *clks, 127*4882a593Smuzhiyun int nums, struct hisi_clock_data *data); 128*4882a593Smuzhiyun int hisi_clk_register_divider(const struct hisi_divider_clock *, 129*4882a593Smuzhiyun int, struct hisi_clock_data *); 130*4882a593Smuzhiyun int hisi_clk_register_gate(const struct hisi_gate_clock *, 131*4882a593Smuzhiyun int, struct hisi_clock_data *); 132*4882a593Smuzhiyun void hisi_clk_register_gate_sep(const struct hisi_gate_clock *, 133*4882a593Smuzhiyun int, struct hisi_clock_data *); 134*4882a593Smuzhiyun void hi6220_clk_register_divider(const struct hi6220_divider_clock *, 135*4882a593Smuzhiyun int, struct hisi_clock_data *); 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun #define hisi_clk_unregister(type) \ 138*4882a593Smuzhiyun static inline \ 139*4882a593Smuzhiyun void hisi_clk_unregister_##type(const struct hisi_##type##_clock *clks, \ 140*4882a593Smuzhiyun int nums, struct hisi_clock_data *data) \ 141*4882a593Smuzhiyun { \ 142*4882a593Smuzhiyun struct clk **clocks = data->clk_data.clks; \ 143*4882a593Smuzhiyun int i; \ 144*4882a593Smuzhiyun for (i = 0; i < nums; i++) { \ 145*4882a593Smuzhiyun int id = clks[i].id; \ 146*4882a593Smuzhiyun if (clocks[id]) \ 147*4882a593Smuzhiyun clk_unregister_##type(clocks[id]); \ 148*4882a593Smuzhiyun } \ 149*4882a593Smuzhiyun } 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun hisi_clk_unregister(fixed_rate) 152*4882a593Smuzhiyun hisi_clk_unregister(fixed_factor) 153*4882a593Smuzhiyun hisi_clk_unregister(mux) 154*4882a593Smuzhiyun hisi_clk_unregister(divider) 155*4882a593Smuzhiyun hisi_clk_unregister(gate) 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun #endif /* __HISI_CLK_H */ 158