^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2018 BayLibre, SAS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Jerome Brunet <jbrunet@baylibre.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #ifndef __CLK_REGMAP_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define __CLK_REGMAP_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * struct clk_regmap - regmap backed clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * @hw: handle between common and hardware-specific interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * @map: pointer to the regmap structure controlling the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @data: data specific to the clock type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Clock which is controlled by regmap backed registers. The actual type of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * of the clock is controlled by the clock_ops and data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct clk_regmap {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct regmap *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return container_of(hw, struct clk_regmap, hw);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * struct clk_regmap_gate_data - regmap backed gate specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @offset: offset of the register controlling gate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @bit_idx: single bit controlling gate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @flags: hardware-specific flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Flags:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct clk_regmap_gate_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u8 bit_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static inline struct clk_regmap_gate_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) clk_get_regmap_gate_data(struct clk_regmap *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return (struct clk_regmap_gate_data *)clk->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) extern const struct clk_ops clk_regmap_gate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) extern const struct clk_ops clk_regmap_gate_ro_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * struct clk_regmap_div_data - regmap backed adjustable divider specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @offset: offset of the register controlling the divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @shift: shift to the divider bit field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @width: width of the divider bit field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * @table: array of value/divider pairs, last entry should have div = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Flags:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct clk_regmap_div_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) const struct clk_div_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static inline struct clk_regmap_div_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) clk_get_regmap_div_data(struct clk_regmap *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return (struct clk_regmap_div_data *)clk->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) extern const struct clk_ops clk_regmap_divider_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) extern const struct clk_ops clk_regmap_divider_ro_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @hw: handle between common and hardware-specific interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @offset: offset of theregister controlling multiplexer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @table: array of parent indexed register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @shift: shift to multiplexer bit field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @mask: mask of mutliplexer bit field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @flags: hardware-specific flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Flags:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct clk_regmap_mux_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u32 *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static inline struct clk_regmap_mux_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) clk_get_regmap_mux_data(struct clk_regmap *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return (struct clk_regmap_mux_data *)clk->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) extern const struct clk_ops clk_regmap_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) extern const struct clk_ops clk_regmap_mux_ro_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define __MESON_PCLK(_name, _reg, _bit, _ops, _pname) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct clk_regmap _name = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .data = &(struct clk_regmap_gate_data){ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .offset = (_reg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .bit_idx = (_bit), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .hw.init = &(struct clk_init_data) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .name = #_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .ops = _ops, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .parent_hws = (const struct clk_hw *[]) { _pname }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .num_parents = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define MESON_PCLK(_name, _reg, _bit, _pname) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define MESON_PCLK_RO(_name, _reg, _bit, _pname) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #endif /* __CLK_REGMAP_H */