linux/drivers/clk/sunxi-ng/ccu_mux.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _CCU_MUX_H_
   3#define _CCU_MUX_H_
   4
   5#include <linux/clk-provider.h>
   6
   7#include "ccu_common.h"
   8
   9struct ccu_mux_fixed_prediv {
  10        u8      index;
  11        u16     div;
  12};
  13
  14struct ccu_mux_var_prediv {
  15        u8      index;
  16        u8      shift;
  17        u8      width;
  18};
  19
  20struct ccu_mux_internal {
  21        u8              shift;
  22        u8              width;
  23        const u8        *table;
  24
  25        const struct ccu_mux_fixed_prediv       *fixed_predivs;
  26        u8              n_predivs;
  27
  28        const struct ccu_mux_var_prediv         *var_predivs;
  29        u8              n_var_predivs;
  30};
  31
  32#define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table)    \
  33        {                                               \
  34                .shift  = _shift,                       \
  35                .width  = _width,                       \
  36                .table  = _table,                       \
  37        }
  38
  39#define _SUNXI_CCU_MUX(_shift, _width) \
  40        _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)
  41
  42struct ccu_mux {
  43        u16                     reg;
  44        u32                     enable;
  45
  46        struct ccu_mux_internal mux;
  47        struct ccu_common       common;
  48};
  49
  50#define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \
  51                                     _reg, _shift, _width, _gate,       \
  52                                     _flags)                            \
  53        struct ccu_mux _struct = {                                      \
  54                .enable = _gate,                                        \
  55                .mux    = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \
  56                .common = {                                             \
  57                        .reg            = _reg,                         \
  58                        .hw.init        = CLK_HW_INIT_PARENTS(_name,    \
  59                                                              _parents, \
  60                                                              &ccu_mux_ops, \
  61                                                              _flags),  \
  62                }                                                       \
  63        }
  64
  65#define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg,         \
  66                                _shift, _width, _gate, _flags)          \
  67        SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,   \
  68                                      _reg, _shift, _width, _gate,      \
  69                                      _flags)
  70
  71#define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width,   \
  72                      _flags)                                           \
  73        SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,   \
  74                                      _reg, _shift, _width, 0, _flags)
  75
  76static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
  77{
  78        struct ccu_common *common = hw_to_ccu_common(hw);
  79
  80        return container_of(common, struct ccu_mux, common);
  81}
  82
  83extern const struct clk_ops ccu_mux_ops;
  84
  85unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
  86                                          struct ccu_mux_internal *cm,
  87                                          int parent_index,
  88                                          unsigned long parent_rate);
  89int ccu_mux_helper_determine_rate(struct ccu_common *common,
  90                                  struct ccu_mux_internal *cm,
  91                                  struct clk_rate_request *req,
  92                                  unsigned long (*round)(struct ccu_mux_internal *,
  93                                                         struct clk_hw *,
  94                                                         unsigned long *,
  95                                                         unsigned long,
  96                                                         void *),
  97                                  void *data);
  98u8 ccu_mux_helper_get_parent(struct ccu_common *common,
  99                             struct ccu_mux_internal *cm);
 100int ccu_mux_helper_set_parent(struct ccu_common *common,
 101                              struct ccu_mux_internal *cm,
 102                              u8 index);
 103
 104struct ccu_mux_nb {
 105        struct notifier_block   clk_nb;
 106        struct ccu_common       *common;
 107        struct ccu_mux_internal *cm;
 108
 109        u32     delay_us;       /* How many us to wait after reparenting */
 110        u8      bypass_index;   /* Which parent to temporarily use */
 111        u8      original_index; /* This is set by the notifier callback */
 112};
 113
 114#define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb)
 115
 116int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb);
 117
 118#endif /* _CCU_MUX_H_ */
 119