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