1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
4*4882a593Smuzhiyun * Author: Elaine Zhang <zhangqing@rock-chips.com>
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun #include <linux/clk-provider.h>
7*4882a593Smuzhiyun #include <linux/clkdev.h>
8*4882a593Smuzhiyun #include <linux/log2.h>
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun static int cru_debug;
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #define cru_dbg(format, ...) do { \
13*4882a593Smuzhiyun if (cru_debug) \
14*4882a593Smuzhiyun pr_info("%s: " format, __func__, ## __VA_ARGS__); \
15*4882a593Smuzhiyun } while (0)
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define PNAME(x) static const char *const x[]
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun enum vop_clk_branch_type {
20*4882a593Smuzhiyun branch_mux,
21*4882a593Smuzhiyun branch_divider,
22*4882a593Smuzhiyun branch_factor,
23*4882a593Smuzhiyun branch_virtual,
24*4882a593Smuzhiyun };
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define VIR(cname) \
27*4882a593Smuzhiyun { \
28*4882a593Smuzhiyun .branch_type = branch_virtual, \
29*4882a593Smuzhiyun .name = cname, \
30*4882a593Smuzhiyun }
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #define MUX(cname, pnames, f) \
34*4882a593Smuzhiyun { \
35*4882a593Smuzhiyun .branch_type = branch_mux, \
36*4882a593Smuzhiyun .name = cname, \
37*4882a593Smuzhiyun .parent_names = pnames, \
38*4882a593Smuzhiyun .num_parents = ARRAY_SIZE(pnames), \
39*4882a593Smuzhiyun .flags = f, \
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #define FACTOR(cname, pname, f) \
43*4882a593Smuzhiyun { \
44*4882a593Smuzhiyun .branch_type = branch_factor, \
45*4882a593Smuzhiyun .name = cname, \
46*4882a593Smuzhiyun .parent_names = (const char *[]){ pname }, \
47*4882a593Smuzhiyun .num_parents = 1, \
48*4882a593Smuzhiyun .flags = f, \
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #define DIV(cname, pname, f, w) \
52*4882a593Smuzhiyun { \
53*4882a593Smuzhiyun .branch_type = branch_divider, \
54*4882a593Smuzhiyun .name = cname, \
55*4882a593Smuzhiyun .parent_names = (const char *[]){ pname }, \
56*4882a593Smuzhiyun .num_parents = 1, \
57*4882a593Smuzhiyun .flags = f, \
58*4882a593Smuzhiyun .div_width = w, \
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun struct vop2_clk_branch {
62*4882a593Smuzhiyun enum vop_clk_branch_type branch_type;
63*4882a593Smuzhiyun const char *name;
64*4882a593Smuzhiyun const char *const *parent_names;
65*4882a593Smuzhiyun u8 num_parents;
66*4882a593Smuzhiyun unsigned long flags;
67*4882a593Smuzhiyun u8 div_shift;
68*4882a593Smuzhiyun u8 div_width;
69*4882a593Smuzhiyun u8 div_flags;
70*4882a593Smuzhiyun };
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun PNAME(mux_port0_dclk_src_p) = { "dclk0", "dclk1" };
73*4882a593Smuzhiyun PNAME(mux_port2_dclk_src_p) = { "dclk2", "dclk1" };
74*4882a593Smuzhiyun PNAME(mux_dp_pixclk_p) = { "dclk_out0", "dclk_out1", "dclk_out2" };
75*4882a593Smuzhiyun PNAME(mux_hdmi_edp_clk_src_p) = { "dclk0", "dclk1", "dclk2" };
76*4882a593Smuzhiyun PNAME(mux_mipi_clk_src_p) = { "dclk_out1", "dclk_out2", "dclk_out3" };
77*4882a593Smuzhiyun PNAME(mux_dsc_8k_clk_src_p) = { "dclk0", "dclk1", "dclk2", "dclk3" };
78*4882a593Smuzhiyun PNAME(mux_dsc_4k_clk_src_p) = { "dclk0", "dclk1", "dclk2", "dclk3" };
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /*
81*4882a593Smuzhiyun * We only use this clk driver calculate the div
82*4882a593Smuzhiyun * of dclk_core/dclk_out/if_pixclk/if_dclk and
83*4882a593Smuzhiyun * the rate of the dclk from the soc.
84*4882a593Smuzhiyun *
85*4882a593Smuzhiyun * We don't touch the cru in the vop here, as
86*4882a593Smuzhiyun * these registers has special read andy write
87*4882a593Smuzhiyun * limits.
88*4882a593Smuzhiyun */
89*4882a593Smuzhiyun static struct vop2_clk_branch rk3588_vop_clk_branches[] = {
90*4882a593Smuzhiyun VIR("dclk0"),
91*4882a593Smuzhiyun VIR("dclk1"),
92*4882a593Smuzhiyun VIR("dclk2"),
93*4882a593Smuzhiyun VIR("dclk3"),
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun MUX("port0_dclk_src", mux_port0_dclk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
96*4882a593Smuzhiyun DIV("dclk_core0", "port0_dclk_src", CLK_SET_RATE_PARENT, 2),
97*4882a593Smuzhiyun DIV("dclk_out0", "port0_dclk_src", CLK_SET_RATE_PARENT, 2),
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun FACTOR("port1_dclk_src", "dclk1", CLK_SET_RATE_PARENT),
100*4882a593Smuzhiyun DIV("dclk_core1", "port1_dclk_src", CLK_SET_RATE_PARENT, 2),
101*4882a593Smuzhiyun DIV("dclk_out1", "port1_dclk_src", CLK_SET_RATE_PARENT, 2),
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun MUX("port2_dclk_src", mux_port2_dclk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
104*4882a593Smuzhiyun DIV("dclk_core2", "port2_dclk_src", CLK_SET_RATE_PARENT, 2),
105*4882a593Smuzhiyun DIV("dclk_out2", "port2_dclk_src", CLK_SET_RATE_PARENT, 2),
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun FACTOR("port3_dclk_src", "dclk3", CLK_SET_RATE_PARENT),
108*4882a593Smuzhiyun DIV("dclk_core3", "port3_dclk_src", CLK_SET_RATE_PARENT, 2),
109*4882a593Smuzhiyun DIV("dclk_out3", "port3_dclk_src", CLK_SET_RATE_PARENT, 2),
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun MUX("dp0_pixclk", mux_dp_pixclk_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
112*4882a593Smuzhiyun MUX("dp1_pixclk", mux_dp_pixclk_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun MUX("hdmi_edp0_clk_src", mux_hdmi_edp_clk_src_p,
115*4882a593Smuzhiyun CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
116*4882a593Smuzhiyun DIV("hdmi_edp0_dclk", "hdmi_edp0_clk_src", 0, 2),
117*4882a593Smuzhiyun DIV("hdmi_edp0_pixclk", "hdmi_edp0_clk_src", CLK_SET_RATE_PARENT, 1),
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun MUX("hdmi_edp1_clk_src", mux_hdmi_edp_clk_src_p,
120*4882a593Smuzhiyun CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
121*4882a593Smuzhiyun DIV("hdmi_edp1_dclk", "hdmi_edp1_clk_src", 0, 2),
122*4882a593Smuzhiyun DIV("hdmi_edp1_pixclk", "hdmi_edp1_clk_src", CLK_SET_RATE_PARENT, 1),
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun MUX("mipi0_clk_src", mux_mipi_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
125*4882a593Smuzhiyun DIV("mipi0_pixclk", "mipi0_clk_src", CLK_SET_RATE_PARENT, 2),
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun MUX("mipi1_clk_src", mux_mipi_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
128*4882a593Smuzhiyun DIV("mipi1_pixclk", "mipi1_clk_src", CLK_SET_RATE_PARENT, 2),
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun FACTOR("rgb_pixclk", "port3_dclk_src", CLK_SET_RATE_PARENT),
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun MUX("dsc_8k_txp_clk_src", mux_dsc_8k_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
133*4882a593Smuzhiyun DIV("dsc_8k_txp_clk", "dsc_8k_txp_clk_src", 0, 2),
134*4882a593Smuzhiyun DIV("dsc_8k_pxl_clk", "dsc_8k_txp_clk_src", 0, 2),
135*4882a593Smuzhiyun DIV("dsc_8k_cds_clk", "dsc_8k_txp_clk_src", 0, 2),
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun MUX("dsc_4k_txp_clk_src", mux_dsc_4k_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
138*4882a593Smuzhiyun DIV("dsc_4k_txp_clk", "dsc_4k_txp_clk_src", 0, 2),
139*4882a593Smuzhiyun DIV("dsc_4k_pxl_clk", "dsc_4k_txp_clk_src", 0, 2),
140*4882a593Smuzhiyun DIV("dsc_4k_cds_clk", "dsc_4k_txp_clk_src", 0, 2),
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun
clk_virtual_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)143*4882a593Smuzhiyun static unsigned long clk_virtual_recalc_rate(struct clk_hw *hw,
144*4882a593Smuzhiyun unsigned long parent_rate)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun struct vop2_clk *vop2_clk = to_vop2_clk(hw);
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun return (unsigned long)vop2_clk->rate;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
clk_virtual_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)151*4882a593Smuzhiyun static long clk_virtual_round_rate(struct clk_hw *hw, unsigned long rate,
152*4882a593Smuzhiyun unsigned long *prate)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun struct vop2_clk *vop2_clk = to_vop2_clk(hw);
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun vop2_clk->rate = rate;
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun cru_dbg("%s rate: %ld\n", clk_hw_get_name(hw), rate);
159*4882a593Smuzhiyun return rate;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
clk_virtual_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)162*4882a593Smuzhiyun static int clk_virtual_set_rate(struct clk_hw *hw, unsigned long rate,
163*4882a593Smuzhiyun unsigned long parent_rate)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun return 0;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun const struct clk_ops clk_virtual_ops = {
169*4882a593Smuzhiyun .round_rate = clk_virtual_round_rate,
170*4882a593Smuzhiyun .set_rate = clk_virtual_set_rate,
171*4882a593Smuzhiyun .recalc_rate = clk_virtual_recalc_rate,
172*4882a593Smuzhiyun };
173*4882a593Smuzhiyun
vop2_mux_get_parent(struct clk_hw * hw)174*4882a593Smuzhiyun static u8 vop2_mux_get_parent(struct clk_hw *hw)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun struct vop2_clk *vop2_clk = to_vop2_clk(hw);
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun cru_dbg("%s index: %d\n", clk_hw_get_name(hw), vop2_clk->parent_index);
179*4882a593Smuzhiyun return vop2_clk->parent_index;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
vop2_mux_set_parent(struct clk_hw * hw,u8 index)182*4882a593Smuzhiyun static int vop2_mux_set_parent(struct clk_hw *hw, u8 index)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun struct vop2_clk *vop2_clk = to_vop2_clk(hw);
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun vop2_clk->parent_index = index;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun cru_dbg("%s index: %d\n", clk_hw_get_name(hw), index);
189*4882a593Smuzhiyun return 0;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
vop2_clk_mux_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)192*4882a593Smuzhiyun static int vop2_clk_mux_determine_rate(struct clk_hw *hw,
193*4882a593Smuzhiyun struct clk_rate_request *req)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun cru_dbg("%s %ld(min: %ld max: %ld)\n",
196*4882a593Smuzhiyun clk_hw_get_name(hw), req->rate, req->min_rate, req->max_rate);
197*4882a593Smuzhiyun return __clk_mux_determine_rate(hw, req);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun static const struct clk_ops vop2_mux_clk_ops = {
201*4882a593Smuzhiyun .get_parent = vop2_mux_get_parent,
202*4882a593Smuzhiyun .set_parent = vop2_mux_set_parent,
203*4882a593Smuzhiyun .determine_rate = vop2_clk_mux_determine_rate,
204*4882a593Smuzhiyun };
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun #define div_mask(width) ((1 << (width)) - 1)
207*4882a593Smuzhiyun
vop2_div_get_val(unsigned long rate,unsigned long parent_rate)208*4882a593Smuzhiyun static int vop2_div_get_val(unsigned long rate, unsigned long parent_rate)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun unsigned int div, value;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun value = ilog2(div);
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun return value;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
vop2_clk_div_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)219*4882a593Smuzhiyun static unsigned long vop2_clk_div_recalc_rate(struct clk_hw *hw,
220*4882a593Smuzhiyun unsigned long parent_rate)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun struct vop2_clk *vop2_clk = to_vop2_clk(hw);
223*4882a593Smuzhiyun unsigned long rate;
224*4882a593Smuzhiyun unsigned int div;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun div = 1 << vop2_clk->div_val;
227*4882a593Smuzhiyun rate = parent_rate / div;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun cru_dbg("%s rate: %ld(prate: %ld)\n", clk_hw_get_name(hw), rate, parent_rate);
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun return rate;
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
vop2_clk_div_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)234*4882a593Smuzhiyun static long vop2_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
235*4882a593Smuzhiyun unsigned long *prate)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun struct vop2_clk *vop2_clk = to_vop2_clk(hw);
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
240*4882a593Smuzhiyun if (*prate < rate)
241*4882a593Smuzhiyun *prate = rate;
242*4882a593Smuzhiyun if ((*prate >> vop2_clk->div.width) > rate)
243*4882a593Smuzhiyun *prate = rate;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun if ((*prate % rate))
246*4882a593Smuzhiyun *prate = rate;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun cru_dbg("%s rate: %ld(prate: %ld)\n", clk_hw_get_name(hw), rate, *prate);
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun return rate;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
vop2_clk_div_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)254*4882a593Smuzhiyun static int vop2_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun struct vop2_clk *vop2_clk = to_vop2_clk(hw);
257*4882a593Smuzhiyun int div_val;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun div_val = vop2_div_get_val(rate, parent_rate);
260*4882a593Smuzhiyun vop2_clk->div_val = div_val;
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun cru_dbg("%s prate: %ld rate: %ld div_val: %d\n",
263*4882a593Smuzhiyun clk_hw_get_name(hw), parent_rate, rate, div_val);
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun return 0;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun static const struct clk_ops vop2_div_clk_ops = {
269*4882a593Smuzhiyun .recalc_rate = vop2_clk_div_recalc_rate,
270*4882a593Smuzhiyun .round_rate = vop2_clk_div_round_rate,
271*4882a593Smuzhiyun .set_rate = vop2_clk_div_set_rate,
272*4882a593Smuzhiyun };
273*4882a593Smuzhiyun
vop2_clk_register(struct vop2 * vop2,struct vop2_clk_branch * branch)274*4882a593Smuzhiyun static struct clk *vop2_clk_register(struct vop2 *vop2, struct vop2_clk_branch *branch)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun struct clk_init_data init = {};
277*4882a593Smuzhiyun struct vop2_clk *vop2_clk;
278*4882a593Smuzhiyun struct clk *clk;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun vop2_clk = devm_kzalloc(vop2->dev, sizeof(*vop2_clk), GFP_KERNEL);
281*4882a593Smuzhiyun if (!vop2_clk)
282*4882a593Smuzhiyun return ERR_PTR(-ENOMEM);
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun vop2_clk->vop2 = vop2;
285*4882a593Smuzhiyun vop2_clk->hw.init = &init;
286*4882a593Smuzhiyun vop2_clk->div.shift = branch->div_shift;
287*4882a593Smuzhiyun vop2_clk->div.width = branch->div_width;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun init.name = branch->name;
290*4882a593Smuzhiyun init.flags = branch->flags;
291*4882a593Smuzhiyun init.num_parents = branch->num_parents;
292*4882a593Smuzhiyun init.parent_names = branch->parent_names;
293*4882a593Smuzhiyun if (branch->branch_type == branch_divider) {
294*4882a593Smuzhiyun init.ops = &vop2_div_clk_ops;
295*4882a593Smuzhiyun } else if (branch->branch_type == branch_virtual) {
296*4882a593Smuzhiyun init.ops = &clk_virtual_ops;
297*4882a593Smuzhiyun init.num_parents = 0;
298*4882a593Smuzhiyun init.parent_names = NULL;
299*4882a593Smuzhiyun } else {
300*4882a593Smuzhiyun init.ops = &vop2_mux_clk_ops;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun clk = devm_clk_register(vop2->dev, &vop2_clk->hw);
304*4882a593Smuzhiyun if (!IS_ERR(clk))
305*4882a593Smuzhiyun list_add_tail(&vop2_clk->list, &vop2->clk_list_head);
306*4882a593Smuzhiyun else
307*4882a593Smuzhiyun DRM_DEV_ERROR(vop2->dev, "Register %s failed\n", branch->name);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun return clk;
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
vop2_clk_init(struct vop2 * vop2)312*4882a593Smuzhiyun static int vop2_clk_init(struct vop2 *vop2)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun struct vop2_clk_branch *branch = rk3588_vop_clk_branches;
315*4882a593Smuzhiyun unsigned int nr_clk = ARRAY_SIZE(rk3588_vop_clk_branches);
316*4882a593Smuzhiyun unsigned int idx;
317*4882a593Smuzhiyun struct vop2_clk *clk, *n;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun INIT_LIST_HEAD(&vop2->clk_list_head);
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun if (vop2->version != VOP_VERSION_RK3588)
322*4882a593Smuzhiyun return 0;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun list_for_each_entry_safe(clk, n, &vop2->clk_list_head, list) {
325*4882a593Smuzhiyun list_del(&clk->list);
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun for (idx = 0; idx < nr_clk; idx++, branch++)
329*4882a593Smuzhiyun vop2_clk_register(vop2, branch);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun return 0;
332*4882a593Smuzhiyun }
333