Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
0004  *
0005  * Baikal-T1 CCU Dividers interface driver
0006  */
0007 #ifndef __CLK_BT1_CCU_DIV_H__
0008 #define __CLK_BT1_CCU_DIV_H__
0009 
0010 #include <linux/clk-provider.h>
0011 #include <linux/spinlock.h>
0012 #include <linux/regmap.h>
0013 #include <linux/bits.h>
0014 #include <linux/of.h>
0015 
0016 /*
0017  * CCU Divider private flags
0018  * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
0019  *            It can be 0 though, which is functionally the same.
0020  * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
0021  *                 It can be either 0 or greater than 3.
0022  * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
0023  * @CCU_DIV_RESET_DOMAIN: Provide reset clock domain method.
0024  */
0025 #define CCU_DIV_SKIP_ONE        BIT(1)
0026 #define CCU_DIV_SKIP_ONE_TO_THREE   BIT(2)
0027 #define CCU_DIV_LOCK_SHIFTED        BIT(3)
0028 #define CCU_DIV_RESET_DOMAIN        BIT(4)
0029 
0030 /*
0031  * enum ccu_div_type - CCU Divider types
0032  * @CCU_DIV_VAR: Clocks gate with variable divider.
0033  * @CCU_DIV_GATE: Clocks gate with fixed divider.
0034  * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
0035  */
0036 enum ccu_div_type {
0037     CCU_DIV_VAR,
0038     CCU_DIV_GATE,
0039     CCU_DIV_FIXED
0040 };
0041 
0042 /*
0043  * struct ccu_div_init_data - CCU Divider initialization data
0044  * @id: Clocks private identifier.
0045  * @name: Clocks name.
0046  * @parent_name: Parent clocks name in a fw node.
0047  * @base: Divider register base address with respect to the sys_regs base.
0048  * @sys_regs: Baikal-T1 System Controller registers map.
0049  * @np: Pointer to the node describing the CCU Dividers.
0050  * @type: CCU divider type (variable, fixed with and without gate).
0051  * @width: Divider width if it's variable.
0052  * @divider: Divider fixed value.
0053  * @flags: CCU Divider clock flags.
0054  * @features: CCU Divider private features.
0055  */
0056 struct ccu_div_init_data {
0057     unsigned int id;
0058     const char *name;
0059     const char *parent_name;
0060     unsigned int base;
0061     struct regmap *sys_regs;
0062     struct device_node *np;
0063     enum ccu_div_type type;
0064     union {
0065         unsigned int width;
0066         unsigned int divider;
0067     };
0068     unsigned long flags;
0069     unsigned long features;
0070 };
0071 
0072 /*
0073  * struct ccu_div - CCU Divider descriptor
0074  * @hw: clk_hw of the divider.
0075  * @id: Clock private identifier.
0076  * @reg_ctl: Divider control register base address.
0077  * @sys_regs: Baikal-T1 System Controller registers map.
0078  * @lock: Divider state change spin-lock.
0079  * @mask: Divider field mask.
0080  * @divider: Divider fixed value.
0081  * @flags: Divider clock flags.
0082  * @features: CCU Divider private features.
0083  */
0084 struct ccu_div {
0085     struct clk_hw hw;
0086     unsigned int id;
0087     unsigned int reg_ctl;
0088     struct regmap *sys_regs;
0089     spinlock_t lock;
0090     union {
0091         u32 mask;
0092         unsigned int divider;
0093     };
0094     unsigned long flags;
0095     unsigned long features;
0096 };
0097 #define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw)
0098 
0099 static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div)
0100 {
0101     return div ? &div->hw : NULL;
0102 }
0103 
0104 struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
0105 
0106 void ccu_div_hw_unregister(struct ccu_div *div);
0107 
0108 int ccu_div_reset_domain(struct ccu_div *div);
0109 
0110 #endif /* __CLK_BT1_CCU_DIV_H__ */