Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
2/*
3 * Copyright (c) 2023 Neil Armstrong <neil.armstrong@linaro.org>
4 */
5
6#ifndef __MESON_CLKC_UTILS_H__
7#define __MESON_CLKC_UTILS_H__
8
9#include <linux/of_device.h>
10#include <linux/clk-provider.h>
11
12struct platform_device;
13
14struct meson_clk_hw_data {
15 struct clk_hw **hws;
16 unsigned int num;
17};
18
19struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_data);
20
21struct meson_clkc_data {
22 const struct reg_sequence *init_regs;
23 unsigned int init_count;
24 struct meson_clk_hw_data hw_clks;
25};
26
27int meson_clkc_syscon_probe(struct platform_device *pdev);
28int meson_clkc_mmio_probe(struct platform_device *pdev);
29
30#define __MESON_PCLK(_name, _reg, _bit, _ops, _pdata, _flags) \
31struct clk_regmap _name = { \
32 .data = &(struct clk_regmap_gate_data) { \
33 .offset = (_reg), \
34 .bit_idx = (_bit), \
35 }, \
36 .hw.init = &(struct clk_init_data) { \
37 .name = #_name, \
38 .ops = _ops, \
39 .parent_data = (_pdata), \
40 .num_parents = 1, \
41 .flags = (_flags), \
42 }, \
43}
44
45#define MESON_PCLK(_name, _reg, _bit, _pdata, _flags) \
46 __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pdata, _flags)
47
48#define MESON_PCLK_RO(_name, _reg, _bit, _pdata, _flags) \
49 __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pdata, _flags)
50
51/* Helpers for the usual sel/div/gate composite clocks */
52#define MESON_COMP_SEL(_prefix, _name, _reg, _shift, _mask, _pdata, \
53 _table, _dflags, _iflags) \
54struct clk_regmap _prefix##_name##_sel = { \
55 .data = &(struct clk_regmap_mux_data) { \
56 .offset = (_reg), \
57 .mask = (_mask), \
58 .shift = (_shift), \
59 .flags = (_dflags), \
60 .table = (_table), \
61 }, \
62 .hw.init = &(struct clk_init_data){ \
63 .name = #_name "_sel", \
64 .ops = &clk_regmap_mux_ops, \
65 .parent_data = _pdata, \
66 .num_parents = ARRAY_SIZE(_pdata), \
67 .flags = (_iflags), \
68 }, \
69}
70
71#define MESON_COMP_DIV(_prefix, _name, _reg, _shift, _width, \
72 _dflags, _iflags) \
73struct clk_regmap _prefix##_name##_div = { \
74 .data = &(struct clk_regmap_div_data) { \
75 .offset = (_reg), \
76 .shift = (_shift), \
77 .width = (_width), \
78 .flags = (_dflags), \
79 }, \
80 .hw.init = &(struct clk_init_data) { \
81 .name = #_name "_div", \
82 .ops = &clk_regmap_divider_ops, \
83 .parent_hws = (const struct clk_hw *[]) { \
84 &_prefix##_name##_sel.hw \
85 }, \
86 .num_parents = 1, \
87 .flags = (_iflags), \
88 }, \
89}
90
91#define MESON_COMP_GATE(_prefix, _name, _reg, _bit, _iflags) \
92struct clk_regmap _prefix##_name = { \
93 .data = &(struct clk_regmap_gate_data) { \
94 .offset = (_reg), \
95 .bit_idx = (_bit), \
96 }, \
97 .hw.init = &(struct clk_init_data) { \
98 .name = #_name, \
99 .ops = &clk_regmap_gate_ops, \
100 .parent_hws = (const struct clk_hw *[]) { \
101 &_prefix##_name##_div.hw \
102 }, \
103 .num_parents = 1, \
104 .flags = (_iflags), \
105 }, \
106}
107
108#endif