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