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