138 lines · c
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_H8#define __CLK_REGMAP_H9 10#include <linux/clk-provider.h>11#include <linux/regmap.h>12 13/**14 * struct clk_regmap - regmap backed clock15 *16 * @hw: handle between common and hardware-specific interfaces17 * @map: pointer to the regmap structure controlling the clock18 * @data: data specific to the clock type19 *20 * Clock which is controlled by regmap backed registers. The actual type of21 * of the clock is controlled by the clock_ops and data.22 */23struct clk_regmap {24 struct clk_hw hw;25 struct regmap *map;26 void *data;27};28 29static inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw)30{31 return container_of(hw, struct clk_regmap, hw);32}33 34/**35 * struct clk_regmap_gate_data - regmap backed gate specific data36 *37 * @offset: offset of the register controlling gate38 * @bit_idx: single bit controlling gate39 * @flags: hardware-specific flags40 *41 * Flags:42 * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored43 */44struct clk_regmap_gate_data {45 unsigned int offset;46 u8 bit_idx;47 u8 flags;48};49 50static inline struct clk_regmap_gate_data *51clk_get_regmap_gate_data(struct clk_regmap *clk)52{53 return (struct clk_regmap_gate_data *)clk->data;54}55 56extern const struct clk_ops clk_regmap_gate_ops;57extern const struct clk_ops clk_regmap_gate_ro_ops;58 59/**60 * struct clk_regmap_div_data - regmap backed adjustable divider specific data61 *62 * @offset: offset of the register controlling the divider63 * @shift: shift to the divider bit field64 * @width: width of the divider bit field65 * @table: array of value/divider pairs, last entry should have div = 066 *67 * Flags:68 * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored69 */70struct clk_regmap_div_data {71 unsigned int offset;72 u8 shift;73 u8 width;74 u8 flags;75 const struct clk_div_table *table;76};77 78static inline struct clk_regmap_div_data *79clk_get_regmap_div_data(struct clk_regmap *clk)80{81 return (struct clk_regmap_div_data *)clk->data;82}83 84extern const struct clk_ops clk_regmap_divider_ops;85extern const struct clk_ops clk_regmap_divider_ro_ops;86 87/**88 * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data89 *90 * @hw: handle between common and hardware-specific interfaces91 * @offset: offset of theregister controlling multiplexer92 * @table: array of parent indexed register values93 * @shift: shift to multiplexer bit field94 * @mask: mask of mutliplexer bit field95 * @flags: hardware-specific flags96 *97 * Flags:98 * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored99 */100struct clk_regmap_mux_data {101 unsigned int offset;102 u32 *table;103 u32 mask;104 u8 shift;105 u8 flags;106};107 108static inline struct clk_regmap_mux_data *109clk_get_regmap_mux_data(struct clk_regmap *clk)110{111 return (struct clk_regmap_mux_data *)clk->data;112}113 114extern const struct clk_ops clk_regmap_mux_ops;115extern const struct clk_ops clk_regmap_mux_ro_ops;116 117#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname) \118struct clk_regmap _name = { \119 .data = &(struct clk_regmap_gate_data){ \120 .offset = (_reg), \121 .bit_idx = (_bit), \122 }, \123 .hw.init = &(struct clk_init_data) { \124 .name = #_name, \125 .ops = _ops, \126 .parent_hws = (const struct clk_hw *[]) { _pname }, \127 .num_parents = 1, \128 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \129 }, \130}131 132#define MESON_PCLK(_name, _reg, _bit, _pname) \133 __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)134 135#define MESON_PCLK_RO(_name, _reg, _bit, _pname) \136 __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)137#endif /* __CLK_REGMAP_H */138