Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 //
0003 // Spreadtrum divider clock driver
0004 //
0005 // Copyright (C) 2017 Spreadtrum, Inc.
0006 // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
0007 
0008 #ifndef _SPRD_DIV_H_
0009 #define _SPRD_DIV_H_
0010 
0011 #include "common.h"
0012 
0013 /**
0014  * struct sprd_div_internal - Internal divider description
0015  * @shift: Bit offset of the divider in its register
0016  * @width: Width of the divider field in its register
0017  *
0018  * That structure represents a single divider, and is meant to be
0019  * embedded in other structures representing the various clock
0020  * classes.
0021  */
0022 struct sprd_div_internal {
0023     u8  shift;
0024     u8  width;
0025 };
0026 
0027 #define _SPRD_DIV_CLK(_shift, _width)   \
0028     {               \
0029         .shift  = _shift,   \
0030         .width  = _width,   \
0031     }
0032 
0033 struct sprd_div {
0034     struct sprd_div_internal    div;
0035     struct sprd_clk_common  common;
0036 };
0037 
0038 #define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,      \
0039                 _shift, _width, _flags, _fn)        \
0040     struct sprd_div _struct = {                 \
0041         .div    = _SPRD_DIV_CLK(_shift, _width),        \
0042         .common = {                     \
0043             .regmap     = NULL,             \
0044             .reg        = _reg,             \
0045             .hw.init    = _fn(_name, _parent,       \
0046                           &sprd_div_ops, _flags),   \
0047         }                           \
0048     }
0049 
0050 #define SPRD_DIV_CLK(_struct, _name, _parent, _reg,         \
0051              _shift, _width, _flags)                \
0052     SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,      \
0053                 _shift, _width, _flags, CLK_HW_INIT)
0054 
0055 #define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg,          \
0056             _shift, _width, _flags)             \
0057     SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,      \
0058                 _shift, _width, _flags, CLK_HW_INIT_HW)
0059 
0060 static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)
0061 {
0062     struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
0063 
0064     return container_of(common, struct sprd_div, common);
0065 }
0066 
0067 long sprd_div_helper_round_rate(struct sprd_clk_common *common,
0068                 const struct sprd_div_internal *div,
0069                 unsigned long rate,
0070                 unsigned long *parent_rate);
0071 
0072 unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
0073                       const struct sprd_div_internal *div,
0074                       unsigned long parent_rate);
0075 
0076 int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
0077                  const struct sprd_div_internal *div,
0078                  unsigned long rate,
0079                  unsigned long parent_rate);
0080 
0081 extern const struct clk_ops sprd_div_ops;
0082 
0083 #endif /* _SPRD_DIV_H_ */