Lines Matching +full:clk +full:- +full:divider +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-only
3 * clk-flexgen.c
5 * Copyright (C) ST-Microelectronics SA 2013
6 * Author: Maxime Coquelin <maxime.coquelin@st.com> for ST-Microelectronics.
9 #include <linux/clk.h>
10 #include <linux/clk-provider.h>
21 bool mode; member
29 /* Pre-divisor's gate */
31 /* Pre-divisor */
37 /* Asynchronous mode control */
49 struct clk_hw *pgate_hw = &flexgen->pgate.hw; in flexgen_enable()
50 struct clk_hw *fgate_hw = &flexgen->fgate.hw; in flexgen_enable()
66 struct clk_hw *fgate_hw = &flexgen->fgate.hw; in flexgen_disable()
79 struct clk_hw *fgate_hw = &flexgen->fgate.hw; in flexgen_is_enabled()
92 struct clk_hw *mux_hw = &flexgen->mux.hw; in flexgen_get_parent()
102 struct clk_hw *mux_hw = &flexgen->mux.hw; in flexgen_set_parent()
135 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; in flexgen_recalc_rate()
136 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; in flexgen_recalc_rate()
151 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; in flexgen_set_rate()
152 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; in flexgen_set_rate()
153 struct clk_hw *sync_hw = &flexgen->sync.hw; in flexgen_set_rate()
162 if (flexgen->control_mode) { in flexgen_set_rate()
163 reg = readl(config->reg); in flexgen_set_rate()
164 reg &= ~BIT(config->bit_idx); in flexgen_set_rate()
165 writel(reg, config->reg); in flexgen_set_rate()
198 static struct clk *clk_register_flexgen(const char *name, in clk_register_flexgen()
201 unsigned long flexgen_flags, bool mode) { in clk_register_flexgen() argument
203 struct clk *clk; in clk_register_flexgen() local
210 return ERR_PTR(-ENOMEM); in clk_register_flexgen()
223 fgxbar->mux.lock = lock; in clk_register_flexgen()
224 fgxbar->mux.mask = BIT(6) - 1; in clk_register_flexgen()
225 fgxbar->mux.reg = xbar_reg; in clk_register_flexgen()
226 fgxbar->mux.shift = xbar_shift; in clk_register_flexgen()
227 fgxbar->mux.table = NULL; in clk_register_flexgen()
230 /* Pre-divider's gate config (in xbar register)*/ in clk_register_flexgen()
231 fgxbar->pgate.lock = lock; in clk_register_flexgen()
232 fgxbar->pgate.reg = xbar_reg; in clk_register_flexgen()
233 fgxbar->pgate.bit_idx = xbar_shift + 6; in clk_register_flexgen()
235 /* Pre-divider config */ in clk_register_flexgen()
236 fgxbar->pdiv.lock = lock; in clk_register_flexgen()
237 fgxbar->pdiv.reg = reg + 0x58 + idx * 4; in clk_register_flexgen()
238 fgxbar->pdiv.width = 10; in clk_register_flexgen()
240 /* Final divider's gate config */ in clk_register_flexgen()
241 fgxbar->fgate.lock = lock; in clk_register_flexgen()
242 fgxbar->fgate.reg = fdiv_reg; in clk_register_flexgen()
243 fgxbar->fgate.bit_idx = 6; in clk_register_flexgen()
245 /* Final divider config */ in clk_register_flexgen()
246 fgxbar->fdiv.lock = lock; in clk_register_flexgen()
247 fgxbar->fdiv.reg = fdiv_reg; in clk_register_flexgen()
248 fgxbar->fdiv.width = 6; in clk_register_flexgen()
250 /* Final divider sync config */ in clk_register_flexgen()
251 fgxbar->sync.lock = lock; in clk_register_flexgen()
252 fgxbar->sync.reg = fdiv_reg; in clk_register_flexgen()
253 fgxbar->sync.bit_idx = 7; in clk_register_flexgen()
255 fgxbar->control_mode = mode; in clk_register_flexgen()
257 fgxbar->hw.init = &init; in clk_register_flexgen()
259 clk = clk_register(NULL, &fgxbar->hw); in clk_register_flexgen()
260 if (IS_ERR(clk)) in clk_register_flexgen()
264 __clk_get_name(clk), in clk_register_flexgen()
265 __clk_get_name(clk_get_parent(clk)), in clk_register_flexgen()
266 (unsigned int)clk_get_rate(clk)); in clk_register_flexgen()
267 return clk; in clk_register_flexgen()
295 .mode = 1,
300 .compatible = "st,flexgen-audio",
304 .compatible = "st,flexgen-video",
341 data = (struct clkgen_data *)match->data; in st_of_flexgen_setup()
342 flex_flags = data->flags; in st_of_flexgen_setup()
343 clk_mode = data->mode; in st_of_flexgen_setup()
350 ret = of_property_count_strings(np, "clock-output-names"); in st_of_flexgen_setup()
353 __func__, clk_data->clk_num); in st_of_flexgen_setup()
356 clk_data->clk_num = ret; in st_of_flexgen_setup()
358 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), in st_of_flexgen_setup()
360 if (!clk_data->clks) in st_of_flexgen_setup()
369 for (i = 0; i < clk_data->clk_num; i++) { in st_of_flexgen_setup()
370 struct clk *clk; in st_of_flexgen_setup() local
373 if (of_property_read_string_index(np, "clock-output-names", in st_of_flexgen_setup()
387 clk = clk_register_flexgen(clk_name, parents, num_parents, in st_of_flexgen_setup()
390 if (IS_ERR(clk)) in st_of_flexgen_setup()
393 clk_data->clks[i] = clk; in st_of_flexgen_setup()
404 kfree(clk_data->clks); in st_of_flexgen_setup()