linux/drivers/clk/meson/clk-regmap.h
<<
>>
Prefs
   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/clk-provider.h>
  11#include <linux/regmap.h>
  12
  13/**
  14 * struct clk_regmap - regmap backed clock
  15 *
  16 * @hw:         handle between common and hardware-specific interfaces
  17 * @map:        pointer to the regmap structure controlling the clock
  18 * @data:       data specific to the clock type
  19 *
  20 * Clock which is controlled by regmap backed registers. The actual type of
  21 * 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 data
  36 *
  37 * @offset:     offset of the register controlling gate
  38 * @bit_idx:    single bit controlling gate
  39 * @flags:      hardware-specific flags
  40 *
  41 * Flags:
  42 * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
  43 */
  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 data
  61 *
  62 * @offset:     offset of the register controlling the divider
  63 * @shift:      shift to the divider bit field
  64 * @width:      width of the divider bit field
  65 * @table:      array of value/divider pairs, last entry should have div = 0
  66 *
  67 * Flags:
  68 * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
  69 */
  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 data
  89 *
  90 * @hw:         handle between common and hardware-specific interfaces
  91 * @offset:     offset of theregister controlling multiplexer
  92 * @table:      array of parent indexed register values
  93 * @shift:      shift to multiplexer bit field
  94 * @mask:       mask of mutliplexer bit field
  95 * @flags:      hardware-specific flags
  96 *
  97 * Flags:
  98 * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
  99 */
 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