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