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