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