Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (c) 2018 BayLibre, SAS.
0004  * Author: Jerome Brunet <jbrunet@baylibre.com>
0005  */
0006 
0007 #ifndef __CLK_REGMAP_H
0008 #define __CLK_REGMAP_H
0009 
0010 #include <linux/clk-provider.h>
0011 #include <linux/regmap.h>
0012 
0013 /**
0014  * struct clk_regmap - regmap backed clock
0015  *
0016  * @hw:     handle between common and hardware-specific interfaces
0017  * @map:    pointer to the regmap structure controlling the clock
0018  * @data:   data specific to the clock type
0019  *
0020  * Clock which is controlled by regmap backed registers. The actual type of
0021  * of the clock is controlled by the clock_ops and data.
0022  */
0023 struct clk_regmap {
0024     struct clk_hw   hw;
0025     struct regmap   *map;
0026     void        *data;
0027 };
0028 
0029 static inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw)
0030 {
0031     return container_of(hw, struct clk_regmap, hw);
0032 }
0033 
0034 /**
0035  * struct clk_regmap_gate_data - regmap backed gate specific data
0036  *
0037  * @offset: offset of the register controlling gate
0038  * @bit_idx:    single bit controlling gate
0039  * @flags:  hardware-specific flags
0040  *
0041  * Flags:
0042  * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
0043  */
0044 struct clk_regmap_gate_data {
0045     unsigned int    offset;
0046     u8      bit_idx;
0047     u8      flags;
0048 };
0049 
0050 static inline struct clk_regmap_gate_data *
0051 clk_get_regmap_gate_data(struct clk_regmap *clk)
0052 {
0053     return (struct clk_regmap_gate_data *)clk->data;
0054 }
0055 
0056 extern const struct clk_ops clk_regmap_gate_ops;
0057 extern const struct clk_ops clk_regmap_gate_ro_ops;
0058 
0059 /**
0060  * struct clk_regmap_div_data - regmap backed adjustable divider specific data
0061  *
0062  * @offset: offset of the register controlling the divider
0063  * @shift:  shift to the divider bit field
0064  * @width:  width of the divider bit field
0065  * @table:  array of value/divider pairs, last entry should have div = 0
0066  *
0067  * Flags:
0068  * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
0069  */
0070 struct clk_regmap_div_data {
0071     unsigned int    offset;
0072     u8      shift;
0073     u8      width;
0074     u8      flags;
0075     const struct clk_div_table  *table;
0076 };
0077 
0078 static inline struct clk_regmap_div_data *
0079 clk_get_regmap_div_data(struct clk_regmap *clk)
0080 {
0081     return (struct clk_regmap_div_data *)clk->data;
0082 }
0083 
0084 extern const struct clk_ops clk_regmap_divider_ops;
0085 extern const struct clk_ops clk_regmap_divider_ro_ops;
0086 
0087 /**
0088  * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data
0089  *
0090  * @hw:     handle between common and hardware-specific interfaces
0091  * @offset: offset of theregister controlling multiplexer
0092  * @table:  array of parent indexed register values
0093  * @shift:  shift to multiplexer bit field
0094  * @mask:   mask of mutliplexer bit field
0095  * @flags:  hardware-specific flags
0096  *
0097  * Flags:
0098  * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
0099  */
0100 struct clk_regmap_mux_data {
0101     unsigned int    offset;
0102     u32     *table;
0103     u32     mask;
0104     u8      shift;
0105     u8      flags;
0106 };
0107 
0108 static inline struct clk_regmap_mux_data *
0109 clk_get_regmap_mux_data(struct clk_regmap *clk)
0110 {
0111     return (struct clk_regmap_mux_data *)clk->data;
0112 }
0113 
0114 extern const struct clk_ops clk_regmap_mux_ops;
0115 extern const struct clk_ops clk_regmap_mux_ro_ops;
0116 
0117 #define __MESON_PCLK(_name, _reg, _bit, _ops, _pname)           \
0118 struct clk_regmap _name = {                     \
0119     .data = &(struct clk_regmap_gate_data){             \
0120         .offset = (_reg),                   \
0121         .bit_idx = (_bit),                  \
0122     },                              \
0123     .hw.init = &(struct clk_init_data) {                \
0124         .name = #_name,                     \
0125         .ops = _ops,                        \
0126         .parent_hws = (const struct clk_hw *[]) { _pname }, \
0127         .num_parents = 1,                   \
0128         .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
0129     },                              \
0130 }
0131 
0132 #define MESON_PCLK(_name, _reg, _bit, _pname)   \
0133     __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)
0134 
0135 #define MESON_PCLK_RO(_name, _reg, _bit, _pname)    \
0136     __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
0137 #endif /* __CLK_REGMAP_H */