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