^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2013 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013 Linaro Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Thomas Abraham <thomas.ab@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Common Clock Framework support for all Samsung platforms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #ifndef __SAMSUNG_CLK_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define __SAMSUNG_CLK_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "clk-pll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * struct samsung_clk_provider: information about clock provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @reg_base: virtual address for the register base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @lock: maintains exclusion between callbacks for a given clock-provider.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @clk_data: holds clock related data like clk_hw* and number of clocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct samsung_clk_provider {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* clk_data must be the last entry due to variable length 'hws' array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct clk_hw_onecell_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * struct samsung_clock_alias: information about mux clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @id: platform specific id of the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @dev_name: name of the device to which this clock belongs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @alias: optional clock alias name to be assigned to this clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct samsung_clock_alias {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) const char *dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) const char *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ALIAS(_id, dname, a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .dev_name = dname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .alias = a, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MHZ (1000 * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * struct samsung_fixed_rate_clock: information about fixed-rate clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @id: platform specific id of the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @name: name of this fixed-rate clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @parent_name: optional parent clock name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @flags: optional fixed-rate clock flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @fixed-rate: fixed clock rate of this clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct samsung_fixed_rate_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned long fixed_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define FRATE(_id, cname, pname, f, frate) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .name = cname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .parent_name = pname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .flags = f, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .fixed_rate = frate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * struct samsung_fixed_factor_clock: information about fixed-factor clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @id: platform specific id of the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * @name: name of this fixed-factor clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @parent_name: parent clock name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @mult: fixed multiplication factor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * @div: fixed division factor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @flags: optional fixed-factor clock flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct samsung_fixed_factor_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define FFACTOR(_id, cname, pname, m, d, f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .name = cname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .parent_name = pname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .mult = m, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .div = d, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .flags = f, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * struct samsung_mux_clock: information about mux clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @id: platform specific id of the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @name: name of this mux clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @parent_names: array of pointer to parent clock names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @num_parents: number of parents listed in @parent_names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @flags: optional flags for basic clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @offset: offset of the register for configuring the mux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @shift: starting bit location of the mux control bit-field in @reg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @width: width of the mux control bit-field in @reg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @mux_flags: flags for mux-type clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct samsung_mux_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) const char *const *parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u8 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u8 mux_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define __MUX(_id, cname, pnames, o, s, w, f, mf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .name = cname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .parent_names = pnames, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .num_parents = ARRAY_SIZE(pnames), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .flags = (f) | CLK_SET_RATE_NO_REPARENT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .offset = o, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .shift = s, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .width = w, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .mux_flags = mf, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define MUX(_id, cname, pnames, o, s, w) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) __MUX(_id, cname, pnames, o, s, w, 0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) __MUX(_id, cname, pnames, o, s, w, f, mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * @id: platform specific id of the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * struct samsung_div_clock: information about div clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @name: name of this div clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * @parent_name: name of the parent clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @flags: optional flags for basic clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @offset: offset of the register for configuring the div.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @shift: starting bit location of the div control bit-field in @reg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @div_flags: flags for div-type clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct samsung_div_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) u8 div_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct clk_div_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define __DIV(_id, cname, pname, o, s, w, f, df, t) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .name = cname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .parent_name = pname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .flags = f, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .offset = o, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .shift = s, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .width = w, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .div_flags = df, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .table = t, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define DIV(_id, cname, pname, o, s, w) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) __DIV(_id, cname, pname, o, s, w, 0, 0, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define DIV_F(_id, cname, pname, o, s, w, f, df) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) __DIV(_id, cname, pname, o, s, w, f, df, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define DIV_T(_id, cname, pname, o, s, w, t) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) __DIV(_id, cname, pname, o, s, w, 0, 0, t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * struct samsung_gate_clock: information about gate clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * @id: platform specific id of the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * @name: name of this gate clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @parent_name: name of the parent clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @flags: optional flags for basic clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @offset: offset of the register for configuring the gate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @bit_idx: bit index of the gate control bit-field in @reg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @gate_flags: flags for gate-type clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct samsung_gate_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u8 bit_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u8 gate_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define __GATE(_id, cname, pname, o, b, f, gf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .name = cname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .parent_name = pname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .flags = f, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .offset = o, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .bit_idx = b, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .gate_flags = gf, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define GATE(_id, cname, pname, o, b, f, gf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) __GATE(_id, cname, pname, o, b, f, gf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define PNAME(x) static const char * const x[] __initconst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * struct samsung_clk_reg_dump: register dump of clock controller registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @offset: clock register offset from the controller base address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @value: the value to be register at offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct samsung_clk_reg_dump {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * struct samsung_pll_clock: information about pll clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @id: platform specific id of the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * @name: name of this pll clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @parent_name: name of the parent clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @flags: optional flags for basic clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @con_offset: offset of the register for configuring the PLL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @lock_offset: offset of the register for locking the PLL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * @type: Type of PLL to be registered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct samsung_pll_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int con_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int lock_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) enum samsung_pll_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) const struct samsung_pll_rate_table *rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .type = _typ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .parent_name = _pname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .flags = _flags, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .con_offset = _con, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .lock_offset = _lock, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .rate_table = _rtable, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) _con, _rtable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct samsung_clock_reg_cache {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct samsung_clk_reg_dump *rdump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned int rd_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) const struct samsung_clk_reg_dump *rsuspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned int rsuspend_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct samsung_cmu_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* list of pll clocks and respective count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) const struct samsung_pll_clock *pll_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unsigned int nr_pll_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* list of mux clocks and respective count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) const struct samsung_mux_clock *mux_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) unsigned int nr_mux_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* list of div clocks and respective count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) const struct samsung_div_clock *div_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int nr_div_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* list of gate clocks and respective count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) const struct samsung_gate_clock *gate_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) unsigned int nr_gate_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* list of fixed clocks and respective count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) const struct samsung_fixed_rate_clock *fixed_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned int nr_fixed_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* list of fixed factor clocks and respective count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) const struct samsung_fixed_factor_clock *fixed_factor_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) unsigned int nr_fixed_factor_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* total number of clocks with IDs assigned*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned int nr_clk_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* list and number of clocks registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) const unsigned long *clk_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned int nr_clk_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* list and number of clocks registers to set before suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) const struct samsung_clk_reg_dump *suspend_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) unsigned int nr_suspend_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* name of the parent clock needed for CMU register access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) const char *clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) extern struct samsung_clk_provider *__init samsung_clk_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct device_node *np, void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned long nr_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) extern void __init samsung_clk_of_add_provider(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct samsung_clk_provider *ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) extern void __init samsung_clk_of_register_fixed_ext(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct samsung_fixed_rate_clock *fixed_rate_clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned int nr_fixed_rate_clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) const struct of_device_id *clk_matches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct clk_hw *clk_hw, unsigned int id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) const struct samsung_clock_alias *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) unsigned int nr_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) extern void __init samsung_clk_register_fixed_rate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) const struct samsung_fixed_rate_clock *clk_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) unsigned int nr_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) extern void __init samsung_clk_register_fixed_factor(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) const struct samsung_fixed_factor_clock *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) unsigned int nr_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) const struct samsung_mux_clock *clk_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unsigned int nr_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) const struct samsung_div_clock *clk_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned int nr_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) const struct samsung_gate_clock *clk_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) unsigned int nr_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) const struct samsung_pll_clock *pll_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) unsigned int nr_clk, void __iomem *base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) extern struct samsung_clk_provider __init *samsung_cmu_register_one(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct device_node *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) const struct samsung_cmu_info *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) extern unsigned long _get_rate(const char *clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) extern void samsung_clk_extended_sleep_init(void __iomem *reg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) const unsigned long *rdump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) unsigned long nr_rdump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) const struct samsung_clk_reg_dump *rsuspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) unsigned long nr_rsuspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) const unsigned long *rdump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) unsigned long nr_rdump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) const struct samsung_clk_reg_dump *rsuspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned long nr_rsuspend) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) extern void samsung_clk_save(void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct samsung_clk_reg_dump *rd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) unsigned int num_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) extern void samsung_clk_restore(void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) const struct samsung_clk_reg_dump *rd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) unsigned int num_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) const unsigned long *rdump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) unsigned long nr_rdump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #endif /* __SAMSUNG_CLK_H */