ebbd25c6a2b772d4fdb94972c8963800b731ec08
[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(576000,        1,      48,     2),
35         _RK3188PLUS_PLL_SET_CLKS(500000,        3,      250,    4),
36         _RK3188PLUS_PLL_SET_CLKS(408000,        1,      68,     4),
37         _RK3188PLUS_PLL_SET_CLKS(400000,        3,      200,    4),
38         _RK3188PLUS_PLL_SET_CLKS(396000,        1,      66,     4),
39         _RK3188PLUS_PLL_SET_CLKS(384000,        2,      128,    4),
40         _RK3188PLUS_PLL_SET_CLKS(360000,        1,      60,     4),
41         _RK3188PLUS_PLL_SET_CLKS(300000,        1,      50,     4),
42         _RK3188PLUS_PLL_SET_CLKS(297000,        2,      198,    8),
43         _RK3188PLUS_PLL_SET_CLKS(148500,        2,      99,     8),
44         _RK3188PLUS_PLL_SET_CLKS(0,             0,      0,      0),
45 };
46
47 static const struct apll_clk_set rk3188_apll_table[] = {
48         //            (_mhz,    nr,     nf,     no,     _periph_div,    _aclk_div)
49         _RK3188_APLL_SET_CLKS(2208,     1,      92,     1,      8,      81),
50         _RK3188_APLL_SET_CLKS(2184,     1,      91,     1,      8,      81),
51         _RK3188_APLL_SET_CLKS(2160,     1,      90,     1,      8,      81),
52         _RK3188_APLL_SET_CLKS(2136,     1,      89,     1,      8,      81),
53         _RK3188_APLL_SET_CLKS(2112,     1,      88,     1,      8,      81),
54         _RK3188_APLL_SET_CLKS(2088,     1,      87,     1,      8,      81),
55         _RK3188_APLL_SET_CLKS(2064,     1,      86,     1,      8,      81),
56         _RK3188_APLL_SET_CLKS(2040,     1,      85,     1,      8,      81),
57         _RK3188_APLL_SET_CLKS(2016,     1,      84,     1,      8,      81),
58         _RK3188_APLL_SET_CLKS(1992,     1,      83,     1,      8,      81),
59         _RK3188_APLL_SET_CLKS(1968,     1,      82,     1,      8,      81),
60         _RK3188_APLL_SET_CLKS(1944,     1,      81,     1,      8,      81),
61         _RK3188_APLL_SET_CLKS(1920,     1,      80,     1,      8,      81),
62         _RK3188_APLL_SET_CLKS(1896,     1,      79,     1,      8,      81),
63         _RK3188_APLL_SET_CLKS(1872,     1,      78,     1,      8,      81),
64         _RK3188_APLL_SET_CLKS(1848,     1,      77,     1,      8,      81),
65         _RK3188_APLL_SET_CLKS(1824,     1,      76,     1,      8,      81),
66         _RK3188_APLL_SET_CLKS(1800,     1,      75,     1,      8,      81),
67         _RK3188_APLL_SET_CLKS(1776,     1,      74,     1,      8,      81),
68         _RK3188_APLL_SET_CLKS(1752,     1,      73,     1,      8,      81),
69         _RK3188_APLL_SET_CLKS(1728,     1,      72,     1,      8,      81),
70         _RK3188_APLL_SET_CLKS(1704,     1,      71,     1,      8,      81),
71         _RK3188_APLL_SET_CLKS(1680,     1,      70,     1,      8,      41),
72         _RK3188_APLL_SET_CLKS(1656,     1,      69,     1,      8,      41),
73         _RK3188_APLL_SET_CLKS(1632,     1,      68,     1,      8,      41),
74         _RK3188_APLL_SET_CLKS(1608,     1,      67,     1,      8,      41),
75         _RK3188_APLL_SET_CLKS(1560,     1,      65,     1,      8,      41),
76         _RK3188_APLL_SET_CLKS(1512,     1,      63,     1,      8,      41),
77         _RK3188_APLL_SET_CLKS(1488,     1,      62,     1,      8,      41),
78         _RK3188_APLL_SET_CLKS(1464,     1,      61,     1,      8,      41),
79         _RK3188_APLL_SET_CLKS(1440,     1,      60,     1,      8,      41),
80         _RK3188_APLL_SET_CLKS(1416,     1,      59,     1,      8,      41),
81         _RK3188_APLL_SET_CLKS(1392,     1,      58,     1,      8,      41),
82         _RK3188_APLL_SET_CLKS(1368,     1,      57,     1,      8,      41),
83         _RK3188_APLL_SET_CLKS(1344,     1,      56,     1,      8,      41),
84         _RK3188_APLL_SET_CLKS(1320,     1,      55,     1,      8,      41),
85         _RK3188_APLL_SET_CLKS(1296,     1,      54,     1,      8,      41),
86         _RK3188_APLL_SET_CLKS(1272,     1,      53,     1,      8,      41),
87         _RK3188_APLL_SET_CLKS(1248,     1,      52,     1,      8,      41),
88         _RK3188_APLL_SET_CLKS(1224,     1,      51,     1,      8,      41),
89         _RK3188_APLL_SET_CLKS(1200,     1,      50,     1,      8,      41),
90         _RK3188_APLL_SET_CLKS(1176,     1,      49,     1,      8,      41),
91         _RK3188_APLL_SET_CLKS(1128,     1,      47,     1,      8,      41),
92         _RK3188_APLL_SET_CLKS(1104,     1,      46,     1,      8,      41),
93         _RK3188_APLL_SET_CLKS(1008,     1,      84,     2,      8,      41),
94         _RK3188_APLL_SET_CLKS(912,      1,      76,     2,      8,      41),
95         _RK3188_APLL_SET_CLKS(888,      1,      74,     2,      8,      41),
96         _RK3188_APLL_SET_CLKS(816,      1,      68,     2,      8,      41),
97         _RK3188_APLL_SET_CLKS(792,      1,      66,     2,      8,      41),
98         _RK3188_APLL_SET_CLKS(696,      1,      58,     2,      8,      41),
99         _RK3188_APLL_SET_CLKS(600,      1,      50,     2,      4,      41),
100         _RK3188_APLL_SET_CLKS(552,      1,      92,     4,      4,      41),
101         _RK3188_APLL_SET_CLKS(504,      1,      84,     4,      4,      41),
102         _RK3188_APLL_SET_CLKS(408,      1,      68,     4,      4,      21),
103         _RK3188_APLL_SET_CLKS(312,      1,      52,     4,      2,      21),
104         _RK3188_APLL_SET_CLKS(252,      1,      84,     8,      2,      21),
105         _RK3188_APLL_SET_CLKS(216,      1,      72,     8,      2,      21),
106         _RK3188_APLL_SET_CLKS(126,      1,      84,     16,     2,      11),
107         _RK3188_APLL_SET_CLKS(48,       1,      32,     16,     2,      11),
108         _RK3188_APLL_SET_CLKS(0,        1,      32,     16,     2,      11),
109 };
110
111 static const struct apll_clk_set rk3288_apll_table[] = {
112         //                   (_mhz,     nr,     nf,     no,     l2ram,  m0,     mp,     atclk,  pclk_dbg)
113         _RK3288_APLL_SET_CLKS(2208,     1,      92,     1,      2,      2,      4,      4,      4),
114         _RK3288_APLL_SET_CLKS(2184,     1,      91,     1,      2,      2,      4,      4,      4),
115         _RK3288_APLL_SET_CLKS(2160,     1,      90,     1,      2,      2,      4,      4,      4),
116         _RK3288_APLL_SET_CLKS(2136,     1,      89,     1,      2,      2,      4,      4,      4),
117         _RK3288_APLL_SET_CLKS(2112,     1,      88,     1,      2,      2,      4,      4,      4),
118         _RK3288_APLL_SET_CLKS(2088,     1,      87,     1,      2,      2,      4,      4,      4),
119         _RK3288_APLL_SET_CLKS(2064,     1,      86,     1,      2,      2,      4,      4,      4),
120         _RK3288_APLL_SET_CLKS(2040,     1,      85,     1,      2,      2,      4,      4,      4),
121         _RK3288_APLL_SET_CLKS(2016,     1,      84,     1,      2,      2,      4,      4,      4),
122         _RK3288_APLL_SET_CLKS(1992,     1,      83,     1,      2,      2,      4,      4,      4),
123         _RK3288_APLL_SET_CLKS(1968,     1,      82,     1,      2,      2,      4,      4,      4),
124         _RK3288_APLL_SET_CLKS(1944,     1,      81,     1,      2,      2,      4,      4,      4),
125         _RK3288_APLL_SET_CLKS(1920,     1,      80,     1,      2,      2,      4,      4,      4),
126         _RK3288_APLL_SET_CLKS(1896,     1,      79,     1,      2,      2,      4,      4,      4),
127         _RK3288_APLL_SET_CLKS(1872,     1,      78,     1,      2,      2,      4,      4,      4),
128         _RK3288_APLL_SET_CLKS(1848,     1,      77,     1,      2,      2,      4,      4,      4),
129         _RK3288_APLL_SET_CLKS(1824,     1,      76,     1,      2,      2,      4,      4,      4),
130         _RK3288_APLL_SET_CLKS(1800,     1,      75,     1,      2,      2,      4,      4,      4),
131         _RK3288_APLL_SET_CLKS(1776,     1,      74,     1,      2,      2,      4,      4,      4),
132         _RK3288_APLL_SET_CLKS(1752,     1,      73,     1,      2,      2,      4,      4,      4),
133         _RK3288_APLL_SET_CLKS(1728,     1,      72,     1,      2,      2,      4,      4,      4),
134         _RK3288_APLL_SET_CLKS(1704,     1,      71,     1,      2,      2,      4,      4,      4),
135         _RK3288_APLL_SET_CLKS(1680,     1,      70,     1,      2,      2,      4,      4,      4),
136         _RK3288_APLL_SET_CLKS(1656,     1,      69,     1,      2,      2,      4,      4,      4),
137         _RK3288_APLL_SET_CLKS(1632,     1,      68,     1,      2,      2,      4,      4,      4),
138         _RK3288_APLL_SET_CLKS(1608,     1,      67,     1,      2,      2,      4,      4,      4),
139         _RK3288_APLL_SET_CLKS(1560,     1,      65,     1,      2,      2,      4,      4,      4),
140         _RK3288_APLL_SET_CLKS(1512,     1,      63,     1,      2,      2,      4,      4,      4),
141         _RK3288_APLL_SET_CLKS(1488,     1,      62,     1,      2,      2,      4,      4,      4),
142         _RK3288_APLL_SET_CLKS(1464,     1,      61,     1,      2,      2,      4,      4,      4),
143         _RK3288_APLL_SET_CLKS(1440,     1,      60,     1,      2,      2,      4,      4,      4),
144         _RK3288_APLL_SET_CLKS(1416,     1,      59,     1,      2,      2,      4,      4,      4),
145         _RK3288_APLL_SET_CLKS(1392,     1,      58,     1,      2,      2,      4,      4,      4),
146         _RK3288_APLL_SET_CLKS(1368,     1,      57,     1,      2,      2,      4,      4,      4),
147         _RK3288_APLL_SET_CLKS(1344,     1,      56,     1,      2,      2,      4,      4,      4),
148         _RK3288_APLL_SET_CLKS(1320,     1,      55,     1,      2,      2,      4,      4,      4),
149         _RK3288_APLL_SET_CLKS(1296,     1,      54,     1,      2,      2,      4,      4,      4),
150         _RK3288_APLL_SET_CLKS(1272,     1,      53,     1,      2,      2,      4,      4,      4),
151         _RK3288_APLL_SET_CLKS(1248,     1,      52,     1,      2,      2,      4,      4,      4),
152         _RK3288_APLL_SET_CLKS(1224,     1,      51,     1,      2,      2,      4,      4,      4),
153         _RK3288_APLL_SET_CLKS(1200,     1,      50,     1,      2,      2,      4,      4,      4),
154         _RK3288_APLL_SET_CLKS(1176,     1,      49,     1,      2,      2,      4,      4,      4),
155         _RK3288_APLL_SET_CLKS(1128,     1,      47,     1,      2,      2,      4,      4,      4),
156         _RK3288_APLL_SET_CLKS(1104,     1,      46,     1,      2,      2,      4,      4,      4),
157         _RK3288_APLL_SET_CLKS(1008,     1,      84,     2,      2,      2,      4,      4,      4),
158         _RK3288_APLL_SET_CLKS(912,      1,      76,     2,      2,      2,      4,      4,      4),
159         _RK3288_APLL_SET_CLKS(888,      1,      74,     2,      2,      2,      4,      4,      4),
160         _RK3288_APLL_SET_CLKS(816,      1,      68,     2,      2,      2,      4,      4,      4),
161         _RK3288_APLL_SET_CLKS(792,      1,      66,     2,      2,      2,      4,      4,      4),
162         _RK3288_APLL_SET_CLKS(696,      1,      58,     2,      2,      2,      4,      4,      4),
163         _RK3288_APLL_SET_CLKS(672,  1,      56,   2,     2,      2,      4,      4,      4),
164         _RK3288_APLL_SET_CLKS(648,  1,      54,   2,     2,      2,      4,      4,      4),
165         _RK3288_APLL_SET_CLKS(624,  1,      52,   2,     2,      2,      4,      4,      4),
166         _RK3288_APLL_SET_CLKS(600,  1,      50, 2,      2,      2,      4,      4,      4),
167         _RK3288_APLL_SET_CLKS(576,  1,      48,   2,     2,      2,      4,      4,      4), 
168         _RK3288_APLL_SET_CLKS(552,      1,      92,     4,      2,      2,      4,      4,      4),
169         _RK3288_APLL_SET_CLKS(528,  1,      88,   4,     2,      2,      4,      4,      4),
170         _RK3288_APLL_SET_CLKS(504,      1,      84,     4,      2,      2,      4,      4,      4),
171         _RK3288_APLL_SET_CLKS(480,  1,      80,   4,     2,      2,      4,      4,      4),
172         _RK3288_APLL_SET_CLKS(456,  1,      76,   4,     2,      2,      4,      4,      4),
173         _RK3288_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      4,      4,      4),
174         _RK3288_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      4,      4,      4),
175         _RK3288_APLL_SET_CLKS(252,      1,      84,     8,      2,      2,      4,      4,      4),
176         _RK3288_APLL_SET_CLKS(216,      1,      72,     8,      2,      2,      4,      4,      4),
177         _RK3288_APLL_SET_CLKS(126,      2,      84,     8,      2,      2,      4,      4,      4),
178         _RK3288_APLL_SET_CLKS(48,       2,      32,     8,      2,      2,      4,      4,      4),
179         _RK3288_APLL_SET_CLKS(0,        1,      32,     16,     2,      2,      4,      4,      4),
180 };
181
182 static const struct apll_clk_set rk3036_apll_table[] = {
183         _RK3036_APLL_SET_CLKS(1608, 1, 67, 1, 1, 1, 0, 81),
184         _RK3036_APLL_SET_CLKS(1584, 1, 66, 1, 1, 1, 0, 81),
185         _RK3036_APLL_SET_CLKS(1560, 1, 65, 1, 1, 1, 0, 81),
186         _RK3036_APLL_SET_CLKS(1536, 1, 64, 1, 1, 1, 0, 81),
187         _RK3036_APLL_SET_CLKS(1512, 1, 63, 1, 1, 1, 0, 81),
188         _RK3036_APLL_SET_CLKS(1488, 1, 62, 1, 1, 1, 0, 81),
189         _RK3036_APLL_SET_CLKS(1464, 1, 61, 1, 1, 1, 0, 81),
190         _RK3036_APLL_SET_CLKS(1440, 1, 60, 1, 1, 1, 0, 81),
191         _RK3036_APLL_SET_CLKS(1416, 1, 59, 1, 1, 1, 0, 81),
192         _RK3036_APLL_SET_CLKS(1392, 1, 58, 1, 1, 1, 0, 81),
193         _RK3036_APLL_SET_CLKS(1368, 1, 57, 1, 1, 1, 0, 81),
194         _RK3036_APLL_SET_CLKS(1344, 1, 56, 1, 1, 1, 0, 81),
195         _RK3036_APLL_SET_CLKS(1320, 1, 55, 1, 1, 1, 0, 81),
196         _RK3036_APLL_SET_CLKS(1296, 1, 54, 1, 1, 1, 0, 81),
197         _RK3036_APLL_SET_CLKS(1272, 1, 53, 1, 1, 1, 0, 81),
198         _RK3036_APLL_SET_CLKS(1248, 1, 52, 1, 1, 1, 0, 81),
199         _RK3036_APLL_SET_CLKS(1200, 1, 50, 1, 1, 1, 0, 81),
200         _RK3036_APLL_SET_CLKS(1104, 1, 46, 1, 1, 1, 0, 81),
201         _RK3036_APLL_SET_CLKS(1100, 12, 550, 1, 1, 1, 0, 81),
202         _RK3036_APLL_SET_CLKS(1008, 1, 84, 2, 1, 1, 0, 81),
203         _RK3036_APLL_SET_CLKS(1000, 6, 500, 2, 1, 1, 0, 81),
204         _RK3036_APLL_SET_CLKS(984, 1, 82, 2, 1, 1, 0, 81),
205         _RK3036_APLL_SET_CLKS(960, 1, 80, 2, 1, 1, 0, 81),
206         _RK3036_APLL_SET_CLKS(936, 1, 78, 2, 1, 1, 0, 81),
207         _RK3036_APLL_SET_CLKS(912, 1, 76, 2, 1, 1, 0, 41),
208         _RK3036_APLL_SET_CLKS(900, 4, 300, 2, 1, 1, 0, 41),
209         _RK3036_APLL_SET_CLKS(888, 1, 74, 2, 1, 1, 0, 41),
210         _RK3036_APLL_SET_CLKS(864, 1, 72, 2, 1, 1, 0, 41),
211         _RK3036_APLL_SET_CLKS(840, 1, 70, 2, 1, 1, 0, 41),
212         _RK3036_APLL_SET_CLKS(816, 1, 68, 2, 1, 1, 0, 41),
213         _RK3036_APLL_SET_CLKS(800, 6, 400, 2, 1, 1, 0, 41),
214         _RK3036_APLL_SET_CLKS(700, 6, 350, 2, 1, 1, 0, 41),
215         _RK3036_APLL_SET_CLKS(696, 1, 58, 2, 1, 1, 0, 41),
216         _RK3036_APLL_SET_CLKS(600, 1, 75, 3, 1, 1, 0, 41),
217         _RK3036_APLL_SET_CLKS(504, 1, 63, 3, 1, 1, 0, 41),
218         _RK3036_APLL_SET_CLKS(500, 6, 250, 2, 1, 1, 0, 41),
219         _RK3036_APLL_SET_CLKS(408, 1, 68, 2, 2, 1, 0, 41),
220         _RK3036_APLL_SET_CLKS(312, 1, 52, 2, 2, 1, 0, 41),
221         _RK3036_APLL_SET_CLKS(216, 1, 72, 4, 2, 1, 0, 41),
222         _RK3036_APLL_SET_CLKS(96, 1, 64, 4, 4, 1, 0, 21),
223         _RK3036_APLL_SET_CLKS(0, 1, 0, 1, 1, 1, 0, 21),
224 };
225
226 static const struct pll_clk_set rk3036plus_pll_com_table[] = {
227         _RK3036_PLL_SET_CLKS(1188000, 2, 99, 1, 1, 1, 0),
228         _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
229         /*_RK3036_PLL_SET_CLKS(297000, 2, 99, 4, 1, 1, 0),*/
230 };
231
232 static const struct pll_clk_set rk312xplus_pll_com_table[] = {
233         /*_RK3036_PLL_SET_CLKS(1064000, 3, 133, 1, 1, 1, 0),*/
234         /*_RK3036_PLL_SET_CLKS(798000, 2, 133, 2, 1, 1, 0),*/
235         _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
236         _RK3036_PLL_SET_CLKS(500000, 6, 250, 2, 1, 1, 0),
237         _RK3036_PLL_SET_CLKS(400000, 6, 400, 2, 2, 1, 0),
238 };
239
240 static const struct apll_clk_set rk3368_apllb_table[] = {
241                         /*(_mhz,        nr,     nf,     no,     aclkm,  atclk,  pclk_dbg)*/
242         _RK3368_APLL_SET_CLKS(1608,     1,      67,     1,      2,      6,      6),
243         _RK3368_APLL_SET_CLKS(1560,     1,      65,     1,      2,      6,      6),
244         _RK3368_APLL_SET_CLKS(1512,     1,      63,     1,      2,      6,      6),
245         _RK3368_APLL_SET_CLKS(1488,     1,      62,     1,      2,      5,      5),
246         _RK3368_APLL_SET_CLKS(1464,     1,      61,     1,      2,      5,      5),
247         _RK3368_APLL_SET_CLKS(1440,     1,      60,     1,      2,      5,      5),
248         _RK3368_APLL_SET_CLKS(1416,     1,      59,     1,      2,      5,      5),
249         _RK3368_APLL_SET_CLKS(1392,     1,      58,     1,      2,      5,      5),
250         _RK3368_APLL_SET_CLKS(1368,     1,      57,     1,      2,      5,      5),
251         _RK3368_APLL_SET_CLKS(1344,     1,      56,     1,      2,      5,      5),
252         _RK3368_APLL_SET_CLKS(1320,     1,      55,     1,      2,      5,      5),
253         _RK3368_APLL_SET_CLKS(1296,     1,      54,     1,      2,      5,      5),
254         _RK3368_APLL_SET_CLKS(1272,     1,      53,     1,      2,      5,      5),
255         _RK3368_APLL_SET_CLKS(1248,     1,      52,     1,      2,      5,      5),
256         _RK3368_APLL_SET_CLKS(1224,     1,      51,     1,      2,      5,      5),
257         _RK3368_APLL_SET_CLKS(1200,     1,      50,     1,      2,      4,      4),
258         _RK3368_APLL_SET_CLKS(1176,     1,      49,     1,      2,      4,      4),
259         _RK3368_APLL_SET_CLKS(1128,     1,      47,     1,      2,      4,      4),
260         _RK3368_APLL_SET_CLKS(1104,     1,      46,     1,      2,      4,      4),
261         _RK3368_APLL_SET_CLKS(1008,     1,      84,     2,      2,      4,      4),
262         _RK3368_APLL_SET_CLKS(912,      1,      76,     2,      2,      4,      4),
263         _RK3368_APLL_SET_CLKS(888,      1,      74,     2,      2,      3,      3),
264         _RK3368_APLL_SET_CLKS(816,      1,      68,     2,      2,      3,      3),
265         _RK3368_APLL_SET_CLKS(792,      1,      66,     2,      2,      3,      3),
266         _RK3368_APLL_SET_CLKS(696,      1,      58,     2,      2,      3,      3),
267         _RK3368_APLL_SET_CLKS(672,      1,      56,     2,      2,      3,      3),
268         _RK3368_APLL_SET_CLKS(648,      1,      54,     2,      2,      3,      3),
269         _RK3368_APLL_SET_CLKS(624,      1,      52,     2,      2,      3,      3),
270         _RK3368_APLL_SET_CLKS(600,      1,      50,     2,      2,      2,      2),
271         _RK3368_APLL_SET_CLKS(576,      1,      48,     2,      2,      2,      2),
272         _RK3368_APLL_SET_CLKS(552,      1,      92,     4,      2,      2,      2),
273         _RK3368_APLL_SET_CLKS(528,      1,      88,     4,      2,      2,      2),
274         _RK3368_APLL_SET_CLKS(504,      1,      84,     4,      2,      2,      2),
275         _RK3368_APLL_SET_CLKS(480,      1,      80,     4,      2,      2,      2),
276         _RK3368_APLL_SET_CLKS(456,      1,      76,     4,      2,      2,      2),
277         _RK3368_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      2),
278         _RK3368_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      2),
279         _RK3368_APLL_SET_CLKS(252,      1,      84,     8,      2,      1,      1),
280         _RK3368_APLL_SET_CLKS(216,      1,      72,     8,      2,      1,      1),
281         _RK3368_APLL_SET_CLKS(126,      2,      84,     8,      2,      1,      1),
282         _RK3368_APLL_SET_CLKS(48,       2,      32,     8,      2,      1,      1),
283         _RK3368_APLL_SET_CLKS(0,        1,      32,     16,     2,      1,      1),
284 };
285
286 static const struct apll_clk_set rk3368_aplll_table[] = {
287                         /*(_mhz,        nr,     nf,     no,     aclkm,  atclk,  pclk_dbg)*/
288         _RK3368_APLL_SET_CLKS(1608,     1,      67,     1,      2,      7,      7),
289         _RK3368_APLL_SET_CLKS(1560,     1,      65,     1,      2,      7,      7),
290         _RK3368_APLL_SET_CLKS(1512,     1,      63,     1,      2,      7,      7),
291         _RK3368_APLL_SET_CLKS(1488,     1,      62,     1,      2,      6,      6),
292         _RK3368_APLL_SET_CLKS(1464,     1,      61,     1,      2,      6,      6),
293         _RK3368_APLL_SET_CLKS(1440,     1,      60,     1,      2,      6,      6),
294         _RK3368_APLL_SET_CLKS(1416,     1,      59,     1,      2,      6,      6),
295         _RK3368_APLL_SET_CLKS(1392,     1,      58,     1,      2,      6,      6),
296         _RK3368_APLL_SET_CLKS(1368,     1,      57,     1,      2,      6,      6),
297         _RK3368_APLL_SET_CLKS(1344,     1,      56,     1,      2,      6,      6),
298         _RK3368_APLL_SET_CLKS(1320,     1,      55,     1,      2,      6,      6),
299         _RK3368_APLL_SET_CLKS(1296,     1,      54,     1,      2,      6,      6),
300         _RK3368_APLL_SET_CLKS(1272,     1,      53,     1,      2,      6,      6),
301         _RK3368_APLL_SET_CLKS(1248,     1,      52,     1,      2,      5,      5),
302         _RK3368_APLL_SET_CLKS(1224,     1,      51,     1,      2,      5,      5),
303         _RK3368_APLL_SET_CLKS(1200,     1,      50,     1,      2,      5,      5),
304         _RK3368_APLL_SET_CLKS(1176,     1,      49,     1,      2,      5,      5),
305         _RK3368_APLL_SET_CLKS(1128,     1,      47,     1,      2,      5,      5),
306         _RK3368_APLL_SET_CLKS(1104,     1,      46,     1,      2,      5,      5),
307         _RK3368_APLL_SET_CLKS(1008,     1,      84,     2,      2,      5,      5),
308         _RK3368_APLL_SET_CLKS(912,      1,      76,     2,      2,      4,      4),
309         _RK3368_APLL_SET_CLKS(888,      1,      74,     2,      2,      4,      4),
310         _RK3368_APLL_SET_CLKS(816,      1,      68,     2,      2,      4,      4),
311         _RK3368_APLL_SET_CLKS(792,      1,      66,     2,      2,      4,      4),
312         _RK3368_APLL_SET_CLKS(696,      1,      58,     2,      2,      3,      3),
313         _RK3368_APLL_SET_CLKS(672,      1,      56,     2,      2,      3,      3),
314         _RK3368_APLL_SET_CLKS(648,      1,      54,     2,      2,      3,      3),
315         _RK3368_APLL_SET_CLKS(624,      1,      52,     2,      2,      3,      3),
316         _RK3368_APLL_SET_CLKS(600,      1,      50,     2,      2,      3,      3),
317         _RK3368_APLL_SET_CLKS(576,      1,      48,     2,      2,      3,      3),
318         _RK3368_APLL_SET_CLKS(552,      1,      92,     4,      2,      3,      3),
319         _RK3368_APLL_SET_CLKS(528,      1,      88,     4,      2,      3,      3),
320         _RK3368_APLL_SET_CLKS(504,      1,      84,     4,      2,      3,      3),
321         _RK3368_APLL_SET_CLKS(480,      1,      80,     4,      2,      2,      2),
322         _RK3368_APLL_SET_CLKS(456,      1,      76,     4,      2,      2,      2),
323         _RK3368_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      2),
324         _RK3368_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      2),
325         _RK3368_APLL_SET_CLKS(252,      1,      84,     8,      2,      2,      2),
326         _RK3368_APLL_SET_CLKS(216,      1,      72,     8,      2,      1,      1),
327         _RK3368_APLL_SET_CLKS(126,      2,      84,     8,      2,      1,      1),
328         _RK3368_APLL_SET_CLKS(48,       2,      32,     8,      2,      1,      1),
329         _RK3368_APLL_SET_CLKS(0,        1,      32,     16,     2,      1,      1),
330 };
331
332 static const struct pll_clk_set rk3368_pll_table_low_jitter[] = {
333         /*                             _khz, nr,  nf, no, nb */
334         _RK3188PLUS_PLL_SET_CLKS_NB(1188000,  1,  99,  2,  1),
335         _RK3188PLUS_PLL_SET_CLKS_NB(400000,  1,  100,  6,  1),
336         _RK3188PLUS_PLL_SET_CLKS(         0,  0,   0,  0),
337 };
338
339 static void pll_wait_lock(struct clk_hw *hw)
340 {
341         struct clk_pll *pll = to_clk_pll(hw);
342         int delay = 24000000;
343
344         while (delay > 0) {
345                 if (grf_readl(pll->status_offset) & (1 << pll->status_shift))
346                         break;
347                 delay--;
348         }
349
350         if (delay == 0) {
351                 clk_err("pll %s: can't lock! status_shift=%u\n"
352                                 "pll_con0=%08x\npll_con1=%08x\n"
353                                 "pll_con2=%08x\npll_con3=%08x\n",
354                                 __clk_get_name(hw->clk),
355                                 pll->status_shift,
356                                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
357                                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
358                                 cru_readl(pll->reg + RK3188_PLL_CON(2)),
359                                 cru_readl(pll->reg + RK3188_PLL_CON(3)));
360
361                 while(1);
362         }
363 }
364
365 static void rk3036_pll_wait_lock(struct clk_hw *hw)
366 {
367         struct clk_pll *pll = to_clk_pll(hw);
368         int delay = 24000000;
369
370
371         while (delay > 0) {
372                 if (cru_readl(pll->status_offset) & (1 << pll->status_shift))
373                         break;
374                 delay--;
375         }
376
377         if (delay == 0) {
378                 clk_err("pll %s: can't lock! status_shift=%u\n"
379                                 "pll_con0=%08x\npll_con1=%08x\n"
380                                 "pll_con2=%08x\n",
381                                 __clk_get_name(hw->clk),
382                                 pll->status_shift,
383                                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
384                                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
385                                 cru_readl(pll->reg + RK3188_PLL_CON(2)));
386                 while (1);
387
388         }
389 }
390
391
392 /* get rate that is most close to target */
393 static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
394                 const struct apll_clk_set *table)
395 {
396         const struct apll_clk_set *ps, *pt;
397
398         ps = pt = table;
399         while (pt->rate) {
400                 if (pt->rate == rate) {
401                         ps = pt;
402                         break;
403                 }
404
405                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
406                         ps = pt;
407                 if (pt->rate < rate)
408                         break;
409                 pt++;
410         }
411
412         return ps;
413 }
414
415 /* get rate that is most close to target */
416 static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
417                 const struct pll_clk_set *table)
418 {
419         const struct pll_clk_set *ps, *pt;
420
421         ps = pt = table;
422         while (pt->rate) {
423                 if (pt->rate == rate) {
424                         ps = pt;
425                         break;
426                 }
427
428                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
429                         ps = pt;
430                 if (pt->rate < rate)
431                         break;
432                 pt++;
433         }
434
435         return ps;
436 }
437
438 /* CLK_PLL_3188 type ops */
439 static unsigned long clk_pll_recalc_rate_3188(struct clk_hw *hw,
440                 unsigned long parent_rate)
441 {
442         struct clk_pll *pll = to_clk_pll(hw);
443         unsigned long rate;
444
445
446         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
447                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
448                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
449
450                 u64 rate64 = (u64)parent_rate * RK3188_PLL_NF(pll_con1);
451
452                 do_div(rate64, RK3188_PLL_NR(pll_con0));
453                 do_div(rate64, RK3188_PLL_NO(pll_con0));
454
455                 rate = rate64;
456         } else {
457                 /*FIXME*/
458                 rate = parent_rate;
459                 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
460         }
461
462         clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
463
464         return rate;
465 }
466
467 static long clk_pll_round_rate_3188(struct clk_hw *hw, unsigned long rate,
468                 unsigned long *prate)
469 {
470         struct clk *parent = __clk_get_parent(hw->clk);
471
472         if (parent && (rate==__clk_get_rate(parent))) {
473                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
474                                 __clk_get_name(hw->clk), rate);
475                 return rate;
476         }
477
478         return (pll_com_get_best_set(rate, rk3188_pll_com_table)->rate);
479 }
480
481 static int _pll_clk_set_rate_3188(struct pll_clk_set *clk_set,
482                 struct clk_hw *hw)
483 {
484         struct clk_pll *pll = to_clk_pll(hw);
485         unsigned long flags = 0;
486
487
488         clk_debug("%s start!\n", __func__);
489
490         if(pll->lock)
491                 spin_lock_irqsave(pll->lock, flags);
492
493         //enter slowmode
494         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
495         //pll power down
496         cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
497         dsb(sy);
498         dsb(sy);
499         dsb(sy);
500         dsb(sy);
501         dsb(sy);
502         dsb(sy);
503         cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
504         cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
505
506         udelay(1);
507
508         //pll no power down
509         cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
510
511         pll_wait_lock(hw);
512
513         //return from slow
514         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
515
516         if (pll->lock)
517                 spin_unlock_irqrestore(pll->lock, flags);
518
519         clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
520                         __clk_get_name(hw->clk),
521                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
522                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
523                         cru_readl(pll->mode_offset));
524
525         clk_debug("%s end!\n", __func__);
526
527         return 0;
528 }
529
530 static int clk_pll_set_rate_3188(struct clk_hw *hw, unsigned long rate,
531                 unsigned long parent_rate)
532 {
533         struct clk_pll *pll = to_clk_pll(hw);
534         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188_pll_com_table);
535         int ret = 0;
536
537
538         if (rate == parent_rate) {
539                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
540                                 __clk_get_name(hw->clk), rate);
541                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
542                                 pll->mode_offset);
543                 /* pll power down */
544                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
545                 clk_debug("pll %s enter slow mode, set rate OK!\n",
546                                 __clk_get_name(hw->clk));
547                 return 0;
548         }
549
550         while(clk_set->rate) {
551                 if (clk_set->rate == rate) {
552                         break;
553                 }
554                 clk_set++;
555         }
556
557         if (clk_set->rate == rate) {
558                 ret = _pll_clk_set_rate_3188(clk_set, hw);
559                 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
560                                 rate);
561         } else {
562                 clk_err("pll %s is no corresponding rate=%lu\n",
563                                 __clk_get_name(hw->clk), rate);
564                 return -EINVAL;
565         }
566
567         return ret;
568 }
569
570 static const struct clk_ops clk_pll_ops_3188 = {
571         .recalc_rate = clk_pll_recalc_rate_3188,
572         .round_rate = clk_pll_round_rate_3188,
573         .set_rate = clk_pll_set_rate_3188,
574 };
575
576
577 /* CLK_PLL_3188_APLL type ops */
578 static unsigned long clk_pll_recalc_rate_3188_apll(struct clk_hw *hw,
579                 unsigned long parent_rate)
580 {
581         return clk_pll_recalc_rate_3188(hw, parent_rate);
582 }
583
584 static long clk_pll_round_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
585                 unsigned long *prate)
586 {
587         struct clk *parent = __clk_get_parent(hw->clk);
588
589         if (parent && (rate==__clk_get_rate(parent))) {
590                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
591                                 __clk_get_name(hw->clk), rate);
592                 return rate;
593         }
594
595         return (apll_get_best_set(rate, rk3188_apll_table)->rate);
596 }
597
598 /* 1: use, 0: no use */
599 #define RK3188_USE_ARM_GPLL     1
600
601 static int clk_pll_set_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
602                 unsigned long parent_rate)
603 {
604         struct clk_pll *pll = to_clk_pll(hw);
605         struct clk *clk = hw->clk;
606         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
607         unsigned long arm_gpll_rate;
608         const struct apll_clk_set *ps;
609         u32 old_aclk_div = 0, new_aclk_div = 0;
610         u32 temp_div;
611         unsigned long flags;
612         int sel_gpll = 0;
613
614
615         if (rate == parent_rate) {
616                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
617                                 __clk_get_name(hw->clk), rate);
618                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
619                                 pll->mode_offset);
620                 /* pll power down */
621                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
622                 clk_debug("pll %s enter slow mode, set rate OK!\n",
623                                 __clk_get_name(hw->clk));
624                 return 0;
625         }
626
627
628 #if !RK3188_USE_ARM_GPLL
629         goto CHANGE_APLL;
630 #endif
631
632         /* prepare arm_gpll before reparent clk_core to it */
633         if (!arm_gpll) {
634                 clk_err("clk arm_gpll is NULL!\n");
635                 goto CHANGE_APLL;
636         }
637
638         /* In rk3188, arm_gpll and cpu_gpll share a same gate,
639          * and aclk_cpu selects cpu_gpll as parent, thus this
640          * gate must keep enabled.
641          */
642 #if 0
643         if (clk_prepare(arm_gpll)) {
644                 clk_err("fail to prepare arm_gpll path\n");
645                 clk_unprepare(arm_gpll);
646                 goto CHANGE_APLL;
647         }
648
649         if (clk_enable(arm_gpll)) {
650                 clk_err("fail to enable arm_gpll path\n");
651                 clk_disable(arm_gpll);
652                 clk_unprepare(arm_gpll);
653                 goto CHANGE_APLL;
654         }
655 #endif
656
657         arm_gpll_rate = __clk_get_rate(arm_gpll);
658         temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
659         temp_div = (temp_div == 0) ? 1 : temp_div;
660         if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
661                 clk_debug("temp_div %d > max_div %d\n", temp_div,
662                                 RK3188_CORE_CLK_MAX_DIV);
663                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
664                                 __clk_get_rate(clk), arm_gpll_rate);
665                 //clk_disable(arm_gpll);
666                 //clk_unprepare(arm_gpll);
667                 goto CHANGE_APLL;
668         }
669
670         local_irq_save(flags);
671
672         /* firstly set div, then select arm_gpll path */
673         cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
674                         RK3188_CRU_CLKSELS_CON(0));
675         cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
676                         RK3188_CRU_CLKSELS_CON(0));
677
678         sel_gpll = 1;
679         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
680         smp_wmb();
681
682         local_irq_restore(flags);
683
684         clk_debug("temp select arm_gpll path, get rate %lu\n",
685                         arm_gpll_rate/temp_div);
686         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
687                         temp_div);
688
689 CHANGE_APLL:
690         ps = apll_get_best_set(rate, rk3188_apll_table);
691         clk_debug("apll will set rate %lu\n", ps->rate);
692         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
693                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
694                         ps->clksel0, ps->clksel1);
695
696         local_irq_save(flags);
697
698         /* If core src don't select gpll, apll need to enter slow mode
699          * before power down
700          */
701         //FIXME
702         //if (!sel_gpll)
703         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
704
705         /* PLL power down */
706         cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
707         dsb(sy);
708         dsb(sy);
709         dsb(sy);
710         dsb(sy);
711         dsb(sy);
712         dsb(sy);
713         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
714         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
715
716         udelay(1);
717
718         /* PLL power up and wait for locked */
719         cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
720         pll_wait_lock(hw);
721
722         old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
723                         RK3188_CORE_ACLK_MSK);
724         new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
725
726         if (new_aclk_div >= old_aclk_div) {
727                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
728                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
729         }
730
731         /* PLL return from slow mode */
732         //FIXME
733         //if (!sel_gpll)
734         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
735
736         /* reparent to apll, and set div to 1 */
737         if (sel_gpll) {
738                 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
739                                 RK3188_CRU_CLKSELS_CON(0));
740                 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
741                                 RK3188_CRU_CLKSELS_CON(0));
742         }
743
744         if (old_aclk_div > new_aclk_div) {
745                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
746                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
747         }
748
749         //loops_per_jiffy = ps->lpj;
750         smp_wmb();
751
752         local_irq_restore(flags);
753
754         if (sel_gpll) {
755                 sel_gpll = 0;
756                 //clk_disable(arm_gpll);
757                 //clk_unprepare(arm_gpll);
758         }
759
760         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
761
762         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
763                         ps->rate,
764                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
765                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
766                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
767                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
768                         cru_readl(RK3188_CRU_CLKSELS_CON(0)),
769                         cru_readl(RK3188_CRU_CLKSELS_CON(1)));
770
771         return 0;
772 }
773
774 static const struct clk_ops clk_pll_ops_3188_apll = {
775         .recalc_rate = clk_pll_recalc_rate_3188_apll,
776         .round_rate = clk_pll_round_rate_3188_apll,
777         .set_rate = clk_pll_set_rate_3188_apll,
778 };
779
780
781 /* CLK_PLL_3188PLUS type ops */
782 static unsigned long clk_pll_recalc_rate_3188plus(struct clk_hw *hw,
783                 unsigned long parent_rate)
784 {
785         struct clk_pll *pll = to_clk_pll(hw);
786         unsigned long rate;
787
788
789         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
790                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
791                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
792
793                 u64 rate64 = (u64)parent_rate * RK3188PLUS_PLL_NF(pll_con1);
794
795                 do_div(rate64, RK3188PLUS_PLL_NR(pll_con0));
796                 do_div(rate64, RK3188PLUS_PLL_NO(pll_con0));
797
798                 rate = rate64;
799         } else {
800                 /*FIXME*/
801                 rate = parent_rate;
802                 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
803         }
804
805         clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
806
807         return rate;
808 }
809
810 static long clk_pll_round_rate_3188plus(struct clk_hw *hw, unsigned long rate,
811                 unsigned long *prate)
812 {
813         struct clk *parent = __clk_get_parent(hw->clk);
814
815         if (parent && (rate==__clk_get_rate(parent))) {
816                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
817                                 __clk_get_name(hw->clk), rate);
818                 return rate;
819         }
820
821         return (pll_com_get_best_set(rate, rk3188plus_pll_com_table)->rate);
822 }
823
824 static int _pll_clk_set_rate_3188plus(struct pll_clk_set *clk_set,
825                 struct clk_hw *hw)
826 {
827         struct clk_pll *pll = to_clk_pll(hw);
828         unsigned long flags = 0;
829
830
831         clk_debug("%s start!\n", __func__);
832
833         if(pll->lock)
834                 spin_lock_irqsave(pll->lock, flags);
835
836         //enter slowmode
837         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
838
839         //enter rest
840         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
841
842         cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
843         cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
844         cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
845
846         udelay(5);
847
848         //return from rest
849         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
850
851         //wating lock state
852         udelay(clk_set->rst_dly);
853
854         pll_wait_lock(hw);
855
856         //return from slow
857         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
858
859         if (pll->lock)
860                 spin_unlock_irqrestore(pll->lock, flags);
861
862         clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
863                         __clk_get_name(hw->clk),
864                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
865                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
866                         cru_readl(pll->mode_offset));
867
868         clk_debug("%s end!\n", __func__);
869
870         return 0;
871 }
872
873 static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
874                 unsigned long parent_rate)
875 {
876         //struct clk_pll *pll = to_clk_pll(hw);
877         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188plus_pll_com_table);
878         int ret = 0;
879
880 #if 0
881         if (rate == parent_rate) {
882                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
883                                 __clk_get_name(hw->clk), rate);
884                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
885                                 pll->mode_offset);
886                 /* pll power down */
887                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
888                 clk_debug("pll %s enter slow mode, set rate OK!\n",
889                                 __clk_get_name(hw->clk));
890                 return 0;
891         }
892 #endif
893
894         while(clk_set->rate) {
895                 if (clk_set->rate == rate) {
896                         break;
897                 }
898                 clk_set++;
899         }
900
901         if (cpu_is_rk3288() && ((rate == 297*MHZ) || (rate == 594*MHZ))) {
902                 if((strncmp(__clk_get_name(hw->clk), "clk_gpll",
903                         strlen("clk_gpll")) == 0)) {
904
905                         printk("rk3288 set GPLL BW 20 for HDMI!\n");
906                         clk_set->pllcon2 = RK3188_PLL_CLK_BWADJ_SET(20);
907                 }
908         }
909
910         if (clk_set->rate == rate) {
911                 ret = _pll_clk_set_rate_3188plus(clk_set, hw);
912                 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
913                                 rate);
914         } else {
915                 clk_err("pll %s is no corresponding rate=%lu\n",
916                                 __clk_get_name(hw->clk), rate);
917                 return -EINVAL;
918         }
919
920         return ret;
921 }
922
923 static int clk_pll_is_enabled_3188plus(struct clk_hw *hw)
924 {
925         unsigned long flags;
926         struct clk_pll *pll = to_clk_pll(hw);
927         int ret;
928
929         if(pll->lock)
930                 spin_lock_irqsave(pll->lock, flags);
931
932         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift))
933                 ret = 1;
934         else
935                 ret = 0;
936
937         if (pll->lock)
938                 spin_unlock_irqrestore(pll->lock, flags);
939
940         return ret;
941 }
942
943 static int clk_pll_enable_3188plus(struct clk_hw *hw)
944 {
945         struct clk_pll *pll = to_clk_pll(hw);
946         unsigned long flags;
947         unsigned long rst_dly;
948         u32 nr;
949
950         clk_debug("%s enter\n", __func__);
951
952         if (clk_pll_is_enabled_3188plus(hw)) {
953                 clk_debug("pll has been enabled\n");
954                 return 0;
955         }
956
957         if(pll->lock)
958                 spin_lock_irqsave(pll->lock, flags);
959
960         //enter slowmode
961         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
962
963         //power up
964         cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(0), pll->reg + RK3188_PLL_CON(3));
965
966         //enter reset
967         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
968
969         //cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
970         //cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
971         //cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
972
973         udelay(5);
974
975         //return from reset
976         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
977
978         //wating lock state
979         nr = RK3188PLUS_PLL_NR(cru_readl(pll->reg + RK3188_PLL_CON(0)));
980         rst_dly = ((nr*500)/24+1);
981         udelay(rst_dly);
982
983         pll_wait_lock(hw);
984
985         //return from slow
986         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
987
988         if (pll->lock)
989                 spin_unlock_irqrestore(pll->lock, flags);
990
991         clk_debug("pll %s dump reg:\n con0=0x%08x,\n con1=0x%08x,\n con2=0x%08x,\n"
992                         "con3=0x%08x,\n mode=0x%08x\n",
993                         __clk_get_name(hw->clk),
994                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
995                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
996                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
997                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
998                         cru_readl(pll->mode_offset));
999
1000         return 0;
1001 }
1002
1003 static void clk_pll_disable_3188plus(struct clk_hw *hw)
1004 {
1005         struct clk_pll *pll = to_clk_pll(hw);
1006         unsigned long flags;
1007
1008         clk_debug("%s enter\n", __func__);
1009
1010         if(pll->lock)
1011                 spin_lock_irqsave(pll->lock, flags);
1012
1013         //enter slowmode
1014         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1015
1016         //power down
1017         cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(1), pll->reg + RK3188_PLL_CON(3));
1018
1019         if (pll->lock)
1020                 spin_unlock_irqrestore(pll->lock, flags);
1021 }
1022
1023 static const struct clk_ops clk_pll_ops_3188plus = {
1024         .recalc_rate = clk_pll_recalc_rate_3188plus,
1025         .round_rate = clk_pll_round_rate_3188plus,
1026         .set_rate = clk_pll_set_rate_3188plus,
1027         .enable = clk_pll_enable_3188plus,
1028         .disable = clk_pll_disable_3188plus,
1029         .is_enabled = clk_pll_is_enabled_3188plus,
1030 };
1031
1032 /* CLK_PLL_3188PLUS_AUTO type ops */
1033 #define PLL_FREF_MIN (269*KHZ)
1034 #define PLL_FREF_MAX (2200*MHZ)
1035
1036 #define PLL_FVCO_MIN (440*MHZ)
1037 #define PLL_FVCO_MAX (2200*MHZ)
1038
1039 #define PLL_FOUT_MIN (27500*KHZ) 
1040 #define PLL_FOUT_MAX (2200*MHZ)
1041
1042 #define PLL_NF_MAX (4096)
1043 #define PLL_NR_MAX (64)
1044 #define PLL_NO_MAX (16)
1045
1046 static u32 clk_gcd(u32 numerator, u32 denominator)
1047 {
1048         u32 a, b;
1049
1050         if (!numerator || !denominator)
1051                 return 0;
1052         if (numerator > denominator) {
1053                 a = numerator;
1054                 b = denominator;
1055         } else {
1056                 a = denominator;
1057                 b = numerator;
1058         }
1059         while (b != 0) {
1060                 int r = b;
1061
1062                 b = a % b;
1063                 a = r;
1064         }
1065
1066         return a;
1067 }
1068
1069 static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
1070                                 u32 *best_nr, u32 *best_nf, u32 *best_no)
1071 {
1072         u32 nr, nf, no, nonr;
1073         u32 nr_out, nf_out, no_out;
1074         u32 n;
1075         u32 YFfenzi;
1076         u32 YFfenmu;
1077         u64 fref, fvco, fout;
1078         u32 gcd_val = 0;
1079
1080         nr_out = PLL_NR_MAX + 1;
1081         no_out = 0;
1082
1083         if (!fin_hz || !fout_hz || fout_hz == fin_hz)
1084                 return -EINVAL;
1085         gcd_val = clk_gcd(fin_hz, fout_hz);
1086
1087         YFfenzi = fout_hz / gcd_val;
1088         YFfenmu = fin_hz / gcd_val;
1089
1090         for (n = 1;; n++) {
1091                 nf = YFfenzi * n;
1092                 nonr = YFfenmu * n;
1093                 if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
1094                         break;
1095
1096                 for (no = 1; no <= PLL_NO_MAX; no++) {
1097                         if (!(no == 1 || !(no % 2)))
1098                                 continue;
1099
1100                         if (nonr % no)
1101                                 continue;
1102                         nr = nonr / no;
1103
1104                         if (nr > PLL_NR_MAX)
1105                                 continue;
1106
1107                         fref = fin_hz / nr;
1108                         if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
1109                                 continue;
1110
1111                         fvco = fref * nf;
1112                         if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
1113                                 continue;
1114
1115                         fout = fvco / no;
1116                         if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
1117                                 continue;
1118
1119                         /* select the best from all available PLL settings */
1120                         if ((no > no_out) || ((no == no_out) && (nr < nr_out))) {
1121                                 nr_out = nr;
1122                                 nf_out = nf;
1123                                 no_out = no;
1124                         }
1125                 }
1126         }
1127
1128         /* output the best PLL setting */
1129         if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) {
1130                 if (best_nr && best_nf && best_no) {
1131                         *best_nr = nr_out;
1132                         *best_nf = nf_out;
1133                         *best_no = no_out;
1134                 }
1135                 return 0;
1136         } else {
1137                 return -EINVAL;
1138         }
1139 }
1140
1141 static unsigned long clk_pll_recalc_rate_3188plus_auto(struct clk_hw *hw,
1142                 unsigned long parent_rate)
1143 {
1144         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1145 }
1146
1147 static long clk_pll_round_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
1148                 unsigned long *prate)
1149 {
1150         unsigned long best;
1151
1152         for(best=rate; best>0; best--){
1153                 if(!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
1154                         return best;
1155         }
1156
1157         return 0;
1158 }
1159
1160 static int clk_pll_set_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
1161                 unsigned long parent_rate)
1162 {
1163         unsigned long best;
1164         u32 nr,nf,no;
1165         struct pll_clk_set clk_set;
1166         int ret;
1167
1168
1169         best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
1170
1171         if(!best)
1172                 return -EINVAL;
1173
1174         pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
1175
1176         /* prepare clk_set */
1177         clk_set.rate = best;
1178         clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
1179         clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
1180         clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
1181         clk_set.rst_dly = ((nr*500)/24+1);
1182
1183         ret = _pll_clk_set_rate_3188plus(&clk_set, hw);
1184         clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk), best);
1185
1186         return ret;
1187 }
1188
1189
1190 static const struct clk_ops clk_pll_ops_3188plus_auto = {
1191         .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
1192         .round_rate = clk_pll_round_rate_3188plus_auto,
1193         .set_rate = clk_pll_set_rate_3188plus_auto,
1194         .enable = clk_pll_enable_3188plus,
1195         .disable = clk_pll_disable_3188plus,
1196         .is_enabled = clk_pll_is_enabled_3188plus,
1197 };
1198
1199 static long clk_pll_round_rate_3368_low_jitter(struct clk_hw *hw,
1200                                                unsigned long rate,
1201                                                unsigned long *prate)
1202 {
1203         unsigned long best;
1204         struct pll_clk_set *p_clk_set;
1205
1206         p_clk_set = (struct pll_clk_set *)(rk3368_pll_table_low_jitter);
1207
1208         while (p_clk_set->rate) {
1209                 if (p_clk_set->rate == rate)
1210                         break;
1211                 p_clk_set++;
1212         }
1213
1214         if (p_clk_set->rate == rate) {
1215                 clk_debug("get rate from table\n");
1216                 return rate;
1217         }
1218
1219         for (best = rate; best > 0; best--) {
1220                 if (!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
1221                         return best;
1222         }
1223
1224         clk_err("%s: can't round rate %lu\n", __func__, rate);
1225         return 0;
1226 }
1227
1228
1229 static int clk_pll_set_rate_3368_low_jitter(struct clk_hw *hw,
1230                                             unsigned long rate,
1231                                             unsigned long parent_rate)
1232 {
1233         unsigned long best;
1234         u32 nr, nf, no;
1235         struct pll_clk_set clk_set, *p_clk_set;
1236         int ret;
1237
1238         p_clk_set = (struct pll_clk_set *)(rk3368_pll_table_low_jitter);
1239
1240         while (p_clk_set->rate) {
1241                 if (p_clk_set->rate == rate)
1242                         break;
1243                 p_clk_set++;
1244         }
1245
1246         if (p_clk_set->rate == rate) {
1247                 clk_debug("get rate from table\n");
1248                 goto set_rate;
1249         }
1250
1251         best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
1252
1253         if (!best)
1254                 return -EINVAL;
1255
1256         pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
1257
1258         /* prepare clk_set */
1259         clk_set.rate = best;
1260         clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
1261         clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
1262         clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
1263         clk_set.rst_dly = ((nr*500)/24+1);
1264
1265         p_clk_set = &clk_set;
1266
1267 set_rate:
1268         ret = _pll_clk_set_rate_3188plus(p_clk_set, hw);
1269         clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
1270                   p_clk_set->rate);
1271
1272         return ret;
1273 }
1274
1275 static const struct clk_ops clk_pll_ops_3368_low_jitter = {
1276         .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
1277         .round_rate = clk_pll_round_rate_3368_low_jitter,
1278         .set_rate = clk_pll_set_rate_3368_low_jitter,
1279         .enable = clk_pll_enable_3188plus,
1280         .disable = clk_pll_disable_3188plus,
1281         .is_enabled = clk_pll_is_enabled_3188plus,
1282 };
1283
1284 /* CLK_PLL_3188PLUS_APLL type ops */
1285 static unsigned long clk_pll_recalc_rate_3188plus_apll(struct clk_hw *hw,
1286                 unsigned long parent_rate)
1287 {
1288         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1289 }
1290
1291 static long clk_pll_round_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
1292                 unsigned long *prate)
1293 {
1294         return clk_pll_round_rate_3188_apll(hw, rate, prate);
1295 }
1296
1297 /* 1: use, 0: no use */
1298 #define RK3188PLUS_USE_ARM_GPLL 1
1299
1300 static int clk_pll_set_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
1301                 unsigned long parent_rate)
1302 {
1303         struct clk_pll *pll = to_clk_pll(hw);
1304         struct clk *clk = hw->clk;
1305         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1306         unsigned long arm_gpll_rate;
1307         const struct apll_clk_set *ps;
1308         u32 old_aclk_div = 0, new_aclk_div = 0;
1309         u32 temp_div;
1310         unsigned long flags;
1311         int sel_gpll = 0;
1312
1313 #if 0
1314         if (rate == parent_rate) {
1315                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1316                                 __clk_get_name(hw->clk), rate);
1317                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1318                                 pll->mode_offset);
1319                 /* pll power down */
1320                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1321                 clk_debug("pll %s enter slow mode, set rate OK!\n",
1322                                 __clk_get_name(hw->clk));
1323                 return 0;
1324         }
1325 #endif
1326
1327
1328 #if !RK3188PLUS_USE_ARM_GPLL
1329         goto CHANGE_APLL;
1330 #endif
1331
1332         /* prepare arm_gpll before reparent clk_core to it */
1333         if (!arm_gpll) {
1334                 clk_err("clk arm_gpll is NULL!\n");
1335                 goto CHANGE_APLL;
1336         }
1337
1338         /* In rk3188plus, arm_gpll and cpu_gpll share a same gate,
1339          * and aclk_cpu selects cpu_gpll as parent, thus this
1340          * gate must keep enabled.
1341          */
1342 #if 0
1343         if (clk_prepare(arm_gpll)) {
1344                 clk_err("fail to prepare arm_gpll path\n");
1345                 clk_unprepare(arm_gpll);
1346                 goto CHANGE_APLL;
1347         }
1348
1349         if (clk_enable(arm_gpll)) {
1350                 clk_err("fail to enable arm_gpll path\n");
1351                 clk_disable(arm_gpll);
1352                 clk_unprepare(arm_gpll);
1353                 goto CHANGE_APLL;
1354         }
1355 #endif
1356
1357         arm_gpll_rate = __clk_get_rate(arm_gpll);
1358         temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
1359         temp_div = (temp_div == 0) ? 1 : temp_div;
1360         if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
1361                 clk_debug("temp_div %d > max_div %d\n", temp_div,
1362                                 RK3188_CORE_CLK_MAX_DIV);
1363                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1364                                 __clk_get_rate(clk), arm_gpll_rate);
1365                 //clk_disable(arm_gpll);
1366                 //clk_unprepare(arm_gpll);
1367                 goto CHANGE_APLL;
1368         }
1369
1370         local_irq_save(flags);
1371
1372         /* firstly set div, then select arm_gpll path */
1373         cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
1374                         RK3188_CRU_CLKSELS_CON(0));
1375         cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
1376                         RK3188_CRU_CLKSELS_CON(0));
1377
1378         sel_gpll = 1;
1379         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1380         smp_wmb();
1381
1382         local_irq_restore(flags);
1383
1384         clk_debug("temp select arm_gpll path, get rate %lu\n",
1385                         arm_gpll_rate/temp_div);
1386         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1387                         temp_div);
1388
1389 CHANGE_APLL:
1390         ps = apll_get_best_set(rate, rk3188_apll_table);
1391         clk_debug("apll will set rate %lu\n", ps->rate);
1392         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1393                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
1394                         ps->clksel0, ps->clksel1);
1395
1396         local_irq_save(flags);
1397
1398         /* If core src don't select gpll, apll need to enter slow mode
1399          * before reset
1400          */
1401         //FIXME
1402         //if (!sel_gpll)
1403         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1404
1405         /* PLL enter rest */
1406         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1407
1408         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1409         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1410         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1411
1412         udelay(5);
1413
1414         /* return from rest */
1415         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1416
1417         //wating lock state
1418         udelay(ps->rst_dly);
1419         pll_wait_lock(hw);
1420
1421         old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
1422                         RK3188_CORE_ACLK_MSK);
1423         new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
1424
1425         if (new_aclk_div >= old_aclk_div) {
1426                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1427                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1428         }
1429
1430         /* PLL return from slow mode */
1431         //FIXME
1432         //if (!sel_gpll)
1433         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1434
1435         /* reparent to apll, and set div to 1 */
1436         if (sel_gpll) {
1437                 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
1438                                 RK3188_CRU_CLKSELS_CON(0));
1439                 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
1440                                 RK3188_CRU_CLKSELS_CON(0));
1441         }
1442
1443         if (old_aclk_div > new_aclk_div) {
1444                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1445                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1446         }
1447
1448         //loops_per_jiffy = ps->lpj;
1449         smp_wmb();
1450
1451         local_irq_restore(flags);
1452
1453         if (sel_gpll) {
1454                 sel_gpll = 0;
1455                 //clk_disable(arm_gpll);
1456                 //clk_unprepare(arm_gpll);
1457         }
1458
1459         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1460
1461         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1462                         ps->rate,
1463                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
1464                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
1465                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
1466                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
1467                         cru_readl(RK3188_CRU_CLKSELS_CON(0)),
1468                         cru_readl(RK3188_CRU_CLKSELS_CON(1)));
1469
1470         return 0;
1471 }
1472
1473 static const struct clk_ops clk_pll_ops_3188plus_apll = {
1474         .recalc_rate = clk_pll_recalc_rate_3188plus_apll,
1475         .round_rate = clk_pll_round_rate_3188plus_apll,
1476         .set_rate = clk_pll_set_rate_3188plus_apll,
1477 };
1478
1479 /* CLK_PLL_3288_APLL type ops */
1480 static unsigned long clk_pll_recalc_rate_3288_apll(struct clk_hw *hw,
1481                 unsigned long parent_rate)
1482 {
1483         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1484 }
1485
1486 static long clk_pll_round_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1487                 unsigned long *prate)
1488 {
1489         struct clk *parent = __clk_get_parent(hw->clk);
1490
1491         if (parent && (rate==__clk_get_rate(parent))) {
1492                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1493                                 __clk_get_name(hw->clk), rate);
1494                 return rate;
1495         }
1496
1497         return (apll_get_best_set(rate, rk3288_apll_table)->rate);
1498 }
1499
1500 /* 1: use, 0: no use */
1501 #define RK3288_USE_ARM_GPLL     1
1502
1503 static int clk_pll_set_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1504                 unsigned long parent_rate)
1505 {
1506         struct clk_pll *pll = to_clk_pll(hw);
1507         struct clk *clk = hw->clk;
1508         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1509         unsigned long arm_gpll_rate, temp_rate, old_rate;
1510         const struct apll_clk_set *ps;
1511 //      u32 old_aclk_div = 0, new_aclk_div = 0;
1512         u32 temp_div;
1513         unsigned long flags;
1514         int sel_gpll = 0;
1515
1516
1517 #if 0
1518         if (rate == parent_rate) {
1519                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1520                                 __clk_get_name(hw->clk), rate);
1521                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1522                                 pll->mode_offset);
1523                 /* pll power down */
1524                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1525                 clk_debug("pll %s enter slow mode, set rate OK!\n",
1526                                 __clk_get_name(hw->clk));
1527                 return 0;
1528         }
1529 #endif
1530
1531 #if !RK3288_USE_ARM_GPLL
1532         goto CHANGE_APLL;
1533 #endif
1534
1535         /* prepare arm_gpll before reparent clk_core to it */
1536         if (!arm_gpll) {
1537                 clk_err("clk arm_gpll is NULL!\n");
1538                 goto CHANGE_APLL;
1539         }
1540
1541         arm_gpll_rate = __clk_get_rate(arm_gpll);
1542         old_rate = __clk_get_rate(clk);
1543
1544         temp_rate = (old_rate > rate) ? old_rate : rate;
1545         temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
1546
1547         if (temp_div > RK3288_CORE_CLK_MAX_DIV) {
1548                 clk_debug("temp_div %d > max_div %d\n", temp_div,
1549                                 RK3288_CORE_CLK_MAX_DIV);
1550                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1551                                 __clk_get_rate(clk), arm_gpll_rate);
1552                 goto CHANGE_APLL;
1553         }
1554
1555 #if 0
1556         if (clk_prepare(arm_gpll)) {
1557                 clk_err("fail to prepare arm_gpll path\n");
1558                 clk_unprepare(arm_gpll);
1559                 goto CHANGE_APLL;
1560         }
1561
1562         if (clk_enable(arm_gpll)) {
1563                 clk_err("fail to enable arm_gpll path\n");
1564                 clk_disable(arm_gpll);
1565                 clk_unprepare(arm_gpll);
1566                 goto CHANGE_APLL;
1567         }
1568 #endif
1569
1570         local_irq_save(flags);
1571
1572         /* select gpll */
1573         if (temp_div == 1) {
1574                 /* when old_rate/2 < (old_rate-arm_gpll_rate),
1575                    we can set div to make rate change more gently */
1576                 if (old_rate > (2*arm_gpll_rate)) {
1577                         cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1578                         udelay(10);
1579                         cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1580                         udelay(10);
1581                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1582                                 RK3288_CRU_CLKSELS_CON(0));
1583                         udelay(10);
1584                         cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1585                         udelay(10);
1586                         cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1587                 } else {
1588                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1589                                 RK3288_CRU_CLKSELS_CON(0));
1590                 }
1591         } else {
1592                 cru_writel(RK3288_CORE_CLK_DIV(temp_div), RK3288_CRU_CLKSELS_CON(0));
1593                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1594                                 RK3288_CRU_CLKSELS_CON(0));
1595         }
1596
1597         sel_gpll = 1;
1598         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1599         smp_wmb();
1600
1601         local_irq_restore(flags);
1602
1603         clk_debug("temp select arm_gpll path, get rate %lu\n",
1604                         arm_gpll_rate/temp_div);
1605         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1606                         temp_div);
1607
1608 CHANGE_APLL:
1609         ps = apll_get_best_set(rate, rk3288_apll_table);
1610         clk_debug("apll will set rate %lu\n", ps->rate);
1611         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1612                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
1613                         ps->clksel0, ps->clksel1);
1614
1615         local_irq_save(flags);
1616
1617         /* If core src don't select gpll, apll need to enter slow mode
1618          * before reset
1619          */
1620         //FIXME
1621         //if (!sel_gpll)
1622         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1623
1624         /* PLL enter rest */
1625         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1626
1627         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1628         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1629         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1630
1631         udelay(5);
1632
1633         /* return from rest */
1634         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1635
1636         //wating lock state
1637         udelay(ps->rst_dly);
1638         pll_wait_lock(hw);
1639
1640         if (rate >= __clk_get_rate(hw->clk)) {
1641                 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1642                 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1643         }
1644
1645         /* PLL return from slow mode */
1646         //FIXME
1647         //if (!sel_gpll)
1648         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1649
1650         /* reparent to apll, and set div to 1 */
1651         if (sel_gpll) {
1652                 if (temp_div == 1) {
1653                         /* when rate/2 < (rate-arm_gpll_rate),
1654                            we can set div to make rate change more gently */
1655                         if (rate > (2*arm_gpll_rate)) {
1656                                 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1657                                 udelay(10);
1658                                 cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1659                                 udelay(10);
1660                                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1661                                         RK3288_CRU_CLKSELS_CON(0));
1662                                 udelay(10);
1663                                 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1664                                 udelay(10);
1665                                 cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1666                         } else {
1667                                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1668                                                 RK3288_CRU_CLKSELS_CON(0));
1669                         }
1670                 } else {
1671                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1672                                 RK3288_CRU_CLKSELS_CON(0));
1673                         cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1674                 }
1675         }
1676
1677         if (rate < __clk_get_rate(hw->clk)) {
1678                 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1679                 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1680         }
1681
1682         //loops_per_jiffy = ps->lpj;
1683         smp_wmb();
1684
1685         local_irq_restore(flags);
1686
1687         if (sel_gpll) {
1688                 sel_gpll = 0;
1689                 //clk_disable(arm_gpll);
1690                 //clk_unprepare(arm_gpll);
1691         }
1692
1693         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1694
1695         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1696                         ps->rate,
1697                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
1698                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
1699                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
1700                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
1701                         cru_readl(RK3288_CRU_CLKSELS_CON(0)),
1702                         cru_readl(RK3288_CRU_CLKSELS_CON(1)));
1703
1704         return 0;
1705 }
1706
1707
1708 static const struct clk_ops clk_pll_ops_3288_apll = {
1709         .recalc_rate = clk_pll_recalc_rate_3288_apll,
1710         .round_rate = clk_pll_round_rate_3288_apll,
1711         .set_rate = clk_pll_set_rate_3288_apll,
1712 };
1713
1714 /* CLK_PLL_3036_APLL type ops */
1715 #define FRAC_MODE       0
1716 static unsigned long rk3036_pll_clk_recalc(struct clk_hw *hw,
1717 unsigned long parent_rate)
1718 {
1719         struct clk_pll *pll = to_clk_pll(hw);
1720         unsigned long rate;
1721         unsigned int dsmp = 0;
1722         u64 rate64 = 0, frac_rate64 = 0;
1723
1724         dsmp = RK3036_PLL_GET_DSMPD(cru_readl(pll->reg + RK3188_PLL_CON(1)));
1725
1726         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
1727                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
1728                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
1729                 u32 pll_con2 = cru_readl(pll->reg + RK3188_PLL_CON(2));
1730                 /*integer mode*/
1731                 rate64 = (u64)parent_rate * RK3036_PLL_GET_FBDIV(pll_con0);
1732                 do_div(rate64, RK3036_PLL_GET_REFDIV(pll_con1));
1733
1734                 if (FRAC_MODE == dsmp) {
1735                         /*fractional mode*/
1736                         frac_rate64 = (u64)parent_rate
1737                         * RK3036_PLL_GET_FRAC(pll_con2);
1738                         do_div(frac_rate64, RK3036_PLL_GET_REFDIV(pll_con1));
1739                         rate64 += frac_rate64 >> 24;
1740                         clk_debug("%s frac_rate=%llu(%08x/2^24) by pass mode\n",
1741                                         __func__, frac_rate64 >> 24,
1742                                         RK3036_PLL_GET_FRAC(pll_con2));
1743                 }
1744                 do_div(rate64, RK3036_PLL_GET_POSTDIV1(pll_con0));
1745                 do_div(rate64, RK3036_PLL_GET_POSTDIV2(pll_con1));
1746
1747                 rate = rate64;
1748                 } else {
1749                 rate = parent_rate;
1750                 clk_debug("pll_clk_recalc rate=%lu by pass mode\n", rate);
1751         }
1752         return rate;
1753 }
1754
1755 static unsigned long clk_pll_recalc_rate_3036_apll(struct clk_hw *hw,
1756                 unsigned long parent_rate)
1757 {
1758         return rk3036_pll_clk_recalc(hw, parent_rate);
1759 }
1760
1761 static long clk_pll_round_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
1762                 unsigned long *prate)
1763 {
1764         struct clk *parent = __clk_get_parent(hw->clk);
1765
1766         if (parent && (rate == __clk_get_rate(parent))) {
1767                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1768                                 __clk_get_name(hw->clk), rate);
1769                 return rate;
1770         }
1771
1772         return (apll_get_best_set(rate, rk3036_apll_table)->rate);
1773 }
1774
1775 static  int rk3036_pll_clk_set_rate(struct pll_clk_set *clk_set,
1776         struct clk_hw *hw)
1777 {
1778         struct clk_pll *pll = to_clk_pll(hw);
1779
1780         /*enter slowmode*/
1781         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1782         pll->mode_offset);
1783
1784         cru_writel(clk_set->pllcon0,  pll->reg + RK3188_PLL_CON(0));
1785         cru_writel(clk_set->pllcon1,  pll->reg + RK3188_PLL_CON(1));
1786         cru_writel(clk_set->pllcon2,  pll->reg + RK3188_PLL_CON(2));
1787
1788         clk_debug("pllcon0%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1789         clk_debug("pllcon1%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1790         clk_debug("pllcon2%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1791         /*wating lock state*/
1792         udelay(clk_set->rst_dly);
1793         rk3036_pll_wait_lock(hw);
1794
1795         /*return form slow*/
1796         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
1797         pll->mode_offset);
1798
1799         return 0;
1800 }
1801
1802 #define MIN_FOUTVCO_FREQ        (400 * 1000 * 1000)
1803 #define MAX_FOUTVCO_FREQ        (1600 * 1000 * 1000)
1804 static int rk3036_pll_clk_set_postdiv(unsigned long fout_hz,
1805 u32 *postdiv1, u32 *postdiv2, u32 *foutvco)
1806 {
1807         if (fout_hz < MIN_FOUTVCO_FREQ) {
1808                 for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++)
1809                         for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
1810                                 if (fout_hz * (*postdiv1) * (*postdiv2)
1811                                         >= MIN_FOUTVCO_FREQ && fout_hz
1812                                         * (*postdiv1) * (*postdiv2)
1813                                         <= MAX_FOUTVCO_FREQ) {
1814                                         *foutvco = fout_hz * (*postdiv1)
1815                                                 * (*postdiv2);
1816                                         return 0;
1817                                 }
1818                         }
1819                 clk_debug("CANNOT FINE postdiv1/2 to make fout in range from 400M to 1600M, fout = %lu\n",
1820                                 fout_hz);
1821         } else {
1822                 *postdiv1 = 1;
1823                 *postdiv2 = 1;
1824         }
1825         return 0;
1826 }
1827
1828 static int rk3036_pll_clk_get_set(unsigned long fin_hz, unsigned long fout_hz,
1829                 u32 *refdiv, u32 *fbdiv, u32 *postdiv1,
1830                 u32 *postdiv2, u32 *frac)
1831 {
1832         /* FIXME set postdiv1/2 always 1*/
1833         u32 gcd, foutvco = fout_hz;
1834         u64 fin_64, frac_64;
1835         u32 f_frac;
1836
1837         if (!fin_hz || !fout_hz || fout_hz == fin_hz)
1838                 return -1;
1839
1840         rk3036_pll_clk_set_postdiv(fout_hz, postdiv1, postdiv2, &foutvco);
1841         if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
1842                 fin_hz /= MHZ;
1843                 foutvco /= MHZ;
1844                 gcd = clk_gcd(fin_hz, foutvco);
1845                 *refdiv = fin_hz / gcd;
1846                 *fbdiv = foutvco / gcd;
1847
1848                 *frac = 0;
1849
1850                 clk_debug("fin=%lu,fout=%lu,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
1851                         fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
1852         } else {
1853                 clk_debug("******frac div running, fin_hz=%lu, fout_hz=%lu,fin_INT_mhz=%lu, fout_INT_mhz=%lu\n",
1854                         fin_hz, fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
1855                 clk_debug("******frac get postdiv1=%u, postdiv2=%u,foutvco=%u\n",
1856                         *postdiv1, *postdiv2, foutvco);
1857                 gcd = clk_gcd(fin_hz / MHZ, foutvco / MHZ);
1858                 *refdiv = fin_hz / MHZ / gcd;
1859                 *fbdiv = foutvco / MHZ / gcd;
1860                 clk_debug("******frac get refdiv=%u, fbdiv=%u\n", *refdiv, *fbdiv);
1861
1862                 *frac = 0;
1863
1864                 f_frac = (foutvco % MHZ);
1865                 fin_64 = fin_hz;
1866                 do_div(fin_64, (u64)*refdiv);
1867                 frac_64 = (u64)f_frac << 24;
1868                 do_div(frac_64, fin_64);
1869                 *frac = (u32) frac_64;
1870                 clk_debug("frac=%x\n", *frac);
1871         }
1872         return 0;
1873 }
1874 static int rk3036_pll_set_con(struct clk_hw *hw, u32 refdiv, u32 fbdiv, u32 postdiv1, u32 postdiv2, u32 frac)
1875 {
1876         struct pll_clk_set temp_clk_set;
1877         temp_clk_set.pllcon0 = RK3036_PLL_SET_FBDIV(fbdiv) | RK3036_PLL_SET_POSTDIV1(postdiv1);
1878         temp_clk_set.pllcon1 = RK3036_PLL_SET_REFDIV(refdiv) | RK3036_PLL_SET_POSTDIV2(postdiv2);
1879         if (frac != 0)
1880                 temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(0);
1881         else
1882                 temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(1);
1883
1884         temp_clk_set.pllcon2 = RK3036_PLL_SET_FRAC(frac);
1885         temp_clk_set.rst_dly = 0;
1886         clk_debug("setting....\n");
1887         return rk3036_pll_clk_set_rate(&temp_clk_set, hw);
1888 }
1889
1890 static int clk_pll_set_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
1891                 unsigned long parent_rate)
1892 {
1893         struct clk_pll *pll = to_clk_pll(hw);
1894         struct apll_clk_set *ps = (struct apll_clk_set *)(rk3036_apll_table);
1895         struct clk *arm_gpll = __clk_lookup("clk_gpll");
1896         struct clk *clk = hw->clk;
1897         unsigned long flags, arm_gpll_rate, old_rate, temp_rate;
1898         u32 temp_div;
1899
1900         while (ps->rate) {
1901                 if (ps->rate == rate) {
1902                         break;
1903                 }
1904                 ps++;
1905         }
1906
1907         if (ps->rate != rate) {
1908                 clk_err("%s: unsupport arm rate %lu\n", __func__, rate);
1909                 return 0;
1910         }
1911
1912         if (!arm_gpll) {
1913                 clk_err("clk arm_gpll is NULL!\n");
1914                 return 0;
1915         }
1916
1917         old_rate = __clk_get_rate(clk);
1918         arm_gpll_rate = __clk_get_rate(arm_gpll);
1919         if (soc_is_rk3128() || soc_is_rk3126())
1920                 arm_gpll_rate /= 2;
1921
1922         temp_rate = (old_rate > rate) ? old_rate : rate;
1923         temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
1924
1925         local_irq_save(flags);
1926
1927         if (rate >= old_rate) {
1928                 cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
1929                 cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
1930         }
1931
1932         /* set div first, then select gpll */
1933         if (temp_div > 1)
1934                 cru_writel(RK3036_CLK_CORE_DIV(temp_div), RK3036_CRU_CLKSELS_CON(0));
1935         cru_writel(RK3036_CORE_SEL_PLL(1), RK3036_CRU_CLKSELS_CON(0));
1936
1937         clk_debug("temp select arm_gpll path, get rate %lu\n",
1938                   arm_gpll_rate/temp_div);
1939         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1940                   temp_div);
1941
1942         /**************enter slow mode 24M***********/
1943         /*cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);*/
1944         loops_per_jiffy = LPJ_24M;
1945
1946         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1947         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1948         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1949
1950         clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1951         clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1952         clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1953         clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
1954         clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
1955
1956         /*wating lock state*/
1957         udelay(ps->rst_dly);
1958         rk3036_pll_wait_lock(hw);
1959
1960         /************select apll******************/
1961         cru_writel(RK3036_CORE_SEL_PLL(0), RK3036_CRU_CLKSELS_CON(0));
1962         /**************return slow mode***********/
1963         /*cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);*/
1964
1965         cru_writel(RK3036_CLK_CORE_DIV(1), RK3036_CRU_CLKSELS_CON(0));
1966
1967         if (rate < old_rate) {
1968                 cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
1969                 cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
1970         }
1971
1972         loops_per_jiffy = ps->lpj;
1973         local_irq_restore(flags);
1974
1975         return 0;       
1976 }
1977 static const struct clk_ops clk_pll_ops_3036_apll = {
1978         .recalc_rate = clk_pll_recalc_rate_3036_apll,
1979         .round_rate = clk_pll_round_rate_3036_apll,
1980         .set_rate = clk_pll_set_rate_3036_apll,
1981 };
1982
1983
1984 /* CLK_PLL_3036_plus_autotype ops */
1985
1986 static long clk_pll_round_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
1987                 unsigned long *prate)
1988 {
1989         struct clk *parent = __clk_get_parent(hw->clk);
1990
1991         if (parent && (rate == __clk_get_rate(parent))) {
1992                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1993                                 __clk_get_name(hw->clk), rate);
1994                 return rate;
1995         }
1996
1997         return (pll_com_get_best_set(rate, rk3036plus_pll_com_table)->rate);
1998 }
1999
2000 static int clk_pll_set_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
2001                 unsigned long parent_rate)
2002 {
2003         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3036plus_pll_com_table);
2004
2005         clk_debug("******%s\n", __func__);
2006         while (clk_set->rate) {
2007                 clk_debug("******%s clk_set->rate=%lu\n", __func__, clk_set->rate);
2008                 if (clk_set->rate == rate) {
2009                         break;
2010                 }
2011                 clk_set++;
2012         }
2013         if (clk_set->rate == rate) {
2014                 rk3036_pll_clk_set_rate(clk_set, hw);
2015         } else {
2016                 clk_debug("gpll is no corresponding rate=%lu\n", rate);
2017                 return -1;
2018         }
2019         clk_debug("******%s end\n", __func__);
2020
2021         return 0;       
2022 }
2023
2024 static const struct clk_ops clk_pll_ops_3036plus_auto = {
2025         .recalc_rate = clk_pll_recalc_rate_3036_apll,
2026         .round_rate = clk_pll_round_rate_3036plus_auto,
2027         .set_rate = clk_pll_set_rate_3036plus_auto,
2028 };
2029
2030 static long clk_cpll_round_rate_312xplus(struct clk_hw *hw, unsigned long rate,
2031                 unsigned long *prate)
2032 {
2033         unsigned long best;
2034
2035         for (best = rate; best > 0; best--) {
2036                 if (!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
2037                         return best;
2038         }
2039
2040         return 0;
2041 }
2042
2043 static int clk_cpll_set_rate_312xplus(struct clk_hw *hw, unsigned long rate,
2044                 unsigned long parent_rate)
2045 {
2046         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk312xplus_pll_com_table);
2047         u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
2048
2049         while (clk_set->rate) {
2050                 if (clk_set->rate == rate) {
2051                         break;
2052                 }
2053                 clk_set++;
2054         }
2055
2056         if (clk_set->rate == rate) {
2057                 clk_debug("cpll get a rate\n");
2058                 rk3036_pll_clk_set_rate(clk_set, hw);
2059
2060         } else {
2061                 clk_debug("cpll get auto calc a rate\n");
2062                 if (rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac) != 0) {
2063                         pr_err("cpll auto set rate error\n");
2064                         return -ENOENT;
2065                 }
2066                 clk_debug("%s get rate=%lu, refdiv=%u, fbdiv=%u, postdiv1=%u, postdiv2=%u",
2067                                 __func__, rate, refdiv, fbdiv, postdiv1, postdiv2);
2068                 rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac);
2069
2070         }
2071
2072         clk_debug("setting OK\n");
2073         return 0;
2074 }
2075
2076 static const struct clk_ops clk_pll_ops_312xplus = {
2077         .recalc_rate = clk_pll_recalc_rate_3036_apll,
2078         .round_rate = clk_cpll_round_rate_312xplus,
2079         .set_rate = clk_cpll_set_rate_312xplus,
2080 };
2081
2082 static long clk_pll_round_rate_3368_apllb(struct clk_hw *hw, unsigned long rate,
2083                                           unsigned long *prate)
2084 {
2085         struct clk *parent = __clk_get_parent(hw->clk);
2086
2087         if (parent && (rate == __clk_get_rate(parent))) {
2088                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
2089                           __clk_get_name(hw->clk), rate);
2090                 return rate;
2091         }
2092
2093         return (apll_get_best_set(rate, rk3368_apllb_table)->rate);
2094 }
2095
2096 /* 1: use, 0: no use */
2097 #define RK3368_APLLB_USE_GPLL   1
2098
2099 /* when define 1, we will set div to make rate change gently, but it will cost
2100  more time */
2101 #define RK3368_APLLB_DIV_MORE   1
2102
2103 static int clk_pll_set_rate_3368_apllb(struct clk_hw *hw, unsigned long rate,
2104                                        unsigned long parent_rate)
2105 {
2106         struct clk_pll *pll = to_clk_pll(hw);
2107         struct clk *clk = hw->clk;
2108         struct clk *arm_gpll = __clk_lookup("clk_gpll");
2109         unsigned long arm_gpll_rate, temp_rate, old_rate;
2110         const struct apll_clk_set *ps;
2111         u32 temp_div;
2112         unsigned long flags;
2113         int sel_gpll = 0;
2114
2115         ps = apll_get_best_set(rate, rk3368_apllb_table);
2116         clk_debug("apllb will set rate %lu\n", ps->rate);
2117         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
2118                   ps->pllcon0, ps->pllcon1, ps->pllcon2,
2119                   ps->clksel0, ps->clksel1);
2120
2121 #if !RK3368_APLLB_USE_GPLL
2122         goto CHANGE_APLL;
2123 #endif
2124
2125         /* prepare arm_gpll before reparent clk_core to it */
2126         if (!arm_gpll) {
2127                 clk_err("clk arm_gpll is NULL!\n");
2128                 goto CHANGE_APLL;
2129         }
2130
2131         arm_gpll_rate = __clk_get_rate(arm_gpll);
2132         old_rate = __clk_get_rate(clk);
2133
2134         temp_rate = (old_rate > rate) ? old_rate : rate;
2135         temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
2136
2137         if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
2138                 clk_debug("temp_div %d > max_div %d\n", temp_div,
2139                           RK3368_CORE_CLK_MAX_DIV);
2140                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
2141                           __clk_get_rate(clk), arm_gpll_rate);
2142                 goto CHANGE_APLL;
2143         }
2144
2145         local_irq_save(flags);
2146
2147         if (rate >= old_rate) {
2148                 cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
2149                 cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
2150         }
2151
2152         /* select gpll */
2153 #if RK3368_APLLB_DIV_MORE
2154         if (temp_div == 1) {
2155                 /* when old_rate/2 < (old_rate-arm_gpll_rate),
2156                    we can set div to make rate change more gently */
2157                 if (old_rate > (2*arm_gpll_rate)) {
2158                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
2159                         udelay(10);
2160                         cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
2161                         udelay(10);
2162                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2163                                    RK3368_CRU_CLKSELS_CON(0));
2164                         udelay(10);
2165                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
2166                         udelay(10);
2167                         cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
2168                 } else {
2169                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2170                                    RK3368_CRU_CLKSELS_CON(0));
2171                 }
2172         } else {
2173                 cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
2174                 cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2175                            RK3368_CRU_CLKSELS_CON(0));
2176         }
2177 #else
2178         cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
2179         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2180                    RK3368_CRU_CLKSELS_CON(0));
2181 #endif
2182
2183         sel_gpll = 1;
2184
2185         smp_wmb();
2186
2187         local_irq_restore(flags);
2188
2189         clk_debug("temp select arm_gpll path, get rate %lu\n",
2190                   arm_gpll_rate/temp_div);
2191         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
2192                   temp_div);
2193
2194 CHANGE_APLL:
2195         local_irq_save(flags);
2196
2197         /* apll enter slow mode */
2198         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
2199                    pll->mode_offset);
2200
2201         /* PLL enter reset */
2202         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
2203
2204         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
2205         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
2206         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
2207
2208         udelay(5);
2209
2210         /* return from rest */
2211         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
2212
2213         /* wating lock state */
2214         udelay(ps->rst_dly);
2215         pll_wait_lock(hw);
2216
2217         if (!sel_gpll) {
2218                 if (rate >= old_rate) {
2219                         cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
2220                         cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
2221                 }
2222         }
2223
2224         /* apll return from slow mode */
2225         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
2226                    pll->mode_offset);
2227
2228         /* reparent to apll, and set div to 1 */
2229         if (sel_gpll) {
2230 #if RK3368_APLLB_DIV_MORE
2231                 /* when rate/2 < (rate-arm_gpll_rate), we can set div to make
2232                    rate change more gently */
2233                 if ((temp_div == 1) && (rate > (2*arm_gpll_rate))) {
2234                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
2235                         udelay(10);
2236                         cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
2237                         udelay(10);
2238                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
2239                                    RK3368_CRU_CLKSELS_CON(0));
2240                         udelay(10);
2241                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
2242                         udelay(10);
2243                 } else
2244                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
2245                                    RK3368_CRU_CLKSELS_CON(0));
2246 #else
2247                 cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
2248                            RK3368_CRU_CLKSELS_CON(0));
2249 #endif
2250         }
2251
2252         cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
2253
2254         if (rate < old_rate) {
2255                 cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
2256                 cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
2257         }
2258
2259         smp_wmb();
2260
2261         local_irq_restore(flags);
2262
2263         if (sel_gpll)
2264                 sel_gpll = 0;
2265
2266         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
2267                   ps->rate,
2268                   cru_readl(pll->reg + RK3188_PLL_CON(0)),
2269                   cru_readl(pll->reg + RK3188_PLL_CON(1)),
2270                   cru_readl(pll->reg + RK3188_PLL_CON(2)),
2271                   cru_readl(pll->reg + RK3188_PLL_CON(3)),
2272                   cru_readl(RK3368_CRU_CLKSELS_CON(0)),
2273                   cru_readl(RK3368_CRU_CLKSELS_CON(1)));
2274
2275         return 0;
2276 }
2277
2278 static const struct clk_ops clk_pll_ops_3368_apllb = {
2279         .recalc_rate = clk_pll_recalc_rate_3188plus,
2280         .round_rate = clk_pll_round_rate_3368_apllb,
2281         .set_rate = clk_pll_set_rate_3368_apllb,
2282 };
2283
2284 static long clk_pll_round_rate_3368_aplll(struct clk_hw *hw, unsigned long rate,
2285                                           unsigned long *prate)
2286 {
2287         struct clk *parent = __clk_get_parent(hw->clk);
2288
2289         if (parent && (rate == __clk_get_rate(parent))) {
2290                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
2291                           __clk_get_name(hw->clk), rate);
2292                 return rate;
2293         }
2294
2295         return (apll_get_best_set(rate, rk3368_aplll_table)->rate);
2296 }
2297
2298 /* 1: use, 0: no use */
2299 #define RK3368_APLLL_USE_GPLL   1
2300
2301 /* when define 1, we will set div to make rate change gently, but it will cost
2302  more time */
2303 #define RK3368_APLLL_DIV_MORE   1
2304
2305 static int clk_pll_set_rate_3368_aplll(struct clk_hw *hw, unsigned long rate,
2306                                        unsigned long parent_rate)
2307 {
2308         struct clk_pll *pll = to_clk_pll(hw);
2309         struct clk *clk = hw->clk;
2310         struct clk *arm_gpll = __clk_lookup("clk_gpll");
2311         unsigned long arm_gpll_rate, temp_rate, old_rate;
2312         const struct apll_clk_set *ps;
2313         u32 temp_div;
2314         unsigned long flags;
2315         int sel_gpll = 0;
2316
2317         ps = apll_get_best_set(rate, rk3368_aplll_table);
2318         clk_debug("aplll will set rate %lu\n", ps->rate);
2319         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
2320                   ps->pllcon0, ps->pllcon1, ps->pllcon2,
2321                   ps->clksel0, ps->clksel1);
2322
2323 #if !RK3368_APLLL_USE_GPLL
2324         goto CHANGE_APLL;
2325 #endif
2326
2327         /* prepare arm_gpll before reparent clk_core to it */
2328         if (!arm_gpll) {
2329                 clk_err("clk arm_gpll is NULL!\n");
2330                 goto CHANGE_APLL;
2331         }
2332
2333         arm_gpll_rate = __clk_get_rate(arm_gpll);
2334         old_rate = __clk_get_rate(clk);
2335
2336         temp_rate = (old_rate > rate) ? old_rate : rate;
2337         temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
2338
2339         if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
2340                 clk_debug("temp_div %d > max_div %d\n", temp_div,
2341                           RK3368_CORE_CLK_MAX_DIV);
2342                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
2343                           __clk_get_rate(clk), arm_gpll_rate);
2344                 goto CHANGE_APLL;
2345         }
2346
2347         local_irq_save(flags);
2348
2349         if (rate >= old_rate) {
2350                 cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
2351                 cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
2352         }
2353
2354         /* select gpll */
2355 #if RK3368_APLLL_DIV_MORE
2356         if (temp_div == 1) {
2357                 /* when old_rate/2 < (old_rate-arm_gpll_rate),
2358                    we can set div to make rate change more gently */
2359                 if (old_rate > (2*arm_gpll_rate)) {
2360                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
2361                         udelay(10);
2362                         cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
2363                         udelay(10);
2364                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2365                                    RK3368_CRU_CLKSELS_CON(2));
2366                         udelay(10);
2367                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
2368                         udelay(10);
2369                         cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
2370                 } else {
2371                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2372                                    RK3368_CRU_CLKSELS_CON(2));
2373                 }
2374         } else {
2375                 cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
2376                 cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2377                            RK3368_CRU_CLKSELS_CON(2));
2378         }
2379 #else
2380                 cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
2381                 cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
2382                            RK3368_CRU_CLKSELS_CON(2));
2383 #endif
2384
2385         sel_gpll = 1;
2386
2387         smp_wmb();
2388
2389         local_irq_restore(flags);
2390
2391         clk_debug("temp select arm_gpll path, get rate %lu\n",
2392                   arm_gpll_rate/temp_div);
2393         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
2394                   temp_div);
2395
2396 CHANGE_APLL:
2397         local_irq_save(flags);
2398
2399         /* apll enter slow mode */
2400         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
2401                    pll->mode_offset);
2402
2403         /* PLL enter reset */
2404         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
2405
2406         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
2407         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
2408         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
2409
2410         udelay(5);
2411
2412         /* return from rest */
2413         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
2414
2415         /* wating lock state */
2416         udelay(ps->rst_dly);
2417         pll_wait_lock(hw);
2418
2419         if (!sel_gpll) {
2420                 if (rate >= old_rate) {
2421                         cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
2422                         cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
2423                 }
2424         }
2425
2426         /* apll return from slow mode */
2427         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
2428                    pll->mode_offset);
2429
2430         /* reparent to apll, and set div to 1 */
2431         if (sel_gpll) {
2432 #if RK3368_APLLL_DIV_MORE
2433                 /* when rate/2 < (rate-arm_gpll_rate), we can set div to make
2434                    rate change more gently */
2435                 if ((temp_div == 1) && (rate > (2*arm_gpll_rate))) {
2436                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
2437                         udelay(10);
2438                         cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
2439                         udelay(10);
2440                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
2441                                    RK3368_CRU_CLKSELS_CON(2));
2442                         udelay(10);
2443                         cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
2444                         udelay(10);
2445                 } else
2446                         cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
2447                                    RK3368_CRU_CLKSELS_CON(2));
2448 #else
2449                 cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
2450                            RK3368_CRU_CLKSELS_CON(2));
2451 #endif
2452         }
2453
2454         cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
2455
2456         if (rate < old_rate) {
2457                 cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
2458                 cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
2459         }
2460
2461         smp_wmb();
2462
2463         local_irq_restore(flags);
2464
2465         if (sel_gpll)
2466                 sel_gpll = 0;
2467
2468         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
2469                   ps->rate,
2470                   cru_readl(pll->reg + RK3188_PLL_CON(0)),
2471                   cru_readl(pll->reg + RK3188_PLL_CON(1)),
2472                   cru_readl(pll->reg + RK3188_PLL_CON(2)),
2473                   cru_readl(pll->reg + RK3188_PLL_CON(3)),
2474                   cru_readl(RK3368_CRU_CLKSELS_CON(2)),
2475                   cru_readl(RK3368_CRU_CLKSELS_CON(3)));
2476
2477         return 0;
2478 }
2479
2480 static const struct clk_ops clk_pll_ops_3368_aplll = {
2481         .recalc_rate = clk_pll_recalc_rate_3188plus,
2482         .round_rate = clk_pll_round_rate_3368_aplll,
2483         .set_rate = clk_pll_set_rate_3368_aplll,
2484 };
2485
2486 const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
2487 {
2488         switch (pll_flags) {
2489                 case CLK_PLL_3188:
2490                         return &clk_pll_ops_3188;
2491
2492                 case CLK_PLL_3188_APLL:
2493                         return &clk_pll_ops_3188_apll;
2494
2495                 case CLK_PLL_3188PLUS:
2496                         return &clk_pll_ops_3188plus;
2497
2498                 case CLK_PLL_3188PLUS_APLL:
2499                         return &clk_pll_ops_3188plus_apll;
2500
2501                 case CLK_PLL_3288_APLL:
2502                         return &clk_pll_ops_3288_apll;
2503
2504                 case CLK_PLL_3188PLUS_AUTO:
2505                         return &clk_pll_ops_3188plus_auto;
2506
2507                 case CLK_PLL_3036_APLL:
2508                         return &clk_pll_ops_3036_apll;
2509
2510                 case CLK_PLL_3036PLUS_AUTO:
2511                         return &clk_pll_ops_3036plus_auto;
2512
2513                 case CLK_PLL_312XPLUS:
2514                         return &clk_pll_ops_312xplus;
2515
2516                 case CLK_PLL_3368_APLLB:
2517                         return &clk_pll_ops_3368_apllb;
2518
2519                 case CLK_PLL_3368_APLLL:
2520                         return &clk_pll_ops_3368_aplll;
2521
2522                 case CLK_PLL_3368_LOW_JITTER:
2523                         return &clk_pll_ops_3368_low_jitter;
2524
2525                 default:
2526                         clk_err("%s: unknown pll_flags!\n", __func__);
2527                         return NULL;
2528         }
2529 }
2530
2531 struct clk *rk_clk_register_pll(struct device *dev, const char *name,
2532                 const char *parent_name, unsigned long flags, u32 reg,
2533                 u32 width, u32 mode_offset, u8 mode_shift,
2534                 u32 status_offset, u8 status_shift, u32 pll_flags,
2535                 spinlock_t *lock)
2536 {
2537         struct clk_pll *pll;
2538         struct clk *clk;
2539         struct clk_init_data init;
2540
2541
2542         clk_debug("%s: pll name = %s, pll_flags = 0x%x, register start!\n",
2543                         __func__, name, pll_flags);
2544
2545         /* allocate the pll */
2546         pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
2547         if (!pll) {
2548                 clk_err("%s: could not allocate pll clk\n", __func__);
2549                 return ERR_PTR(-ENOMEM);
2550         }
2551
2552         init.name = name;
2553         init.flags = flags;
2554         init.parent_names = (parent_name ? &parent_name: NULL);
2555         init.num_parents = (parent_name ? 1 : 0);
2556         init.ops = rk_get_pll_ops(pll_flags);
2557
2558         /* struct clk_pll assignments */
2559         pll->reg = reg;
2560         pll->width = width;
2561         pll->mode_offset = mode_offset;
2562         pll->mode_shift = mode_shift;
2563         pll->status_offset = status_offset;
2564         pll->status_shift = status_shift;
2565         pll->flags = pll_flags;
2566         pll->lock = lock;
2567         pll->hw.init = &init;
2568
2569         /* register the clock */
2570         clk = clk_register(dev, &pll->hw);
2571
2572         if (IS_ERR(clk))
2573                 kfree(pll);
2574
2575         clk_debug("%s: pll name = %s, pll_flags = 0x%x, register finish!\n",
2576                         __func__, name, pll_flags);
2577
2578         return clk;
2579 }
2580