d198c73001a7e6e45b2ad6a194993f8f85830b4d
[firefly-linux-kernel-4.4.55.git] / drivers / clk / rk / clk.c
1 /*
2  * Copyright (C) 2013 ROCKCHIP, Inc.
3  * Author: chenxing <chenxing@rock-chips.com>
4  *         Dai Kelin <dkl@rock-chips.com>
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/clk-provider.h>
18 #include <linux/clkdev.h>
19 #include <linux/of.h>
20 #include <linux/of_address.h>
21 #include <linux/clk-private.h>
22 #include <asm/io.h>
23
24 #include "clk-ops.h"
25 #include "clk-pll.h"
26 #include "clk-pd.h"
27
28 static void __iomem *rk_cru_base;
29 static void __iomem *rk_grf_base;
30
31 u32 cru_readl(u32 offset)
32 {
33         return readl_relaxed(rk_cru_base + (offset));
34 }
35
36 void cru_writel(u32 val, u32 offset)
37 {
38         writel_relaxed(val, rk_cru_base + (offset));
39         dsb(sy);
40 }
41
42 u32 grf_readl(u32 offset)
43 {
44         return readl_relaxed(rk_grf_base + (offset));
45 }
46
47 struct rkclk_muxinfo {
48         const char              *clk_name;
49         struct device_node      *np;
50         struct clk_mux          *mux;
51         u8                      parent_num;
52         const char              **parent_names;
53         u32                     clkops_idx;
54 };
55
56 struct rkclk_divinfo {
57         const char              *clk_name;
58         struct device_node      *np;
59         struct clk_divider      *div;
60         u32                     div_type;
61         const char              *parent_name;
62         u32                     clkops_idx;
63 };
64
65 struct rkclk_fracinfo {
66         const char              *clk_name;
67         struct device_node      *np;
68         struct clk_divider      *frac;
69         u32                     frac_type;
70         const char              *parent_name;
71         u32                     clkops_idx;
72 };
73
74 struct rkclk_gateinfo {
75         const char              *clk_name;
76         struct device_node      *np;
77         struct clk_gate         *gate;
78         const char              *parent_name;
79         //u32                   clkops_idx;
80 };
81
82 struct rkclk_pllinfo {
83         const char              *clk_name;
84         struct device_node      *np;
85         struct clk_pll          *pll;
86         const char              *parent_name;
87         u32                     clkops_idx;
88 };
89
90 struct rkclk_fixed_rate_info {
91         const char              *clk_name;
92         struct device_node      *np;
93         struct clk_fixed_rate   *fixed_rate;
94         const char              *parent_name;
95 };
96
97 struct rkclk_fixed_factor_info {
98         const char              *clk_name;
99         struct device_node      *np;
100         struct clk_fixed_factor   *fixed_factor;
101         const char              *parent_name;
102 };
103
104 struct rkclk_pd_info {
105         const char              *clk_name;
106         struct device_node      *np;
107         struct clk_pd           *pd;
108         const char              *parent_name;
109 };
110
111
112 struct rkclk {
113         const char              *clk_name;
114         //struct device_node    *np;
115         u32                     clk_type;
116         u32                     flags;
117         struct rkclk_muxinfo    *mux_info;
118         struct rkclk_divinfo    *div_info;
119         struct rkclk_fracinfo   *frac_info;
120         struct rkclk_pllinfo    *pll_info;
121         struct rkclk_gateinfo   *gate_info;
122         struct rkclk_fixed_rate_info *fixed_rate_info;
123         struct rkclk_fixed_factor_info *fixed_factor_info;
124         struct rkclk_pd_info    *pd_info;
125         struct list_head        node;
126 };
127
128 static DEFINE_SPINLOCK(clk_lock);
129 LIST_HEAD(rk_clks);
130
131 #define RKCLK_PLL_TYPE          (1 << 0)
132 #define RKCLK_MUX_TYPE          (1 << 1)
133 #define RKCLK_DIV_TYPE          (1 << 2)
134 #define RKCLK_FRAC_TYPE         (1 << 3)
135 #define RKCLK_GATE_TYPE         (1 << 4)
136 #define RKCLK_FIXED_RATE_TYPE   (1 << 5)
137 #define RKCLK_FIXED_FACTOR_TYPE (1 << 6)
138 #define RKCLK_PD_TYPE           (1 << 7)
139
140
141 static int rkclk_init_muxinfo(struct device_node *np, void __iomem *addr)
142 {
143         struct rkclk_muxinfo *muxinfo = NULL;
144         struct clk_mux *mux = NULL;
145         u32 shift, width;
146         u32 flags;
147         int cnt, i, ret = 0;
148         u8 found = 0;
149         struct rkclk *rkclk = NULL;
150
151
152         muxinfo = kzalloc(sizeof(struct rkclk_muxinfo), GFP_KERNEL);
153         if (!muxinfo) {
154                 ret = -ENOMEM;
155                 goto out;
156         }
157
158         muxinfo->mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
159         if (!muxinfo->mux) {
160                 ret = -ENOMEM;
161                 goto out;
162         }
163         mux = muxinfo->mux;
164
165         ret = of_property_read_string(np, "clock-output-names",
166                         &muxinfo->clk_name);
167         if (ret != 0)
168                 goto out;
169
170         muxinfo->np = np;
171
172         cnt = of_count_phandle_with_args(np, "clocks", "#clock-cells");
173         if (cnt < 0) {
174                 ret = -EINVAL;
175                 goto out;
176         } else {
177                 clk_debug("%s: parent cnt = %d\n", __func__, cnt);
178                 muxinfo->parent_num = (u8)cnt;
179         }
180
181         muxinfo->parent_names = kzalloc(cnt * sizeof(char *), GFP_KERNEL);
182         for (i = 0; i < cnt ; i++) {
183                 muxinfo->parent_names[i] = of_clk_get_parent_name(np, i);
184         }
185
186         mux->reg = addr;
187
188         ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
189         if (ret != 0) {
190                 goto out;
191         } else {
192                 mux->shift = (u8)shift;
193         }
194
195         ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
196         if (ret != 0)
197                 goto out;
198         mux->mask = (1 << width) - 1;
199
200         mux->flags = CLK_MUX_HIWORD_MASK;
201
202         ret = of_property_read_u32(np, "rockchip,clkops-idx",
203                         &muxinfo->clkops_idx);
204         if (ret != 0) {
205                 muxinfo->clkops_idx = CLKOPS_TABLE_END;
206                 ret = 0;
207         }
208
209         ret = of_property_read_u32(np, "rockchip,flags", &flags);
210         if (ret != 0) {
211                 flags = 0;
212                 ret = 0;
213         }
214
215         found = 0;
216         list_for_each_entry(rkclk, &rk_clks, node) {
217                 if (strcmp(muxinfo->clk_name, rkclk->clk_name) == 0) {
218                         if (rkclk->mux_info != NULL) {
219                                 clk_err("%s %d:\n", __func__, __LINE__);
220                                 clk_err("This clk(%s) has been used,"
221                                                 "will be overwrited here!\n",
222                                                 rkclk->clk_name);
223                         }
224                         clk_debug("%s: find match %s\n", __func__,
225                                         rkclk->clk_name);
226                         found = 1;
227                         rkclk->mux_info = muxinfo;
228                         rkclk->clk_type |= RKCLK_MUX_TYPE;
229                         rkclk->flags |= flags;
230                         break;
231                 }
232         }
233
234         if (!found) {
235                 rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
236                 if (!rkclk) {
237                         ret = -ENOMEM;
238                         goto out;
239                 }
240                 rkclk->clk_name = muxinfo->clk_name;
241                 rkclk->mux_info = muxinfo;
242                 rkclk->clk_type = RKCLK_MUX_TYPE;
243                 rkclk->flags = flags;
244                 clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
245                 list_add_tail(&rkclk->node, &rk_clks);
246         }
247
248 out:
249         if (ret) {
250                 clk_err("%s error, ret = %d\n", __func__, ret);
251                 if (muxinfo) {
252                         if (muxinfo->mux)
253                                 kfree(muxinfo->mux);
254                         kfree(muxinfo);
255                 }
256                 if (rkclk)
257                         kfree(rkclk);
258         }
259
260         return ret;
261 }
262
263 static int rkclk_init_divinfo(struct device_node *np, void __iomem *addr)
264 {
265         int cnt = 0, i = 0, ret = 0;
266         struct rkclk *rkclk = NULL;
267         u8 found = 0;
268         u32 flags;
269         u32 shift, width;
270         struct rkclk_divinfo *divinfo = NULL;
271         struct clk_divider *div = NULL;
272         struct clk_div_table    *table;
273         u32 table_val, table_div;
274
275
276         divinfo = kzalloc(sizeof(struct rkclk_divinfo), GFP_KERNEL);
277         if (!divinfo) {
278                 ret = -ENOMEM;
279                 goto out;
280         }
281
282         divinfo->div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
283         if (!divinfo->div) {
284                 ret = -ENOMEM;
285                 goto out;
286         }
287         div = divinfo->div;
288
289         ret = of_property_read_string(np, "clock-output-names",
290                         &divinfo->clk_name);
291         if (ret != 0)
292                 goto out;
293
294         divinfo->parent_name = of_clk_get_parent_name(np, 0);
295
296         divinfo->np = np;
297
298         ret = of_property_read_u32(np, "rockchip,clkops-idx",
299                         &divinfo->clkops_idx);
300         if (ret != 0) {
301                 divinfo->clkops_idx = CLKOPS_TABLE_END;
302                 ret = 0;
303         }
304
305         ret = of_property_read_u32(np, "rockchip,flags", &flags);
306         if (ret != 0) {
307                 flags = 0;
308                 ret = 0;
309         }
310
311         ret = of_property_read_u32(np, "rockchip,div-type", &divinfo->div_type);
312         if (ret != 0)
313                 goto out;
314
315         switch (divinfo->div_type) {
316                 case CLK_DIVIDER_PLUS_ONE:
317                 case CLK_DIVIDER_ONE_BASED:
318                 case CLK_DIVIDER_POWER_OF_TWO:
319                         break;
320                 case CLK_DIVIDER_USER_DEFINE:
321                         of_get_property(np, "rockchip,div-relations", &cnt);
322                         if (cnt <= 0) {
323                                 ret = -EINVAL;
324                                 goto out;
325                         }
326                         cnt /= 4 * 2;
327                         table = kzalloc(cnt * sizeof(struct clk_div_table),
328                                         GFP_KERNEL);
329                         if (!table) {
330                                 ret = -ENOMEM;
331                                 goto out;
332                         }
333                         for (i = 0; i < cnt; i++) {
334                                 ret = of_property_read_u32_index(np,
335                                                 "rockchip,div-relations", i * 2,
336                                                 &table_val);
337                                 if (ret)
338                                         goto out;
339                                 ret = of_property_read_u32_index(np,
340                                                 "rockchip,div-relations",
341                                                 i * 2 + 1, &table_div);
342                                 if (ret)
343                                         goto out;
344                                 table[i].val = (unsigned int)table_val;
345                                 table[i].div = (unsigned int)table_div;
346                                 clk_debug("\tGet div table %d: val=%d, div=%d\n",
347                                                 i, table_val, table_div);
348                         }
349                         div->table = table;
350                         break;
351                 default:
352                         clk_err("%s: %s: unknown rockchip,div-type\n", __func__,
353                                         divinfo->clk_name);
354                         ret = -EINVAL;
355                         goto out;
356         }
357
358         div->reg = addr;
359         ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
360         if (ret)
361                 goto out;
362         ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
363         if (ret)
364                 goto out;
365         div->shift = (u8)shift;
366         div->width = (u8)width;
367         div->flags = CLK_DIVIDER_HIWORD_MASK | divinfo->div_type;
368
369         found = 0;
370         list_for_each_entry(rkclk, &rk_clks, node) {
371                 if (strcmp(divinfo->clk_name, rkclk->clk_name) == 0) {
372                         if (rkclk->div_info != NULL) {
373                                 clk_err("%s %d:\n", __func__, __LINE__);
374                                 clk_err("This clk(%s) has been used,"
375                                                 "will be overwrited here!\n",
376                                                 rkclk->clk_name);
377                         }
378                         clk_debug("%s: find match %s\n", __func__,
379                                         rkclk->clk_name);
380                         found = 1;
381                         rkclk->div_info = divinfo;
382                         rkclk->clk_type |= RKCLK_DIV_TYPE;
383                         rkclk->flags |= flags;
384                         break;
385                 }
386         }
387
388         if (!found) {
389                 rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
390                 if (!rkclk) {
391                         ret = -ENOMEM;
392                         goto out;
393                 }
394                 rkclk->clk_name = divinfo->clk_name;
395                 rkclk->div_info = divinfo;
396                 rkclk->clk_type = RKCLK_DIV_TYPE;
397                 rkclk->flags = flags;
398                 clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
399                 list_add_tail(&rkclk->node, &rk_clks);
400         }
401
402 out:
403         if (ret) {
404                 clk_err("%s error, ret = %d\n", __func__, ret);
405                 if(table)
406                         kfree(table);
407                 if (divinfo) {
408                         if (divinfo->div)
409                                 kfree(divinfo->div);
410                         kfree(divinfo);
411                 }
412                 if (rkclk)
413                         kfree(rkclk);
414         }
415
416         return ret;
417 }
418
419 static int rkclk_init_fracinfo(struct device_node *np, void __iomem *addr)
420 {
421         struct rkclk *rkclk = NULL;
422         u8 found = 0;
423         int ret = 0;
424         struct rkclk_fracinfo *fracinfo = NULL;
425         struct clk_divider *frac = NULL;
426         u32 shift, width, flags;
427
428
429         fracinfo = kzalloc(sizeof(struct rkclk_fracinfo), GFP_KERNEL);
430         if (!fracinfo) {
431                 ret = -ENOMEM;
432                 goto out;
433         }
434
435         fracinfo->frac = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
436         if (!fracinfo->frac) {
437                 ret = -ENOMEM;
438                 goto out;
439         }
440         frac = fracinfo->frac;
441
442         ret = of_property_read_string(np, "clock-output-names",
443                         &fracinfo->clk_name);
444         if (ret != 0)
445                 goto out;
446
447         fracinfo->parent_name = of_clk_get_parent_name(np, 0);
448         fracinfo->np = np;
449
450         ret = of_property_read_u32(np, "rockchip,clkops-idx",
451                         &fracinfo->clkops_idx);
452         if (ret != 0) {
453                 fracinfo->clkops_idx = CLKOPS_TABLE_END;
454                 clk_err("frac node without specified ops!\n");
455                 ret = -EINVAL;
456                 goto out;
457         }
458
459         ret = of_property_read_u32(np, "rockchip,flags", &flags);
460         if (ret != 0) {
461                 clk_debug("if not specified, frac use CLK_SET_RATE_PARENT flag "
462                                 "as default\n");
463                 flags = CLK_SET_RATE_PARENT;
464                 ret = 0;
465         }
466
467         frac->reg = addr;
468         ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
469         if (ret)
470                 goto out;
471         ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
472         if (ret)
473                 goto out;
474         frac->shift = (u8)shift;
475         frac->width = (u8)width;
476         frac->flags = 0;
477
478         found = 0;
479         list_for_each_entry(rkclk, &rk_clks, node) {
480                 if (strcmp(fracinfo->clk_name, rkclk->clk_name) == 0) {
481                         if (rkclk->frac_info != NULL) {
482                                 clk_err("%s %d:\n", __func__, __LINE__);
483                                 clk_err("This clk(%s) has been used,"
484                                                 "will be overwrited here!\n",
485                                                 rkclk->clk_name);
486                         }
487                         clk_debug("%s: find match %s\n", __func__,
488                                         rkclk->clk_name);
489                         found = 1;
490                         rkclk->frac_info = fracinfo;
491                         rkclk->clk_type |= RKCLK_FRAC_TYPE;
492                         rkclk->flags |= flags;
493                         break;
494                 }
495         }
496
497         if (!found) {
498                 rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
499                 if (!rkclk) {
500                         ret = -ENOMEM;
501                         goto out;
502                 }
503                 rkclk->clk_name = fracinfo->clk_name;
504                 rkclk->frac_info = fracinfo;
505                 rkclk->clk_type = RKCLK_FRAC_TYPE;
506                 rkclk->flags = flags;
507                 clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
508                 list_add_tail(&rkclk->node, &rk_clks);
509         }
510
511 out:
512         if (ret) {
513                 clk_err("%s error, ret = %d\n", __func__, ret);
514                 if (fracinfo) {
515                         if (fracinfo->frac)
516                                 kfree(fracinfo->frac);
517                         kfree(fracinfo);
518                 }
519                 if (rkclk)
520                         kfree(rkclk);
521         }
522
523         return ret;
524 }
525
526 static int __init rkclk_init_selcon(struct device_node *np)
527 {
528         struct device_node *node_con, *node;
529         void __iomem *reg = 0;
530         int ret = 0;
531
532
533         for_each_available_child_of_node(np, node_con) {
534                 reg = of_iomap(node_con, 0);
535                 clk_debug("\n");
536                 clk_debug("%s: reg = 0x%x\n", __func__, (u32)reg);
537
538                 for_each_available_child_of_node(node_con, node) {
539                         clk_debug("\n");
540                         if (of_device_is_compatible(node,
541                                                 "rockchip,rk3188-div-con"))
542                                 ret = rkclk_init_divinfo(node, reg);
543
544                         else if (of_device_is_compatible(node,
545                                                 "rockchip,rk3188-mux-con"))
546                                 ret = rkclk_init_muxinfo(node, reg);
547
548                         else if (of_device_is_compatible(node,
549                                                 "rockchip,rk3188-frac-con"))
550                                 ret = rkclk_init_fracinfo(node, reg);
551
552                         else if (of_device_is_compatible(node,
553                                                 "rockchip,rk3188-inv-con"))
554                                 clk_debug("INV clk\n");
555
556                         else {
557                                 clk_err("%s: unknown controller type\n",
558                                                 __func__);
559                                 ret = -EINVAL;
560                         }
561                 }
562         }
563
564         return ret;
565 }
566
567 static int __init rkclk_init_gatecon(struct device_node *np)
568 {
569         struct device_node *node;
570         const char *clk_name;
571         void __iomem *reg;
572         int cnt;
573         int i;
574         struct rkclk_gateinfo *gateinfo;
575         u8 found = 0;
576         struct rkclk *rkclk;
577         int ret = 0;
578         struct clk_gate *gate = NULL;
579
580
581         for_each_available_child_of_node(np, node) {
582                 cnt = of_property_count_strings(node, "clock-output-names");
583                 if (cnt < 0) {
584                         clk_err("%s: error in clock-output-names %d\n",
585                                         __func__, cnt);
586                         continue;
587                 }
588
589                 if (cnt == 0) {
590                         clk_debug("%s: nothing to do\n", __func__);
591                         continue;
592                 }
593
594                 reg = of_iomap(node, 0);
595                 clk_debug("\n");
596                 clk_debug("%s: reg = 0x%x\n", __func__, (u32)reg);
597
598                 for (i = 0; i < cnt; i++) {
599                         ret = of_property_read_string_index(node,
600                                         "clock-output-names", i, &clk_name);
601                         if (ret != 0)
602                                 goto out;
603
604                         /* ignore empty slots */
605                         if (!strcmp("reserved", clk_name)) {
606                                 clk_debug("do nothing for reserved clk\n");
607                                 continue;
608                         }
609
610                         gateinfo = kzalloc(sizeof(struct rkclk_gateinfo),
611                                         GFP_KERNEL);
612                         if (!gateinfo) {
613                                 ret = -ENOMEM;
614                                 goto out;
615                         }
616
617                         gateinfo->gate = kzalloc(sizeof(struct clk_gate),
618                                         GFP_KERNEL);
619                         if (!gateinfo->gate) {
620                                 ret = -ENOMEM;
621                                 goto out;
622                         }
623                         gate = gateinfo->gate;
624
625                         gateinfo->clk_name = clk_name;
626                         gateinfo->parent_name = of_clk_get_parent_name(node, i);
627                         gateinfo->np = node;
628
629                         gate->reg = reg;
630                         gate->bit_idx = (i % 16);
631                         gate->flags = CLK_GATE_HIWORD_MASK |
632                                 CLK_GATE_SET_TO_DISABLE;
633
634                         found = 0;
635                         list_for_each_entry(rkclk, &rk_clks, node) {
636                                 if (strcmp(clk_name, rkclk->clk_name) == 0) {
637                                         if (rkclk->gate_info != NULL) {
638                                                 clk_err("%s %d:\n", __func__,
639                                                                 __LINE__);
640                                                 clk_err("This clk(%s) has been used,"
641                                                                 "will be overwrited here!\n",
642                                                                 rkclk->clk_name);
643                                         }
644                                         clk_debug("%s: find match %s\n",
645                                                         __func__, rkclk->clk_name);
646                                         found = 1;
647                                         rkclk->gate_info = gateinfo;
648                                         rkclk->clk_type |= RKCLK_GATE_TYPE;
649                                         break;
650                                 }
651                         }
652                         if (!found) {
653                                 rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
654                                 if (!rkclk) {
655                                         ret = -ENOMEM;
656                                         goto out;
657                                 }
658                                 rkclk->clk_name = gateinfo->clk_name;
659                                 rkclk->gate_info = gateinfo;
660                                 rkclk->clk_type = RKCLK_GATE_TYPE;
661                                 clk_debug("%s: creat %s\n", __func__,
662                                                 rkclk->clk_name);
663                                 list_add_tail(&rkclk->node, &rk_clks);
664                         }
665
666 out:
667                         if (ret) {
668                                 clk_err("%s error, ret = %d\n", __func__, ret);
669                                 if (gateinfo) {
670                                         if (gateinfo->gate)
671                                                 kfree(gateinfo->gate);
672                                         kfree(gateinfo);
673                                 }
674                                 if (rkclk)
675                                         kfree(rkclk);
676                         }
677                 }
678
679         }
680
681         return 0;
682 }
683
684 static int __init rkclk_init_pllcon(struct device_node *np)
685 {
686         struct device_node *node = NULL;
687         struct rkclk_pllinfo *pllinfo = NULL;
688         struct clk_pll *pll = NULL;
689         u8 found = 0;
690         int ret = 0;
691         struct rkclk *rkclk = NULL;
692         u32 flags;
693         u32 mode_shift, status_shift;
694
695
696         for_each_available_child_of_node(np, node) {
697                 pllinfo = kzalloc(sizeof(struct rkclk_pllinfo), GFP_KERNEL);
698                 if (!pllinfo) {
699                         ret = -ENOMEM;
700                         goto out;
701                 }
702
703                 pllinfo->pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
704                 if (!pllinfo->pll) {
705                         ret = -ENOMEM;
706                         goto out;
707                 }
708                 pll = pllinfo->pll;
709
710                 pllinfo->np = node;
711
712                 ret = of_property_read_string_index(node, "clock-output-names",
713                                 0, &pllinfo->clk_name);
714                 if (ret)
715                         goto out;
716
717                 pllinfo->parent_name = of_clk_get_parent_name(node, 0);
718
719                 ret = of_property_read_u32(np, "rockchip,flags", &flags);
720                 if (ret != 0) {
721                         flags = 0;
722                         ret = 0;
723                 }
724         
725                 ret = of_property_read_u32_index(node, "reg", 0, &pll->reg);
726                 if (ret != 0) {
727                         clk_err("%s: can not get reg addr info\n", __func__);
728                         goto out;
729                 }
730
731                 ret = of_property_read_u32_index(node, "reg", 1, &pll->width);
732                 if (ret != 0) {
733                         clk_err("%s: can not get reg length info\n", __func__);
734                         goto out;
735                 }
736
737                 ret = of_property_read_u32_index(node, "mode-reg", 0,
738                                 &pll->mode_offset);
739                 if (ret != 0) {
740                         clk_err("%s: can not get mode_reg offset\n", __func__);
741                         goto out;
742                 }
743
744                 ret = of_property_read_u32_index(node, "mode-reg", 1,
745                                 &mode_shift);
746                 if (ret != 0) {
747                         clk_err("%s: can not get mode_reg shift\n", __func__);
748                         goto out;
749                 } else {
750                         pll->mode_shift = (u8)mode_shift;
751                 }
752
753                 ret = of_property_read_u32_index(node, "status-reg", 0,
754                                 &pll->status_offset);
755                 if (ret != 0) {
756                         clk_err("%s: can not get status_reg offset\n", __func__);
757                         goto out;
758                 }
759
760                 ret = of_property_read_u32_index(node, "status-reg", 1,
761                                 &status_shift);
762                 if (ret != 0) {
763                         clk_err("%s: can not get status_reg shift\n", __func__);
764                         goto out;
765                 } else {
766                         pll->status_shift= (u8)status_shift;
767                 }
768
769                 ret = of_property_read_u32(node, "rockchip,pll-type", &pll->flags);
770                 if (ret != 0) {
771                         clk_err("%s: can not get pll-type\n", __func__);
772                         goto out;
773                 }
774
775                 clk_debug("%s: pllname=%s, parent=%s, flags=0x%x\n",
776                                 __func__, pllinfo->clk_name,
777                                 pllinfo->parent_name, flags);
778
779                 clk_debug("\t\taddr=0x%x, len=0x%x, mode:offset=0x%x, shift=0x%x,"
780                                 " status:offset=0x%x, shift=0x%x, pll->flags=0x%x\n",
781                                 (u32)pll->reg, pll->width,
782                                 pll->mode_offset, pll->mode_shift,
783                                 pll->status_offset, pll->status_shift,
784                                 pll->flags);
785
786                 found = 0;
787                 list_for_each_entry(rkclk, &rk_clks, node) {
788                         if (strcmp(pllinfo->clk_name, rkclk->clk_name) == 0) {
789                                 if (rkclk->pll_info != NULL) {
790                                         clk_err("%s %d:\n", __func__, __LINE__);
791                                         clk_err("This clk(%s) has been used,"
792                                                         "will be overwrited here!\n",
793                                                         rkclk->clk_name);
794                                 }
795                                 clk_debug("%s: find match %s\n", __func__,
796                                                 rkclk->clk_name);
797                                 found = 1;
798                                 rkclk->pll_info = pllinfo;
799                                 rkclk->clk_type |= RKCLK_PLL_TYPE;
800                                 rkclk->flags |= flags;
801                                 break;
802                         }
803                 }
804
805                 if (!found) {
806                         rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
807                         if (!rkclk) {
808                                 ret = -ENOMEM;
809                                 goto out;
810                         }
811                         rkclk->clk_name = pllinfo->clk_name;
812                         rkclk->pll_info = pllinfo;
813                         rkclk->clk_type = RKCLK_PLL_TYPE;
814                         rkclk->flags = flags;
815                         list_add_tail(&rkclk->node, &rk_clks);
816                 }
817         }
818
819 out:
820         if (ret) {
821                 clk_err("%s error, ret = %d\n", __func__, ret);
822                 if (pllinfo) {
823                         if (pllinfo->pll)
824                                 kfree(pllinfo->pll);
825                         kfree(pllinfo);
826                 }
827                 if (rkclk)
828                         kfree(rkclk);
829         }
830
831         return ret;
832 }
833
834 static int __init rkclk_init_fixed_rate(struct device_node *np)
835 {
836         struct device_node *node = NULL;
837         struct rkclk_fixed_rate_info *fixed_rate_info = NULL;
838         struct clk_fixed_rate *fixed_rate = NULL;
839         u32 rate;
840         int ret = 0;
841         u8 found = 0;
842         struct rkclk *rkclk = NULL;
843
844
845         for_each_available_child_of_node(np, node) {
846                 fixed_rate_info = kzalloc(sizeof(struct rkclk_fixed_rate_info),
847                         GFP_KERNEL);
848                 if (!fixed_rate_info) {
849                         ret = -ENOMEM;
850                         goto out;
851                 }
852
853                 fixed_rate_info->fixed_rate = kzalloc(sizeof(struct clk_fixed_rate),
854                         GFP_KERNEL);
855                 if (!fixed_rate_info->fixed_rate) {
856                         ret = -ENOMEM;
857                         goto out;
858                 }
859                 fixed_rate = fixed_rate_info->fixed_rate;
860
861                 fixed_rate_info->np = node;
862
863                 ret = of_property_read_string_index(node, "clock-output-names",
864                                 0, &fixed_rate_info->clk_name);
865                 if (ret)
866                         goto out;
867
868                 fixed_rate_info->parent_name = of_clk_get_parent_name(node, 0);
869
870                 ret = of_property_read_u32(node, "clock-frequency", &rate);
871                 if (ret != 0) {
872                         clk_err("%s: can not get clock-frequency\n", __func__);
873                         goto out;
874                 }
875                 fixed_rate->fixed_rate = (unsigned long)rate;
876
877                 found = 0;
878                 list_for_each_entry(rkclk, &rk_clks, node) {
879                         if (strcmp(fixed_rate_info->clk_name, rkclk->clk_name) == 0) {
880                                 if (rkclk->fixed_rate_info != NULL) {
881                                         clk_err("%s %d:\n", __func__, __LINE__);
882                                         clk_err("This clk(%s) has been used,"
883                                                         "will be overwrited here!\n",
884                                                         rkclk->clk_name);
885                                 }
886                                 clk_debug("%s: find match %s\n", __func__,
887                                                 rkclk->clk_name);
888                                 found = 1;
889                                 rkclk->fixed_rate_info = fixed_rate_info;
890                                 rkclk->clk_type |= RKCLK_FIXED_RATE_TYPE;
891                                 rkclk->flags |= CLK_IS_ROOT;
892                                 break;
893                         }
894                 }
895
896                 if (!found) {
897                         rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
898                         if (!rkclk) {
899                                 ret = -ENOMEM;
900                                 goto out;
901                         }
902                         rkclk->clk_name = fixed_rate_info->clk_name;
903                         rkclk->fixed_rate_info = fixed_rate_info;
904                         rkclk->clk_type = RKCLK_FIXED_RATE_TYPE;
905                         rkclk->flags = CLK_IS_ROOT;
906                         clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
907                         list_add_tail(&rkclk->node, &rk_clks);
908                 }
909         }
910
911 out:
912         if (ret) {
913                 clk_err("%s error, ret = %d\n", __func__, ret);
914                 if (fixed_rate_info) {
915                         if (fixed_rate_info->fixed_rate)
916                                 kfree(fixed_rate_info->fixed_rate);
917                         kfree(fixed_rate_info);
918                 }
919                 if (rkclk)
920                         kfree(rkclk);
921         }
922
923         return ret;
924 }
925
926 static int __init rkclk_init_fixed_factor(struct device_node *np)
927 {
928         struct device_node *node = NULL;
929         struct rkclk_fixed_factor_info *fixed_factor_info = NULL;
930         struct clk_fixed_factor *fixed_factor = NULL;
931         u32 flags, mult, div;
932         int ret = 0;
933         u8 found = 0;
934         struct rkclk *rkclk = NULL;
935
936
937         for_each_available_child_of_node(np, node) {
938                 fixed_factor_info = kzalloc(sizeof(struct rkclk_fixed_factor_info),
939                         GFP_KERNEL);
940                 if (!fixed_factor_info) {
941                         ret = -ENOMEM;
942                         goto out;
943                 }
944
945                 fixed_factor_info->fixed_factor = kzalloc(sizeof(struct clk_fixed_factor),
946                         GFP_KERNEL);
947                 if (!fixed_factor_info->fixed_factor) {
948                         ret = -ENOMEM;
949                         goto out;
950                 }
951                 fixed_factor = fixed_factor_info->fixed_factor;
952
953                 fixed_factor_info->np = node;
954
955                 ret = of_property_read_string_index(node, "clock-output-names",
956                                 0, &fixed_factor_info->clk_name);
957                 if (ret)
958                         goto out;
959
960                 fixed_factor_info->parent_name = of_clk_get_parent_name(node, 0);
961
962                 ret = of_property_read_u32(node, "rockchip,flags", &flags);
963                 if (ret != 0) {
964                         flags = 0;
965                         ret = 0;
966                 }
967
968                 ret = of_property_read_u32(node, "clock-mult", &mult);
969                 if (ret != 0) {
970                         clk_err("%s: can not get mult\n", __func__);
971                         goto out;
972                 }
973                 fixed_factor->mult = (unsigned int)mult;
974
975                 ret = of_property_read_u32(node, "clock-div", &div);
976                 if (ret != 0) {
977                         clk_err("%s: can not get div\n", __func__);
978                         goto out;
979                 }
980                 fixed_factor->div = (unsigned int)div;
981
982
983                 found = 0;
984                 list_for_each_entry(rkclk, &rk_clks, node) {
985                         if (strcmp(fixed_factor_info->clk_name, rkclk->clk_name) == 0) {
986                                 if (rkclk->fixed_factor_info != NULL) {
987                                         clk_err("%s %d:\n", __func__, __LINE__);
988                                         clk_err("This clk(%s) has been used,"
989                                                         "will be overwrited here!\n",
990                                                         rkclk->clk_name);
991                                 }
992                                 clk_debug("%s: find match %s\n", __func__,
993                                                 rkclk->clk_name);
994                                 found = 1;
995                                 rkclk->fixed_factor_info = fixed_factor_info;
996                                 rkclk->clk_type |= RKCLK_FIXED_FACTOR_TYPE;
997                                 rkclk->flags |= flags;
998                                 break;
999                         }
1000                 }
1001
1002                 if (!found) {
1003                         rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
1004                         if (!rkclk) {
1005                                 ret = -ENOMEM;
1006                                 goto out;
1007                         }
1008                         rkclk->clk_name = fixed_factor_info->clk_name;
1009                         rkclk->fixed_factor_info = fixed_factor_info;
1010                         rkclk->clk_type = RKCLK_FIXED_FACTOR_TYPE;
1011                         rkclk->flags = flags;
1012                         clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
1013                         list_add_tail(&rkclk->node, &rk_clks);
1014                 }
1015         }
1016
1017 out:
1018         if (ret) {
1019                 clk_err("%s error, ret = %d\n", __func__, ret);
1020                 if (fixed_factor_info) {
1021                         if (fixed_factor_info->fixed_factor)
1022                                 kfree(fixed_factor_info->fixed_factor);
1023                         kfree(fixed_factor_info);
1024                 }
1025                 if (rkclk)
1026                         kfree(rkclk);
1027         }
1028
1029         return ret;
1030 }
1031
1032 static int __init rkclk_init_regcon(struct device_node *np)
1033 {
1034         struct device_node *node;
1035         const char *compatible;
1036         int ret = 0;
1037
1038
1039         for_each_available_child_of_node(np, node) {
1040                 clk_debug("\n");
1041                 of_property_read_string(node, "compatible", &compatible);
1042
1043                 if (strcmp(compatible, "rockchip,rk-pll-cons") == 0) {
1044                         ret = rkclk_init_pllcon(node);
1045                         if (ret != 0) {
1046                                 clk_err("%s: init pll cons err\n", __func__);
1047                                 goto out;
1048                         }
1049                 } else if (strcmp(compatible, "rockchip,rk-sel-cons") == 0) {
1050                         ret = rkclk_init_selcon(node);
1051                         if (ret != 0) {
1052                                 clk_err("%s: init sel cons err\n", __func__);
1053                                 goto out;
1054                         }
1055                 } else if (strcmp(compatible, "rockchip,rk-gate-cons") == 0) {
1056                         ret = rkclk_init_gatecon(node);
1057                         if (ret != 0) {
1058                                 clk_err("%s: init gate cons err\n", __func__);
1059                                 goto out;
1060                         }
1061                 } else {
1062                         clk_err("%s: unknown\n", __func__);
1063                         ret = -EINVAL;
1064                         goto out;
1065                 }
1066         }
1067 out:
1068         return ret;
1069 }
1070
1071 static int __init rkclk_init_special_regs(struct device_node *np)
1072 {
1073         struct device_node *node;
1074         const char *compatible;
1075         void __iomem *reg = 0;
1076         int ret = 0;
1077
1078
1079         for_each_available_child_of_node(np, node) {
1080                 clk_debug("\n");
1081                 of_property_read_string(node, "compatible", &compatible);
1082                 if (strcmp(compatible, "rockchip,rk3188-mux-con") == 0) {
1083                         reg = of_iomap(node, 0);
1084                         ret = rkclk_init_muxinfo(node, reg);
1085                         if (ret != 0) {
1086                                 clk_err("%s: init mux con err\n", __func__);
1087                                 goto out;
1088                         }
1089                 }
1090         }
1091
1092 out:
1093         return ret;
1094 }
1095
1096 static int __init rkclk_init_pd(struct device_node *np)
1097 {
1098         struct device_node *node = NULL;
1099         struct rkclk_pd_info *pd_info = NULL;
1100         struct clk_pd *pd = NULL;
1101         int ret = 0;
1102         u8 found = 0;
1103         struct rkclk *rkclk = NULL;
1104
1105
1106         for_each_available_child_of_node(np, node) {
1107                 pd_info = kzalloc(sizeof(struct rkclk_pd_info), GFP_KERNEL);
1108                 if (!pd_info) {
1109                         ret = -ENOMEM;
1110                         goto out;
1111                 }
1112
1113                 pd_info->pd = kzalloc(sizeof(struct clk_pd), GFP_KERNEL);
1114                 if (!pd_info->pd) {
1115                         ret = -ENOMEM;
1116                         goto out;
1117                 }
1118                 pd = pd_info->pd;
1119
1120                 pd_info->np = node;
1121
1122                 ret = of_property_read_string_index(node, "clock-output-names",
1123                                 0, &pd_info->clk_name);
1124                 if (ret)
1125                         goto out;
1126
1127                 pd_info->parent_name = of_clk_get_parent_name(node, 0);
1128
1129                 ret = of_property_read_u32(node, "rockchip,pd-id", &pd->id);
1130                 if (ret != 0) {
1131                         clk_err("%s: can not get pd-id\n", __func__);
1132                         goto out;
1133                 }
1134
1135                 found = 0;
1136                 list_for_each_entry(rkclk, &rk_clks, node) {
1137                         if (strcmp(pd_info->clk_name, rkclk->clk_name) == 0) {
1138                                 clk_err("%s %d:\n", __func__, __LINE__);
1139                                 clk_err("This clk (%s) has been used, error!\n",
1140                                         rkclk->clk_name);
1141                                 goto out;
1142                         }
1143                 }
1144
1145                 if (!found) {
1146                         rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
1147                         if (!rkclk) {
1148                                 ret = -ENOMEM;
1149                                 goto out;
1150                         }
1151                         rkclk->clk_name = pd_info->clk_name;
1152                         rkclk->pd_info = pd_info;
1153                         rkclk->clk_type = RKCLK_PD_TYPE;
1154                         rkclk->flags = 0;
1155                         clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
1156                         list_add_tail(&rkclk->node, &rk_clks);
1157                 }
1158         }
1159
1160 out:
1161         if (ret) {
1162                 clk_err("%s error, ret = %d\n", __func__, ret);
1163                 if (pd_info) {
1164                         if (pd_info->pd)
1165                                 kfree(pd_info->pd);
1166                         kfree(pd_info);
1167                 }
1168                 if (rkclk)
1169                         kfree(rkclk);
1170         }
1171
1172         return ret;
1173 }
1174
1175 static int rkclk_register(struct rkclk *rkclk)
1176 {
1177         struct clk              *clk = NULL;
1178         struct clk_mux          *mux = NULL;
1179         struct clk_divider      *div = NULL;
1180         struct clk_gate         *gate = NULL;
1181         struct clk_pll          *pll = NULL;
1182         struct clk_divider      *frac = NULL;
1183         struct clk_fixed_rate   *fixed_rate = NULL;
1184         struct clk_fixed_factor *fixed_factor = NULL;
1185         struct clk_pd           *pd = NULL;
1186
1187         struct clk_hw           *mux_hw = NULL;
1188         const struct clk_ops    *mux_ops = NULL;
1189         struct clk_hw           *rate_hw = NULL;
1190         const struct clk_ops    *rate_ops = NULL;
1191         struct clk_hw           *gate_hw = NULL;
1192         const struct clk_ops    *gate_ops = NULL;
1193
1194         int                     parent_num;
1195         const char              **parent_names = NULL;
1196         u8                      rate_type_count = 0;
1197
1198
1199         if (rkclk && rkclk->clk_name) {
1200                 clk_debug("%s: clk_name=%s, clk_type=0x%x, flags=0x%x\n",
1201                                 __func__, rkclk->clk_name, rkclk->clk_type,
1202                                 rkclk->flags);
1203         } else {
1204                 clk_err("%s: rkclk or clk_name is NULL!\n", __func__);
1205                 return -EINVAL;
1206         }
1207
1208         if (rkclk->mux_info && rkclk->mux_info->mux)
1209                 mux = rkclk->mux_info->mux;
1210         if (rkclk->div_info && rkclk->div_info->div)
1211                 div = rkclk->div_info->div;
1212         if (rkclk->gate_info && rkclk->gate_info->gate)
1213                 gate = rkclk->gate_info->gate;
1214         if (rkclk->pll_info && rkclk->pll_info->pll)
1215                 pll = rkclk->pll_info->pll;
1216         if (rkclk->frac_info && rkclk->frac_info->frac)
1217                 frac = rkclk->frac_info->frac;
1218         if (rkclk->fixed_rate_info && rkclk->fixed_rate_info->fixed_rate)
1219                 fixed_rate = rkclk->fixed_rate_info->fixed_rate;
1220         if (rkclk->fixed_factor_info && rkclk->fixed_factor_info->fixed_factor)
1221                 fixed_factor = rkclk->fixed_factor_info->fixed_factor;
1222         if (rkclk->pd_info && rkclk->pd_info->pd)
1223                 pd = rkclk->pd_info->pd;
1224
1225
1226         switch (rkclk->clk_type) {
1227                 case RKCLK_MUX_TYPE:
1228                         /* only mux without specified ops will be registered here */
1229                         if (rkclk->mux_info->clkops_idx == CLKOPS_TABLE_END) {
1230                                 clk_debug("use clk_register_mux\n");
1231                                 clk = clk_register_mux_table(NULL, rkclk->clk_name,
1232                                                 rkclk->mux_info->parent_names,
1233                                                 rkclk->mux_info->parent_num,
1234                                                 rkclk->flags, mux->reg, mux->shift,
1235                                                 mux->mask, mux->flags, NULL, &clk_lock);
1236                                 goto add_lookup;
1237                         } else
1238                                 goto rgs_comp;
1239                 case RKCLK_PLL_TYPE:
1240                         clk_debug("use rk_clk_register_pll\n");
1241                         clk = rk_clk_register_pll(NULL, rkclk->clk_name,
1242                                         rkclk->pll_info->parent_name,
1243                                         rkclk->flags, pll->reg, pll->width,
1244                                         pll->mode_offset, pll->mode_shift,
1245                                         pll->status_offset, pll->status_shift,
1246                                         pll->flags, &clk_lock);
1247                         //kfree!!!!!!!
1248                         goto add_lookup;
1249                 case RKCLK_DIV_TYPE:
1250                         /* only div without specified ops will be registered here */
1251                         if (rkclk->div_info->clkops_idx == CLKOPS_TABLE_END) {
1252                                 clk_debug("use clk_register_divider\n");
1253                                 clk = clk_register_divider(NULL, rkclk->clk_name,
1254                                                 rkclk->div_info->parent_name,
1255                                                 rkclk->flags, div->reg, div->shift,
1256                                                 div->width, div->flags, &clk_lock);
1257                                 goto add_lookup;
1258                         } else
1259                                 goto rgs_comp;
1260                 case RKCLK_FRAC_TYPE:
1261                         if (rkclk->frac_info->clkops_idx == CLKOPS_TABLE_END) {
1262                                 clk_err("frac node without specified ops!\n");
1263                                 return -EINVAL;
1264                         } else
1265                                 goto rgs_comp;
1266                 case RKCLK_GATE_TYPE:
1267                         clk_debug("use clk_register_gate\n");
1268                         clk = clk_register_gate(NULL, rkclk->clk_name,
1269                                         rkclk->gate_info->parent_name, rkclk->flags,
1270                                         gate->reg, gate->bit_idx, gate->flags,
1271                                         &clk_lock);
1272                         goto add_lookup;
1273                 case RKCLK_FIXED_RATE_TYPE:
1274                         clk_debug("use clk_register_fixed_rate\n");
1275                         clk = clk_register_fixed_rate(NULL, rkclk->clk_name,
1276                                         rkclk->fixed_rate_info->parent_name,
1277                                         rkclk->flags, fixed_rate->fixed_rate);
1278                         goto add_lookup;
1279                 case RKCLK_FIXED_FACTOR_TYPE:
1280                         clk_debug("use clk_register_fixed_factor\n");
1281                         clk = clk_register_fixed_factor(NULL, rkclk->clk_name,
1282                                         rkclk->fixed_factor_info->parent_name,
1283                                         rkclk->flags, fixed_factor->mult,
1284                                         fixed_factor->div);
1285                         goto add_lookup;
1286                 case RKCLK_PD_TYPE:
1287                         clk_debug("use rk_clk_register_pd\n");
1288                         clk = rk_clk_register_pd(NULL, rkclk->clk_name,
1289                                         rkclk->pd_info->parent_name, rkclk->flags,
1290                                         pd->id, &clk_lock);
1291                         goto add_lookup;
1292                 default:
1293                         goto rgs_comp;
1294         }
1295
1296 rgs_comp:
1297
1298         if (rkclk->clk_type & RKCLK_DIV_TYPE)
1299                 rate_type_count++;
1300         if (rkclk->clk_type & RKCLK_PLL_TYPE)
1301                 rate_type_count++;
1302         if (rkclk->clk_type & RKCLK_FRAC_TYPE)
1303                 rate_type_count++;
1304         if (rkclk->clk_type & RKCLK_FIXED_RATE_TYPE)
1305                 rate_type_count++;
1306         if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE)
1307                 rate_type_count++;
1308
1309         if (rate_type_count > 1) {
1310                 clk_err("Invalid rkclk type!\n");
1311                 return -EINVAL;
1312         }
1313
1314         clk_debug("use clk_register_composite\n");
1315
1316         /* prepare args for clk_register_composite */
1317
1318         /* prepare parent_num && parent_names
1319          * priority: MUX > DIV=PLL=FRAC=FIXED_FACTOR > GATE
1320          */
1321         if (rkclk->clk_type & RKCLK_MUX_TYPE) {
1322                 parent_num = rkclk->mux_info->parent_num;
1323                 parent_names = rkclk->mux_info->parent_names;
1324         } else if (rkclk->clk_type & RKCLK_DIV_TYPE ) {
1325                 parent_num = 1;
1326                 parent_names = &(rkclk->div_info->parent_name);
1327         } else if (rkclk->clk_type & RKCLK_PLL_TYPE) {
1328                 parent_num = 1;
1329                 parent_names = &(rkclk->pll_info->parent_name);
1330         } else if (rkclk->clk_type & RKCLK_FRAC_TYPE) {
1331                 parent_num = 1;
1332                 parent_names = &(rkclk->frac_info->parent_name);
1333         } else if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE) {
1334                 parent_num = 1;
1335                 parent_names = &(rkclk->fixed_factor_info->parent_name);
1336         } else if (rkclk->clk_type & RKCLK_GATE_TYPE) {
1337                 parent_num = 1;
1338                 parent_names = &(rkclk->gate_info->parent_name);
1339         }
1340
1341         /* prepare mux_hw && mux_ops */
1342         if (rkclk->clk_type & RKCLK_MUX_TYPE) {
1343                 mux_hw = &mux->hw;
1344                 mux_ops = &clk_mux_ops;
1345         }
1346
1347         /* prepare rate_hw && rate_ops
1348          * priority: DIV=PLL=FRAC=FIXED_FACTOR > MUX
1349          */
1350         if (rkclk->clk_type & RKCLK_DIV_TYPE) {
1351                 rate_hw = &div->hw;
1352                 if (rkclk->div_info->clkops_idx != CLKOPS_TABLE_END)
1353                         rate_ops = rk_get_clkops(rkclk->div_info->clkops_idx);
1354                 else
1355                         rate_ops = &clk_divider_ops;
1356         } else if (rkclk->clk_type & RKCLK_PLL_TYPE) {
1357                 rate_hw = &pll->hw;
1358                 rate_ops = rk_get_pll_ops(pll->flags);
1359         } else if (rkclk->clk_type & RKCLK_FRAC_TYPE) {
1360                 rate_hw = &frac->hw;
1361                 rate_ops = rk_get_clkops(rkclk->frac_info->clkops_idx);
1362         } else if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE) {
1363                 rate_hw = &fixed_factor->hw;
1364                 rate_ops = &clk_fixed_factor_ops;
1365         } else if ((rkclk->clk_type & RKCLK_MUX_TYPE) &&
1366                         (rkclk->mux_info->clkops_idx != CLKOPS_TABLE_END)) {
1367                 /* when a mux node has specified clkops_idx, prepare rate_hw &&
1368                  * rate_ops and use clk_register_composite to register it later.
1369                  */
1370                 /*FIXME*/
1371                 rate_hw = kzalloc(sizeof(struct clk_hw), GFP_KERNEL);
1372                 if (!rate_hw) {
1373                         clk_err("%s: fail to alloc rate_hw!\n", __func__);
1374                         return -ENOMEM;
1375                 }
1376                 rate_ops = rk_get_clkops(rkclk->mux_info->clkops_idx);
1377         }
1378
1379         if (rkclk->clk_type & RKCLK_GATE_TYPE) {
1380                 gate_hw = &gate->hw;
1381                 gate_ops = &clk_gate_ops;
1382         }
1383
1384         clk_debug("parent_num=%d, mux_hw=%d mux_ops=%d, rate_hw=%d rate_ops=%d,"
1385                         " gate_hw=%d gate_ops=%d\n",
1386                         parent_num, mux_hw?1:0, mux_ops?1:0, rate_hw?1:0,
1387                         rate_ops?1:0, gate_hw?1:0, gate_ops?1:0);
1388
1389         clk = clk_register_composite(NULL, rkclk->clk_name, parent_names,
1390                         parent_num, mux_hw, mux_ops, rate_hw, rate_ops,
1391                         gate_hw, gate_ops, rkclk->flags);
1392
1393 add_lookup:
1394         if (clk) {
1395                 clk_debug("clk name=%s, flags=0x%lx\n", clk->name, clk->flags);
1396                 clk_register_clkdev(clk, rkclk->clk_name, NULL);
1397         } else {
1398                 clk_err("%s: clk(\"%s\") register clk error\n", __func__,
1399                                 rkclk->clk_name);
1400         }
1401
1402         return 0;
1403 }
1404
1405 static int _rkclk_add_provider(struct device_node *np)
1406 {
1407         int i, cnt, ret = 0;
1408         const char *name = NULL;
1409         struct clk *clk = NULL;
1410         struct clk_onecell_data *clk_data = NULL;
1411
1412
1413         clk_debug("\n");
1414
1415         cnt = of_property_count_strings(np, "clock-output-names");
1416         if (cnt < 0) {
1417                 clk_err("%s: error in clock-output-names, cnt=%d\n", __func__,
1418                                 cnt);
1419                 return -EINVAL;
1420         }
1421
1422         clk_debug("%s: cnt = %d\n", __func__, cnt);
1423
1424         if (cnt == 0) {
1425                 clk_debug("%s: nothing to do\n", __func__);
1426                 return 0;
1427         }
1428
1429         if (cnt == 1) {
1430                 of_property_read_string(np, "clock-output-names", &name);
1431                 clk_debug("clock-output-names = %s\n", name);
1432
1433                 clk = clk_get_sys(NULL, name);
1434                 if (IS_ERR(clk)) {
1435                         clk_err("%s: fail to get %s\n", __func__, name);
1436                         return -EINVAL;
1437                 }
1438
1439                 ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
1440                 clk_debug("use of_clk_src_simple_get, ret=%d\n", ret);
1441         } else {
1442                 clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
1443                 if (!clk_data)
1444                         return -ENOMEM;
1445
1446                 clk_data->clks = kzalloc(cnt * sizeof(struct clk *), GFP_KERNEL);
1447                 if (!clk_data->clks) {
1448                         kfree(clk_data);
1449                         return -ENOMEM;
1450                 }
1451
1452                 clk_data->clk_num = cnt;
1453
1454                 for (i=0; i<cnt; i++) {
1455                         of_property_read_string_index(np, "clock-output-names",
1456                                         i, &name);
1457                         clk_debug("clock-output-names[%d]=%s\n", i, name);
1458
1459                         /* ignore empty slots */
1460                         if (!strcmp("reserved", name))
1461                                 continue;
1462
1463                         clk = clk_get_sys(NULL, name);
1464                         if (IS_ERR(clk)) {
1465                                 clk_err("%s: fail to get %s\n", __func__, name);
1466                                 continue;
1467                         }
1468
1469                         clk_data->clks[i] = clk;
1470                 }
1471
1472                 ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
1473                 clk_debug("use of_clk_src_onecell_get, ret=%d\n", ret);
1474         }
1475
1476         return ret;
1477 }
1478
1479 static void rkclk_add_provider(struct device_node *np)
1480 {
1481         struct device_node *node, *node_reg, *node_tmp, *node_prd;
1482         const char *compatible;
1483
1484
1485         for_each_available_child_of_node(np, node) {
1486                 of_property_read_string(node, "compatible", &compatible);
1487
1488                 if (strcmp(compatible, "rockchip,rk-fixed-rate-cons") == 0) {
1489                         for_each_available_child_of_node(node, node_prd) {
1490                                  _rkclk_add_provider(node_prd);
1491                         }
1492                 } else if (strcmp(compatible, "rockchip,rk-fixed-factor-cons") == 0) {
1493                         for_each_available_child_of_node(node, node_prd) {
1494                                  _rkclk_add_provider(node_prd);
1495                         }
1496                 } else if (strcmp(compatible, "rockchip,rk-clock-regs") == 0) {
1497                         for_each_available_child_of_node(node, node_reg) {
1498                                 of_property_read_string(node_reg, "compatible", &compatible);
1499
1500                                 if (strcmp(compatible, "rockchip,rk-pll-cons") == 0) {
1501                                         for_each_available_child_of_node(node_reg, node_prd) {
1502                                                 _rkclk_add_provider(node_prd);
1503                                         }
1504                                 } else if (strcmp(compatible, "rockchip,rk-sel-cons") == 0) {
1505                                         for_each_available_child_of_node(node_reg, node_tmp) {
1506                                                 for_each_available_child_of_node(node_tmp,
1507                                                         node_prd) {
1508                                                         _rkclk_add_provider(node_prd);
1509                                                 }
1510                                         }
1511                                 } else if (strcmp(compatible, "rockchip,rk-gate-cons") == 0) {
1512                                         for_each_available_child_of_node(node_reg, node_prd) {
1513                                                  _rkclk_add_provider(node_prd);
1514                                         }
1515                                 } else {
1516                                         clk_err("%s: unknown\n", __func__);
1517                                 }
1518                         }
1519                 } else if (strcmp(compatible, "rockchip,rk-pd-cons") == 0) {
1520                         for_each_available_child_of_node(node, node_prd) {
1521                                  _rkclk_add_provider(node_prd);
1522                         }
1523                 } else if (strcmp(compatible, "rockchip,rk-clock-special-regs") == 0) {
1524                         for_each_available_child_of_node(node, node_prd) {
1525                                  _rkclk_add_provider(node_prd);
1526                         }
1527                 } else {
1528                         clk_err("%s: unknown\n", __func__);
1529                 }
1530         }
1531
1532 }
1533
1534 static void rkclk_cache_parents(struct rkclk *rkclk)
1535 {
1536         struct clk *clk, *parent;
1537         u8 num_parents;
1538         int i;
1539
1540
1541         clk = clk_get(NULL, rkclk->clk_name);
1542         if (IS_ERR(clk)) {
1543                 clk_err("%s: %s clk_get error\n",
1544                                 __func__, rkclk->clk_name);
1545                 return;
1546         } else {
1547                 clk_debug("%s: %s clk_get success\n",
1548                                 __func__, __clk_get_name(clk));
1549         }
1550
1551         num_parents = __clk_get_num_parents(clk);
1552         clk_debug("\t\tnum_parents=%d, parent=%s\n", num_parents,
1553                         __clk_get_name(__clk_get_parent(clk)));
1554
1555         for (i=0; i<num_parents; i++) {
1556                 /* parent will be cached after this func is called */
1557                 parent = clk_get_parent_by_index(clk, i);
1558                 if (IS_ERR(parent)) {
1559                         clk_err("fail to get parents[%d]=%s\n", i,
1560                                         clk->parent_names[i]);
1561                         continue;
1562                 } else {
1563                         clk_debug("\t\tparents[%d]: %s\n", i,
1564                                         __clk_get_name(parent));
1565                 }
1566         }
1567 }
1568
1569 void rk_dump_cru(void)
1570 {
1571         printk(KERN_WARNING "CRU:\n");
1572         print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 32, 4, rk_cru_base,
1573                        0x420, false);
1574 }
1575 EXPORT_SYMBOL_GPL(rk_dump_cru);
1576
1577
1578 #ifdef RKCLK_DEBUG
1579 void rkclk_dump_info(struct rkclk *rkclk)
1580 {
1581         struct clk_mux          *mux = NULL;
1582         struct clk_divider      *div = NULL;
1583         struct clk_gate         *gate = NULL;
1584         struct clk_pll          *pll = NULL;
1585         struct clk_divider      *frac = NULL;
1586         struct clk_fixed_rate   *fixed_rate = NULL;
1587         struct clk_fixed_factor *fixed_factor = NULL;
1588         struct clk_pd           *pd = NULL;
1589         int i;
1590
1591
1592         clk_debug("%s: clkname=%s, type=0x%x, flags=0x%x\n",
1593                         __func__, (rkclk->clk_name)?(rkclk->clk_name):NULL,
1594                         rkclk->clk_type, rkclk->flags);
1595
1596         if (rkclk->mux_info && rkclk->mux_info->mux)
1597                 mux = rkclk->mux_info->mux;
1598         if (rkclk->div_info && rkclk->div_info->div)
1599                 div = rkclk->div_info->div;
1600         if (rkclk->pll_info && rkclk->pll_info->pll)
1601                 pll = rkclk->pll_info->pll;
1602         if (rkclk->frac_info && rkclk->frac_info->frac)
1603                 frac = rkclk->frac_info->frac;
1604         if (rkclk->gate_info && rkclk->gate_info->gate)
1605                 gate = rkclk->gate_info->gate;
1606         if (rkclk->fixed_rate_info && rkclk->fixed_rate_info->fixed_rate)
1607                 fixed_rate = rkclk->fixed_rate_info->fixed_rate;
1608         if (rkclk->fixed_factor_info && rkclk->fixed_factor_info->fixed_factor)
1609                 fixed_factor = rkclk->fixed_factor_info->fixed_factor;
1610         if (rkclk->pd_info && rkclk->pd_info->pd)
1611                 pd = rkclk->pd_info->pd;
1612
1613
1614         if (rkclk->mux_info) {
1615                 clk_debug("\t\tmux_info: name=%s, clkops_idx=%u\n",
1616                                 rkclk->mux_info->clk_name,
1617                                 rkclk->mux_info->clkops_idx);
1618                 for (i = 0; i < rkclk->mux_info->parent_num; i++)
1619                         clk_debug("\t\t\tparent[%d]: %s\n", i,
1620                                         rkclk->mux_info->parent_names[i]);
1621                 if (mux) {
1622                         clk_debug("\t\tmux: reg=0x%x, mask=0x%x, shift=0x%x, "
1623                                         "mux_flags=0x%x\n", (u32)mux->reg,
1624                                         mux->mask, mux->shift, mux->flags);
1625                 }
1626         }
1627
1628         if (rkclk->pll_info) {
1629                 clk_debug("\t\tpll_info: name=%s, parent=%s, clkops_idx=0x%x\n",
1630                                 rkclk->pll_info->clk_name,
1631                                 rkclk->pll_info->parent_name,
1632                                 rkclk->pll_info->clkops_idx);
1633                 if (pll) {
1634                         clk_debug("\t\tpll: reg=0x%x, width=0x%x, "
1635                                         "mode_offset=0x%x, mode_shift=%u, "
1636                                         "status_offset=0x%x, status_shift=%u, "
1637                                         "pll->flags=%u\n",
1638                                         (u32)pll->reg, pll->width,
1639                                         pll->mode_offset, pll->mode_shift,
1640                                         pll->status_offset, pll->status_shift,
1641                                         pll->flags);
1642                 }
1643         }
1644
1645         if (rkclk->div_info) {
1646                 clk_debug("\t\tdiv_info: name=%s, div_type=0x%x, parent=%s, "
1647                                 "clkops_idx=%d\n",
1648                                 rkclk->div_info->clk_name,
1649                                 rkclk->div_info->div_type,
1650                                 rkclk->div_info->parent_name,
1651                                 rkclk->div_info->clkops_idx);
1652                 if (div) {
1653                         clk_debug("\t\tdiv: reg=0x%x, shift=0x%x, width=0x%x, "
1654                                         "div_flags=0x%x\n", (u32)div->reg,
1655                                         div->shift, div->width, div->flags);
1656                 }
1657         }
1658
1659         if (rkclk->frac_info) {
1660                 clk_debug("\t\tfrac_info: name=%s, parent=%s, clkops_idx=%d\n",
1661                                 rkclk->frac_info->clk_name,
1662                                 rkclk->frac_info->parent_name,
1663                                 rkclk->frac_info->clkops_idx);
1664                 if (frac) {
1665                         clk_debug("\t\tfrac: reg=0x%x, shift=0x%x, width=0x%x, "
1666                                         "div_flags=0x%x\n", (u32)frac->reg,
1667                                         frac->shift, frac->width, frac->flags);
1668                 }
1669         }
1670
1671         if (rkclk->gate_info) {
1672                 clk_debug("\t\tgate_info: name=%s, parent=%s\n",
1673                                 rkclk->gate_info->clk_name,
1674                                 rkclk->gate_info->parent_name);
1675                 if (gate) {
1676                         clk_debug("\t\tgate: reg=0x%x, bit_idx=%d, "
1677                                         "gate_flags=0x%x\n", (u32)gate->reg,
1678                                         gate->bit_idx, gate->flags);
1679                 }
1680         }
1681
1682         if (rkclk->fixed_rate_info) {
1683                 clk_debug("\t\tfixed_rate_info: name=%s\n",
1684                                 rkclk->fixed_rate_info->clk_name);
1685                 if (fixed_rate) {
1686                         clk_debug("\t\tfixed_rate=%lu, fixed_rate_flags=0x%x\n",
1687                                 fixed_rate->fixed_rate, fixed_rate->flags);
1688                 }
1689         }
1690
1691         if (rkclk->fixed_factor_info) {
1692                 clk_debug("\t\tfixed_factor_info: name=%s, parent=%s\n",
1693                                 rkclk->fixed_factor_info->clk_name,
1694                                 rkclk->fixed_factor_info->parent_name);
1695                 if (fixed_factor) {
1696                         clk_debug("\t\tfixed_factor: mult=%u, div=%u\n",
1697                                 fixed_factor->mult, fixed_factor->div);
1698                 }
1699         }
1700
1701         if (rkclk->pd_info) {
1702                 clk_debug("\t\tpd_info: name=%s, parent=%s\n",
1703                                 rkclk->pd_info->clk_name,
1704                                 rkclk->pd_info->parent_name);
1705                 if (pd) {
1706                         clk_debug("\t\tpd: id=%u\n", pd->id);
1707                 }
1708         }
1709 }
1710 #else
1711 void rkclk_dump_info(struct rkclk *rkclk) {}
1712 #endif
1713
1714
1715 #ifdef RKCLK_TEST
1716 char* pd_table[] = {
1717         "pd_gpu",
1718         "pd_video",
1719         "pd_vio",
1720         "pd_hevc",
1721 };
1722
1723 void rk_clk_pd_test(void)
1724 {
1725         struct clk *clk;
1726         bool state;
1727         int j, ret;
1728
1729
1730         for (j = 0; j < ARRAY_SIZE(pd_table); j++) {
1731
1732                 clk = clk_get(NULL, pd_table[j]);
1733
1734                 ret = clk_prepare_enable(clk);
1735                 printk("%s: clk_prepare_enable %s, ret=%d\n", __func__,
1736                         __clk_get_name(clk), ret);
1737
1738                 state = __clk_is_enabled(clk);
1739                 printk("%s: clk_pd %s is %s\n", __func__, __clk_get_name(clk),
1740                         state ? "enable" : "disable");
1741
1742                 clk_disable_unprepare(clk);
1743                 printk("%s: clk_disable_unprepare %s\n", __func__,
1744                         __clk_get_name(clk));
1745
1746                 state = __clk_is_enabled(clk);
1747                 printk("%s: clk_pd %s is %s\n", __func__, __clk_get_name(clk),
1748                         state ? "enable" : "disable");
1749
1750                 printk("\n");
1751         }
1752 }
1753
1754 struct test_table {
1755         const char *name;
1756         u32 rate;
1757 };
1758
1759 struct test_table t_table[] = {
1760         {.name = "clk_gpu",     .rate = 297000000},
1761         {.name = "dclk_lcdc0",  .rate = 100000000},
1762         {.name = "aclk_lcdc0",  .rate = 297000000},
1763
1764         {.name = "clk_sdmmc",   .rate = 50000000},
1765         {.name = "clk_emmc",    .rate = 50000000},
1766         {.name = "clk_sdio",    .rate = 50000000},
1767
1768         {.name = "clk_i2s_div", .rate = 300000000},
1769         {.name = "clk_i2s_frac",.rate = 22579200},
1770         {.name = "clk_i2s",     .rate = 11289600},
1771         {.name = "clk_spdif",   .rate = 11289600},
1772
1773         {.name = "cif_out_pll", .rate = 48000000},
1774         {.name = "clk_cif0",    .rate = 12000000},
1775
1776         {.name = "clk_uart0",   .rate = 12288000},
1777         {.name = "clk_uart1",   .rate = 48000000},
1778         {.name = "clk_hsadc",   .rate = 12288000},
1779         {.name = "clk_mac",     .rate = 50000000},
1780
1781 //      {.name = "clk_apll",    .rate = 500000000},
1782 //      {.name = "clk_dpll",    .rate = 400000000},
1783         {.name = "clk_cpll",    .rate = 600000000},
1784         {.name = "clk_gpll",    .rate = 800000000},
1785
1786         {.name = "clk_core",    .rate = 100000000},
1787         {.name = "clk_core",    .rate = 24000000},
1788         {.name = "clk_core",    .rate = 500000000},
1789 };
1790
1791
1792 void rk_clk_test(void)
1793 {
1794         const char *clk_name;
1795         struct clk *clk;
1796         unsigned long rate=0, recalc_rate=0, round_rate=0, get_rate=0;
1797         u32 j = 0;
1798         int ret;
1799
1800         for (j = 0; j < ARRAY_SIZE(t_table); j++) {
1801                 clk_debug(">>>>>>test %u\n", j);
1802
1803                 clk_name = t_table[j].name;
1804                 rate = t_table[j].rate;
1805
1806                 clk = clk_get(NULL, clk_name);
1807                 if (IS_ERR(clk)) {
1808                         clk_err("%s: clk(\"%s\") \tclk_get error\n",
1809                                         __func__, clk_name);
1810                 } else
1811                         clk_debug("%s: clk(\"%s\") \tclk_get success\n",
1812                                         __func__, clk_name);
1813
1814                 /* TEST: clk_round_rate */
1815                 round_rate = clk_round_rate(clk, rate);
1816                 clk_debug("%s: clk(\"%s\") \tclk_round_rate from %lu to %lu\n",
1817                                 __func__, clk_name, rate, round_rate);
1818
1819                 /* TEST: clk_set_rate */
1820                 ret = clk_set_rate(clk, rate);
1821                 if (ret) {
1822                         clk_err("%s: clk(\"%s\") \tclk_set_rate error, ret=%d\n",
1823                                         __func__, clk_name, ret);
1824                 } else {
1825                         clk_debug("%s: clk(\"%s\") \tclk_set_rate success\n",
1826                                         __func__, clk_name);
1827                 }
1828
1829                 /* TEST: recalc_rate\clk_get_rate */
1830                 if (clk->ops->recalc_rate) {
1831                         recalc_rate = clk->ops->recalc_rate(clk->hw,
1832                                         clk->parent->rate);
1833                         clk_debug("%s: clk(\"%s\") \tclk_recalc_rate %lu\n",
1834                                         __func__, clk_name, recalc_rate);
1835                 } else {
1836                         clk_debug("%s: clk(\"%s\") have no recalc ops\n",
1837                                         __func__, clk_name);
1838                         get_rate = clk_get_rate(clk);
1839                         clk_debug("%s: clk(\"%s\") \tclk_get_rate %lu\n",
1840                                         __func__, clk_name, get_rate);
1841                 }
1842
1843                 rk_dump_cru();
1844         }
1845
1846         rk_clk_pd_test();
1847 }
1848 #else
1849 void rk_clk_test(void) {}
1850 #endif
1851 EXPORT_SYMBOL_GPL(rk_clk_test);
1852
1853 static int rkclk_panic(struct notifier_block *this, unsigned long ev, void *ptr)
1854 {
1855         rk_dump_cru();
1856         return NOTIFY_DONE;
1857 }
1858
1859 static struct notifier_block rkclk_panic_block = {
1860         .notifier_call = rkclk_panic,
1861 };
1862
1863 void __init rkclk_init_clks(struct device_node *node);
1864
1865 static struct device_node * clk_root_node=NULL;
1866 static void __init rk_clk_tree_init(struct device_node *np)
1867 {
1868         struct device_node *node, *node_init;
1869         struct rkclk *rkclk;
1870         const char *compatible;
1871
1872         printk("%s start!\n", __func__);
1873
1874         node_init = of_find_node_by_name(NULL, "clocks-init");
1875         if (!node_init) {
1876                 clk_err("%s: can not get clocks-init node\n", __func__);
1877                 return;
1878         }
1879
1880         clk_root_node = of_find_node_by_name(NULL, "clock_regs");
1881         rk_cru_base = of_iomap(clk_root_node, 0);
1882         if (!rk_cru_base) {
1883                 clk_err("%s: could not map cru region\n", __func__);
1884                 return;
1885         }
1886
1887         node = of_parse_phandle(np, "rockchip,grf", 0);
1888         if (node)
1889                 rk_grf_base = of_iomap(node, 0);
1890 #ifdef CONFIG_ARM
1891         if (!rk_grf_base)
1892                 rk_grf_base = RK_GRF_VIRT;
1893 #endif
1894
1895         for_each_available_child_of_node(np, node) {
1896                 clk_debug("\n");
1897                 of_property_read_string(node, "compatible",
1898                                 &compatible);
1899
1900                 if (strcmp(compatible, "rockchip,rk-fixed-rate-cons") == 0) {
1901                         if (rkclk_init_fixed_rate(node) != 0) {
1902                                 clk_err("%s: init fixed_rate err\n", __func__);
1903                                 return;
1904                         }
1905                 } else if (strcmp(compatible, "rockchip,rk-fixed-factor-cons") == 0) {
1906                         if (rkclk_init_fixed_factor(node) != 0) {
1907                                 clk_err("%s: init fixed_factor err\n", __func__);
1908                                 return;
1909                         }
1910                 } else if (strcmp(compatible, "rockchip,rk-clock-regs") == 0) {
1911                         if (rkclk_init_regcon(node) != 0) {
1912                                 clk_err("%s: init reg cons err\n", __func__);
1913                                 return;
1914                         }
1915                 } else if (strcmp(compatible, "rockchip,rk-pd-cons") == 0) {
1916                         if (rkclk_init_pd(node) != 0) {
1917                                 clk_err("%s: init pd err\n", __func__);
1918                                 return;
1919                         }
1920                 } else if (strcmp(compatible, "rockchip,rk-clock-special-regs") == 0) {
1921                         if (rkclk_init_special_regs(node) != 0) {
1922                                 clk_err("%s: init special reg err\n", __func__);
1923                                 return;
1924                         }
1925                 } else {
1926                         clk_err("%s: unknown\n", __func__);
1927                 }
1928         }
1929
1930         list_for_each_entry(rkclk, &rk_clks, node) {
1931                 clk_debug("\n");
1932                 rkclk_dump_info(rkclk);
1933                 clk_debug("\n");
1934                 rkclk_register(rkclk);
1935         }
1936
1937         rkclk_add_provider(np);
1938
1939         /* fill clock parents cache after all clocks have been registered */
1940         list_for_each_entry(rkclk, &rk_clks, node) {
1941                 clk_debug("\n");
1942                 rkclk_cache_parents(rkclk);
1943         }
1944
1945         rkclk_init_clks(node_init);
1946
1947         rk_clk_test();
1948
1949         atomic_notifier_chain_register(&panic_notifier_list, &rkclk_panic_block);
1950 }
1951 CLK_OF_DECLARE(rk_clocks, "rockchip,rk-clocks", rk_clk_tree_init);
1952
1953
1954 /***************************** rockchip clks init******************************/
1955 const char *of_clk_init_rate_get_info(struct device_node *np,
1956                 int index,u32 *rate)
1957 {
1958         struct of_phandle_args clkspec;
1959         const char *clk_name;
1960         int rc;
1961
1962         if (index < 0)
1963                 return NULL;
1964
1965         rc = of_parse_phandle_with_args(np, "rockchip,clocks-init-rate",
1966                         "#clock-init-cells", index, &clkspec);
1967         if (rc)
1968                 return NULL;
1969
1970         if (of_property_read_string_index(clkspec.np, "clock-output-names", 0,
1971                                 &clk_name) < 0)
1972                 return NULL;
1973
1974         *rate= clkspec.args[0];
1975
1976         of_node_put(clkspec.np);
1977         return clk_name;
1978 }
1979
1980 const char *of_clk_init_parent_get_info(struct device_node *np, int index,
1981                 const char **clk_child_name)
1982 {
1983         struct of_phandle_args clkspec;
1984         const char *clk_name;
1985         int rc;
1986         phandle phandle;
1987         struct device_node *node = NULL;
1988
1989         if (index < 0)
1990                 return NULL;
1991
1992         rc = of_parse_phandle_with_args(np, "rockchip,clocks-init-parent",
1993                         "#clock-init-cells", index, &clkspec);
1994         if (rc)
1995                 return NULL;
1996
1997         if (of_property_read_string_index(clkspec.np, "clock-output-names", 0,
1998                                 &clk_name) < 0)
1999                 return NULL;
2000
2001
2002         phandle = clkspec.args[0];
2003
2004         of_node_put(clkspec.np);
2005
2006         if (phandle) {
2007
2008                 node = of_find_node_by_phandle(phandle);
2009                 if (!node) {
2010                         return NULL;
2011                 }
2012
2013                 if (of_property_read_string_index(node, "clock-output-names", 0,
2014                                         clk_child_name) < 0)
2015                         return NULL;
2016
2017                 of_node_put(node);//???
2018                 node=NULL;
2019         }
2020         else
2021                 return NULL;
2022
2023         return clk_name;
2024 }
2025
2026 static int __init rkclk_init_enable(void)
2027 {
2028         struct device_node *node;
2029         int cnt, i, ret = 0;
2030         const char *clk_name;
2031         struct clk *clk;
2032
2033
2034         node = of_find_node_by_name(NULL, "clocks-enable");
2035         if (!node) {
2036                 clk_err("%s: can not get clocks-enable node\n", __func__);
2037                 return -EINVAL;
2038         }
2039
2040         cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
2041         if (cnt < 0) {
2042                 return -EINVAL;
2043         } else {
2044                 clk_debug("%s: cnt = %d\n", __func__, cnt);
2045         }
2046
2047         for (i = 0; i < cnt ; i++) {
2048                 clk_name = of_clk_get_parent_name(node, i);
2049                 clk = clk_get(NULL, clk_name);
2050                 if (IS_ERR_OR_NULL(clk)) {
2051                         clk_err("%s: fail to get %s\n", __func__, clk_name);
2052                         return -EINVAL;
2053                 }
2054
2055                 ret = clk_prepare_enable(clk);
2056                 if (ret) {
2057                         clk_err("%s: fail to prepare_enable %s\n", __func__,
2058                                 clk_name);
2059                         return ret;
2060                 } else {
2061                         clk_debug("%s: prepare_enable %s OK\n", __func__,
2062                                 clk_name);
2063                 }
2064         }
2065
2066         return ret;
2067 }
2068
2069 static int uboot_logo_on = 0;
2070
2071 static void __init rk_get_uboot_display_flag(void)
2072 {
2073        struct device_node *node;
2074
2075        node = of_find_node_by_name(NULL, "fb");
2076        if (node)
2077                of_property_read_u32(node, "rockchip,uboot-logo-on", &uboot_logo_on);
2078
2079        printk("%s: uboot_logo_on = %d\n", __FUNCTION__, uboot_logo_on);
2080 }
2081
2082 static const char *of_clk_uboot_has_init_get_name(struct device_node *np, int index)
2083 {
2084         struct of_phandle_args clkspec;
2085         const char *clk_name;
2086         int rc;
2087
2088         if (index < 0)
2089                 return NULL;
2090
2091         rc = of_parse_phandle_with_args(np, "rockchip,clocks-uboot-has-init", 
2092                 "#clock-cells", index, &clkspec);
2093         if (rc)
2094                 return NULL;
2095
2096         if (of_property_read_string_index(clkspec.np, "clock-output-names",
2097                                           clkspec.args_count ? clkspec.args[0] : 0,
2098                                           &clk_name) < 0)
2099                 clk_name = NULL;
2100
2101         of_node_put(clkspec.np);
2102         return clk_name;
2103 }
2104
2105 /* If clk has been inited, return 1; else return 0. */
2106 static int rkclk_uboot_has_init(struct device_node *np, const char *clk_name)
2107 {
2108         int cnt, i;
2109         const char *name;
2110
2111
2112         if ((!np) || (!clk_name))
2113                 return 0;
2114
2115         cnt = of_count_phandle_with_args(np, "rockchip,clocks-uboot-has-init", 
2116                 "#clock-cells");
2117         if (cnt < 0)
2118                 return 0;
2119
2120         for (i = 0; i < cnt ; i++) {
2121                 name = of_clk_uboot_has_init_get_name(np, i);
2122                 if (name && (!strcmp(clk_name, name)))
2123                         return 1;
2124         }
2125
2126         return 0;
2127 }
2128
2129 void __init rkclk_init_clks(struct device_node *np)
2130 {
2131         //struct device_node *np;
2132         int i,cnt_parent,cnt_rate;
2133         u32 clk_rate;
2134         //int ret;
2135         struct clk *clk_p, *clk_c;
2136         const char *clk_name, *clk_parent_name;
2137
2138
2139         rk_get_uboot_display_flag();
2140
2141         cnt_parent = of_count_phandle_with_args(np,
2142                         "rockchip,clocks-init-parent", "#clock-init-cells");
2143
2144         printk("%s: cnt_parent = %d\n",__FUNCTION__,cnt_parent);
2145
2146         for (i = 0; i < cnt_parent; i++) {
2147                 clk_parent_name=NULL;
2148                 clk_name=of_clk_init_parent_get_info(np, i,&clk_parent_name);
2149
2150                 if(clk_name==NULL||clk_parent_name==NULL)
2151                         continue;
2152
2153                 clk_c=clk_get(NULL,clk_name);
2154                 clk_p=clk_get(NULL,clk_parent_name);
2155
2156                 if(IS_ERR(clk_c)||IS_ERR(clk_p))
2157                         continue;
2158
2159                 clk_set_parent(clk_c, clk_p);
2160
2161                 clk_debug("%s: set %s parent = %s\n", __FUNCTION__, clk_name,
2162                                 clk_parent_name);
2163         }
2164
2165         cnt_rate = of_count_phandle_with_args(np, "rockchip,clocks-init-rate",
2166                         "#clock-init-cells");
2167
2168         printk("%s: cnt_rate = %d\n",__FUNCTION__,cnt_rate);
2169
2170         for (i = 0; i < cnt_rate; i++) {
2171                 clk_name=of_clk_init_rate_get_info(np, i, &clk_rate);
2172
2173                 if (clk_name==NULL)
2174                         continue;
2175
2176                 if (uboot_logo_on && rkclk_uboot_has_init(np, clk_name)) {
2177                         printk("%s: %s has been inited in uboot, ingored\n", 
2178                                 __FUNCTION__, clk_name);
2179                         continue;
2180                 }
2181
2182                 clk_c = clk_get(NULL, clk_name);
2183
2184                 if(IS_ERR(clk_c))
2185                         continue;
2186
2187                 if((clk_rate<1*MHZ)||(clk_rate>2000*MHZ))
2188                         clk_err("warning: clk_rate < 1*MHZ or > 2000*MHZ\n");
2189
2190                 clk_set_rate(clk_c, clk_rate);
2191
2192                 clk_debug("%s: set %s rate = %u\n", __FUNCTION__, clk_name,
2193                                 clk_rate);
2194         }
2195
2196         rkclk_init_enable();
2197
2198 }
2199
2200 u32 clk_suspend_clkgt_info_get(u32 *clk_ungt_msk,u32 *clk_ungt_msk_last,u32 buf_cnt)
2201 {
2202
2203     struct device_node *node,*node_gt;
2204     u32 temp_val[2];
2205     int gt_cnt;
2206     int ret;
2207     void __iomem *cru_base,*gt_base, *reg_n, *reg_p;
2208
2209     gt_cnt=0;
2210     cru_base= of_iomap(clk_root_node, 0);
2211
2212     for_each_available_child_of_node(clk_root_node, node) {
2213
2214            if (of_device_is_compatible(node,"rockchip,rk-gate-cons"))
2215             {
2216
2217                 for_each_available_child_of_node(node, node_gt) {
2218
2219                     if(gt_cnt>=buf_cnt)
2220                     {
2221                         clk_err("%s:save buf is overflow\n",__FUNCTION__);
2222                         return 0;
2223                     }
2224
2225                     ret = of_property_read_u32_array(node_gt,"rockchip,suspend-clkgating-setting",temp_val,2);
2226                     if(!ret)
2227                     {
2228                         clk_ungt_msk[gt_cnt]=temp_val[0];
2229                         clk_ungt_msk_last[gt_cnt]=temp_val[1];
2230                     }
2231                     else
2232                     {
2233                         clk_ungt_msk[gt_cnt]=0xffff;
2234                         clk_ungt_msk_last[gt_cnt]=0xffff;
2235                     }
2236
2237                     if(gt_cnt==0)
2238                     {
2239                         gt_base=of_iomap(node_gt, 0);
2240                         reg_p=gt_base;
2241                         reg_n=gt_base;
2242                     }
2243                     else
2244                     {
2245                         reg_n=of_iomap(node_gt, 0);
2246
2247                         if(((long)reg_n-(long)reg_p)!=4)
2248                         {
2249                             printk("%s: gt reg is not continue\n",__FUNCTION__);
2250                             return 0;
2251                         }
2252                         reg_p=reg_n;
2253                     }
2254
2255                     clk_debug("%s:gt%d,reg=%p,val=(%x,%x)\n",__FUNCTION__,gt_cnt, reg_n,
2256                     clk_ungt_msk[gt_cnt], clk_ungt_msk_last[gt_cnt]);
2257
2258                     gt_cnt++;
2259
2260                 }
2261
2262                 break;
2263             }
2264     }
2265
2266     if(gt_cnt!=buf_cnt)
2267     {
2268            clk_err("%s:save buf is not  Enough\n",__FUNCTION__);
2269            return 0;
2270     }
2271     clk_debug("%s:crubase=%x,gtbase=%x\n",__FUNCTION__,cru_base,gt_base);
2272
2273     return (u32)(gt_base-cru_base);
2274
2275 }
2276
2277
2278
2279