rk312x:clk:support set pll clk and modify init clocks
[firefly-linux-kernel-4.4.55.git] / drivers / clk / rockchip / clk-pll.c
1 #include <linux/slab.h>
2 #include <asm/io.h>
3 #include <linux/rockchip/cpu.h>
4
5 #include "clk-ops.h"
6 #include "clk-pll.h"
7
8
9 static const struct pll_clk_set rk3188_pll_com_table[] = {
10         _RK3188_PLL_SET_CLKS(1250000,   12,     625,    1),
11         _RK3188_PLL_SET_CLKS(1200000,   1,      50,     1),
12         _RK3188_PLL_SET_CLKS(1188000,   2,      99,     1),
13         _RK3188_PLL_SET_CLKS(891000,    8,      594,    2),
14         _RK3188_PLL_SET_CLKS(768000,    1,      64,     2),
15         _RK3188_PLL_SET_CLKS(594000,    2,      198,    4),
16         _RK3188_PLL_SET_CLKS(500000,    3,      250,    4),
17         _RK3188_PLL_SET_CLKS(408000,    1,      68,     4),
18         _RK3188_PLL_SET_CLKS(396000,    1,      66,     4),
19         _RK3188_PLL_SET_CLKS(384000,    2,      128,    4),
20         _RK3188_PLL_SET_CLKS(360000,    1,      60,     4),
21         _RK3188_PLL_SET_CLKS(300000,    1,      50,     4),
22         _RK3188_PLL_SET_CLKS(297000,    2,      198,    8),
23         _RK3188_PLL_SET_CLKS(148500,    2,      99,     8),
24         _RK3188_PLL_SET_CLKS(0,         0,      0,      0),
25 };
26
27 static const struct pll_clk_set rk3188plus_pll_com_table[] = {
28         _RK3188PLUS_PLL_SET_CLKS(1250000,       12,     625,    1),
29         _RK3188PLUS_PLL_SET_CLKS(1200000,       1,      50,     1),
30         _RK3188PLUS_PLL_SET_CLKS(1188000,       2,      99,     1),
31         _RK3188PLUS_PLL_SET_CLKS(891000,        8,      594,    2),
32         _RK3188PLUS_PLL_SET_CLKS(768000,        1,      64,     2),
33         _RK3188PLUS_PLL_SET_CLKS(594000,        2,      198,    4),
34         _RK3188PLUS_PLL_SET_CLKS(500000,        3,      250,    4),
35         _RK3188PLUS_PLL_SET_CLKS(408000,        1,      68,     4),
36         _RK3188PLUS_PLL_SET_CLKS(396000,        1,      66,     4),
37         _RK3188PLUS_PLL_SET_CLKS(384000,        2,      128,    4),
38         _RK3188PLUS_PLL_SET_CLKS(360000,        1,      60,     4),
39         _RK3188PLUS_PLL_SET_CLKS(300000,        1,      50,     4),
40         _RK3188PLUS_PLL_SET_CLKS(297000,        2,      198,    8),
41         _RK3188PLUS_PLL_SET_CLKS(148500,        2,      99,     8),
42         _RK3188PLUS_PLL_SET_CLKS(0,             0,      0,      0),
43 };
44
45 static const struct apll_clk_set rk3188_apll_table[] = {
46         //            (_mhz,    nr,     nf,     no,     _periph_div,    _aclk_div)
47         _RK3188_APLL_SET_CLKS(2208,     1,      92,     1,      8,      81),
48         _RK3188_APLL_SET_CLKS(2184,     1,      91,     1,      8,      81),
49         _RK3188_APLL_SET_CLKS(2160,     1,      90,     1,      8,      81),
50         _RK3188_APLL_SET_CLKS(2136,     1,      89,     1,      8,      81),
51         _RK3188_APLL_SET_CLKS(2112,     1,      88,     1,      8,      81),
52         _RK3188_APLL_SET_CLKS(2088,     1,      87,     1,      8,      81),
53         _RK3188_APLL_SET_CLKS(2064,     1,      86,     1,      8,      81),
54         _RK3188_APLL_SET_CLKS(2040,     1,      85,     1,      8,      81),
55         _RK3188_APLL_SET_CLKS(2016,     1,      84,     1,      8,      81),
56         _RK3188_APLL_SET_CLKS(1992,     1,      83,     1,      8,      81),
57         _RK3188_APLL_SET_CLKS(1968,     1,      82,     1,      8,      81),
58         _RK3188_APLL_SET_CLKS(1944,     1,      81,     1,      8,      81),
59         _RK3188_APLL_SET_CLKS(1920,     1,      80,     1,      8,      81),
60         _RK3188_APLL_SET_CLKS(1896,     1,      79,     1,      8,      81),
61         _RK3188_APLL_SET_CLKS(1872,     1,      78,     1,      8,      81),
62         _RK3188_APLL_SET_CLKS(1848,     1,      77,     1,      8,      81),
63         _RK3188_APLL_SET_CLKS(1824,     1,      76,     1,      8,      81),
64         _RK3188_APLL_SET_CLKS(1800,     1,      75,     1,      8,      81),
65         _RK3188_APLL_SET_CLKS(1776,     1,      74,     1,      8,      81),
66         _RK3188_APLL_SET_CLKS(1752,     1,      73,     1,      8,      81),
67         _RK3188_APLL_SET_CLKS(1728,     1,      72,     1,      8,      81),
68         _RK3188_APLL_SET_CLKS(1704,     1,      71,     1,      8,      81),
69         _RK3188_APLL_SET_CLKS(1680,     1,      70,     1,      8,      41),
70         _RK3188_APLL_SET_CLKS(1656,     1,      69,     1,      8,      41),
71         _RK3188_APLL_SET_CLKS(1632,     1,      68,     1,      8,      41),
72         _RK3188_APLL_SET_CLKS(1608,     1,      67,     1,      8,      41),
73         _RK3188_APLL_SET_CLKS(1560,     1,      65,     1,      8,      41),
74         _RK3188_APLL_SET_CLKS(1512,     1,      63,     1,      8,      41),
75         _RK3188_APLL_SET_CLKS(1488,     1,      62,     1,      8,      41),
76         _RK3188_APLL_SET_CLKS(1464,     1,      61,     1,      8,      41),
77         _RK3188_APLL_SET_CLKS(1440,     1,      60,     1,      8,      41),
78         _RK3188_APLL_SET_CLKS(1416,     1,      59,     1,      8,      41),
79         _RK3188_APLL_SET_CLKS(1392,     1,      58,     1,      8,      41),
80         _RK3188_APLL_SET_CLKS(1368,     1,      57,     1,      8,      41),
81         _RK3188_APLL_SET_CLKS(1344,     1,      56,     1,      8,      41),
82         _RK3188_APLL_SET_CLKS(1320,     1,      55,     1,      8,      41),
83         _RK3188_APLL_SET_CLKS(1296,     1,      54,     1,      8,      41),
84         _RK3188_APLL_SET_CLKS(1272,     1,      53,     1,      8,      41),
85         _RK3188_APLL_SET_CLKS(1248,     1,      52,     1,      8,      41),
86         _RK3188_APLL_SET_CLKS(1224,     1,      51,     1,      8,      41),
87         _RK3188_APLL_SET_CLKS(1200,     1,      50,     1,      8,      41),
88         _RK3188_APLL_SET_CLKS(1176,     1,      49,     1,      8,      41),
89         _RK3188_APLL_SET_CLKS(1128,     1,      47,     1,      8,      41),
90         _RK3188_APLL_SET_CLKS(1104,     1,      46,     1,      8,      41),
91         _RK3188_APLL_SET_CLKS(1008,     1,      84,     2,      8,      41),
92         _RK3188_APLL_SET_CLKS(912,      1,      76,     2,      8,      41),
93         _RK3188_APLL_SET_CLKS(888,      1,      74,     2,      8,      41),
94         _RK3188_APLL_SET_CLKS(816,      1,      68,     2,      8,      41),
95         _RK3188_APLL_SET_CLKS(792,      1,      66,     2,      8,      41),
96         _RK3188_APLL_SET_CLKS(696,      1,      58,     2,      8,      41),
97         _RK3188_APLL_SET_CLKS(600,      1,      50,     2,      4,      41),
98         _RK3188_APLL_SET_CLKS(552,      1,      92,     4,      4,      41),
99         _RK3188_APLL_SET_CLKS(504,      1,      84,     4,      4,      41),
100         _RK3188_APLL_SET_CLKS(408,      1,      68,     4,      4,      21),
101         _RK3188_APLL_SET_CLKS(312,      1,      52,     4,      2,      21),
102         _RK3188_APLL_SET_CLKS(252,      1,      84,     8,      2,      21),
103         _RK3188_APLL_SET_CLKS(216,      1,      72,     8,      2,      21),
104         _RK3188_APLL_SET_CLKS(126,      1,      84,     16,     2,      11),
105         _RK3188_APLL_SET_CLKS(48,       1,      32,     16,     2,      11),
106         _RK3188_APLL_SET_CLKS(0,        1,      32,     16,     2,      11),
107 };
108
109 static const struct apll_clk_set rk3288_apll_table[] = {
110         //                   (_mhz,     nr,     nf,     no,     l2ram,  m0,     mp,     atclk,  pclk_dbg)
111         _RK3288_APLL_SET_CLKS(2208,     1,      92,     1,      2,      2,      4,      4,      4),
112         _RK3288_APLL_SET_CLKS(2184,     1,      91,     1,      2,      2,      4,      4,      4),
113         _RK3288_APLL_SET_CLKS(2160,     1,      90,     1,      2,      2,      4,      4,      4),
114         _RK3288_APLL_SET_CLKS(2136,     1,      89,     1,      2,      2,      4,      4,      4),
115         _RK3288_APLL_SET_CLKS(2112,     1,      88,     1,      2,      2,      4,      4,      4),
116         _RK3288_APLL_SET_CLKS(2088,     1,      87,     1,      2,      2,      4,      4,      4),
117         _RK3288_APLL_SET_CLKS(2064,     1,      86,     1,      2,      2,      4,      4,      4),
118         _RK3288_APLL_SET_CLKS(2040,     1,      85,     1,      2,      2,      4,      4,      4),
119         _RK3288_APLL_SET_CLKS(2016,     1,      84,     1,      2,      2,      4,      4,      4),
120         _RK3288_APLL_SET_CLKS(1992,     1,      83,     1,      2,      2,      4,      4,      4),
121         _RK3288_APLL_SET_CLKS(1968,     1,      82,     1,      2,      2,      4,      4,      4),
122         _RK3288_APLL_SET_CLKS(1944,     1,      81,     1,      2,      2,      4,      4,      4),
123         _RK3288_APLL_SET_CLKS(1920,     1,      80,     1,      2,      2,      4,      4,      4),
124         _RK3288_APLL_SET_CLKS(1896,     1,      79,     1,      2,      2,      4,      4,      4),
125         _RK3288_APLL_SET_CLKS(1872,     1,      78,     1,      2,      2,      4,      4,      4),
126         _RK3288_APLL_SET_CLKS(1848,     1,      77,     1,      2,      2,      4,      4,      4),
127         _RK3288_APLL_SET_CLKS(1824,     1,      76,     1,      2,      2,      4,      4,      4),
128         _RK3288_APLL_SET_CLKS(1800,     1,      75,     1,      2,      2,      4,      4,      4),
129         _RK3288_APLL_SET_CLKS(1776,     1,      74,     1,      2,      2,      4,      4,      4),
130         _RK3288_APLL_SET_CLKS(1752,     1,      73,     1,      2,      2,      4,      4,      4),
131         _RK3288_APLL_SET_CLKS(1728,     1,      72,     1,      2,      2,      4,      4,      4),
132         _RK3288_APLL_SET_CLKS(1704,     1,      71,     1,      2,      2,      4,      4,      4),
133         _RK3288_APLL_SET_CLKS(1680,     1,      70,     1,      2,      2,      4,      4,      4),
134         _RK3288_APLL_SET_CLKS(1656,     1,      69,     1,      2,      2,      4,      4,      4),
135         _RK3288_APLL_SET_CLKS(1632,     1,      68,     1,      2,      2,      4,      4,      4),
136         _RK3288_APLL_SET_CLKS(1608,     1,      67,     1,      2,      2,      4,      4,      4),
137         _RK3288_APLL_SET_CLKS(1560,     1,      65,     1,      2,      2,      4,      4,      4),
138         _RK3288_APLL_SET_CLKS(1512,     1,      63,     1,      2,      2,      4,      4,      4),
139         _RK3288_APLL_SET_CLKS(1488,     1,      62,     1,      2,      2,      4,      4,      4),
140         _RK3288_APLL_SET_CLKS(1464,     1,      61,     1,      2,      2,      4,      4,      4),
141         _RK3288_APLL_SET_CLKS(1440,     1,      60,     1,      2,      2,      4,      4,      4),
142         _RK3288_APLL_SET_CLKS(1416,     1,      59,     1,      2,      2,      4,      4,      4),
143         _RK3288_APLL_SET_CLKS(1392,     1,      58,     1,      2,      2,      4,      4,      4),
144         _RK3288_APLL_SET_CLKS(1368,     1,      57,     1,      2,      2,      4,      4,      4),
145         _RK3288_APLL_SET_CLKS(1344,     1,      56,     1,      2,      2,      4,      4,      4),
146         _RK3288_APLL_SET_CLKS(1320,     1,      55,     1,      2,      2,      4,      4,      4),
147         _RK3288_APLL_SET_CLKS(1296,     1,      54,     1,      2,      2,      4,      4,      4),
148         _RK3288_APLL_SET_CLKS(1272,     1,      53,     1,      2,      2,      4,      4,      4),
149         _RK3288_APLL_SET_CLKS(1248,     1,      52,     1,      2,      2,      4,      4,      4),
150         _RK3288_APLL_SET_CLKS(1224,     1,      51,     1,      2,      2,      4,      4,      4),
151         _RK3288_APLL_SET_CLKS(1200,     1,      50,     1,      2,      2,      4,      4,      4),
152         _RK3288_APLL_SET_CLKS(1176,     1,      49,     1,      2,      2,      4,      4,      4),
153         _RK3288_APLL_SET_CLKS(1128,     1,      47,     1,      2,      2,      4,      4,      4),
154         _RK3288_APLL_SET_CLKS(1104,     1,      46,     1,      2,      2,      4,      4,      4),
155         _RK3288_APLL_SET_CLKS(1008,     1,      84,     2,      2,      2,      4,      4,      4),
156         _RK3288_APLL_SET_CLKS(912,      1,      76,     2,      2,      2,      4,      4,      4),
157         _RK3288_APLL_SET_CLKS(888,      1,      74,     2,      2,      2,      4,      4,      4),
158         _RK3288_APLL_SET_CLKS(816,      1,      68,     2,      2,      2,      4,      4,      4),
159         _RK3288_APLL_SET_CLKS(792,      1,      66,     2,      2,      2,      4,      4,      4),
160         _RK3288_APLL_SET_CLKS(696,      1,      58,     2,      2,      2,      4,      4,      4),
161         _RK3288_APLL_SET_CLKS(672,  1,      56,   2,     2,      2,      4,      4,      4),
162         _RK3288_APLL_SET_CLKS(648,  1,      54,   2,     2,      2,      4,      4,      4),
163         _RK3288_APLL_SET_CLKS(624,  1,      52,   2,     2,      2,      4,      4,      4),
164         _RK3288_APLL_SET_CLKS(600,  1,      50, 2,      2,      2,      4,      4,      4),
165         _RK3288_APLL_SET_CLKS(576,  1,      48,   2,     2,      2,      4,      4,      4), 
166         _RK3288_APLL_SET_CLKS(552,      1,      92,     4,      2,      2,      4,      4,      4),
167         _RK3288_APLL_SET_CLKS(528,  1,      88,   4,     2,      2,      4,      4,      4),
168         _RK3288_APLL_SET_CLKS(504,      1,      84,     4,      2,      2,      4,      4,      4),
169         _RK3288_APLL_SET_CLKS(480,  1,      80,   4,     2,      2,      4,      4,      4),
170         _RK3288_APLL_SET_CLKS(456,  1,      76,   4,     2,      2,      4,      4,      4),
171         _RK3288_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      4,      4,      4),
172         _RK3288_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      4,      4,      4),
173         _RK3288_APLL_SET_CLKS(252,      1,      84,     8,      2,      2,      4,      4,      4),
174         _RK3288_APLL_SET_CLKS(216,      1,      72,     8,      2,      2,      4,      4,      4),
175         _RK3288_APLL_SET_CLKS(126,      2,      84,     8,      2,      2,      4,      4,      4),
176         _RK3288_APLL_SET_CLKS(48,       2,      32,     8,      2,      2,      4,      4,      4),
177         _RK3288_APLL_SET_CLKS(0,        1,      32,     16,     2,      2,      4,      4,      4),
178 };
179
180 static const struct apll_clk_set rk3036_apll_table[] = {
181         _RK3036_APLL_SET_CLKS(1608, 1, 67, 1, 1, 1, 0, 81, 41, 41, 21, 21),
182         _RK3036_APLL_SET_CLKS(1584, 1, 66, 1, 1, 1, 0, 81, 41, 41, 21, 21),
183         _RK3036_APLL_SET_CLKS(1560, 1, 65, 1, 1, 1, 0, 81, 41, 41, 21, 21),
184         _RK3036_APLL_SET_CLKS(1536, 1, 64, 1, 1, 1, 0, 81, 41, 41, 21, 21),
185         _RK3036_APLL_SET_CLKS(1512, 1, 63, 1, 1, 1, 0, 81, 41, 41, 21, 21),
186         _RK3036_APLL_SET_CLKS(1488, 1, 62, 1, 1, 1, 0, 81, 41, 41, 21, 21),
187         _RK3036_APLL_SET_CLKS(1464, 1, 61, 1, 1, 1, 0, 81, 41, 41, 21, 21),
188         _RK3036_APLL_SET_CLKS(1440, 1, 60, 1, 1, 1, 0, 81, 41, 41, 21, 21),
189         _RK3036_APLL_SET_CLKS(1416, 1, 59, 1, 1, 1, 0, 81, 41, 41, 21, 21),
190         _RK3036_APLL_SET_CLKS(1392, 1, 58, 1, 1, 1, 0, 81, 41, 41, 21, 21),
191         _RK3036_APLL_SET_CLKS(1368, 1, 57, 1, 1, 1, 0, 81, 41, 41, 21, 21),
192         _RK3036_APLL_SET_CLKS(1344, 1, 56, 1, 1, 1, 0, 81, 41, 41, 21, 21),
193         _RK3036_APLL_SET_CLKS(1320, 1, 55, 1, 1, 1, 0, 81, 41, 41, 21, 21),
194         _RK3036_APLL_SET_CLKS(1296, 1, 54, 1, 1, 1, 0, 81, 81, 41, 21, 21),
195         _RK3036_APLL_SET_CLKS(1272, 1, 53, 1, 1, 1, 0, 81, 41, 41, 21, 21),
196         _RK3036_APLL_SET_CLKS(1248, 1, 52, 1, 1, 1, 0, 81, 41, 41, 21, 21),
197         _RK3036_APLL_SET_CLKS(1200, 1, 50, 1, 1, 1, 0, 81, 41, 41, 21, 21),
198         _RK3036_APLL_SET_CLKS(1104, 1, 46, 1, 1, 1, 0, 81, 41, 41, 21, 21),
199         _RK3036_APLL_SET_CLKS(1100, 12, 550, 1, 1, 1, 0, 81, 41, 41, 21, 21),
200         _RK3036_APLL_SET_CLKS(1008, 1, 84, 2, 1, 1, 0, 81, 41, 41, 21, 21),
201         _RK3036_APLL_SET_CLKS(1000, 6, 500, 2, 1, 1, 0, 81, 41, 41, 21, 21),
202         _RK3036_APLL_SET_CLKS(984, 1, 82, 2, 1, 1, 0, 81, 41, 41, 21, 21),
203         _RK3036_APLL_SET_CLKS(960, 1, 80, 2, 1, 1, 0, 81, 41, 41, 21, 21),
204         _RK3036_APLL_SET_CLKS(936, 1, 78, 2, 1, 1, 0, 81, 41, 41, 21, 21),
205         _RK3036_APLL_SET_CLKS(912, 1, 76, 2, 1, 1, 0, 41, 41, 41, 21, 21),
206         _RK3036_APLL_SET_CLKS(900, 4, 300, 2, 1, 1, 0, 41, 41, 41, 21, 21),
207         _RK3036_APLL_SET_CLKS(888, 1, 74, 2, 1, 1, 0, 41, 41, 41, 21, 21),
208         _RK3036_APLL_SET_CLKS(864, 1, 72, 2, 1, 1, 0, 41, 41, 41, 21, 21),
209         _RK3036_APLL_SET_CLKS(840, 1, 70, 2, 1, 1, 0, 41, 41, 41, 21, 21),
210         _RK3036_APLL_SET_CLKS(816, 1, 68, 2, 1, 1, 0, 41, 41, 41, 21, 21),
211         _RK3036_APLL_SET_CLKS(800, 6, 400, 2, 1, 1, 0, 41, 41, 41, 21, 21),
212         _RK3036_APLL_SET_CLKS(700, 6, 350, 2, 1, 1, 0, 41, 41, 41, 21, 21),
213         _RK3036_APLL_SET_CLKS(696, 1, 58, 2, 1, 1, 0, 41, 41, 41, 21, 21),
214         _RK3036_APLL_SET_CLKS(600, 1, 75, 3, 1, 1, 0, 41, 21, 41, 21, 21),
215         _RK3036_APLL_SET_CLKS(504, 1, 63, 3, 1, 1, 0, 41, 21, 41, 21, 21),
216         _RK3036_APLL_SET_CLKS(500, 6, 250, 2, 1, 1, 0, 41, 21, 41, 21, 21),
217         _RK3036_APLL_SET_CLKS(408, 1, 68, 2, 2, 1, 0, 41, 21, 41, 21, 21),
218         _RK3036_APLL_SET_CLKS(312, 1, 52, 2, 2, 1, 0, 41, 21, 41, 21, 21),
219         _RK3036_APLL_SET_CLKS(216, 1, 72, 4, 2, 1, 0, 41, 21, 41, 21, 21),
220         _RK3036_APLL_SET_CLKS(96, 1, 64, 4, 4, 1, 0, 21, 21, 41, 21, 21),
221         _RK3036_APLL_SET_CLKS(0, 1, 0, 1, 1, 1, 0, 21, 21, 41, 21, 21),
222 };
223
224 static const struct pll_clk_set rk3036plus_pll_com_table[] = {
225         _RK3036_PLL_SET_CLKS(1188000, 2, 99, 1, 1, 1, 0),
226         _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
227         /*_RK3036_PLL_SET_CLKS(297000, 2, 99, 4, 1, 1, 0),*/
228 };
229
230 static const struct pll_clk_set rk312xplus_pll_com_table[] = {
231         /*_RK3036_PLL_SET_CLKS(1064000, 3, 133, 1, 1, 1, 0),*/
232         /*_RK3036_PLL_SET_CLKS(798000, 2, 133, 2, 1, 1, 0),*/
233         _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
234         _RK3036_PLL_SET_CLKS(500000, 6, 250, 2, 1, 1, 0),
235         _RK3036_PLL_SET_CLKS(400000, 6, 400, 2, 2, 1, 0),
236 };
237
238 static void pll_wait_lock(struct clk_hw *hw)
239 {
240         struct clk_pll *pll = to_clk_pll(hw);
241         int delay = 24000000;
242
243
244         while (delay > 0) {
245                 if (grf_readl(pll->status_offset) & (1 << pll->status_shift))
246                         break;
247                 delay--;
248         }
249
250         if (delay == 0) {
251                 clk_err("pll %s: can't lock! status_shift=%u\n"
252                                 "pll_con0=%08x\npll_con1=%08x\n"
253                                 "pll_con2=%08x\npll_con3=%08x\n",
254                                 __clk_get_name(hw->clk),
255                                 pll->status_shift,
256                                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
257                                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
258                                 cru_readl(pll->reg + RK3188_PLL_CON(2)),
259                                 cru_readl(pll->reg + RK3188_PLL_CON(3)));
260
261                 while(1);
262         }
263 }
264
265 static void rk3036_pll_wait_lock(struct clk_hw *hw)
266 {
267         struct clk_pll *pll = to_clk_pll(hw);
268         int delay = 24000000;
269
270
271         while (delay > 0) {
272                 if (cru_readl(pll->status_offset) & (1 << pll->status_shift))
273                         break;
274                 delay--;
275         }
276
277         if (delay == 0) {
278                 clk_err("pll %s: can't lock! status_shift=%u\n"
279                                 "pll_con0=%08x\npll_con1=%08x\n"
280                                 "pll_con2=%08x\n",
281                                 __clk_get_name(hw->clk),
282                                 pll->status_shift,
283                                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
284                                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
285                                 cru_readl(pll->reg + RK3188_PLL_CON(2)));
286                 while (1);
287
288         }
289 }
290
291
292 /* get rate that is most close to target */
293 static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
294                 const struct apll_clk_set *table)
295 {
296         const struct apll_clk_set *ps, *pt;
297
298         ps = pt = table;
299         while (pt->rate) {
300                 if (pt->rate == rate) {
301                         ps = pt;
302                         break;
303                 }
304
305                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
306                         ps = pt;
307                 if (pt->rate < rate)
308                         break;
309                 pt++;
310         }
311
312         return ps;
313 }
314
315 /* get rate that is most close to target */
316 static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
317                 const struct pll_clk_set *table)
318 {
319         const struct pll_clk_set *ps, *pt;
320
321         ps = pt = table;
322         while (pt->rate) {
323                 if (pt->rate == rate) {
324                         ps = pt;
325                         break;
326                 }
327
328                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
329                         ps = pt;
330                 if (pt->rate < rate)
331                         break;
332                 pt++;
333         }
334
335         return ps;
336 }
337
338 /* CLK_PLL_3188 type ops */
339 static unsigned long clk_pll_recalc_rate_3188(struct clk_hw *hw,
340                 unsigned long parent_rate)
341 {
342         struct clk_pll *pll = to_clk_pll(hw);
343         unsigned long rate;
344
345
346         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
347                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
348                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
349
350                 u64 rate64 = (u64)parent_rate * RK3188_PLL_NF(pll_con1);
351
352                 do_div(rate64, RK3188_PLL_NR(pll_con0));
353                 do_div(rate64, RK3188_PLL_NO(pll_con0));
354
355                 rate = rate64;
356         } else {
357                 /*FIXME*/
358                 rate = parent_rate;
359                 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
360         }
361
362         clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
363
364         return rate;
365 }
366
367 static long clk_pll_round_rate_3188(struct clk_hw *hw, unsigned long rate,
368                 unsigned long *prate)
369 {
370         struct clk *parent = __clk_get_parent(hw->clk);
371
372         if (parent && (rate==__clk_get_rate(parent))) {
373                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
374                                 __clk_get_name(hw->clk), rate);
375                 return rate;
376         }
377
378         return (pll_com_get_best_set(rate, rk3188_pll_com_table)->rate);
379 }
380
381 static int _pll_clk_set_rate_3188(struct pll_clk_set *clk_set,
382                 struct clk_hw *hw)
383 {
384         struct clk_pll *pll = to_clk_pll(hw);
385         unsigned long flags = 0;
386
387
388         clk_debug("%s start!\n", __func__);
389
390         if(pll->lock)
391                 spin_lock_irqsave(pll->lock, flags);
392
393         //enter slowmode
394         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
395         //pll power down
396         cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
397         dsb();
398         dsb();
399         dsb();
400         dsb();
401         dsb();
402         dsb();
403         cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
404         cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
405
406         udelay(1);
407
408         //pll no power down
409         cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
410
411         pll_wait_lock(hw);
412
413         //return from slow
414         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
415
416         if (pll->lock)
417                 spin_unlock_irqrestore(pll->lock, flags);
418
419         clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
420                         __clk_get_name(hw->clk),
421                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
422                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
423                         cru_readl(pll->mode_offset));
424
425         clk_debug("%s end!\n", __func__);
426
427         return 0;
428 }
429
430 static int clk_pll_set_rate_3188(struct clk_hw *hw, unsigned long rate,
431                 unsigned long parent_rate)
432 {
433         struct clk_pll *pll = to_clk_pll(hw);
434         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188_pll_com_table);
435         int ret = 0;
436
437
438         if (rate == parent_rate) {
439                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
440                                 __clk_get_name(hw->clk), rate);
441                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
442                                 pll->mode_offset);
443                 /* pll power down */
444                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
445                 clk_debug("pll %s enter slow mode, set rate OK!\n",
446                                 __clk_get_name(hw->clk));
447                 return 0;
448         }
449
450         while(clk_set->rate) {
451                 if (clk_set->rate == rate) {
452                         break;
453                 }
454                 clk_set++;
455         }
456
457         if (clk_set->rate == rate) {
458                 ret = _pll_clk_set_rate_3188(clk_set, hw);
459                 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
460                                 rate);
461         } else {
462                 clk_err("pll %s is no corresponding rate=%lu\n",
463                                 __clk_get_name(hw->clk), rate);
464                 return -EINVAL;
465         }
466
467         return ret;
468 }
469
470 static const struct clk_ops clk_pll_ops_3188 = {
471         .recalc_rate = clk_pll_recalc_rate_3188,
472         .round_rate = clk_pll_round_rate_3188,
473         .set_rate = clk_pll_set_rate_3188,
474 };
475
476
477 /* CLK_PLL_3188_APLL type ops */
478 static unsigned long clk_pll_recalc_rate_3188_apll(struct clk_hw *hw,
479                 unsigned long parent_rate)
480 {
481         return clk_pll_recalc_rate_3188(hw, parent_rate);
482 }
483
484 static long clk_pll_round_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
485                 unsigned long *prate)
486 {
487         struct clk *parent = __clk_get_parent(hw->clk);
488
489         if (parent && (rate==__clk_get_rate(parent))) {
490                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
491                                 __clk_get_name(hw->clk), rate);
492                 return rate;
493         }
494
495         return (apll_get_best_set(rate, rk3188_apll_table)->rate);
496 }
497
498 /* 1: use, 0: no use */
499 #define RK3188_USE_ARM_GPLL     1
500
501 static int clk_pll_set_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
502                 unsigned long parent_rate)
503 {
504         struct clk_pll *pll = to_clk_pll(hw);
505         struct clk *clk = hw->clk;
506         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
507         unsigned long arm_gpll_rate;
508         const struct apll_clk_set *ps;
509         u32 old_aclk_div = 0, new_aclk_div = 0;
510         u32 temp_div;
511         unsigned long flags;
512         int sel_gpll = 0;
513
514
515         if (rate == parent_rate) {
516                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
517                                 __clk_get_name(hw->clk), rate);
518                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
519                                 pll->mode_offset);
520                 /* pll power down */
521                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
522                 clk_debug("pll %s enter slow mode, set rate OK!\n",
523                                 __clk_get_name(hw->clk));
524                 return 0;
525         }
526
527
528 #if !RK3188_USE_ARM_GPLL
529         goto CHANGE_APLL;
530 #endif
531
532         /* prepare arm_gpll before reparent clk_core to it */
533         if (!arm_gpll) {
534                 clk_err("clk arm_gpll is NULL!\n");
535                 goto CHANGE_APLL;
536         }
537
538         /* In rk3188, arm_gpll and cpu_gpll share a same gate,
539          * and aclk_cpu selects cpu_gpll as parent, thus this
540          * gate must keep enabled.
541          */
542 #if 0
543         if (clk_prepare(arm_gpll)) {
544                 clk_err("fail to prepare arm_gpll path\n");
545                 clk_unprepare(arm_gpll);
546                 goto CHANGE_APLL;
547         }
548
549         if (clk_enable(arm_gpll)) {
550                 clk_err("fail to enable arm_gpll path\n");
551                 clk_disable(arm_gpll);
552                 clk_unprepare(arm_gpll);
553                 goto CHANGE_APLL;
554         }
555 #endif
556
557         arm_gpll_rate = __clk_get_rate(arm_gpll);
558         temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
559         temp_div = (temp_div == 0) ? 1 : temp_div;
560         if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
561                 clk_debug("temp_div %d > max_div %d\n", temp_div,
562                                 RK3188_CORE_CLK_MAX_DIV);
563                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
564                                 __clk_get_rate(clk), arm_gpll_rate);
565                 //clk_disable(arm_gpll);
566                 //clk_unprepare(arm_gpll);
567                 goto CHANGE_APLL;
568         }
569
570         local_irq_save(flags);
571
572         /* firstly set div, then select arm_gpll path */
573         cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
574                         RK3188_CRU_CLKSELS_CON(0));
575         cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
576                         RK3188_CRU_CLKSELS_CON(0));
577
578         sel_gpll = 1;
579         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
580         smp_wmb();
581
582         local_irq_restore(flags);
583
584         clk_debug("temp select arm_gpll path, get rate %lu\n",
585                         arm_gpll_rate/temp_div);
586         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
587                         temp_div);
588
589 CHANGE_APLL:
590         ps = apll_get_best_set(rate, rk3188_apll_table);
591         clk_debug("apll will set rate %lu\n", ps->rate);
592         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
593                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
594                         ps->clksel0, ps->clksel1);
595
596         local_irq_save(flags);
597
598         /* If core src don't select gpll, apll need to enter slow mode
599          * before power down
600          */
601         //FIXME
602         //if (!sel_gpll)
603         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
604
605         /* PLL power down */
606         cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
607         dsb();
608         dsb();
609         dsb();
610         dsb();
611         dsb();
612         dsb();
613         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
614         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
615
616         udelay(1);
617
618         /* PLL power up and wait for locked */
619         cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
620         pll_wait_lock(hw);
621
622         old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
623                         RK3188_CORE_ACLK_MSK);
624         new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
625
626         if (new_aclk_div >= old_aclk_div) {
627                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
628                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
629         }
630
631         /* PLL return from slow mode */
632         //FIXME
633         //if (!sel_gpll)
634         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
635
636         /* reparent to apll, and set div to 1 */
637         if (sel_gpll) {
638                 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
639                                 RK3188_CRU_CLKSELS_CON(0));
640                 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
641                                 RK3188_CRU_CLKSELS_CON(0));
642         }
643
644         if (old_aclk_div > new_aclk_div) {
645                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
646                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
647         }
648
649         //loops_per_jiffy = ps->lpj;
650         smp_wmb();
651
652         local_irq_restore(flags);
653
654         if (sel_gpll) {
655                 sel_gpll = 0;
656                 //clk_disable(arm_gpll);
657                 //clk_unprepare(arm_gpll);
658         }
659
660         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
661
662         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
663                         ps->rate,
664                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
665                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
666                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
667                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
668                         cru_readl(RK3188_CRU_CLKSELS_CON(0)),
669                         cru_readl(RK3188_CRU_CLKSELS_CON(1)));
670
671         return 0;
672 }
673
674 static const struct clk_ops clk_pll_ops_3188_apll = {
675         .recalc_rate = clk_pll_recalc_rate_3188_apll,
676         .round_rate = clk_pll_round_rate_3188_apll,
677         .set_rate = clk_pll_set_rate_3188_apll,
678 };
679
680
681 /* CLK_PLL_3188PLUS type ops */
682 static unsigned long clk_pll_recalc_rate_3188plus(struct clk_hw *hw,
683                 unsigned long parent_rate)
684 {
685         struct clk_pll *pll = to_clk_pll(hw);
686         unsigned long rate;
687
688
689         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
690                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
691                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
692
693                 u64 rate64 = (u64)parent_rate * RK3188PLUS_PLL_NF(pll_con1);
694
695                 do_div(rate64, RK3188PLUS_PLL_NR(pll_con0));
696                 do_div(rate64, RK3188PLUS_PLL_NO(pll_con0));
697
698                 rate = rate64;
699         } else {
700                 /*FIXME*/
701                 rate = parent_rate;
702                 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
703         }
704
705         clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
706
707         return rate;
708 }
709
710 static long clk_pll_round_rate_3188plus(struct clk_hw *hw, unsigned long rate,
711                 unsigned long *prate)
712 {
713         struct clk *parent = __clk_get_parent(hw->clk);
714
715         if (parent && (rate==__clk_get_rate(parent))) {
716                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
717                                 __clk_get_name(hw->clk), rate);
718                 return rate;
719         }
720
721         return (pll_com_get_best_set(rate, rk3188plus_pll_com_table)->rate);
722 }
723
724 static int _pll_clk_set_rate_3188plus(struct pll_clk_set *clk_set,
725                 struct clk_hw *hw)
726 {
727         struct clk_pll *pll = to_clk_pll(hw);
728         unsigned long flags = 0;
729
730
731         clk_debug("%s start!\n", __func__);
732
733         if(pll->lock)
734                 spin_lock_irqsave(pll->lock, flags);
735
736         //enter slowmode
737         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
738
739         //enter rest
740         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
741
742         cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
743         cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
744         cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
745
746         udelay(5);
747
748         //return from rest
749         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
750
751         //wating lock state
752         udelay(clk_set->rst_dly);
753
754         pll_wait_lock(hw);
755
756         //return from slow
757         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
758
759         if (pll->lock)
760                 spin_unlock_irqrestore(pll->lock, flags);
761
762         clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
763                         __clk_get_name(hw->clk),
764                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
765                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
766                         cru_readl(pll->mode_offset));
767
768         clk_debug("%s end!\n", __func__);
769
770         return 0;
771 }
772
773 static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
774                 unsigned long parent_rate)
775 {
776         //struct clk_pll *pll = to_clk_pll(hw);
777         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188plus_pll_com_table);
778         int ret = 0;
779
780 #if 0
781         if (rate == parent_rate) {
782                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
783                                 __clk_get_name(hw->clk), rate);
784                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
785                                 pll->mode_offset);
786                 /* pll power down */
787                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
788                 clk_debug("pll %s enter slow mode, set rate OK!\n",
789                                 __clk_get_name(hw->clk));
790                 return 0;
791         }
792 #endif
793
794         while(clk_set->rate) {
795                 if (clk_set->rate == rate) {
796                         break;
797                 }
798                 clk_set++;
799         }
800
801         if (cpu_is_rk3288() && (rate == 297*MHZ)) {
802                 if((strncmp(__clk_get_name(hw->clk), "clk_gpll",
803                         strlen("clk_gpll")) == 0)) {
804
805                         printk("rk3288 set GPLL BW 20 for HDMI!\n");
806                         clk_set->pllcon2 = RK3188_PLL_CLK_BWADJ_SET(20);
807                 }
808         }
809
810         if (clk_set->rate == rate) {
811                 ret = _pll_clk_set_rate_3188plus(clk_set, hw);
812                 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
813                                 rate);
814         } else {
815                 clk_err("pll %s is no corresponding rate=%lu\n",
816                                 __clk_get_name(hw->clk), rate);
817                 return -EINVAL;
818         }
819
820         return ret;
821 }
822
823 static const struct clk_ops clk_pll_ops_3188plus = {
824         .recalc_rate = clk_pll_recalc_rate_3188plus,
825         .round_rate = clk_pll_round_rate_3188plus,
826         .set_rate = clk_pll_set_rate_3188plus,
827 };
828
829 /* CLK_PLL_3188PLUS_AUTO type ops */
830 #define PLL_FREF_MIN (269*KHZ)
831 #define PLL_FREF_MAX (2200*MHZ)
832
833 #define PLL_FVCO_MIN (440*MHZ)
834 #define PLL_FVCO_MAX (2200*MHZ)
835
836 #define PLL_FOUT_MIN (27500*KHZ) 
837 #define PLL_FOUT_MAX (2200*MHZ)
838
839 #define PLL_NF_MAX (4096)
840 #define PLL_NR_MAX (64)
841 #define PLL_NO_MAX (16)
842
843 static u32 clk_gcd(u32 numerator, u32 denominator)
844 {
845         u32 a, b;
846
847         if (!numerator || !denominator)
848                 return 0;
849         if (numerator > denominator) {
850                 a = numerator;
851                 b = denominator;
852         } else {
853                 a = denominator;
854                 b = numerator;
855         }
856         while (b != 0) {
857                 int r = b;
858                 b = a % b;
859                 a = r;
860         }
861
862         return a;
863 }
864
865 /* FIXME: calc using u64 */
866 static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
867                                 u32 *best_nr, u32 *best_nf, u32 *best_no)
868 {
869         u32 nr, nf, no, nonr;
870         u32 nr_out, nf_out, no_out;
871         u32 n;
872         u32 YFfenzi;
873         u32 YFfenmu;
874         u64 fref, fvco, fout;
875         u32 gcd_val = 0;
876
877
878         nr_out = PLL_NR_MAX + 1;
879         no_out = 0;
880
881 //      printk("pll_clk_get_set fin=%lu,fout=%lu\n", fin_hz, fout_hz);
882         if(!fin_hz || !fout_hz || fout_hz == fin_hz)
883                 return -EINVAL;
884         gcd_val = clk_gcd(fin_hz, fout_hz);
885
886 //      printk("gcd_val = %d\n",gcd_val);
887
888         YFfenzi = fout_hz / gcd_val;
889         YFfenmu = fin_hz / gcd_val;
890
891 //      printk("YFfenzi = %d, YFfenmu = %d\n",YFfenzi,YFfenmu);
892
893         for(n = 1;; n++) {
894                nf = YFfenzi * n;
895                nonr = YFfenmu * n;
896                if(nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
897                        break;
898                for(no = 1; no <= PLL_NO_MAX; no++) {
899                        if(!(no == 1 || !(no % 2)))
900                                continue;
901
902                        if(nonr % no)
903                                continue;
904                        nr = nonr / no;
905
906                        if(nr > PLL_NR_MAX) //PLL_NR_MAX
907                                continue;
908
909                        fref = fin_hz / nr;
910                        if(fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
911                                continue;
912
913                        fvco = fref * nf;
914                        if(fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
915                                continue;
916                        fout = fvco / no;
917                        if(fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
918                                continue;
919
920                        /* output all available PLL settings */
921                        //printk("nr=%d,\tnf=%d,\tno=%d\n",nr,nf,no);
922                        //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr,nf,no);
923
924                        /* select the best from all available PLL settings */
925                        if((nr < nr_out) || ((nr == nr_out)&&(no > no_out)))
926                        {
927                                nr_out = nr;
928                                nf_out = nf;
929                                no_out = no;
930                        }
931                }
932
933        }
934
935         /* output the best PLL setting */
936         if((nr_out <= PLL_NR_MAX) && (no_out > 0)){
937                 //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr_out,nf_out,no_out);
938                 if(best_nr && best_nf && best_no){
939                         *best_nr = nr_out;
940                         *best_nf = nf_out;
941                         *best_no = no_out;
942                 }
943                 return 0;
944         } else {
945                 return -EINVAL;
946         }
947 }
948
949 static unsigned long clk_pll_recalc_rate_3188plus_auto(struct clk_hw *hw,
950                 unsigned long parent_rate)
951 {
952         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
953 }
954
955 static long clk_pll_round_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
956                 unsigned long *prate)
957 {
958         unsigned long best;
959
960         for(best=rate; best>0; best--){
961                 if(!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
962                         return best;
963         }
964
965         return 0;
966 }
967
968 static int clk_pll_set_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
969                 unsigned long parent_rate)
970 {
971         unsigned long best;
972         u32 nr,nf,no;
973         struct pll_clk_set clk_set;
974         int ret;
975
976
977         best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
978
979         if(!best)
980                 return -EINVAL;
981
982         pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
983
984         /* prepare clk_set */
985         clk_set.rate = best;
986         clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
987         clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
988         clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
989         clk_set.rst_dly = ((nr*500)/24+1);
990
991         ret = _pll_clk_set_rate_3188plus(&clk_set, hw);
992         clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk), best);
993
994         return ret;
995 }
996
997
998 static const struct clk_ops clk_pll_ops_3188plus_auto = {
999         .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
1000         .round_rate = clk_pll_round_rate_3188plus_auto,
1001         .set_rate = clk_pll_set_rate_3188plus_auto,
1002 };
1003
1004
1005 /* CLK_PLL_3188PLUS_APLL type ops */
1006 static unsigned long clk_pll_recalc_rate_3188plus_apll(struct clk_hw *hw,
1007                 unsigned long parent_rate)
1008 {
1009         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1010 }
1011
1012 static long clk_pll_round_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
1013                 unsigned long *prate)
1014 {
1015         return clk_pll_round_rate_3188_apll(hw, rate, prate);
1016 }
1017
1018 /* 1: use, 0: no use */
1019 #define RK3188PLUS_USE_ARM_GPLL 1
1020
1021 static int clk_pll_set_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
1022                 unsigned long parent_rate)
1023 {
1024         struct clk_pll *pll = to_clk_pll(hw);
1025         struct clk *clk = hw->clk;
1026         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1027         unsigned long arm_gpll_rate;
1028         const struct apll_clk_set *ps;
1029         u32 old_aclk_div = 0, new_aclk_div = 0;
1030         u32 temp_div;
1031         unsigned long flags;
1032         int sel_gpll = 0;
1033
1034 #if 0
1035         if (rate == parent_rate) {
1036                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1037                                 __clk_get_name(hw->clk), rate);
1038                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1039                                 pll->mode_offset);
1040                 /* pll power down */
1041                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1042                 clk_debug("pll %s enter slow mode, set rate OK!\n",
1043                                 __clk_get_name(hw->clk));
1044                 return 0;
1045         }
1046 #endif
1047
1048
1049 #if !RK3188PLUS_USE_ARM_GPLL
1050         goto CHANGE_APLL;
1051 #endif
1052
1053         /* prepare arm_gpll before reparent clk_core to it */
1054         if (!arm_gpll) {
1055                 clk_err("clk arm_gpll is NULL!\n");
1056                 goto CHANGE_APLL;
1057         }
1058
1059         /* In rk3188plus, arm_gpll and cpu_gpll share a same gate,
1060          * and aclk_cpu selects cpu_gpll as parent, thus this
1061          * gate must keep enabled.
1062          */
1063 #if 0
1064         if (clk_prepare(arm_gpll)) {
1065                 clk_err("fail to prepare arm_gpll path\n");
1066                 clk_unprepare(arm_gpll);
1067                 goto CHANGE_APLL;
1068         }
1069
1070         if (clk_enable(arm_gpll)) {
1071                 clk_err("fail to enable arm_gpll path\n");
1072                 clk_disable(arm_gpll);
1073                 clk_unprepare(arm_gpll);
1074                 goto CHANGE_APLL;
1075         }
1076 #endif
1077
1078         arm_gpll_rate = __clk_get_rate(arm_gpll);
1079         temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
1080         temp_div = (temp_div == 0) ? 1 : temp_div;
1081         if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
1082                 clk_debug("temp_div %d > max_div %d\n", temp_div,
1083                                 RK3188_CORE_CLK_MAX_DIV);
1084                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1085                                 __clk_get_rate(clk), arm_gpll_rate);
1086                 //clk_disable(arm_gpll);
1087                 //clk_unprepare(arm_gpll);
1088                 goto CHANGE_APLL;
1089         }
1090
1091         local_irq_save(flags);
1092
1093         /* firstly set div, then select arm_gpll path */
1094         cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
1095                         RK3188_CRU_CLKSELS_CON(0));
1096         cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
1097                         RK3188_CRU_CLKSELS_CON(0));
1098
1099         sel_gpll = 1;
1100         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1101         smp_wmb();
1102
1103         local_irq_restore(flags);
1104
1105         clk_debug("temp select arm_gpll path, get rate %lu\n",
1106                         arm_gpll_rate/temp_div);
1107         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1108                         temp_div);
1109
1110 CHANGE_APLL:
1111         ps = apll_get_best_set(rate, rk3188_apll_table);
1112         clk_debug("apll will set rate %lu\n", ps->rate);
1113         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1114                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
1115                         ps->clksel0, ps->clksel1);
1116
1117         local_irq_save(flags);
1118
1119         /* If core src don't select gpll, apll need to enter slow mode
1120          * before reset
1121          */
1122         //FIXME
1123         //if (!sel_gpll)
1124         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1125
1126         /* PLL enter rest */
1127         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1128
1129         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1130         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1131         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1132
1133         udelay(5);
1134
1135         /* return from rest */
1136         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1137
1138         //wating lock state
1139         udelay(ps->rst_dly);
1140         pll_wait_lock(hw);
1141
1142         old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
1143                         RK3188_CORE_ACLK_MSK);
1144         new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
1145
1146         if (new_aclk_div >= old_aclk_div) {
1147                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1148                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1149         }
1150
1151         /* PLL return from slow mode */
1152         //FIXME
1153         //if (!sel_gpll)
1154         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1155
1156         /* reparent to apll, and set div to 1 */
1157         if (sel_gpll) {
1158                 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
1159                                 RK3188_CRU_CLKSELS_CON(0));
1160                 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
1161                                 RK3188_CRU_CLKSELS_CON(0));
1162         }
1163
1164         if (old_aclk_div > new_aclk_div) {
1165                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1166                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1167         }
1168
1169         //loops_per_jiffy = ps->lpj;
1170         smp_wmb();
1171
1172         local_irq_restore(flags);
1173
1174         if (sel_gpll) {
1175                 sel_gpll = 0;
1176                 //clk_disable(arm_gpll);
1177                 //clk_unprepare(arm_gpll);
1178         }
1179
1180         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1181
1182         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1183                         ps->rate,
1184                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
1185                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
1186                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
1187                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
1188                         cru_readl(RK3188_CRU_CLKSELS_CON(0)),
1189                         cru_readl(RK3188_CRU_CLKSELS_CON(1)));
1190
1191         return 0;
1192 }
1193
1194 static const struct clk_ops clk_pll_ops_3188plus_apll = {
1195         .recalc_rate = clk_pll_recalc_rate_3188plus_apll,
1196         .round_rate = clk_pll_round_rate_3188plus_apll,
1197         .set_rate = clk_pll_set_rate_3188plus_apll,
1198 };
1199
1200 /* CLK_PLL_3288_APLL type ops */
1201 static unsigned long clk_pll_recalc_rate_3288_apll(struct clk_hw *hw,
1202                 unsigned long parent_rate)
1203 {
1204         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1205 }
1206
1207 static long clk_pll_round_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1208                 unsigned long *prate)
1209 {
1210         struct clk *parent = __clk_get_parent(hw->clk);
1211
1212         if (parent && (rate==__clk_get_rate(parent))) {
1213                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1214                                 __clk_get_name(hw->clk), rate);
1215                 return rate;
1216         }
1217
1218         return (apll_get_best_set(rate, rk3288_apll_table)->rate);
1219 }
1220
1221 /* 1: use, 0: no use */
1222 #define RK3288_USE_ARM_GPLL     1
1223
1224 static int clk_pll_set_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1225                 unsigned long parent_rate)
1226 {
1227         struct clk_pll *pll = to_clk_pll(hw);
1228         struct clk *clk = hw->clk;
1229         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1230         unsigned long arm_gpll_rate, temp_rate, old_rate;
1231         const struct apll_clk_set *ps;
1232 //      u32 old_aclk_div = 0, new_aclk_div = 0;
1233         u32 temp_div;
1234         unsigned long flags;
1235         int sel_gpll = 0;
1236
1237
1238 #if 0
1239         if (rate == parent_rate) {
1240                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1241                                 __clk_get_name(hw->clk), rate);
1242                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1243                                 pll->mode_offset);
1244                 /* pll power down */
1245                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1246                 clk_debug("pll %s enter slow mode, set rate OK!\n",
1247                                 __clk_get_name(hw->clk));
1248                 return 0;
1249         }
1250 #endif
1251
1252 #if !RK3288_USE_ARM_GPLL
1253         goto CHANGE_APLL;
1254 #endif
1255
1256         /* prepare arm_gpll before reparent clk_core to it */
1257         if (!arm_gpll) {
1258                 clk_err("clk arm_gpll is NULL!\n");
1259                 goto CHANGE_APLL;
1260         }
1261
1262         arm_gpll_rate = __clk_get_rate(arm_gpll);
1263         old_rate = __clk_get_rate(clk);
1264
1265         temp_rate = (old_rate > rate) ? old_rate : rate;
1266         temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
1267
1268         if (temp_div > RK3288_CORE_CLK_MAX_DIV) {
1269                 clk_debug("temp_div %d > max_div %d\n", temp_div,
1270                                 RK3288_CORE_CLK_MAX_DIV);
1271                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1272                                 __clk_get_rate(clk), arm_gpll_rate);
1273                 goto CHANGE_APLL;
1274         }
1275
1276 #if 0
1277         if (clk_prepare(arm_gpll)) {
1278                 clk_err("fail to prepare arm_gpll path\n");
1279                 clk_unprepare(arm_gpll);
1280                 goto CHANGE_APLL;
1281         }
1282
1283         if (clk_enable(arm_gpll)) {
1284                 clk_err("fail to enable arm_gpll path\n");
1285                 clk_disable(arm_gpll);
1286                 clk_unprepare(arm_gpll);
1287                 goto CHANGE_APLL;
1288         }
1289 #endif
1290
1291         local_irq_save(flags);
1292
1293         /* select gpll */
1294         if (temp_div == 1) {
1295                 /* when old_rate/2 < (old_rate-arm_gpll_rate),
1296                    we can set div to make rate change more gently */
1297                 if (old_rate > (2*arm_gpll_rate)) {
1298                         cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1299                         udelay(10);
1300                         cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1301                         udelay(10);
1302                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1303                                 RK3288_CRU_CLKSELS_CON(0));
1304                         udelay(10);
1305                         cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1306                         udelay(10);
1307                         cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1308                 } else {
1309                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1310                                 RK3288_CRU_CLKSELS_CON(0));
1311                 }
1312         } else {
1313                 cru_writel(RK3288_CORE_CLK_DIV(temp_div), RK3288_CRU_CLKSELS_CON(0));
1314                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1315                                 RK3288_CRU_CLKSELS_CON(0));
1316         }
1317
1318         sel_gpll = 1;
1319         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1320         smp_wmb();
1321
1322         local_irq_restore(flags);
1323
1324         clk_debug("temp select arm_gpll path, get rate %lu\n",
1325                         arm_gpll_rate/temp_div);
1326         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1327                         temp_div);
1328
1329 CHANGE_APLL:
1330         ps = apll_get_best_set(rate, rk3288_apll_table);
1331         clk_debug("apll will set rate %lu\n", ps->rate);
1332         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1333                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
1334                         ps->clksel0, ps->clksel1);
1335
1336         local_irq_save(flags);
1337
1338         /* If core src don't select gpll, apll need to enter slow mode
1339          * before reset
1340          */
1341         //FIXME
1342         //if (!sel_gpll)
1343         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1344
1345         /* PLL enter rest */
1346         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1347
1348         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1349         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1350         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1351
1352         udelay(5);
1353
1354         /* return from rest */
1355         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1356
1357         //wating lock state
1358         udelay(ps->rst_dly);
1359         pll_wait_lock(hw);
1360
1361         if (rate >= __clk_get_rate(hw->clk)) {
1362                 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1363                 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1364         }
1365
1366         /* PLL return from slow mode */
1367         //FIXME
1368         //if (!sel_gpll)
1369         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1370
1371         /* reparent to apll, and set div to 1 */
1372         if (sel_gpll) {
1373                 if (temp_div == 1) {
1374                         /* when rate/2 < (old_rate-arm_gpll_rate),
1375                            we can set div to make rate change more gently */
1376                         if (rate > (2*arm_gpll_rate)) {
1377                                 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1378                                 udelay(10);
1379                                 cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1380                                 udelay(10);
1381                                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1382                                         RK3288_CRU_CLKSELS_CON(0));
1383                                 udelay(10);
1384                                 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1385                                 udelay(10);
1386                                 cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1387                         } else {
1388                                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1389                                                 RK3288_CRU_CLKSELS_CON(0));
1390                         }
1391                 } else {
1392                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1393                                 RK3288_CRU_CLKSELS_CON(0));
1394                         cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1395                 }
1396         }
1397
1398         if (rate < __clk_get_rate(hw->clk)) {
1399                 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1400                 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1401         }
1402
1403         //loops_per_jiffy = ps->lpj;
1404         smp_wmb();
1405
1406         local_irq_restore(flags);
1407
1408         if (sel_gpll) {
1409                 sel_gpll = 0;
1410                 //clk_disable(arm_gpll);
1411                 //clk_unprepare(arm_gpll);
1412         }
1413
1414         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1415
1416         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1417                         ps->rate,
1418                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
1419                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
1420                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
1421                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
1422                         cru_readl(RK3288_CRU_CLKSELS_CON(0)),
1423                         cru_readl(RK3288_CRU_CLKSELS_CON(1)));
1424
1425         return 0;
1426 }
1427
1428
1429 static const struct clk_ops clk_pll_ops_3288_apll = {
1430         .recalc_rate = clk_pll_recalc_rate_3288_apll,
1431         .round_rate = clk_pll_round_rate_3288_apll,
1432         .set_rate = clk_pll_set_rate_3288_apll,
1433 };
1434
1435 /* CLK_PLL_3036_APLL type ops */
1436 #define FRAC_MODE       0
1437 static unsigned long rk3036_pll_clk_recalc(struct clk_hw *hw,
1438 unsigned long parent_rate)
1439 {
1440         struct clk_pll *pll = to_clk_pll(hw);
1441         unsigned long rate;
1442         unsigned int dsmp = 0;
1443         u64 rate64 = 0, frac_rate64 = 0;
1444
1445         dsmp = RK3036_PLL_GET_DSMPD(cru_readl(pll->reg + RK3188_PLL_CON(1)));
1446
1447         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
1448                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
1449                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
1450                 u32 pll_con2 = cru_readl(pll->reg + RK3188_PLL_CON(2));
1451                 /*integer mode*/
1452                 rate64 = (u64)parent_rate * RK3036_PLL_GET_FBDIV(pll_con0);
1453                 do_div(rate64, RK3036_PLL_GET_REFDIV(pll_con1));
1454
1455                 if (FRAC_MODE == dsmp) {
1456                         /*fractional mode*/
1457                         frac_rate64 = (u64)parent_rate
1458                         * RK3036_PLL_GET_FRAC(pll_con2);
1459                         do_div(frac_rate64, RK3036_PLL_GET_REFDIV(pll_con1));
1460                         rate64 += frac_rate64 >> 24;
1461                         clk_debug("%s frac_rate=%llu(%08x/2^24) by pass mode\n",
1462                                         __func__, frac_rate64 >> 24,
1463                                         RK3036_PLL_GET_FRAC(pll_con2));
1464                 }
1465                 do_div(rate64, RK3036_PLL_GET_POSTDIV1(pll_con0));
1466                 do_div(rate64, RK3036_PLL_GET_POSTDIV2(pll_con1));
1467
1468                 rate = rate64;
1469                 } else {
1470                 rate = parent_rate;
1471                 clk_debug("pll_clk_recalc rate=%lu by pass mode\n", rate);
1472         }
1473         return rate;
1474 }
1475
1476 static unsigned long clk_pll_recalc_rate_3036_apll(struct clk_hw *hw,
1477                 unsigned long parent_rate)
1478 {
1479         return rk3036_pll_clk_recalc(hw, parent_rate);
1480 }
1481
1482 static long clk_pll_round_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
1483                 unsigned long *prate)
1484 {
1485         struct clk *parent = __clk_get_parent(hw->clk);
1486
1487         if (parent && (rate == __clk_get_rate(parent))) {
1488                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1489                                 __clk_get_name(hw->clk), rate);
1490                 return rate;
1491         }
1492
1493         return (apll_get_best_set(rate, rk3036_apll_table)->rate);
1494 }
1495
1496 static  int rk3036_pll_clk_set_rate(struct pll_clk_set *clk_set,
1497         struct clk_hw *hw)
1498 {
1499         struct clk_pll *pll = to_clk_pll(hw);
1500
1501         /*enter slowmode*/
1502         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1503         pll->mode_offset);
1504
1505         cru_writel(clk_set->pllcon0,  pll->reg + RK3188_PLL_CON(0));
1506         cru_writel(clk_set->pllcon1,  pll->reg + RK3188_PLL_CON(1));
1507         cru_writel(clk_set->pllcon2,  pll->reg + RK3188_PLL_CON(2));
1508
1509         clk_debug("pllcon0%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1510         clk_debug("pllcon1%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1511         clk_debug("pllcon2%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1512         /*wating lock state*/
1513         udelay(clk_set->rst_dly);
1514         rk3036_pll_wait_lock(hw);
1515
1516         /*return form slow*/
1517         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
1518         pll->mode_offset);
1519
1520         return 0;
1521 }
1522
1523 #define MIN_FOUTVCO_FREQ        (400 * 1000 * 1000)
1524 #define MAX_FOUTVCO_FREQ        (1600 * 1000 * 1000)
1525 static int rk3036_pll_clk_set_postdiv(unsigned long fout_hz,
1526 u32 *postdiv1, u32 *postdiv2, u32 *foutvco)
1527 {
1528         if (fout_hz < MIN_FOUTVCO_FREQ) {
1529                 for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++)
1530                         for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
1531                                 if (fout_hz * (*postdiv1) * (*postdiv2)
1532                                         >= MIN_FOUTVCO_FREQ && fout_hz
1533                                         * (*postdiv1) * (*postdiv2)
1534                                         <= MAX_FOUTVCO_FREQ) {
1535                                         *foutvco = fout_hz * (*postdiv1)
1536                                                 * (*postdiv2);
1537                                         return 0;
1538                                 }
1539                         }
1540                 clk_debug("CANNOT FINE postdiv1/2 to make fout in range from 400M to 1600M, fout = %lu\n",
1541                                 fout_hz);
1542         } else {
1543                 *postdiv1 = 1;
1544                 *postdiv2 = 1;
1545         }
1546         return 0;
1547 }
1548
1549 static int rk3036_pll_clk_get_set(unsigned long fin_hz, unsigned long fout_hz,
1550                 u32 *refdiv, u32 *fbdiv, u32 *postdiv1,
1551                 u32 *postdiv2, u32 *frac)
1552 {
1553         /* FIXME set postdiv1/2 always 1*/
1554         u32 gcd, foutvco = fout_hz;
1555         u64 fin_64, frac_64;
1556         u32 f_frac;
1557
1558         if (!fin_hz || !fout_hz || fout_hz == fin_hz)
1559                 return -1;
1560
1561         rk3036_pll_clk_set_postdiv(fout_hz, postdiv1, postdiv2, &foutvco);
1562         if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
1563                 fin_hz /= MHZ;
1564                 foutvco /= MHZ;
1565                 gcd = clk_gcd(fin_hz, foutvco);
1566                 *refdiv = fin_hz / gcd;
1567                 *fbdiv = foutvco / gcd;
1568
1569                 *frac = 0;
1570
1571                 clk_debug("fin=%lu,fout=%lu,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
1572                         fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
1573         } else {
1574                 clk_debug("******frac div running, fin_hz=%lu, fout_hz=%lu,fin_INT_mhz=%lu, fout_INT_mhz=%lu\n",
1575                         fin_hz, fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
1576                 clk_debug("******frac get postdiv1=%u, postdiv2=%u,foutvco=%u\n",
1577                         *postdiv1, *postdiv2, foutvco);
1578                 gcd = clk_gcd(fin_hz / MHZ, foutvco / MHZ);
1579                 *refdiv = fin_hz / MHZ / gcd;
1580                 *fbdiv = foutvco / MHZ / gcd;
1581                 clk_debug("******frac get refdiv=%u, fbdiv=%u\n", *refdiv, *fbdiv);
1582
1583                 *frac = 0;
1584
1585                 f_frac = (foutvco % MHZ);
1586                 fin_64 = fin_hz;
1587                 do_div(fin_64, (u64)*refdiv);
1588                 frac_64 = (u64)f_frac << 24;
1589                 do_div(frac_64, fin_64);
1590                 *frac = (u32) frac_64;
1591                 clk_debug("frac=%x\n", *frac);
1592         }
1593         return 0;
1594 }
1595 static int rk3036_pll_set_con(struct clk_hw *hw, u32 refdiv, u32 fbdiv, u32 postdiv1, u32 postdiv2, u32 frac)
1596 {
1597         struct pll_clk_set temp_clk_set;
1598         temp_clk_set.pllcon0 = RK3036_PLL_SET_FBDIV(fbdiv) | RK3036_PLL_SET_POSTDIV1(postdiv1);
1599         temp_clk_set.pllcon1 = RK3036_PLL_SET_REFDIV(refdiv) | RK3036_PLL_SET_POSTDIV2(postdiv2);
1600         if (frac != 0)
1601                 temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(0);
1602         else
1603                 temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(1);
1604
1605         temp_clk_set.pllcon2 = RK3036_PLL_SET_FRAC(frac);
1606         temp_clk_set.rst_dly = 0;
1607         clk_debug("setting....\n");
1608         return rk3036_pll_clk_set_rate(&temp_clk_set, hw);
1609 }
1610
1611 static int clk_pll_set_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
1612                 unsigned long parent_rate)
1613 {
1614         struct clk_pll *pll = to_clk_pll(hw);
1615         unsigned long flags;
1616         u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
1617         struct apll_clk_set *ps = (struct apll_clk_set *)(rk3036_apll_table);
1618
1619         while (ps->rate) {
1620                 if (ps->rate == rate) {
1621                         break;
1622                 }
1623                 ps++;
1624         }
1625
1626         clk_debug("%s %lu\n", __func__,  rate);
1627         clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1628         clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1629         clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1630         clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
1631         clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
1632         if (ps->rate == rate) {
1633                 clk_debug("apll get a rate\n");
1634
1635                 /*enter slowmode*/
1636                 local_irq_save(flags);
1637                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1638                 loops_per_jiffy = LPJ_24M;
1639
1640                 cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1641                 cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1642                 cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1643                 cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
1644                 cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
1645
1646                 clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1647                 clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1648                 clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1649                 clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
1650                 clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
1651
1652                 /*wating lock state*/
1653                 udelay(ps->rst_dly);
1654                 rk3036_pll_wait_lock(hw);
1655
1656                 /*return form slow*/
1657                 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1658                 loops_per_jiffy = ps->lpj;
1659                 local_irq_restore(flags);
1660         } else {
1661                 /*FIXME*/
1662                 rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac);
1663                 rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac);
1664         }
1665         clk_debug("setting OK\n");
1666
1667         return 0;       
1668 }
1669 static const struct clk_ops clk_pll_ops_3036_apll = {
1670         .recalc_rate = clk_pll_recalc_rate_3036_apll,
1671         .round_rate = clk_pll_round_rate_3036_apll,
1672         .set_rate = clk_pll_set_rate_3036_apll,
1673 };
1674
1675
1676 /* CLK_PLL_3036_plus_autotype ops */
1677
1678 static long clk_pll_round_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
1679                 unsigned long *prate)
1680 {
1681         struct clk *parent = __clk_get_parent(hw->clk);
1682
1683         if (parent && (rate == __clk_get_rate(parent))) {
1684                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1685                                 __clk_get_name(hw->clk), rate);
1686                 return rate;
1687         }
1688
1689         return (pll_com_get_best_set(rate, rk3036plus_pll_com_table)->rate);
1690 }
1691
1692 static int clk_pll_set_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
1693                 unsigned long parent_rate)
1694 {
1695         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3036plus_pll_com_table);
1696
1697         clk_debug("******%s\n", __func__);
1698         while (clk_set->rate) {
1699                 clk_debug("******%s clk_set->rate=%lu\n", __func__, clk_set->rate);
1700                 if (clk_set->rate == rate) {
1701                         break;
1702                 }
1703                 clk_set++;
1704         }
1705         if (clk_set->rate == rate) {
1706                 rk3036_pll_clk_set_rate(clk_set, hw);
1707         } else {
1708                 clk_debug("gpll is no corresponding rate=%lu\n", rate);
1709                 return -1;
1710         }
1711         clk_debug("******%s end\n", __func__);
1712
1713         return 0;       
1714 }
1715
1716 static const struct clk_ops clk_pll_ops_3036plus_auto = {
1717         .recalc_rate = clk_pll_recalc_rate_3036_apll,
1718         .round_rate = clk_pll_round_rate_3036plus_auto,
1719         .set_rate = clk_pll_set_rate_3036plus_auto,
1720 };
1721
1722 static long clk_cpll_round_rate_312xplus(struct clk_hw *hw, unsigned long rate,
1723                 unsigned long *prate)
1724 {
1725         struct clk *parent = __clk_get_parent(hw->clk);
1726
1727         if (parent && (rate == __clk_get_rate(parent))) {
1728                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1729                                 __clk_get_name(hw->clk), rate);
1730                 return rate;
1731         }
1732
1733         return (pll_com_get_best_set(rate, rk312xplus_pll_com_table)->rate);
1734 }
1735
1736 static int clk_cpll_set_rate_312xplus(struct clk_hw *hw, unsigned long rate,
1737                 unsigned long parent_rate)
1738 {
1739         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk312xplus_pll_com_table);
1740         u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
1741
1742         while (clk_set->rate) {
1743                 if (clk_set->rate == rate) {
1744                         break;
1745                 }
1746                 clk_set++;
1747         }
1748
1749         if (clk_set->rate == rate) {
1750                 clk_debug("cpll get a rate\n");
1751                 rk3036_pll_clk_set_rate(clk_set, hw);
1752
1753         } else {
1754                 clk_debug("cpll get auto calc a rate\n");
1755                 if (rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac) != 0) {
1756                         pr_err("cpll auto set rate error\n");
1757                         return -ENOENT;
1758                 }
1759                 clk_debug("%s get rate=%lu, refdiv=%u, fbdiv=%u, postdiv1=%u, postdiv2=%u",
1760                                 __func__, rate, refdiv, fbdiv, postdiv1, postdiv2);
1761                 rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac);
1762
1763         }
1764
1765         clk_debug("setting OK\n");
1766         return 0;
1767 }
1768
1769 static const struct clk_ops clk_pll_ops_312xplus = {
1770         .recalc_rate = clk_pll_recalc_rate_3036_apll,
1771         .round_rate = clk_cpll_round_rate_312xplus,
1772         .set_rate = clk_cpll_set_rate_312xplus,
1773 };
1774
1775 const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
1776 {
1777         switch (pll_flags) {
1778                 case CLK_PLL_3188:
1779                         return &clk_pll_ops_3188;
1780
1781                 case CLK_PLL_3188_APLL:
1782                         return &clk_pll_ops_3188_apll;
1783
1784                 case CLK_PLL_3188PLUS:
1785                         return &clk_pll_ops_3188plus;
1786
1787                 case CLK_PLL_3188PLUS_APLL:
1788                         return &clk_pll_ops_3188plus_apll;
1789
1790                 case CLK_PLL_3288_APLL:
1791                         return &clk_pll_ops_3288_apll;
1792
1793                 case CLK_PLL_3188PLUS_AUTO:
1794                         return &clk_pll_ops_3188plus_auto;
1795
1796                 case CLK_PLL_3036_APLL:
1797                         return &clk_pll_ops_3036_apll;
1798
1799                 case CLK_PLL_3036PLUS_AUTO:
1800                         return &clk_pll_ops_3036plus_auto;
1801
1802                 case CLK_PLL_312XPLUS:
1803                         return &clk_pll_ops_312xplus;
1804
1805                 default:
1806                         clk_err("%s: unknown pll_flags!\n", __func__);
1807                         return NULL;
1808         }
1809 }
1810
1811 struct clk *rk_clk_register_pll(struct device *dev, const char *name,
1812                 const char *parent_name, unsigned long flags, u32 reg,
1813                 u32 width, u32 mode_offset, u8 mode_shift,
1814                 u32 status_offset, u8 status_shift, u32 pll_flags,
1815                 spinlock_t *lock)
1816 {
1817         struct clk_pll *pll;
1818         struct clk *clk;
1819         struct clk_init_data init;
1820
1821
1822         clk_debug("%s: pll name = %s, pll_flags = 0x%x, register start!\n",
1823                         __func__, name, pll_flags);
1824
1825         /* allocate the pll */
1826         pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
1827         if (!pll) {
1828                 clk_err("%s: could not allocate pll clk\n", __func__);
1829                 return ERR_PTR(-ENOMEM);
1830         }
1831
1832         init.name = name;
1833         init.flags = flags;
1834         init.parent_names = (parent_name ? &parent_name: NULL);
1835         init.num_parents = (parent_name ? 1 : 0);
1836         init.ops = rk_get_pll_ops(pll_flags);
1837
1838         /* struct clk_pll assignments */
1839         pll->reg = reg;
1840         pll->width = width;
1841         pll->mode_offset = mode_offset;
1842         pll->mode_shift = mode_shift;
1843         pll->status_offset = status_offset;
1844         pll->status_shift = status_shift;
1845         pll->flags = pll_flags;
1846         pll->lock = lock;
1847         pll->hw.init = &init;
1848
1849         /* register the clock */
1850         clk = clk_register(dev, &pll->hw);
1851
1852         if (IS_ERR(clk))
1853                 kfree(pll);
1854
1855         clk_debug("%s: pll name = %s, pll_flags = 0x%x, register finish!\n",
1856                         __func__, name, pll_flags);
1857
1858         return clk;
1859 }
1860