diff options
Diffstat (limited to 'drivers/clk/sophgo/clk-cv18xx-common.h')
-rw-r--r-- | drivers/clk/sophgo/clk-cv18xx-common.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/clk/sophgo/clk-cv18xx-common.h b/drivers/clk/sophgo/clk-cv18xx-common.h new file mode 100644 index 0000000000..2bfda02b20 --- /dev/null +++ b/drivers/clk/sophgo/clk-cv18xx-common.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com> + */ + +#ifndef _CLK_SOPHGO_CV18XX_IP_H_ +#define _CLK_SOPHGO_CV18XX_IP_H_ + +#include <linux/compiler.h> +#include <linux/clk-provider.h> +#include <linux/bitfield.h> + +struct cv1800_clk_common { + void __iomem *base; + spinlock_t *lock; + struct clk_hw hw; + unsigned long features; +}; + +#define CV1800_CLK_COMMON(_name, _parents, _op, _flags) \ + { \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parents, \ + _op, _flags), \ + } + +static inline struct cv1800_clk_common * +hw_to_cv1800_clk_common(struct clk_hw *hw) +{ + return container_of(hw, struct cv1800_clk_common, hw); +} + +struct cv1800_clk_regbit { + u16 reg; + s8 shift; +}; + +struct cv1800_clk_regfield { + u16 reg; + u8 shift; + u8 width; + s16 initval; + unsigned long flags; +}; + +#define CV1800_CLK_BIT(_reg, _shift) \ + { \ + .reg = _reg, \ + .shift = _shift, \ + } + +#define CV1800_CLK_REG(_reg, _shift, _width, _initval, _flags) \ + { \ + .reg = _reg, \ + .shift = _shift, \ + .width = _width, \ + .initval = _initval, \ + .flags = _flags, \ + } + +#define cv1800_clk_regfield_genmask(_reg) \ + GENMASK((_reg)->shift + (_reg)->width - 1, (_reg)->shift) +#define cv1800_clk_regfield_get(_val, _reg) \ + (((_val) >> (_reg)->shift) & GENMASK((_reg)->width - 1, 0)) +#define cv1800_clk_regfield_set(_val, _new, _reg) \ + (((_val) & ~cv1800_clk_regfield_genmask((_reg))) | \ + (((_new) & GENMASK((_reg)->width - 1, 0)) << (_reg)->shift)) + +#define _CV1800_SET_FIELD(_reg, _val, _field) \ + (((_reg) & ~(_field)) | FIELD_PREP((_field), (_val))) + +int cv1800_clk_setbit(struct cv1800_clk_common *common, + struct cv1800_clk_regbit *field); +int cv1800_clk_clearbit(struct cv1800_clk_common *common, + struct cv1800_clk_regbit *field); +int cv1800_clk_checkbit(struct cv1800_clk_common *common, + struct cv1800_clk_regbit *field); + +void cv1800_clk_wait_for_lock(struct cv1800_clk_common *common, + u32 reg, u32 lock); + +#endif // _CLK_SOPHGO_CV18XX_IP_H_ |