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