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_divider_clock { 72 unsigned int id; 73 const char *name; 74 const char *parent_name; 75 unsigned long flags; 76 unsigned long offset; 77 u8 shift; 78 u8 width; 79 u8 div_flags; 80 struct clk_div_table *table; 81 const char *alias; 82 }; 83 84 struct hi6220_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 u32 mask_bit; 93 const char *alias; 94 }; 95 96 struct hisi_gate_clock { 97 unsigned int id; 98 const char *name; 99 const char *parent_name; 100 unsigned long flags; 101 unsigned long offset; 102 u8 bit_idx; 103 u8 gate_flags; 104 const char *alias; 105 }; 106 107 struct clk *hisi_register_clkgate_sep(struct device *, const char *, 108 const char *, unsigned long, 109 void __iomem *, u8, 110 u8, spinlock_t *); 111 struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, 112 const char *parent_name, unsigned long flags, void __iomem *reg, 113 u8 shift, u8 width, u32 mask_bit, spinlock_t *lock); 114 115 struct hisi_clock_data *hisi_clk_alloc(struct platform_device *, int); 116 struct hisi_clock_data *hisi_clk_init(struct device_node *, int); 117 int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *, 118 int, struct hisi_clock_data *); 119 int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *, 120 int, struct hisi_clock_data *); 121 int hisi_clk_register_mux(const struct hisi_mux_clock *, int, 122 struct hisi_clock_data *); 123 int hisi_clk_register_divider(const struct hisi_divider_clock *, 124 int, struct hisi_clock_data *); 125 int hisi_clk_register_gate(const struct hisi_gate_clock *, 126 int, struct hisi_clock_data *); 127 void hisi_clk_register_gate_sep(const struct hisi_gate_clock *, 128 int, struct hisi_clock_data *); 129 void hi6220_clk_register_divider(const struct hi6220_divider_clock *, 130 int, struct hisi_clock_data *); 131 132 #define hisi_clk_unregister(type) \ 133 static inline \ 134 void hisi_clk_unregister_##type(const struct hisi_##type##_clock *clks, \ 135 int nums, struct hisi_clock_data *data) \ 136 { \ 137 struct clk **clocks = data->clk_data.clks; \ 138 int i; \ 139 for (i = 0; i < nums; i++) { \ 140 int id = clks[i].id; \ 141 if (clocks[id]) \ 142 clk_unregister_##type(clocks[id]); \ 143 } \ 144 } 145 146 hisi_clk_unregister(fixed_rate) 147 hisi_clk_unregister(fixed_factor) 148 hisi_clk_unregister(mux) 149 hisi_clk_unregister(divider) 150 hisi_clk_unregister(gate) 151 152 #endif /* __HISI_CLK_H */ 153