1 /*
2  * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include <subdev/clk.h>
24 #include <core/device.h>
25 
26 #include "priv.h"
27 #include "gk20a.h"
28 
29 #define KHZ (1000)
30 #define MHZ (KHZ * 1000)
31 
32 #define MASK(w)	((1 << w) - 1)
33 
34 #define BYPASSCTRL_SYS	(SYS_GPCPLL_CFG_BASE + 0x340)
35 #define BYPASSCTRL_SYS_GPCPLL_SHIFT	0
36 #define BYPASSCTRL_SYS_GPCPLL_WIDTH	1
37 
38 static u32 pl_to_div(u32 pl)
39 {
40 	return pl;
41 }
42 
43 static u32 div_to_pl(u32 div)
44 {
45 	return div;
46 }
47 
48 static const struct gk20a_clk_pllg_params gm20b_pllg_params = {
49 	.min_vco = 1300000, .max_vco = 2600000,
50 	.min_u = 12000, .max_u = 38400,
51 	.min_m = 1, .max_m = 255,
52 	.min_n = 8, .max_n = 255,
53 	.min_pl = 1, .max_pl = 31,
54 };
55 
56 static struct nvkm_pstate
57 gm20b_pstates[] = {
58 	{
59 		.base = {
60 			.domain[nv_clk_src_gpc] = 76800,
61 			.voltage = 0,
62 		},
63 	},
64 	{
65 		.base = {
66 			.domain[nv_clk_src_gpc] = 153600,
67 			.voltage = 1,
68 		},
69 	},
70 	{
71 		.base = {
72 			.domain[nv_clk_src_gpc] = 230400,
73 			.voltage = 2,
74 		},
75 	},
76 	{
77 		.base = {
78 			.domain[nv_clk_src_gpc] = 307200,
79 			.voltage = 3,
80 		},
81 	},
82 	{
83 		.base = {
84 			.domain[nv_clk_src_gpc] = 384000,
85 			.voltage = 4,
86 		},
87 	},
88 	{
89 		.base = {
90 			.domain[nv_clk_src_gpc] = 460800,
91 			.voltage = 5,
92 		},
93 	},
94 	{
95 		.base = {
96 			.domain[nv_clk_src_gpc] = 537600,
97 			.voltage = 6,
98 		},
99 	},
100 	{
101 		.base = {
102 			.domain[nv_clk_src_gpc] = 614400,
103 			.voltage = 7,
104 		},
105 	},
106 	{
107 		.base = {
108 			.domain[nv_clk_src_gpc] = 691200,
109 			.voltage = 8,
110 		},
111 	},
112 	{
113 		.base = {
114 			.domain[nv_clk_src_gpc] = 768000,
115 			.voltage = 9,
116 		},
117 	},
118 	{
119 		.base = {
120 			.domain[nv_clk_src_gpc] = 844800,
121 			.voltage = 10,
122 		},
123 	},
124 	{
125 		.base = {
126 			.domain[nv_clk_src_gpc] = 921600,
127 			.voltage = 11,
128 		},
129 	},
130 	{
131 		.base = {
132 			.domain[nv_clk_src_gpc] = 998400,
133 			.voltage = 12,
134 		},
135 	},
136 
137 };
138 
139 static int
140 gm20b_clk_init(struct nvkm_clk *base)
141 {
142 	struct gk20a_clk *clk = gk20a_clk(base);
143 	struct nvkm_subdev *subdev = &clk->base.subdev;
144 	struct nvkm_device *device = subdev->device;
145 	int ret;
146 
147 	/* Set the global bypass control to VCO */
148 	nvkm_mask(device, BYPASSCTRL_SYS,
149 	       MASK(BYPASSCTRL_SYS_GPCPLL_WIDTH) << BYPASSCTRL_SYS_GPCPLL_SHIFT,
150 	       0);
151 
152 	/* Start with lowest frequency */
153 	base->func->calc(base, &base->func->pstates[0].base);
154 	ret = base->func->prog(&clk->base);
155 	if (ret) {
156 		nvkm_error(subdev, "cannot initialize clock\n");
157 		return ret;
158 	}
159 
160 	return 0;
161 }
162 
163 static const struct nvkm_clk_func
164 gm20b_clk_speedo0 = {
165 	.init = gm20b_clk_init,
166 	.fini = gk20a_clk_fini,
167 	.read = gk20a_clk_read,
168 	.calc = gk20a_clk_calc,
169 	.prog = gk20a_clk_prog,
170 	.tidy = gk20a_clk_tidy,
171 	.pstates = gm20b_pstates,
172 	.nr_pstates = ARRAY_SIZE(gm20b_pstates) - 1,
173 	.domains = {
174 		{ nv_clk_src_crystal, 0xff },
175 		{ nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV },
176 		{ nv_clk_src_max },
177 	},
178 };
179 
180 int
181 gm20b_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
182 {
183 	struct gk20a_clk *clk;
184 	int ret;
185 
186 	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
187 	if (!clk)
188 		return -ENOMEM;
189 	*pclk = &clk->base;
190 
191 	ret = _gk20a_clk_ctor(device, index, &gm20b_clk_speedo0,
192 			      &gm20b_pllg_params, clk);
193 
194 	clk->pl_to_div = pl_to_div;
195 	clk->div_to_pl = div_to_pl;
196 
197 	return ret;
198 }
199