xref: /kernel/linux/linux-5.10/drivers/clk/zte/clk.h (revision 8c2ecf20)
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright 2015 Linaro Ltd.
4 * Copyright (C) 2014 ZTE Corporation.
5 */
6
7#ifndef __ZTE_CLK_H
8#define __ZTE_CLK_H
9#include <linux/clk-provider.h>
10#include <linux/spinlock.h>
11
12#define PNAME(x) static const char *x[]
13
14struct zx_pll_config {
15	unsigned long rate;
16	u32 cfg0;
17	u32 cfg1;
18};
19
20struct clk_zx_pll {
21	struct clk_hw hw;
22	void __iomem *reg_base;
23	const struct zx_pll_config *lookup_table; /* order by rate asc */
24	int count;
25	spinlock_t *lock;
26	u8 pd_bit;		/* power down bit */
27	u8 lock_bit;		/* pll lock flag bit */
28};
29
30#define PLL_RATE(_rate, _cfg0, _cfg1)	\
31{					\
32	.rate = _rate,			\
33	.cfg0 = _cfg0,			\
34	.cfg1 = _cfg1,			\
35}
36
37#define ZX_PLL(_name, _parent, _reg, _table, _pd, _lock)		\
38{									\
39	.reg_base	= (void __iomem *) _reg,			\
40	.lookup_table	= _table,					\
41	.count		= ARRAY_SIZE(_table),				\
42	.pd_bit		= _pd,						\
43	.lock_bit	= _lock,					\
44	.hw.init	 = CLK_HW_INIT(_name, _parent, &zx_pll_ops,	\
45				CLK_GET_RATE_NOCACHE),			\
46}
47
48/*
49 * The pd_bit is not available on ZX296718, so let's pass something
50 * bigger than 31, e.g. 0xff, to indicate that.
51 */
52#define ZX296718_PLL(_name, _parent, _reg, _table)			\
53ZX_PLL(_name, _parent, _reg, _table, 0xff, 30)
54
55struct zx_clk_gate {
56	struct clk_gate gate;
57	u16		id;
58};
59
60#define GATE(_id, _name, _parent, _reg, _bit, _flag, _gflags)		\
61{									\
62	.gate = {							\
63		.reg = (void __iomem *) _reg,				\
64		.bit_idx = (_bit),					\
65		.flags = _gflags,					\
66		.lock = &clk_lock,					\
67		.hw.init = CLK_HW_INIT(_name,				\
68					_parent,			\
69					&clk_gate_ops,			\
70					_flag | CLK_IGNORE_UNUSED),	\
71	},								\
72	.id	= _id,							\
73}
74
75struct zx_clk_fixed_factor {
76	struct clk_fixed_factor factor;
77	u16	id;
78};
79
80#define FFACTOR(_id, _name, _parent, _mult, _div, _flag)		\
81{									\
82	.factor = {							\
83		.div		= _div,					\
84		.mult		= _mult,				\
85		.hw.init	= CLK_HW_INIT(_name,			\
86					      _parent,			\
87					      &clk_fixed_factor_ops,	\
88					      _flag),			\
89	},								\
90	.id = _id,							\
91}
92
93struct zx_clk_mux {
94	struct clk_mux mux;
95	u16	id;
96};
97
98#define MUX_F(_id, _name, _parent, _reg, _shift, _width, _flag, _mflag)	\
99{									\
100	.mux = {							\
101		.reg		= (void __iomem *) _reg,		\
102		.mask		= BIT(_width) - 1,			\
103		.shift		= _shift,				\
104		.flags		= _mflag,				\
105		.lock		= &clk_lock,				\
106		.hw.init	= CLK_HW_INIT_PARENTS(_name,		\
107						      _parent,		\
108						      &clk_mux_ops,	\
109						      _flag),		\
110	},								\
111	.id = _id,							\
112}
113
114#define MUX(_id, _name, _parent, _reg, _shift, _width)			\
115MUX_F(_id, _name, _parent, _reg, _shift, _width, 0, 0)
116
117struct zx_clk_div {
118	struct clk_divider div;
119	u16	id;
120};
121
122#define DIV_T(_id, _name, _parent, _reg, _shift, _width, _flag, _table)	\
123{									\
124	.div = {							\
125		.reg		= (void __iomem *) _reg,		\
126		.shift		= _shift,				\
127		.width		= _width,				\
128		.flags		= 0,					\
129		.table		= _table,				\
130		.lock		= &clk_lock,				\
131		.hw.init	= CLK_HW_INIT(_name,			\
132					      _parent,			\
133					      &clk_divider_ops,		\
134					      _flag),			\
135	},								\
136	.id = _id,							\
137}
138
139struct clk_zx_audio_divider {
140	struct clk_hw				hw;
141	void __iomem				*reg_base;
142	unsigned int				rate_count;
143	spinlock_t				*lock;
144	u16					id;
145};
146
147#define AUDIO_DIV(_id, _name, _parent, _reg)				\
148{									\
149	.reg_base	= (void __iomem *) _reg,			\
150	.lock		= &clk_lock,					\
151	.hw.init	= CLK_HW_INIT(_name,				\
152				      _parent,				\
153				      &zx_audio_div_ops,		\
154				      0),				\
155	.id = _id,							\
156}
157
158struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
159	unsigned long flags, void __iomem *reg_base,
160	const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
161
162struct clk_zx_audio {
163	struct clk_hw hw;
164	void __iomem *reg_base;
165};
166
167struct clk *clk_register_zx_audio(const char *name,
168				  const char * const parent_name,
169				  unsigned long flags, void __iomem *reg_base);
170
171extern const struct clk_ops zx_pll_ops;
172extern const struct clk_ops zx_audio_div_ops;
173
174#endif
175