blob: 4df0f121b56d7cf622cf6ca9103d3200ca7f6c2c [file] [log] [blame]
Jun Nie5a465802015-06-04 11:21:01 +08001/*
2 * Copyright 2015 Linaro Ltd.
3 * Copyright (C) 2014 ZTE Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef __ZTE_CLK_H
11#define __ZTE_CLK_H
12#include <linux/clk-provider.h>
13#include <linux/spinlock.h>
14
Jun Nieca023322016-09-06 14:02:42 +080015#define PNAME(x) static const char *x[]
16
17#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
18 &(struct clk_init_data) { \
19 .flags = _flags, \
20 .name = _name, \
21 .parent_names = (const char *[]) { _parent }, \
22 .num_parents = 1, \
23 .ops = _ops, \
24 }
25
26#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
27 &(struct clk_init_data) { \
28 .flags = _flags, \
29 .name = _name, \
30 .parent_names = _parents, \
31 .num_parents = ARRAY_SIZE(_parents), \
32 .ops = _ops, \
33 }
34
Jun Nie5a465802015-06-04 11:21:01 +080035struct zx_pll_config {
36 unsigned long rate;
37 u32 cfg0;
38 u32 cfg1;
39};
40
41struct clk_zx_pll {
42 struct clk_hw hw;
43 void __iomem *reg_base;
44 const struct zx_pll_config *lookup_table; /* order by rate asc */
45 int count;
46 spinlock_t *lock;
Jun Nie8d9a0862016-09-06 14:02:41 +080047 u8 pd_bit; /* power down bit */
48 u8 lock_bit; /* pll lock flag bit */
Jun Nie5a465802015-06-04 11:21:01 +080049};
50
Jun Nieca023322016-09-06 14:02:42 +080051#define PLL_RATE(_rate, _cfg0, _cfg1) \
52{ \
53 .rate = _rate, \
54 .cfg0 = _cfg0, \
55 .cfg1 = _cfg1, \
56}
57
58#define ZX_PLL(_name, _parent, _reg, _table, _pd, _lock) \
59{ \
60 .reg_base = (void __iomem *) _reg, \
61 .lookup_table = _table, \
62 .count = ARRAY_SIZE(_table), \
63 .pd_bit = _pd, \
64 .lock_bit = _lock, \
65 .hw.init = CLK_HW_INIT(_name, _parent, &zx_pll_ops, \
66 CLK_GET_RATE_NOCACHE), \
67}
68
Shawn Guoee249cb2017-03-21 16:38:22 +080069/*
70 * The pd_bit is not available on ZX296718, so let's pass something
71 * bigger than 31, e.g. 0xff, to indicate that.
72 */
Jun Nieca023322016-09-06 14:02:42 +080073#define ZX296718_PLL(_name, _parent, _reg, _table) \
Shawn Guoee249cb2017-03-21 16:38:22 +080074ZX_PLL(_name, _parent, _reg, _table, 0xff, 30)
Jun Nieca023322016-09-06 14:02:42 +080075
76struct zx_clk_gate {
77 struct clk_gate gate;
78 u16 id;
79};
80
81#define GATE(_id, _name, _parent, _reg, _bit, _flag, _gflags) \
82{ \
83 .gate = { \
84 .reg = (void __iomem *) _reg, \
85 .bit_idx = (_bit), \
86 .flags = _gflags, \
87 .lock = &clk_lock, \
88 .hw.init = CLK_HW_INIT(_name, \
89 _parent, \
90 &clk_gate_ops, \
91 _flag | CLK_IGNORE_UNUSED), \
92 }, \
93 .id = _id, \
94}
95
96struct zx_clk_fixed_factor {
97 struct clk_fixed_factor factor;
98 u16 id;
99};
100
101#define FFACTOR(_id, _name, _parent, _mult, _div, _flag) \
102{ \
103 .factor = { \
104 .div = _div, \
105 .mult = _mult, \
106 .hw.init = CLK_HW_INIT(_name, \
107 _parent, \
108 &clk_fixed_factor_ops, \
109 _flag), \
110 }, \
111 .id = _id, \
112}
113
114struct zx_clk_mux {
115 struct clk_mux mux;
116 u16 id;
117};
118
119#define MUX_F(_id, _name, _parent, _reg, _shift, _width, _flag, _mflag) \
120{ \
121 .mux = { \
122 .reg = (void __iomem *) _reg, \
123 .mask = BIT(_width) - 1, \
124 .shift = _shift, \
125 .flags = _mflag, \
126 .lock = &clk_lock, \
127 .hw.init = CLK_HW_INIT_PARENTS(_name, \
128 _parent, \
129 &clk_mux_ops, \
130 _flag), \
131 }, \
132 .id = _id, \
133}
134
135#define MUX(_id, _name, _parent, _reg, _shift, _width) \
136MUX_F(_id, _name, _parent, _reg, _shift, _width, 0, 0)
137
138struct zx_clk_div {
139 struct clk_divider div;
140 u16 id;
141};
142
143#define DIV_T(_id, _name, _parent, _reg, _shift, _width, _flag, _table) \
144{ \
145 .div = { \
146 .reg = (void __iomem *) _reg, \
147 .shift = _shift, \
148 .width = _width, \
149 .flags = 0, \
150 .table = _table, \
151 .lock = &clk_lock, \
152 .hw.init = CLK_HW_INIT(_name, \
153 _parent, \
154 &clk_divider_ops, \
155 _flag), \
156 }, \
157 .id = _id, \
158}
159
Jun Nieedc6da22016-12-16 15:26:47 +0800160struct clk_zx_audio_divider {
161 struct clk_hw hw;
162 void __iomem *reg_base;
163 unsigned int rate_count;
164 spinlock_t *lock;
165 u16 id;
166};
167
168#define AUDIO_DIV(_id, _name, _parent, _reg) \
169{ \
170 .reg_base = (void __iomem *) _reg, \
171 .lock = &clk_lock, \
172 .hw.init = CLK_HW_INIT(_name, \
173 _parent, \
174 &zx_audio_div_ops, \
175 0), \
176 .id = _id, \
177}
178
Jun Nie5a465802015-06-04 11:21:01 +0800179struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
180 unsigned long flags, void __iomem *reg_base,
181 const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
Jun Nie4599dd22015-07-23 15:02:51 +0800182
183struct clk_zx_audio {
184 struct clk_hw hw;
185 void __iomem *reg_base;
186};
187
188struct clk *clk_register_zx_audio(const char *name,
189 const char * const parent_name,
190 unsigned long flags, void __iomem *reg_base);
Jun Nie8d9a0862016-09-06 14:02:41 +0800191
192extern const struct clk_ops zx_pll_ops;
Jun Nieedc6da22016-12-16 15:26:47 +0800193extern const struct clk_ops zx_audio_div_ops;
194
Jun Nie5a465802015-06-04 11:21:01 +0800195#endif