Merge remote-tracking branch 'origin/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, 41, 41, 41, 21, 21),
189         _RK3036_APLL_SET_CLKS(1416, 1, 59, 1, 1, 1, 0, 41, 41, 41, 21, 21),
190         _RK3036_APLL_SET_CLKS(1392, 1, 58, 1, 1, 1, 0, 41, 41, 41, 21, 21),
191         _RK3036_APLL_SET_CLKS(1368, 1, 57, 1, 1, 1, 0, 41, 41, 41, 21, 21),
192         _RK3036_APLL_SET_CLKS(1344, 1, 56, 1, 1, 1, 0, 41, 41, 41, 21, 21),
193         _RK3036_APLL_SET_CLKS(1320, 1, 55, 1, 1, 1, 0, 41, 41, 41, 21, 21),
194         _RK3036_APLL_SET_CLKS(1296, 1, 54, 1, 1, 1, 0, 41, 41, 41, 21, 21),
195         _RK3036_APLL_SET_CLKS(1272, 1, 53, 1, 1, 1, 0, 41, 41, 41, 21, 21),
196         _RK3036_APLL_SET_CLKS(1248, 1, 52, 1, 1, 1, 0, 41, 41, 41, 21, 21),
197         _RK3036_APLL_SET_CLKS(1200, 1, 50, 1, 1, 1, 0, 41, 41, 41, 21, 21),
198         _RK3036_APLL_SET_CLKS(1104, 1, 46, 1, 1, 1, 0, 41, 41, 41, 21, 21),
199         _RK3036_APLL_SET_CLKS(1008, 1, 84, 2, 1, 1, 0, 41, 41, 41, 21, 21),
200         _RK3036_APLL_SET_CLKS(984, 1, 82, 2, 1, 1, 0, 41, 41, 41, 21, 21),
201         _RK3036_APLL_SET_CLKS(960, 1, 80, 2, 1, 1, 0, 41, 41, 41, 21, 21),
202         _RK3036_APLL_SET_CLKS(936, 1, 78, 2, 1, 1, 0, 41, 41, 41, 21, 21),
203         _RK3036_APLL_SET_CLKS(912, 1, 76, 2, 1, 1, 0, 41, 41, 41, 21, 21),
204         _RK3036_APLL_SET_CLKS(888, 1, 74, 2, 1, 1, 0, 41, 41, 41, 21, 21),
205         _RK3036_APLL_SET_CLKS(864, 1, 72, 2, 1, 1, 0, 41, 41, 41, 21, 21),
206         _RK3036_APLL_SET_CLKS(840, 1, 70, 2, 1, 1, 0, 41, 41, 41, 21, 21),
207         _RK3036_APLL_SET_CLKS(816, 1, 68, 2, 1, 1, 0, 41, 41, 41, 21, 21),
208         _RK3036_APLL_SET_CLKS(696, 1, 58, 2, 1, 1, 0, 41, 41, 41, 21, 21),
209         _RK3036_APLL_SET_CLKS(600, 1, 75, 3, 1, 1, 0, 41, 21, 41, 21, 21),
210         _RK3036_APLL_SET_CLKS(504, 1, 63, 3, 1, 1, 0, 41, 21, 41, 21, 21),
211         _RK3036_APLL_SET_CLKS(408, 1, 68, 2, 2, 1, 0, 41, 21, 41, 21, 21),
212         _RK3036_APLL_SET_CLKS(312, 1, 52, 2, 2, 1, 0, 41, 21, 41, 21, 21),
213         _RK3036_APLL_SET_CLKS(216, 1, 72, 4, 2, 1, 0, 41, 21, 41, 21, 21),
214         _RK3036_APLL_SET_CLKS(96, 1, 64, 4, 4, 1, 0, 21, 21, 41, 21, 21),
215         _RK3036_APLL_SET_CLKS(0, 1, 0, 1, 1, 1, 0, 21, 21, 41, 21, 21),
216 };
217
218 static const struct pll_clk_set rk3036plus_pll_com_table[] = {
219 //      _RK3036_PLL_SET_CLKS(297000, 2, 99, 4, 1, 1, 0),
220         _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
221         _RK3036_PLL_SET_CLKS(1188000, 2, 99, 1, 1, 1, 0),
222
223 };
224
225 static void pll_wait_lock(struct clk_hw *hw)
226 {
227         struct clk_pll *pll = to_clk_pll(hw);
228         int delay = 24000000;
229
230
231         while (delay > 0) {
232                 if (grf_readl(pll->status_offset) & (1 << pll->status_shift))
233                         break;
234                 delay--;
235         }
236
237         if (delay == 0) {
238                 clk_err("pll %s: can't lock! status_shift=%u\n"
239                                 "pll_con0=%08x\npll_con1=%08x\n"
240                                 "pll_con2=%08x\npll_con3=%08x\n",
241                                 __clk_get_name(hw->clk),
242                                 pll->status_shift,
243                                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
244                                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
245                                 cru_readl(pll->reg + RK3188_PLL_CON(2)),
246                                 cru_readl(pll->reg + RK3188_PLL_CON(3)));
247
248                 while(1);
249         }
250 }
251
252 static void rk3036_pll_wait_lock(struct clk_hw *hw)
253 {
254         struct clk_pll *pll = to_clk_pll(hw);
255         int delay = 24000000;
256
257
258         while (delay > 0) {
259                 if (cru_readl(pll->status_offset) & (1 << pll->status_shift))
260                         break;
261                 delay--;
262         }
263
264         if (delay == 0) {
265                 clk_err("pll %s: can't lock! status_shift=%u\n"
266                                 "pll_con0=%08x\npll_con1=%08x\n"
267                                 "pll_con2=%08x\n",
268                                 __clk_get_name(hw->clk),
269                                 pll->status_shift,
270                                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
271                                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
272                                 cru_readl(pll->reg + RK3188_PLL_CON(2)));
273                 while (1);
274
275         }
276 }
277
278
279 /* get rate that is most close to target */
280 static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
281                 const struct apll_clk_set *table)
282 {
283         const struct apll_clk_set *ps, *pt;
284
285         ps = pt = table;
286         while (pt->rate) {
287                 if (pt->rate == rate) {
288                         ps = pt;
289                         break;
290                 }
291
292                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
293                         ps = pt;
294                 if (pt->rate < rate)
295                         break;
296                 pt++;
297         }
298
299         return ps;
300 }
301
302 /* get rate that is most close to target */
303 static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
304                 const struct pll_clk_set *table)
305 {
306         const struct pll_clk_set *ps, *pt;
307
308         ps = pt = table;
309         while (pt->rate) {
310                 if (pt->rate == rate) {
311                         ps = pt;
312                         break;
313                 }
314
315                 if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
316                         ps = pt;
317                 if (pt->rate < rate)
318                         break;
319                 pt++;
320         }
321
322         return ps;
323 }
324
325 /* CLK_PLL_3188 type ops */
326 static unsigned long clk_pll_recalc_rate_3188(struct clk_hw *hw,
327                 unsigned long parent_rate)
328 {
329         struct clk_pll *pll = to_clk_pll(hw);
330         unsigned long rate;
331
332
333         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
334                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
335                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
336
337                 u64 rate64 = (u64)parent_rate * RK3188_PLL_NF(pll_con1);
338
339                 do_div(rate64, RK3188_PLL_NR(pll_con0));
340                 do_div(rate64, RK3188_PLL_NO(pll_con0));
341
342                 rate = rate64;
343         } else {
344                 /*FIXME*/
345                 rate = parent_rate;
346                 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
347         }
348
349         clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
350
351         return rate;
352 }
353
354 static long clk_pll_round_rate_3188(struct clk_hw *hw, unsigned long rate,
355                 unsigned long *prate)
356 {
357         struct clk *parent = __clk_get_parent(hw->clk);
358
359         if (parent && (rate==__clk_get_rate(parent))) {
360                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
361                                 __clk_get_name(hw->clk), rate);
362                 return rate;
363         }
364
365         return (pll_com_get_best_set(rate, rk3188_pll_com_table)->rate);
366 }
367
368 static int _pll_clk_set_rate_3188(struct pll_clk_set *clk_set,
369                 struct clk_hw *hw)
370 {
371         struct clk_pll *pll = to_clk_pll(hw);
372         unsigned long flags = 0;
373
374
375         clk_debug("%s start!\n", __func__);
376
377         if(pll->lock)
378                 spin_lock_irqsave(pll->lock, flags);
379
380         //enter slowmode
381         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
382         //pll power down
383         cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
384         dsb();
385         dsb();
386         dsb();
387         dsb();
388         dsb();
389         dsb();
390         cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
391         cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
392
393         udelay(1);
394
395         //pll no power down
396         cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
397
398         pll_wait_lock(hw);
399
400         //return from slow
401         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
402
403         if (pll->lock)
404                 spin_unlock_irqrestore(pll->lock, flags);
405
406         clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
407                         __clk_get_name(hw->clk),
408                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
409                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
410                         cru_readl(pll->mode_offset));
411
412         clk_debug("%s end!\n", __func__);
413
414         return 0;
415 }
416
417 static int clk_pll_set_rate_3188(struct clk_hw *hw, unsigned long rate,
418                 unsigned long parent_rate)
419 {
420         struct clk_pll *pll = to_clk_pll(hw);
421         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188_pll_com_table);
422         int ret = 0;
423
424
425         if (rate == parent_rate) {
426                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
427                                 __clk_get_name(hw->clk), rate);
428                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
429                                 pll->mode_offset);
430                 /* pll power down */
431                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
432                 clk_debug("pll %s enter slow mode, set rate OK!\n",
433                                 __clk_get_name(hw->clk));
434                 return 0;
435         }
436
437         while(clk_set->rate) {
438                 if (clk_set->rate == rate) {
439                         break;
440                 }
441                 clk_set++;
442         }
443
444         if (clk_set->rate == rate) {
445                 ret = _pll_clk_set_rate_3188(clk_set, hw);
446                 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
447                                 rate);
448         } else {
449                 clk_err("pll %s is no corresponding rate=%lu\n",
450                                 __clk_get_name(hw->clk), rate);
451                 return -EINVAL;
452         }
453
454         return ret;
455 }
456
457 static const struct clk_ops clk_pll_ops_3188 = {
458         .recalc_rate = clk_pll_recalc_rate_3188,
459         .round_rate = clk_pll_round_rate_3188,
460         .set_rate = clk_pll_set_rate_3188,
461 };
462
463
464 /* CLK_PLL_3188_APLL type ops */
465 static unsigned long clk_pll_recalc_rate_3188_apll(struct clk_hw *hw,
466                 unsigned long parent_rate)
467 {
468         return clk_pll_recalc_rate_3188(hw, parent_rate);
469 }
470
471 static long clk_pll_round_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
472                 unsigned long *prate)
473 {
474         struct clk *parent = __clk_get_parent(hw->clk);
475
476         if (parent && (rate==__clk_get_rate(parent))) {
477                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
478                                 __clk_get_name(hw->clk), rate);
479                 return rate;
480         }
481
482         return (apll_get_best_set(rate, rk3188_apll_table)->rate);
483 }
484
485 /* 1: use, 0: no use */
486 #define RK3188_USE_ARM_GPLL     1
487
488 static int clk_pll_set_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
489                 unsigned long parent_rate)
490 {
491         struct clk_pll *pll = to_clk_pll(hw);
492         struct clk *clk = hw->clk;
493         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
494         unsigned long arm_gpll_rate;
495         const struct apll_clk_set *ps;
496         u32 old_aclk_div = 0, new_aclk_div = 0;
497         u32 temp_div;
498         unsigned long flags;
499         int sel_gpll = 0;
500
501
502         if (rate == parent_rate) {
503                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
504                                 __clk_get_name(hw->clk), rate);
505                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
506                                 pll->mode_offset);
507                 /* pll power down */
508                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
509                 clk_debug("pll %s enter slow mode, set rate OK!\n",
510                                 __clk_get_name(hw->clk));
511                 return 0;
512         }
513
514
515 #if !RK3188_USE_ARM_GPLL
516         goto CHANGE_APLL;
517 #endif
518
519         /* prepare arm_gpll before reparent clk_core to it */
520         if (!arm_gpll) {
521                 clk_err("clk arm_gpll is NULL!\n");
522                 goto CHANGE_APLL;
523         }
524
525         /* In rk3188, arm_gpll and cpu_gpll share a same gate,
526          * and aclk_cpu selects cpu_gpll as parent, thus this
527          * gate must keep enabled.
528          */
529 #if 0
530         if (clk_prepare(arm_gpll)) {
531                 clk_err("fail to prepare arm_gpll path\n");
532                 clk_unprepare(arm_gpll);
533                 goto CHANGE_APLL;
534         }
535
536         if (clk_enable(arm_gpll)) {
537                 clk_err("fail to enable arm_gpll path\n");
538                 clk_disable(arm_gpll);
539                 clk_unprepare(arm_gpll);
540                 goto CHANGE_APLL;
541         }
542 #endif
543
544         arm_gpll_rate = __clk_get_rate(arm_gpll);
545         temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
546         temp_div = (temp_div == 0) ? 1 : temp_div;
547         if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
548                 clk_debug("temp_div %d > max_div %d\n", temp_div,
549                                 RK3188_CORE_CLK_MAX_DIV);
550                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
551                                 __clk_get_rate(clk), arm_gpll_rate);
552                 //clk_disable(arm_gpll);
553                 //clk_unprepare(arm_gpll);
554                 goto CHANGE_APLL;
555         }
556
557         local_irq_save(flags);
558
559         /* firstly set div, then select arm_gpll path */
560         cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
561                         RK3188_CRU_CLKSELS_CON(0));
562         cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
563                         RK3188_CRU_CLKSELS_CON(0));
564
565         sel_gpll = 1;
566         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
567         smp_wmb();
568
569         local_irq_restore(flags);
570
571         clk_debug("temp select arm_gpll path, get rate %lu\n",
572                         arm_gpll_rate/temp_div);
573         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
574                         temp_div);
575
576 CHANGE_APLL:
577         ps = apll_get_best_set(rate, rk3188_apll_table);
578         clk_debug("apll will set rate %lu\n", ps->rate);
579         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
580                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
581                         ps->clksel0, ps->clksel1);
582
583         local_irq_save(flags);
584
585         /* If core src don't select gpll, apll need to enter slow mode
586          * before power down
587          */
588         //FIXME
589         //if (!sel_gpll)
590         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
591
592         /* PLL power down */
593         cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
594         dsb();
595         dsb();
596         dsb();
597         dsb();
598         dsb();
599         dsb();
600         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
601         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
602
603         udelay(1);
604
605         /* PLL power up and wait for locked */
606         cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
607         pll_wait_lock(hw);
608
609         old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
610                         RK3188_CORE_ACLK_MSK);
611         new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
612
613         if (new_aclk_div >= old_aclk_div) {
614                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
615                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
616         }
617
618         /* PLL return from slow mode */
619         //FIXME
620         //if (!sel_gpll)
621         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
622
623         /* reparent to apll, and set div to 1 */
624         if (sel_gpll) {
625                 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
626                                 RK3188_CRU_CLKSELS_CON(0));
627                 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
628                                 RK3188_CRU_CLKSELS_CON(0));
629         }
630
631         if (old_aclk_div > new_aclk_div) {
632                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
633                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
634         }
635
636         //loops_per_jiffy = ps->lpj;
637         smp_wmb();
638
639         local_irq_restore(flags);
640
641         if (sel_gpll) {
642                 sel_gpll = 0;
643                 //clk_disable(arm_gpll);
644                 //clk_unprepare(arm_gpll);
645         }
646
647         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
648
649         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
650                         ps->rate,
651                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
652                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
653                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
654                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
655                         cru_readl(RK3188_CRU_CLKSELS_CON(0)),
656                         cru_readl(RK3188_CRU_CLKSELS_CON(1)));
657
658         return 0;
659 }
660
661 static const struct clk_ops clk_pll_ops_3188_apll = {
662         .recalc_rate = clk_pll_recalc_rate_3188_apll,
663         .round_rate = clk_pll_round_rate_3188_apll,
664         .set_rate = clk_pll_set_rate_3188_apll,
665 };
666
667
668 /* CLK_PLL_3188PLUS type ops */
669 static unsigned long clk_pll_recalc_rate_3188plus(struct clk_hw *hw,
670                 unsigned long parent_rate)
671 {
672         struct clk_pll *pll = to_clk_pll(hw);
673         unsigned long rate;
674
675
676         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
677                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
678                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
679
680                 u64 rate64 = (u64)parent_rate * RK3188PLUS_PLL_NF(pll_con1);
681
682                 do_div(rate64, RK3188PLUS_PLL_NR(pll_con0));
683                 do_div(rate64, RK3188PLUS_PLL_NO(pll_con0));
684
685                 rate = rate64;
686         } else {
687                 /*FIXME*/
688                 rate = parent_rate;
689                 clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
690         }
691
692         clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
693
694         return rate;
695 }
696
697 static long clk_pll_round_rate_3188plus(struct clk_hw *hw, unsigned long rate,
698                 unsigned long *prate)
699 {
700         struct clk *parent = __clk_get_parent(hw->clk);
701
702         if (parent && (rate==__clk_get_rate(parent))) {
703                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
704                                 __clk_get_name(hw->clk), rate);
705                 return rate;
706         }
707
708         return (pll_com_get_best_set(rate, rk3188plus_pll_com_table)->rate);
709 }
710
711 static int _pll_clk_set_rate_3188plus(struct pll_clk_set *clk_set,
712                 struct clk_hw *hw)
713 {
714         struct clk_pll *pll = to_clk_pll(hw);
715         unsigned long flags = 0;
716
717
718         clk_debug("%s start!\n", __func__);
719
720         if(pll->lock)
721                 spin_lock_irqsave(pll->lock, flags);
722
723         //enter slowmode
724         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
725
726         //enter rest
727         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
728
729         cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
730         cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
731         cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
732
733         udelay(5);
734
735         //return from rest
736         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
737
738         //wating lock state
739         udelay(clk_set->rst_dly);
740
741         pll_wait_lock(hw);
742
743         //return from slow
744         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
745
746         if (pll->lock)
747                 spin_unlock_irqrestore(pll->lock, flags);
748
749         clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
750                         __clk_get_name(hw->clk),
751                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
752                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
753                         cru_readl(pll->mode_offset));
754
755         clk_debug("%s end!\n", __func__);
756
757         return 0;
758 }
759
760 static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
761                 unsigned long parent_rate)
762 {
763         //struct clk_pll *pll = to_clk_pll(hw);
764         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188plus_pll_com_table);
765         int ret = 0;
766
767 #if 0
768         if (rate == parent_rate) {
769                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
770                                 __clk_get_name(hw->clk), rate);
771                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
772                                 pll->mode_offset);
773                 /* pll power down */
774                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
775                 clk_debug("pll %s enter slow mode, set rate OK!\n",
776                                 __clk_get_name(hw->clk));
777                 return 0;
778         }
779 #endif
780
781         while(clk_set->rate) {
782                 if (clk_set->rate == rate) {
783                         break;
784                 }
785                 clk_set++;
786         }
787
788         if (cpu_is_rk3288() && (rate == 297*MHZ)) {
789                 if((strncmp(__clk_get_name(hw->clk), "clk_gpll",
790                         strlen("clk_gpll")) == 0)) {
791
792                         printk("rk3288 set GPLL BW 20 for HDMI!\n");
793                         clk_set->pllcon2 = RK3188_PLL_CLK_BWADJ_SET(20);
794                 }
795         }
796
797         if (clk_set->rate == rate) {
798                 ret = _pll_clk_set_rate_3188plus(clk_set, hw);
799                 clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
800                                 rate);
801         } else {
802                 clk_err("pll %s is no corresponding rate=%lu\n",
803                                 __clk_get_name(hw->clk), rate);
804                 return -EINVAL;
805         }
806
807         return ret;
808 }
809
810 static const struct clk_ops clk_pll_ops_3188plus = {
811         .recalc_rate = clk_pll_recalc_rate_3188plus,
812         .round_rate = clk_pll_round_rate_3188plus,
813         .set_rate = clk_pll_set_rate_3188plus,
814 };
815
816 /* CLK_PLL_3188PLUS_AUTO type ops */
817 #define PLL_FREF_MIN (269*KHZ)
818 #define PLL_FREF_MAX (2200*MHZ)
819
820 #define PLL_FVCO_MIN (440*MHZ)
821 #define PLL_FVCO_MAX (2200*MHZ)
822
823 #define PLL_FOUT_MIN (27500*KHZ) 
824 #define PLL_FOUT_MAX (2200*MHZ)
825
826 #define PLL_NF_MAX (4096)
827 #define PLL_NR_MAX (64)
828 #define PLL_NO_MAX (16)
829
830 static u32 clk_gcd(u32 numerator, u32 denominator)
831 {
832         u32 a, b;
833
834         if (!numerator || !denominator)
835                 return 0;
836         if (numerator > denominator) {
837                 a = numerator;
838                 b = denominator;
839         } else {
840                 a = denominator;
841                 b = numerator;
842         }
843         while (b != 0) {
844                 int r = b;
845                 b = a % b;
846                 a = r;
847         }
848
849         return a;
850 }
851
852 /* FIXME: calc using u64 */
853 static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
854                                 u32 *best_nr, u32 *best_nf, u32 *best_no)
855 {
856         u32 nr, nf, no, nonr;
857         u32 nr_out, nf_out, no_out;
858         u32 n;
859         u32 YFfenzi;
860         u32 YFfenmu;
861         u64 fref, fvco, fout;
862         u32 gcd_val = 0;
863
864
865         nr_out = PLL_NR_MAX + 1;
866         no_out = 0;
867
868 //      printk("pll_clk_get_set fin=%lu,fout=%lu\n", fin_hz, fout_hz);
869         if(!fin_hz || !fout_hz || fout_hz == fin_hz)
870                 return -EINVAL;
871         gcd_val = clk_gcd(fin_hz, fout_hz);
872
873 //      printk("gcd_val = %d\n",gcd_val);
874
875         YFfenzi = fout_hz / gcd_val;
876         YFfenmu = fin_hz / gcd_val;
877
878 //      printk("YFfenzi = %d, YFfenmu = %d\n",YFfenzi,YFfenmu);
879
880         for(n = 1;; n++) {
881                nf = YFfenzi * n;
882                nonr = YFfenmu * n;
883                if(nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
884                        break;
885                for(no = 1; no <= PLL_NO_MAX; no++) {
886                        if(!(no == 1 || !(no % 2)))
887                                continue;
888
889                        if(nonr % no)
890                                continue;
891                        nr = nonr / no;
892
893                        if(nr > PLL_NR_MAX) //PLL_NR_MAX
894                                continue;
895
896                        fref = fin_hz / nr;
897                        if(fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
898                                continue;
899
900                        fvco = fref * nf;
901                        if(fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
902                                continue;
903                        fout = fvco / no;
904                        if(fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
905                                continue;
906
907                        /* output all available PLL settings */
908                        //printk("nr=%d,\tnf=%d,\tno=%d\n",nr,nf,no);
909                        //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr,nf,no);
910
911                        /* select the best from all available PLL settings */
912                        if((nr < nr_out) || ((nr == nr_out)&&(no > no_out)))
913                        {
914                                nr_out = nr;
915                                nf_out = nf;
916                                no_out = no;
917                        }
918                }
919
920        }
921
922         /* output the best PLL setting */
923         if((nr_out <= PLL_NR_MAX) && (no_out > 0)){
924                 //printk("_PLL_SET_CLKS(%lu,\t%d,\t%d,\t%d),\n",fout_hz/KHZ,nr_out,nf_out,no_out);
925                 if(best_nr && best_nf && best_no){
926                         *best_nr = nr_out;
927                         *best_nf = nf_out;
928                         *best_no = no_out;
929                 }
930                 return 0;
931         } else {
932                 return -EINVAL;
933         }
934 }
935
936 static unsigned long clk_pll_recalc_rate_3188plus_auto(struct clk_hw *hw,
937                 unsigned long parent_rate)
938 {
939         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
940 }
941
942 static long clk_pll_round_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
943                 unsigned long *prate)
944 {
945         unsigned long best;
946
947         for(best=rate; best>0; best--){
948                 if(!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
949                         return best;
950         }
951
952         return 0;
953 }
954
955 static int clk_pll_set_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
956                 unsigned long parent_rate)
957 {
958         unsigned long best;
959         u32 nr,nf,no;
960         struct pll_clk_set clk_set;
961         int ret;
962
963
964         best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
965
966         if(!best)
967                 return -EINVAL;
968
969         pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
970
971         /* prepare clk_set */
972         clk_set.rate = best;
973         clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
974         clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
975         clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
976         clk_set.rst_dly = ((nr*500)/24+1);
977
978         ret = _pll_clk_set_rate_3188plus(&clk_set, hw);
979         clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk), best);
980
981         return ret;
982 }
983
984
985 static const struct clk_ops clk_pll_ops_3188plus_auto = {
986         .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
987         .round_rate = clk_pll_round_rate_3188plus_auto,
988         .set_rate = clk_pll_set_rate_3188plus_auto,
989 };
990
991
992 /* CLK_PLL_3188PLUS_APLL type ops */
993 static unsigned long clk_pll_recalc_rate_3188plus_apll(struct clk_hw *hw,
994                 unsigned long parent_rate)
995 {
996         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
997 }
998
999 static long clk_pll_round_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
1000                 unsigned long *prate)
1001 {
1002         return clk_pll_round_rate_3188_apll(hw, rate, prate);
1003 }
1004
1005 /* 1: use, 0: no use */
1006 #define RK3188PLUS_USE_ARM_GPLL 1
1007
1008 static int clk_pll_set_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
1009                 unsigned long parent_rate)
1010 {
1011         struct clk_pll *pll = to_clk_pll(hw);
1012         struct clk *clk = hw->clk;
1013         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1014         unsigned long arm_gpll_rate;
1015         const struct apll_clk_set *ps;
1016         u32 old_aclk_div = 0, new_aclk_div = 0;
1017         u32 temp_div;
1018         unsigned long flags;
1019         int sel_gpll = 0;
1020
1021 #if 0
1022         if (rate == parent_rate) {
1023                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1024                                 __clk_get_name(hw->clk), rate);
1025                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1026                                 pll->mode_offset);
1027                 /* pll power down */
1028                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1029                 clk_debug("pll %s enter slow mode, set rate OK!\n",
1030                                 __clk_get_name(hw->clk));
1031                 return 0;
1032         }
1033 #endif
1034
1035
1036 #if !RK3188PLUS_USE_ARM_GPLL
1037         goto CHANGE_APLL;
1038 #endif
1039
1040         /* prepare arm_gpll before reparent clk_core to it */
1041         if (!arm_gpll) {
1042                 clk_err("clk arm_gpll is NULL!\n");
1043                 goto CHANGE_APLL;
1044         }
1045
1046         /* In rk3188plus, arm_gpll and cpu_gpll share a same gate,
1047          * and aclk_cpu selects cpu_gpll as parent, thus this
1048          * gate must keep enabled.
1049          */
1050 #if 0
1051         if (clk_prepare(arm_gpll)) {
1052                 clk_err("fail to prepare arm_gpll path\n");
1053                 clk_unprepare(arm_gpll);
1054                 goto CHANGE_APLL;
1055         }
1056
1057         if (clk_enable(arm_gpll)) {
1058                 clk_err("fail to enable arm_gpll path\n");
1059                 clk_disable(arm_gpll);
1060                 clk_unprepare(arm_gpll);
1061                 goto CHANGE_APLL;
1062         }
1063 #endif
1064
1065         arm_gpll_rate = __clk_get_rate(arm_gpll);
1066         temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
1067         temp_div = (temp_div == 0) ? 1 : temp_div;
1068         if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
1069                 clk_debug("temp_div %d > max_div %d\n", temp_div,
1070                                 RK3188_CORE_CLK_MAX_DIV);
1071                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1072                                 __clk_get_rate(clk), arm_gpll_rate);
1073                 //clk_disable(arm_gpll);
1074                 //clk_unprepare(arm_gpll);
1075                 goto CHANGE_APLL;
1076         }
1077
1078         local_irq_save(flags);
1079
1080         /* firstly set div, then select arm_gpll path */
1081         cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
1082                         RK3188_CRU_CLKSELS_CON(0));
1083         cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
1084                         RK3188_CRU_CLKSELS_CON(0));
1085
1086         sel_gpll = 1;
1087         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1088         smp_wmb();
1089
1090         local_irq_restore(flags);
1091
1092         clk_debug("temp select arm_gpll path, get rate %lu\n",
1093                         arm_gpll_rate/temp_div);
1094         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1095                         temp_div);
1096
1097 CHANGE_APLL:
1098         ps = apll_get_best_set(rate, rk3188_apll_table);
1099         clk_debug("apll will set rate %lu\n", ps->rate);
1100         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1101                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
1102                         ps->clksel0, ps->clksel1);
1103
1104         local_irq_save(flags);
1105
1106         /* If core src don't select gpll, apll need to enter slow mode
1107          * before reset
1108          */
1109         //FIXME
1110         //if (!sel_gpll)
1111         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1112
1113         /* PLL enter rest */
1114         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1115
1116         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1117         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1118         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1119
1120         udelay(5);
1121
1122         /* return from rest */
1123         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1124
1125         //wating lock state
1126         udelay(ps->rst_dly);
1127         pll_wait_lock(hw);
1128
1129         old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
1130                         RK3188_CORE_ACLK_MSK);
1131         new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
1132
1133         if (new_aclk_div >= old_aclk_div) {
1134                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1135                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1136         }
1137
1138         /* PLL return from slow mode */
1139         //FIXME
1140         //if (!sel_gpll)
1141         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1142
1143         /* reparent to apll, and set div to 1 */
1144         if (sel_gpll) {
1145                 cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
1146                                 RK3188_CRU_CLKSELS_CON(0));
1147                 cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
1148                                 RK3188_CRU_CLKSELS_CON(0));
1149         }
1150
1151         if (old_aclk_div > new_aclk_div) {
1152                 cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
1153                 cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
1154         }
1155
1156         //loops_per_jiffy = ps->lpj;
1157         smp_wmb();
1158
1159         local_irq_restore(flags);
1160
1161         if (sel_gpll) {
1162                 sel_gpll = 0;
1163                 //clk_disable(arm_gpll);
1164                 //clk_unprepare(arm_gpll);
1165         }
1166
1167         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1168
1169         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1170                         ps->rate,
1171                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
1172                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
1173                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
1174                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
1175                         cru_readl(RK3188_CRU_CLKSELS_CON(0)),
1176                         cru_readl(RK3188_CRU_CLKSELS_CON(1)));
1177
1178         return 0;
1179 }
1180
1181 static const struct clk_ops clk_pll_ops_3188plus_apll = {
1182         .recalc_rate = clk_pll_recalc_rate_3188plus_apll,
1183         .round_rate = clk_pll_round_rate_3188plus_apll,
1184         .set_rate = clk_pll_set_rate_3188plus_apll,
1185 };
1186
1187 /* CLK_PLL_3288_APLL type ops */
1188 static unsigned long clk_pll_recalc_rate_3288_apll(struct clk_hw *hw,
1189                 unsigned long parent_rate)
1190 {
1191         return clk_pll_recalc_rate_3188plus(hw, parent_rate);
1192 }
1193
1194 static long clk_pll_round_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1195                 unsigned long *prate)
1196 {
1197         struct clk *parent = __clk_get_parent(hw->clk);
1198
1199         if (parent && (rate==__clk_get_rate(parent))) {
1200                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1201                                 __clk_get_name(hw->clk), rate);
1202                 return rate;
1203         }
1204
1205         return (apll_get_best_set(rate, rk3288_apll_table)->rate);
1206 }
1207
1208 /* 1: use, 0: no use */
1209 #define RK3288_USE_ARM_GPLL     1
1210
1211 static int clk_pll_set_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
1212                 unsigned long parent_rate)
1213 {
1214         struct clk_pll *pll = to_clk_pll(hw);
1215         struct clk *clk = hw->clk;
1216         struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
1217         unsigned long arm_gpll_rate, temp_rate, old_rate;
1218         const struct apll_clk_set *ps;
1219 //      u32 old_aclk_div = 0, new_aclk_div = 0;
1220         u32 temp_div;
1221         unsigned long flags;
1222         int sel_gpll = 0;
1223
1224
1225 #if 0
1226         if (rate == parent_rate) {
1227                 clk_debug("pll %s set rate=%lu equal to parent rate\n",
1228                                 __clk_get_name(hw->clk), rate);
1229                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1230                                 pll->mode_offset);
1231                 /* pll power down */
1232                 cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
1233                 clk_debug("pll %s enter slow mode, set rate OK!\n",
1234                                 __clk_get_name(hw->clk));
1235                 return 0;
1236         }
1237 #endif
1238
1239 #if !RK3288_USE_ARM_GPLL
1240         goto CHANGE_APLL;
1241 #endif
1242
1243         /* prepare arm_gpll before reparent clk_core to it */
1244         if (!arm_gpll) {
1245                 clk_err("clk arm_gpll is NULL!\n");
1246                 goto CHANGE_APLL;
1247         }
1248
1249         arm_gpll_rate = __clk_get_rate(arm_gpll);
1250         old_rate = __clk_get_rate(clk);
1251
1252         temp_rate = (old_rate > rate) ? old_rate : rate;
1253         temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
1254
1255         if (temp_div > RK3288_CORE_CLK_MAX_DIV) {
1256                 clk_debug("temp_div %d > max_div %d\n", temp_div,
1257                                 RK3288_CORE_CLK_MAX_DIV);
1258                 clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
1259                                 __clk_get_rate(clk), arm_gpll_rate);
1260                 goto CHANGE_APLL;
1261         }
1262
1263 #if 0
1264         if (clk_prepare(arm_gpll)) {
1265                 clk_err("fail to prepare arm_gpll path\n");
1266                 clk_unprepare(arm_gpll);
1267                 goto CHANGE_APLL;
1268         }
1269
1270         if (clk_enable(arm_gpll)) {
1271                 clk_err("fail to enable arm_gpll path\n");
1272                 clk_disable(arm_gpll);
1273                 clk_unprepare(arm_gpll);
1274                 goto CHANGE_APLL;
1275         }
1276 #endif
1277
1278         local_irq_save(flags);
1279
1280         /* select gpll */
1281         if (temp_div == 1) {
1282                 /* when old_rate/2 < (old_rate-arm_gpll_rate),
1283                    we can set div to make rate change more gently */
1284                 if (old_rate > (2*arm_gpll_rate)) {
1285                         cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1286                         udelay(10);
1287                         cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1288                         udelay(10);
1289                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1290                                 RK3288_CRU_CLKSELS_CON(0));
1291                         udelay(10);
1292                         cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1293                         udelay(10);
1294                         cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1295                 } else {
1296                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1297                                 RK3288_CRU_CLKSELS_CON(0));
1298                 }
1299         } else {
1300                 cru_writel(RK3288_CORE_CLK_DIV(temp_div), RK3288_CRU_CLKSELS_CON(0));
1301                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
1302                                 RK3288_CRU_CLKSELS_CON(0));
1303         }
1304
1305         sel_gpll = 1;
1306         //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
1307         smp_wmb();
1308
1309         local_irq_restore(flags);
1310
1311         clk_debug("temp select arm_gpll path, get rate %lu\n",
1312                         arm_gpll_rate/temp_div);
1313         clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
1314                         temp_div);
1315
1316 CHANGE_APLL:
1317         ps = apll_get_best_set(rate, rk3288_apll_table);
1318         clk_debug("apll will set rate %lu\n", ps->rate);
1319         clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
1320                         ps->pllcon0, ps->pllcon1, ps->pllcon2,
1321                         ps->clksel0, ps->clksel1);
1322
1323         local_irq_save(flags);
1324
1325         /* If core src don't select gpll, apll need to enter slow mode
1326          * before reset
1327          */
1328         //FIXME
1329         //if (!sel_gpll)
1330         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1331
1332         /* PLL enter rest */
1333         cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
1334
1335         cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1336         cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1337         cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1338
1339         udelay(5);
1340
1341         /* return from rest */
1342         cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
1343
1344         //wating lock state
1345         udelay(ps->rst_dly);
1346         pll_wait_lock(hw);
1347
1348         if (rate >= __clk_get_rate(hw->clk)) {
1349                 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1350                 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1351         }
1352
1353         /* PLL return from slow mode */
1354         //FIXME
1355         //if (!sel_gpll)
1356         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1357
1358         /* reparent to apll, and set div to 1 */
1359         if (sel_gpll) {
1360                 if (temp_div == 1) {
1361                         /* when rate/2 < (old_rate-arm_gpll_rate),
1362                            we can set div to make rate change more gently */
1363                         if (rate > (2*arm_gpll_rate)) {
1364                                 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1365                                 udelay(10);
1366                                 cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
1367                                 udelay(10);
1368                                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1369                                         RK3288_CRU_CLKSELS_CON(0));
1370                                 udelay(10);
1371                                 cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
1372                                 udelay(10);
1373                                 cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1374                         } else {
1375                                 cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1376                                                 RK3288_CRU_CLKSELS_CON(0));
1377                         }
1378                 } else {
1379                         cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
1380                                 RK3288_CRU_CLKSELS_CON(0));
1381                         cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
1382                 }
1383         }
1384
1385         if (rate < __clk_get_rate(hw->clk)) {
1386                 cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
1387                 cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
1388         }
1389
1390         //loops_per_jiffy = ps->lpj;
1391         smp_wmb();
1392
1393         local_irq_restore(flags);
1394
1395         if (sel_gpll) {
1396                 sel_gpll = 0;
1397                 //clk_disable(arm_gpll);
1398                 //clk_unprepare(arm_gpll);
1399         }
1400
1401         //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
1402
1403         clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
1404                         ps->rate,
1405                         cru_readl(pll->reg + RK3188_PLL_CON(0)),
1406                         cru_readl(pll->reg + RK3188_PLL_CON(1)),
1407                         cru_readl(pll->reg + RK3188_PLL_CON(2)),
1408                         cru_readl(pll->reg + RK3188_PLL_CON(3)),
1409                         cru_readl(RK3288_CRU_CLKSELS_CON(0)),
1410                         cru_readl(RK3288_CRU_CLKSELS_CON(1)));
1411
1412         return 0;
1413 }
1414
1415
1416 static const struct clk_ops clk_pll_ops_3288_apll = {
1417         .recalc_rate = clk_pll_recalc_rate_3288_apll,
1418         .round_rate = clk_pll_round_rate_3288_apll,
1419         .set_rate = clk_pll_set_rate_3288_apll,
1420 };
1421
1422 /* CLK_PLL_3036_APLL type ops */
1423 #define FRAC_MODE       0
1424 static unsigned long rk3036_pll_clk_recalc(struct clk_hw *hw,
1425 unsigned long parent_rate)
1426 {
1427         struct clk_pll *pll = to_clk_pll(hw);
1428         unsigned long rate;
1429         unsigned int dsmp = 0;
1430         u64 rate64 = 0, frac_rate64 = 0;
1431
1432         dsmp = RK3036_PLL_GET_DSMPD(cru_readl(pll->reg + RK3188_PLL_CON(1)));
1433
1434         if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
1435                 u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
1436                 u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
1437                 u32 pll_con2 = cru_readl(pll->reg + RK3188_PLL_CON(2));
1438                 /*integer mode*/
1439                 rate64 = (u64)parent_rate * RK3036_PLL_GET_FBDIV(pll_con0);
1440                 do_div(rate64, RK3036_PLL_GET_REFDIV(pll_con1));
1441
1442                 if (FRAC_MODE == dsmp) {
1443                         /*fractional mode*/
1444                         frac_rate64 = (u64)parent_rate
1445                         * RK3036_PLL_GET_FRAC(pll_con2);
1446                         do_div(frac_rate64, RK3036_PLL_GET_REFDIV(pll_con1));
1447                         rate64 += frac_rate64 >> 24;
1448                         clk_debug("%s frac_rate=%llu(%08x/2^24) by pass mode\n",
1449                                         __func__, frac_rate64 >> 24,
1450                                         RK3036_PLL_GET_FRAC(pll_con2));
1451                 }
1452                 do_div(rate64, RK3036_PLL_GET_POSTDIV1(pll_con0));
1453                 do_div(rate64, RK3036_PLL_GET_POSTDIV2(pll_con1));
1454
1455                 rate = rate64;
1456                 } else {
1457                 rate = parent_rate;
1458                 clk_debug("pll_clk_recalc rate=%lu by pass mode\n", rate);
1459         }
1460         return rate;
1461 }
1462
1463 static unsigned long clk_pll_recalc_rate_3036_apll(struct clk_hw *hw,
1464                 unsigned long parent_rate)
1465 {
1466         return rk3036_pll_clk_recalc(hw, parent_rate);
1467 }
1468
1469 static long clk_pll_round_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
1470                 unsigned long *prate)
1471 {
1472         struct clk *parent = __clk_get_parent(hw->clk);
1473
1474         if (parent && (rate == __clk_get_rate(parent))) {
1475                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1476                                 __clk_get_name(hw->clk), rate);
1477                 return rate;
1478         }
1479
1480         return (apll_get_best_set(rate, rk3036_apll_table)->rate);
1481 }
1482
1483 static  int rk3036_pll_clk_set_rate(struct pll_clk_set *clk_set,
1484         struct clk_hw *hw)
1485 {
1486         struct clk_pll *pll = to_clk_pll(hw);
1487
1488         /*enter slowmode*/
1489         cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
1490         pll->mode_offset);
1491
1492         cru_writel(clk_set->pllcon0,  pll->reg + RK3188_PLL_CON(0));
1493         cru_writel(clk_set->pllcon1,  pll->reg + RK3188_PLL_CON(1));
1494         cru_writel(clk_set->pllcon2,  pll->reg + RK3188_PLL_CON(2));
1495
1496         clk_debug("pllcon0%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1497         clk_debug("pllcon1%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1498         clk_debug("pllcon2%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1499         /*wating lock state*/
1500         udelay(clk_set->rst_dly);
1501         rk3036_pll_wait_lock(hw);
1502
1503         /*return form slow*/
1504         cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
1505         pll->mode_offset);
1506
1507         return 0;
1508 }
1509
1510 #define MIN_FOUTVCO_FREQ        (400 * 1000 * 1000)
1511 #define MAX_FOUTVCO_FREQ        (1600 * 1000 * 1000)
1512 static int rk3036_pll_clk_set_postdiv(unsigned long fout_hz,
1513 u32 *postdiv1, u32 *postdiv2, u32 *foutvco)
1514 {
1515         if (fout_hz < MIN_FOUTVCO_FREQ) {
1516                 for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++)
1517                         for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
1518                                 if (fout_hz * (*postdiv1) * (*postdiv2)
1519                                         >= MIN_FOUTVCO_FREQ && fout_hz
1520                                         * (*postdiv1) * (*postdiv2)
1521                                         <= MAX_FOUTVCO_FREQ) {
1522                                         *foutvco = fout_hz * (*postdiv1)
1523                                                 * (*postdiv2);
1524                                         return 0;
1525                                 }
1526                         }
1527                 clk_debug("CANNOT FINE postdiv1/2 to make fout in range from 400M to 1600M, fout = %lu\n",
1528                                 fout_hz);
1529         } else {
1530                 *postdiv1 = 1;
1531                 *postdiv2 = 1;
1532         }
1533         return 0;
1534 }
1535
1536 static int rk3036_pll_clk_get_set(unsigned long fin_hz, unsigned long fout_hz,
1537                 u32 *refdiv, u32 *fbdiv, u32 *postdiv1,
1538                 u32 *postdiv2, u32 *frac)
1539 {
1540         /* FIXME set postdiv1/2 always 1*/
1541         u32 gcd, foutvco = fout_hz;
1542         u64 fin_64, frac_64;
1543         u32 f_frac;
1544
1545         if (!fin_hz || !fout_hz || fout_hz == fin_hz)
1546                 return -1;
1547
1548         rk3036_pll_clk_set_postdiv(fout_hz, postdiv1, postdiv2, &foutvco);
1549         if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
1550                 fin_hz /= MHZ;
1551                 foutvco /= MHZ;
1552                 gcd = clk_gcd(fin_hz, foutvco);
1553                 *refdiv = fin_hz / gcd;
1554                 *fbdiv = foutvco / gcd;
1555
1556                 *frac = 0;
1557
1558                 clk_debug("fin=%lu,fout=%lu,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
1559                         fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
1560         } else {
1561                 clk_debug("******frac div running, fin_hz=%lu, fout_hz=%lu,fin_INT_mhz=%lu, fout_INT_mhz=%lu\n",
1562                         fin_hz, fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
1563                 clk_debug("******frac get postdiv1=%u, postdiv2=%u,foutvco=%u\n",
1564                         *postdiv1, *postdiv2, foutvco);
1565                 gcd = clk_gcd(fin_hz / MHZ, foutvco / MHZ);
1566                 *refdiv = fin_hz / MHZ / gcd;
1567                 *fbdiv = foutvco / MHZ / gcd;
1568                 clk_debug("******frac get refdiv=%u, fbdiv=%u\n", *refdiv, *fbdiv);
1569
1570                 *frac = 0;
1571
1572                 f_frac = (foutvco % MHZ);
1573                 fin_64 = fin_hz;
1574                 do_div(fin_64, (u64)*refdiv);
1575                 frac_64 = (u64)f_frac << 24;
1576                 do_div(frac_64, fin_64);
1577                 *frac = (u32) frac_64;
1578                 clk_debug("frac=%x\n", *frac);
1579         }
1580         return 0;
1581 }
1582 static int rk3036_pll_set_con(struct clk_hw *hw, u32 refdiv, u32 fbdiv, u32 postdiv1, u32 postdiv2, u32 frac)
1583 {
1584         struct pll_clk_set temp_clk_set;
1585         temp_clk_set.pllcon0 = RK3036_PLL_SET_FBDIV(fbdiv) | RK3036_PLL_SET_POSTDIV1(postdiv1);
1586         temp_clk_set.pllcon1 = RK3036_PLL_SET_REFDIV(refdiv) | RK3036_PLL_SET_POSTDIV2(postdiv2);
1587         if (frac != 0)
1588                 temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(0);
1589         else
1590                 temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(1);
1591
1592         temp_clk_set.pllcon2 = RK3036_PLL_SET_FRAC(frac);
1593         temp_clk_set.rst_dly = 0;
1594         clk_debug("setting....\n");
1595         return rk3036_pll_clk_set_rate(&temp_clk_set, hw);
1596 }
1597
1598 static int clk_pll_set_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
1599                 unsigned long parent_rate)
1600 {
1601         struct clk_pll *pll = to_clk_pll(hw);
1602         unsigned long flags;
1603         u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
1604         struct apll_clk_set *ps = (struct apll_clk_set *)(rk3036_apll_table);
1605
1606         while (ps->rate) {
1607                 if (ps->rate == rate) {
1608                         break;
1609                 }
1610                 ps++;
1611         }
1612
1613         clk_debug("%s %lu\n", __func__,  rate);
1614         clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1615         clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1616         clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1617         clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
1618         clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
1619         if (ps->rate == rate) {
1620                 printk("apll get a rate\n");
1621
1622                 /*enter slowmode*/
1623                 local_irq_save(flags);
1624                 cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
1625                 loops_per_jiffy = LPJ_24M;
1626
1627                 cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
1628                 cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
1629                 cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
1630                 cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
1631                 cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
1632
1633                 clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
1634                 clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
1635                 clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
1636                 clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
1637                 clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
1638
1639                 /*wating lock state*/
1640                 udelay(ps->rst_dly);
1641                 rk3036_pll_wait_lock(hw);
1642
1643                 /*return form slow*/
1644                 cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
1645                 loops_per_jiffy = ps->lpj;
1646                 local_irq_restore(flags);
1647         } else {
1648                 /*FIXME*/
1649                 rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac);
1650                 rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac);
1651         }
1652         clk_debug("setting OK\n");
1653
1654         return 0;       
1655 }
1656 static const struct clk_ops clk_pll_ops_3036_apll = {
1657         .recalc_rate = clk_pll_recalc_rate_3036_apll,
1658         .round_rate = clk_pll_round_rate_3036_apll,
1659         .set_rate = clk_pll_set_rate_3036_apll,
1660 };
1661
1662
1663 /* CLK_PLL_3036_plus_autotype ops */
1664
1665 static long clk_pll_round_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
1666                 unsigned long *prate)
1667 {
1668         struct clk *parent = __clk_get_parent(hw->clk);
1669
1670         if (parent && (rate == __clk_get_rate(parent))) {
1671                 clk_debug("pll %s round rate=%lu equal to parent rate\n",
1672                                 __clk_get_name(hw->clk), rate);
1673                 return rate;
1674         }
1675
1676         return (pll_com_get_best_set(rate, rk3036plus_pll_com_table)->rate);
1677 }
1678
1679 static int clk_pll_set_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
1680                 unsigned long parent_rate)
1681 {
1682         struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3036plus_pll_com_table);
1683
1684         clk_debug("******%s\n", __func__);
1685         while (clk_set->rate) {
1686                 clk_debug("******%s clk_set->rate=%lu\n", __func__, clk_set->rate);
1687                 if (clk_set->rate == rate) {
1688                         break;
1689                 }
1690                 clk_set++;
1691         }
1692         if (clk_set->rate == rate) {
1693                 rk3036_pll_clk_set_rate(clk_set, hw);
1694         } else {
1695                 clk_debug("gpll is no corresponding rate=%lu\n", rate);
1696                 return -1;
1697         }
1698         clk_debug("******%s end\n", __func__);
1699
1700         return 0;       
1701 }
1702
1703 static const struct clk_ops clk_pll_ops_3036plus_auto = {
1704         .recalc_rate = clk_pll_recalc_rate_3036_apll,
1705         .round_rate = clk_pll_round_rate_3036plus_auto,
1706         .set_rate = clk_pll_set_rate_3036plus_auto,
1707 };
1708
1709 const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
1710 {
1711         switch (pll_flags) {
1712                 case CLK_PLL_3188:
1713                         return &clk_pll_ops_3188;
1714
1715                 case CLK_PLL_3188_APLL:
1716                         return &clk_pll_ops_3188_apll;
1717
1718                 case CLK_PLL_3188PLUS:
1719                         return &clk_pll_ops_3188plus;
1720
1721                 case CLK_PLL_3188PLUS_APLL:
1722                         return &clk_pll_ops_3188plus_apll;
1723
1724                 case CLK_PLL_3288_APLL:
1725                         return &clk_pll_ops_3288_apll;
1726
1727                 case CLK_PLL_3188PLUS_AUTO:
1728                         return &clk_pll_ops_3188plus_auto;
1729
1730                 case CLK_PLL_3036_APLL:
1731                         return &clk_pll_ops_3036_apll;
1732
1733                 case CLK_PLL_3036PLUS_AUTO:
1734                         return &clk_pll_ops_3036plus_auto;
1735
1736                 default:
1737                         clk_err("%s: unknown pll_flags!\n", __func__);
1738                         return NULL;
1739         }
1740 }
1741
1742 struct clk *rk_clk_register_pll(struct device *dev, const char *name,
1743                 const char *parent_name, unsigned long flags, u32 reg,
1744                 u32 width, u32 mode_offset, u8 mode_shift,
1745                 u32 status_offset, u8 status_shift, u32 pll_flags,
1746                 spinlock_t *lock)
1747 {
1748         struct clk_pll *pll;
1749         struct clk *clk;
1750         struct clk_init_data init;
1751
1752
1753         clk_debug("%s: pll name = %s, pll_flags = 0x%x, register start!\n",
1754                         __func__, name, pll_flags);
1755
1756         /* allocate the pll */
1757         pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
1758         if (!pll) {
1759                 clk_err("%s: could not allocate pll clk\n", __func__);
1760                 return ERR_PTR(-ENOMEM);
1761         }
1762
1763         init.name = name;
1764         init.flags = flags;
1765         init.parent_names = (parent_name ? &parent_name: NULL);
1766         init.num_parents = (parent_name ? 1 : 0);
1767         init.ops = rk_get_pll_ops(pll_flags);
1768
1769         /* struct clk_pll assignments */
1770         pll->reg = reg;
1771         pll->width = width;
1772         pll->mode_offset = mode_offset;
1773         pll->mode_shift = mode_shift;
1774         pll->status_offset = status_offset;
1775         pll->status_shift = status_shift;
1776         pll->flags = pll_flags;
1777         pll->lock = lock;
1778         pll->hw.init = &init;
1779
1780         /* register the clock */
1781         clk = clk_register(dev, &pll->hw);
1782
1783         if (IS_ERR(clk))
1784                 kfree(pll);
1785
1786         clk_debug("%s: pll name = %s, pll_flags = 0x%x, register finish!\n",
1787                         __func__, name, pll_flags);
1788
1789         return clk;
1790 }
1791