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