1 /* 2 * Hisilicon Hi3620 clock gate driver 3 * 4 * Copyright (c) 2012-2013 Hisilicon Limited. 5 * Copyright (c) 2012-2013 Linaro Limited. 6 * 7 * Author: Haojian Zhuang <haojian.zhuang@linaro.org> 8 * Xin Li <li.xin@linaro.org> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with this program; if not, write to the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 * 24 */ 25 26 #ifndef __HISI_CLK_H 27 #define __HISI_CLK_H 28 29 #include <linux/clk-provider.h> 30 #include <linux/io.h> 31 #include <linux/spinlock.h> 32 33 struct platform_device; 34 35 struct hisi_clock_data { 36 struct clk_onecell_data clk_data; 37 void __iomem *base; 38 }; 39 40 struct hisi_fixed_rate_clock { 41 unsigned int id; 42 char *name; 43 const char *parent_name; 44 unsigned long flags; 45 unsigned long fixed_rate; 46 }; 47 48 struct hisi_fixed_factor_clock { 49 unsigned int id; 50 char *name; 51 const char *parent_name; 52 unsigned long mult; 53 unsigned long div; 54 unsigned long flags; 55 }; 56 57 struct hisi_mux_clock { 58 unsigned int id; 59 const char *name; 60 const char *const *parent_names; 61 u8 num_parents; 62 unsigned long flags; 63 unsigned long offset; 64 u8 shift; 65 u8 width; 66 u8 mux_flags; 67 u32 *table; 68 const char *alias; 69 }; 70 71 struct hisi_phase_clock { 72 unsigned int id; 73 const char *name; 74 const char *parent_names; 75 unsigned long flags; 76 unsigned long offset; 77 u8 shift; 78 u8 width; 79 u32 *phase_degrees; 80 u32 *phase_regvals; 81 u8 phase_num; 82 }; 83 84 struct hisi_divider_clock { 85 unsigned int id; 86 const char *name; 87 const char *parent_name; 88 unsigned long flags; 89 unsigned long offset; 90 u8 shift; 91 u8 width; 92 u8 div_flags; 93 struct clk_div_table *table; 94 const char *alias; 95 }; 96 97 struct hi6220_divider_clock { 98 unsigned int id; 99 const char *name; 100 const char *parent_name; 101 unsigned long flags; 102 unsigned long offset; 103 u8 shift; 104 u8 width; 105 u32 mask_bit; 106 const char *alias; 107 }; 108 109 struct hisi_gate_clock { 110 unsigned int id; 111 const char *name; 112 const char *parent_name; 113 unsigned long flags; 114 unsigned long offset; 115 u8 bit_idx; 116 u8 gate_flags; 117 const char *alias; 118 }; 119 120 struct clk *hisi_register_clkgate_sep(struct device *, const char *, 121 const char *, unsigned long, 122 void __iomem *, u8, 123 u8, spinlock_t *); 124 struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, 125 const char *parent_name, unsigned long flags, void __iomem *reg, 126 u8 shift, u8 width, u32 mask_bit, spinlock_t *lock); 127 128 struct hisi_clock_data *hisi_clk_alloc(struct platform_device *, int); 129 struct hisi_clock_data *hisi_clk_init(struct device_node *, int); 130 int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *, 131 int, struct hisi_clock_data *); 132 int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *, 133 int, struct hisi_clock_data *); 134 int hisi_clk_register_mux(const struct hisi_mux_clock *, int, 135 struct hisi_clock_data *); 136 struct clk *clk_register_hisi_phase(struct device *dev, 137 const struct hisi_phase_clock *clks, 138 void __iomem *base, spinlock_t *lock); 139 int hisi_clk_register_phase(struct device *dev, 140 const struct hisi_phase_clock *clks, 141 int nums, struct hisi_clock_data *data); 142 int hisi_clk_register_divider(const struct hisi_divider_clock *, 143 int, struct hisi_clock_data *); 144 int hisi_clk_register_gate(const struct hisi_gate_clock *, 145 int, struct hisi_clock_data *); 146 void hisi_clk_register_gate_sep(const struct hisi_gate_clock *, 147 int, struct hisi_clock_data *); 148 void hi6220_clk_register_divider(const struct hi6220_divider_clock *, 149 int, struct hisi_clock_data *); 150 151 #define hisi_clk_unregister(type) \ 152 static inline \ 153 void hisi_clk_unregister_##type(const struct hisi_##type##_clock *clks, \ 154 int nums, struct hisi_clock_data *data) \ 155 { \ 156 struct clk **clocks = data->clk_data.clks; \ 157 int i; \ 158 for (i = 0; i < nums; i++) { \ 159 int id = clks[i].id; \ 160 if (clocks[id]) \ 161 clk_unregister_##type(clocks[id]); \ 162 } \ 163 } 164 165 hisi_clk_unregister(fixed_rate) 166 hisi_clk_unregister(fixed_factor) 167 hisi_clk_unregister(mux) 168 hisi_clk_unregister(divider) 169 hisi_clk_unregister(gate) 170 171 #endif /* __HISI_CLK_H */ 172