126 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef __CLK_STARFIVE_JH71X0_H3#define __CLK_STARFIVE_JH71X0_H4 5#include <linux/bits.h>6#include <linux/clk-provider.h>7#include <linux/device.h>8#include <linux/spinlock.h>9 10/* register fields */11#define JH71X0_CLK_ENABLE BIT(31)12#define JH71X0_CLK_INVERT BIT(30)13#define JH71X0_CLK_MUX_MASK GENMASK(27, 24)14#define JH71X0_CLK_MUX_SHIFT 2415#define JH71X0_CLK_DIV_MASK GENMASK(23, 0)16#define JH71X0_CLK_FRAC_MASK GENMASK(15, 8)17#define JH71X0_CLK_FRAC_SHIFT 818#define JH71X0_CLK_INT_MASK GENMASK(7, 0)19 20/* fractional divider min/max */21#define JH71X0_CLK_FRAC_MIN 100UL22#define JH71X0_CLK_FRAC_MAX 25599UL23 24/* clock data */25struct jh71x0_clk_data {26 const char *name;27 unsigned long flags;28 u32 max;29 u8 parents[4];30};31 32#define JH71X0_GATE(_idx, _name, _flags, _parent) \33[_idx] = { \34 .name = _name, \35 .flags = CLK_SET_RATE_PARENT | (_flags), \36 .max = JH71X0_CLK_ENABLE, \37 .parents = { [0] = _parent }, \38}39 40#define JH71X0__DIV(_idx, _name, _max, _parent) \41[_idx] = { \42 .name = _name, \43 .flags = 0, \44 .max = _max, \45 .parents = { [0] = _parent }, \46}47 48#define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) \49[_idx] = { \50 .name = _name, \51 .flags = _flags, \52 .max = JH71X0_CLK_ENABLE | (_max), \53 .parents = { [0] = _parent }, \54}55 56#define JH71X0_FDIV(_idx, _name, _parent) \57[_idx] = { \58 .name = _name, \59 .flags = 0, \60 .max = JH71X0_CLK_FRAC_MAX, \61 .parents = { [0] = _parent }, \62}63 64#define JH71X0__MUX(_idx, _name, _flags, _nparents, ...) \65[_idx] = { \66 .name = _name, \67 .flags = _flags, \68 .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \69 .parents = { __VA_ARGS__ }, \70}71 72#define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) \73[_idx] = { \74 .name = _name, \75 .flags = _flags, \76 .max = JH71X0_CLK_ENABLE | \77 (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT), \78 .parents = { __VA_ARGS__ }, \79}80 81#define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) \82[_idx] = { \83 .name = _name, \84 .flags = 0, \85 .max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \86 .parents = { __VA_ARGS__ }, \87}88 89#define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) \90[_idx] = { \91 .name = _name, \92 .flags = _flags, \93 .max = JH71X0_CLK_ENABLE | \94 (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \95 .parents = { __VA_ARGS__ }, \96}97 98#define JH71X0__INV(_idx, _name, _parent) \99[_idx] = { \100 .name = _name, \101 .flags = CLK_SET_RATE_PARENT, \102 .max = JH71X0_CLK_INVERT, \103 .parents = { [0] = _parent }, \104}105 106struct jh71x0_clk {107 struct clk_hw hw;108 unsigned int idx;109 unsigned int max_div;110};111 112struct jh71x0_clk_priv {113 /* protect clk enable and set rate/parent from happening at the same time */114 spinlock_t rmw_lock;115 struct device *dev;116 void __iomem *base;117 struct clk *original_clk;118 struct notifier_block pll_clk_nb;119 struct clk_hw *pll[3];120 struct jh71x0_clk reg[];121};122 123const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);124 125#endif126