File Index
Files and directories
Sign in
FILE

gp10b.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c C
  1// SPDX-License-Identifier: MIT
  2#include <subdev/clk.h>
  3#include <subdev/timer.h>
  4#include <core/device.h>
  5#include <core/tegra.h>
  6
  7#include "priv.h"
  8#include "gk20a_devfreq.h"
  9#include "gk20a.h"
 10#include "gp10b.h"
 11
 12static int
 13gp10b_clk_init(struct nvkm_clk *base)
 14{
 15	struct gp10b_clk *clk = gp10b_clk(base);
 16	struct nvkm_subdev *subdev = &clk->base.subdev;
 17	int ret;
 18
 19	/* Start with the highest frequency, matching the BPMP default */
 20	base->func->calc(base, &base->func->pstates[base->func->nr_pstates - 1].base);
 21	ret = base->func->prog(base);
 22	if (ret) {
 23		nvkm_error(subdev, "cannot initialize clock\n");
 24		return ret;
 25	}
 26
 27	ret = gk20a_devfreq_init(base, &clk->devfreq);
 28	if (ret)
 29		return ret;
 30
 31	return 0;
 32}
 33
 34static int
 35gp10b_clk_read(struct nvkm_clk *base, enum nv_clk_src src)
 36{
 37	struct gp10b_clk *clk = gp10b_clk(base);
 38	struct nvkm_subdev *subdev = &clk->base.subdev;
 39
 40	switch (src) {
 41	case nv_clk_src_gpc:
 42		return clk_get_rate(clk->clk) / GK20A_CLK_GPC_MDIV;
 43	default:
 44		nvkm_error(subdev, "invalid clock source %d\n", src);
 45		return -EINVAL;
 46	}
 47}
 48
 49static int
 50gp10b_clk_calc(struct nvkm_clk *base, struct nvkm_cstate *cstate)
 51{
 52	struct gp10b_clk *clk = gp10b_clk(base);
 53	u32 target_rate = cstate->domain[nv_clk_src_gpc] * GK20A_CLK_GPC_MDIV;
 54
 55	clk->new_rate = clk_round_rate(clk->clk, target_rate) / GK20A_CLK_GPC_MDIV;
 56
 57	return 0;
 58}
 59
 60static int
 61gp10b_clk_prog(struct nvkm_clk *base)
 62{
 63	struct gp10b_clk *clk = gp10b_clk(base);
 64	int ret;
 65
 66	ret = clk_set_rate(clk->clk, clk->new_rate * GK20A_CLK_GPC_MDIV);
 67	if (ret < 0)
 68		return ret;
 69
 70	clk->rate = clk_get_rate(clk->clk) / GK20A_CLK_GPC_MDIV;
 71
 72	return 0;
 73}
 74
 75static struct nvkm_pstate
 76gp10b_pstates[] = {
 77	{
 78		.base = {
 79			.domain[nv_clk_src_gpc] = 114750,
 80		},
 81	},
 82	{
 83		.base = {
 84			.domain[nv_clk_src_gpc] = 216750,
 85		},
 86	},
 87	{
 88		.base = {
 89			.domain[nv_clk_src_gpc] = 318750,
 90		},
 91	},
 92	{
 93		.base = {
 94			.domain[nv_clk_src_gpc] = 420750,
 95		},
 96	},
 97	{
 98		.base = {
 99			.domain[nv_clk_src_gpc] = 522750,
100		},
101	},
102	{
103		.base = {
104			.domain[nv_clk_src_gpc] = 624750,
105		},
106	},
107	{
108		.base = {
109			.domain[nv_clk_src_gpc] = 726750,
110		},
111	},
112	{
113		.base = {
114			.domain[nv_clk_src_gpc] = 828750,
115		},
116	},
117	{
118		.base = {
119			.domain[nv_clk_src_gpc] = 930750,
120		},
121	},
122	{
123		.base = {
124			.domain[nv_clk_src_gpc] = 1032750,
125		},
126	},
127	{
128		.base = {
129			.domain[nv_clk_src_gpc] = 1134750,
130		},
131	},
132	{
133		.base = {
134			.domain[nv_clk_src_gpc] = 1236750,
135		},
136	},
137	{
138		.base = {
139			.domain[nv_clk_src_gpc] = 1300500,
140		},
141	},
142};
143
144static const struct nvkm_clk_func
145gp10b_clk = {
146	.init = gp10b_clk_init,
147	.read = gp10b_clk_read,
148	.calc = gp10b_clk_calc,
149	.prog = gp10b_clk_prog,
150	.tidy = gk20a_clk_tidy,
151	.pstates = gp10b_pstates,
152	.nr_pstates = ARRAY_SIZE(gp10b_pstates),
153	.domains = {
154		{ nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV },
155		{ nv_clk_src_max }
156	}
157};
158
159int
160gp10b_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
161	      struct nvkm_clk **pclk)
162{
163	struct nvkm_device_tegra *tdev = device->func->tegra(device);
164	const struct nvkm_clk_func *func = &gp10b_clk;
165	struct gp10b_clk *clk;
166	int ret, i;
167
168	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
169	if (!clk)
170		return -ENOMEM;
171	*pclk = &clk->base;
172	clk->clk = tdev->clk;
173
174	/* Finish initializing the pstates */
175	for (i = 0; i < func->nr_pstates; i++) {
176		INIT_LIST_HEAD(&func->pstates[i].list);
177		func->pstates[i].pstate = i + 1;
178	}
179
180	ret = nvkm_clk_ctor(func, device, type, inst, true, &clk->base);
181	if (ret)
182		return ret;
183
184	return 0;
185}
~/ Read-only file preview.