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