FILE
gp10b.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.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.