123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Baikal-T1 CCU Dividers interface driver
- */
- #ifndef __CLK_BT1_CCU_DIV_H__
- #define __CLK_BT1_CCU_DIV_H__
- #include <linux/clk-provider.h>
- #include <linux/spinlock.h>
- #include <linux/regmap.h>
- #include <linux/bits.h>
- #include <linux/of.h>
- /*
- * CCU Divider private clock IDs
- * @CCU_SYS_SATA_CLK: CCU SATA internal clock
- * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock
- */
- #define CCU_SYS_SATA_CLK -1
- #define CCU_SYS_XGMAC_CLK -2
- /*
- * CCU Divider private flags
- * @CCU_DIV_BASIC: Basic divider clock required by the kernel as early as
- * possible.
- * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
- * It can be 0 though, which is functionally the same.
- * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
- * It can be either 0 or greater than 3.
- * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
- * @CCU_DIV_RESET_DOMAIN: There is a clock domain reset handle.
- */
- #define CCU_DIV_BASIC BIT(0)
- #define CCU_DIV_SKIP_ONE BIT(1)
- #define CCU_DIV_SKIP_ONE_TO_THREE BIT(2)
- #define CCU_DIV_LOCK_SHIFTED BIT(3)
- #define CCU_DIV_RESET_DOMAIN BIT(4)
- /*
- * enum ccu_div_type - CCU Divider types
- * @CCU_DIV_VAR: Clocks gate with variable divider.
- * @CCU_DIV_GATE: Clocks gate with fixed divider.
- * @CCU_DIV_BUF: Clock gate with no divider.
- * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
- */
- enum ccu_div_type {
- CCU_DIV_VAR,
- CCU_DIV_GATE,
- CCU_DIV_BUF,
- CCU_DIV_FIXED
- };
- /*
- * struct ccu_div_init_data - CCU Divider initialization data
- * @id: Clocks private identifier.
- * @name: Clocks name.
- * @parent_name: Parent clocks name in a fw node.
- * @base: Divider register base address with respect to the sys_regs base.
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @np: Pointer to the node describing the CCU Dividers.
- * @type: CCU divider type (variable, fixed with and without gate).
- * @width: Divider width if it's variable.
- * @divider: Divider fixed value.
- * @flags: CCU Divider clock flags.
- * @features: CCU Divider private features.
- */
- struct ccu_div_init_data {
- unsigned int id;
- const char *name;
- const char *parent_name;
- unsigned int base;
- struct regmap *sys_regs;
- struct device_node *np;
- enum ccu_div_type type;
- union {
- unsigned int width;
- unsigned int divider;
- };
- unsigned long flags;
- unsigned long features;
- };
- /*
- * struct ccu_div - CCU Divider descriptor
- * @hw: clk_hw of the divider.
- * @id: Clock private identifier.
- * @reg_ctl: Divider control register base address.
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @lock: Divider state change spin-lock.
- * @mask: Divider field mask.
- * @divider: Divider fixed value.
- * @flags: Divider clock flags.
- * @features: CCU Divider private features.
- */
- struct ccu_div {
- struct clk_hw hw;
- unsigned int id;
- unsigned int reg_ctl;
- struct regmap *sys_regs;
- spinlock_t lock;
- union {
- u32 mask;
- unsigned int divider;
- };
- unsigned long flags;
- unsigned long features;
- };
- #define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw)
- static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div)
- {
- return div ? &div->hw : NULL;
- }
- struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
- void ccu_div_hw_unregister(struct ccu_div *div);
- #endif /* __CLK_BT1_CCU_DIV_H__ */
|