diff options
33 files changed, 3575 insertions, 36 deletions
diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu index 33d158bb..22c679ca 100644 --- a/drivers/gpu/nvgpu/Makefile.nvgpu +++ b/drivers/gpu/nvgpu/Makefile.nvgpu | |||
@@ -88,7 +88,12 @@ nvgpu-y := \ | |||
88 | gm206/acr_gm206.o \ | 88 | gm206/acr_gm206.o \ |
89 | gm206/mm_gm206.o \ | 89 | gm206/mm_gm206.o \ |
90 | gm206/pmu_gm206.o \ | 90 | gm206/pmu_gm206.o \ |
91 | gm206/ce_gm206.o | 91 | gm206/ce_gm206.o \ |
92 | boardobj/boardobj.o \ | ||
93 | boardobj/boardobjgrp.o \ | ||
94 | boardobj/boardobjgrpmask.o \ | ||
95 | boardobj/boardobjgrp_e255.o \ | ||
96 | boardobj/boardobjgrp_e32.o | ||
92 | 97 | ||
93 | nvgpu-$(CONFIG_TEGRA_GK20A) += gk20a/platform_gk20a_tegra.o | 98 | nvgpu-$(CONFIG_TEGRA_GK20A) += gk20a/platform_gk20a_tegra.o |
94 | nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o | 99 | nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o |
diff --git a/drivers/gpu/nvgpu/boardobj/boardobj.c b/drivers/gpu/nvgpu/boardobj/boardobj.c new file mode 100644 index 00000000..86b639cc --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobj.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include "gk20a/gk20a.h" | ||
15 | #include <linux/firmware.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/uaccess.h> | ||
18 | #include "boardobj.h" | ||
19 | #include "ctrl/ctrlboardobj.h" | ||
20 | #include "pmuif/gpmuifboardobj.h" | ||
21 | |||
22 | |||
23 | u32 boardobj_construct_super(struct gk20a *g, struct boardobj **ppboardobj, | ||
24 | u16 size, void *args) | ||
25 | { | ||
26 | struct boardobj *pboardobj = NULL; | ||
27 | struct boardobj *devtmp = (struct boardobj *)args; | ||
28 | |||
29 | gk20a_dbg_info(" "); | ||
30 | |||
31 | if (devtmp == NULL) | ||
32 | return -EINVAL; | ||
33 | |||
34 | if (*ppboardobj == NULL) { | ||
35 | *ppboardobj = kzalloc(size, GFP_KERNEL); | ||
36 | if (ppboardobj == NULL) | ||
37 | return -ENOMEM; | ||
38 | } | ||
39 | |||
40 | pboardobj = *ppboardobj; | ||
41 | pboardobj->type = devtmp->type; | ||
42 | pboardobj->idx = CTRL_BOARDOBJ_IDX_INVALID; | ||
43 | pboardobj->type_mask = BIT(pboardobj->type) | devtmp->type_mask; | ||
44 | |||
45 | pboardobj->implements = boardobj_implements_super; | ||
46 | pboardobj->destruct = boardobj_destruct_super; | ||
47 | pboardobj->pmudatainit = boardobj_pmudatainit_super; | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | u32 boardobj_destruct_super(struct boardobj *pboardobj) | ||
53 | { | ||
54 | gk20a_dbg_info(""); | ||
55 | if (pboardobj == NULL) | ||
56 | return -EINVAL; | ||
57 | kfree(pboardobj); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | bool boardobj_implements_super(struct gk20a *g, struct boardobj *pboardobj, | ||
62 | u8 type) | ||
63 | { | ||
64 | gk20a_dbg_info(""); | ||
65 | |||
66 | return (0 != (pboardobj->type_mask & BIT(type))); | ||
67 | } | ||
68 | |||
69 | u32 boardobj_pmudatainit_super(struct gk20a *g, struct boardobj *pboardobj, | ||
70 | struct nv_pmu_boardobj *pmudata) | ||
71 | { | ||
72 | gk20a_dbg_info(""); | ||
73 | if (pboardobj == NULL) | ||
74 | return -EINVAL; | ||
75 | if (pmudata == NULL) | ||
76 | return -EINVAL; | ||
77 | pmudata->type = pboardobj->type; | ||
78 | gk20a_dbg_info(" Done"); | ||
79 | return 0; | ||
80 | } | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobj.h b/drivers/gpu/nvgpu/boardobj/boardobj.h new file mode 100644 index 00000000..3d437a82 --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobj.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _BOARDOBJ_H_ | ||
15 | #define _BOARDOBJ_H_ | ||
16 | |||
17 | struct boardobj; | ||
18 | |||
19 | #include <linux/nvgpu.h> | ||
20 | #include "gk20a/gk20a.h" | ||
21 | #include "gk20a/pmu_gk20a.h" | ||
22 | #include "ctrl/ctrlboardobj.h" | ||
23 | #include "pmuif/gpmuifboardobj.h" | ||
24 | |||
25 | /* | ||
26 | * check whether the specified BOARDOBJ object implements the queried | ||
27 | * type/class enumeration. | ||
28 | */ | ||
29 | typedef bool boardobj_implements(struct gk20a *g, struct boardobj *pboardobj, | ||
30 | u8 type); | ||
31 | |||
32 | /* | ||
33 | * Fills out the appropriate the nv_pmu_xxxx_device_desc_<xyz> driver->PMU | ||
34 | * description structure, describing this BOARDOBJ board device to the PMU. | ||
35 | * | ||
36 | */ | ||
37 | typedef u32 boardobj_pmudatainit(struct gk20a *g, struct boardobj *pboardobj, | ||
38 | struct nv_pmu_boardobj *pmudata); | ||
39 | |||
40 | /* | ||
41 | * Constructor for the base Board Object. Called by each device-specific | ||
42 | * implementation of the BOARDOBJ interface to initialize the board object. | ||
43 | */ | ||
44 | typedef u32 boardobj_construct(struct gk20a *g, struct boardobj **pboardobj, | ||
45 | u16 size, void *args); | ||
46 | |||
47 | /* | ||
48 | * Destructor for the base board object. Called by each device-Specific | ||
49 | * implementation of the BOARDOBJ interface to destroy the board object. | ||
50 | * This has to be explicitly set by each device that extends from the | ||
51 | * board object. | ||
52 | */ | ||
53 | typedef u32 boardobj_destruct(struct boardobj *pboardobj); | ||
54 | |||
55 | /* | ||
56 | * Base Class for all physical or logical device on the PCB. | ||
57 | * Contains fields common to all devices on the board. Specific types of | ||
58 | * devices may extend this object adding any details specific to that | ||
59 | * device or device-type. | ||
60 | */ | ||
61 | |||
62 | struct boardobj { | ||
63 | u8 type; /*type of the device*/ | ||
64 | u8 idx; /*index of boardobj within in its group*/ | ||
65 | u32 type_mask; /*mask of types this boardobjimplements*/ | ||
66 | boardobj_implements *implements; | ||
67 | boardobj_destruct *destruct; | ||
68 | /* | ||
69 | * Access interface apis which will be overridden by the devices | ||
70 | * that inherit from BOARDOBJ | ||
71 | */ | ||
72 | boardobj_pmudatainit *pmudatainit; | ||
73 | }; | ||
74 | |||
75 | boardobj_construct boardobj_construct_super; | ||
76 | boardobj_destruct boardobj_destruct_super; | ||
77 | boardobj_implements boardobj_implements_super; | ||
78 | boardobj_pmudatainit boardobj_pmudatainit_super; | ||
79 | |||
80 | #define BOARDOBJ_GET_TYPE(pobj) (((struct boardobj *)(pobj))->type) | ||
81 | #define BOARDOBJ_GET_IDX(pobj) (((struct boardobj *)(pobj))->idx) | ||
82 | |||
83 | #endif | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp.c b/drivers/gpu/nvgpu/boardobj/boardobjgrp.c new file mode 100644 index 00000000..dfa394ed --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp.c | |||
@@ -0,0 +1,697 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include "gk20a/gk20a.h" | ||
15 | #include "gk20a/pmu_gk20a.h" | ||
16 | #include "boardobjgrp.h" | ||
17 | #include "ctrl/ctrlboardobj.h" | ||
18 | #include "boardobj.h" | ||
19 | |||
20 | static boardobjgrp_objinsert boardobjgrp_objinsert_final; | ||
21 | static boardobjgrp_objgetbyidx boardobjgrp_objgetbyidx_final; | ||
22 | static boardobjgrp_objgetnext boardobjgrp_objgetnext_final; | ||
23 | static boardobjgrp_objremoveanddestroy boardobjgrp_objremoveanddestroy_final; | ||
24 | static boardobjgrp_pmudatainstget boardobjgrp_pmudatainstget_stub; | ||
25 | static boardobjgrp_pmustatusinstget boardobjgrp_pmustatusinstget_stub; | ||
26 | static u32 boardobjgrp_pmucmdsend(struct gk20a *g, | ||
27 | struct boardobjgrp *pboardobjgrp, | ||
28 | struct boardobjgrp_pmu_cmd *pcmd); | ||
29 | struct boardobjgrp_pmucmdhandler_params { | ||
30 | /* Pointer to the BOARDOBJGRP associated with this CMD */ | ||
31 | struct boardobjgrp *pboardobjgrp; | ||
32 | /* Pointer to structure representing this NV_PMU_BOARDOBJ_CMD_GRP */ | ||
33 | struct boardobjgrp_pmu_cmd *pcmd; | ||
34 | /* Boolean indicating whether the PMU successfully handled the CMD */ | ||
35 | u32 success; | ||
36 | }; | ||
37 | |||
38 | u32 boardobjgrp_construct_super(struct boardobjgrp *pboardobjgrp) | ||
39 | { | ||
40 | gk20a_dbg_info(""); | ||
41 | |||
42 | if (pboardobjgrp == NULL) | ||
43 | return -EINVAL; | ||
44 | |||
45 | if (pboardobjgrp->ppobjects == NULL) | ||
46 | return -EINVAL; | ||
47 | |||
48 | if (pboardobjgrp->mask == NULL) | ||
49 | return -EINVAL; | ||
50 | |||
51 | pboardobjgrp->objmask = 0; | ||
52 | |||
53 | pboardobjgrp->classid = 0; | ||
54 | pboardobjgrp->pmu.unitid = BOARDOBJGRP_UNIT_ID_INVALID; | ||
55 | pboardobjgrp->pmu.classid = BOARDOBJGRP_GRP_CLASS_ID_INVALID; | ||
56 | pboardobjgrp->pmu.set.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; | ||
57 | pboardobjgrp->pmu.getstatus.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; | ||
58 | |||
59 | /* Initialize basic interfaces */ | ||
60 | pboardobjgrp->destruct = boardobjgrp_destruct_super; | ||
61 | pboardobjgrp->objinsert = boardobjgrp_objinsert_final; | ||
62 | pboardobjgrp->objgetbyidx = boardobjgrp_objgetbyidx_final; | ||
63 | pboardobjgrp->objgetnext = boardobjgrp_objgetnext_final; | ||
64 | pboardobjgrp->objremoveanddestroy = | ||
65 | boardobjgrp_objremoveanddestroy_final; | ||
66 | |||
67 | pboardobjgrp->pmuinithandle = boardobjgrp_pmuinithandle_impl; | ||
68 | pboardobjgrp->pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_super; | ||
69 | pboardobjgrp->pmudatainit = boardobjgrp_pmudatainit_super; | ||
70 | pboardobjgrp->pmuset = boardobjgrp_pmuset_impl; | ||
71 | pboardobjgrp->pmugetstatus = boardobjgrp_pmugetstatus_impl; | ||
72 | |||
73 | pboardobjgrp->pmudatainstget = boardobjgrp_pmudatainstget_stub; | ||
74 | pboardobjgrp->pmustatusinstget = boardobjgrp_pmustatusinstget_stub; | ||
75 | |||
76 | pboardobjgrp->objmaxidx = CTRL_BOARDOBJ_IDX_INVALID; | ||
77 | pboardobjgrp->bconstructed = true; | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | u32 boardobjgrp_destruct_impl(struct boardobjgrp *pboardobjgrp) | ||
83 | { | ||
84 | gk20a_dbg_info(""); | ||
85 | |||
86 | if (pboardobjgrp == NULL) | ||
87 | return -EINVAL; | ||
88 | |||
89 | if (!pboardobjgrp->bconstructed) | ||
90 | return 0; | ||
91 | |||
92 | return pboardobjgrp->destruct(pboardobjgrp); | ||
93 | } | ||
94 | |||
95 | u32 boardobjgrp_destruct_super(struct boardobjgrp *pboardobjgrp) | ||
96 | { | ||
97 | struct boardobj *pboardobj; | ||
98 | u32 status = 0; | ||
99 | u32 stat; | ||
100 | u8 index; | ||
101 | |||
102 | gk20a_dbg_info(""); | ||
103 | |||
104 | if (pboardobjgrp->mask == NULL) | ||
105 | return -EINVAL; | ||
106 | if (pboardobjgrp->ppobjects == NULL) | ||
107 | return -EINVAL; | ||
108 | |||
109 | BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { | ||
110 | stat = pboardobjgrp->objremoveanddestroy(pboardobjgrp, index); | ||
111 | if (status == 0) | ||
112 | status = stat; | ||
113 | |||
114 | pboardobjgrp->ppobjects[index] = NULL; | ||
115 | pboardobjgrp->objmask &= ~BIT(index); | ||
116 | } | ||
117 | |||
118 | pboardobjgrp->objmask = 0; | ||
119 | |||
120 | if (pboardobjgrp->objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { | ||
121 | if (status == 0) | ||
122 | status = -EINVAL; | ||
123 | |||
124 | WARN_ON(true); | ||
125 | } | ||
126 | |||
127 | /* Destroy the PMU CMD data */ | ||
128 | stat = boardobjgrp_pmucmd_destroy_impl(&pboardobjgrp->pmu.set); | ||
129 | if (status == 0) | ||
130 | status = stat; | ||
131 | |||
132 | stat = boardobjgrp_pmucmd_destroy_impl(&pboardobjgrp->pmu.getstatus); | ||
133 | if (status == 0) | ||
134 | status = stat; | ||
135 | |||
136 | pboardobjgrp->bconstructed = false; | ||
137 | |||
138 | return status; | ||
139 | } | ||
140 | |||
141 | u32 boardobjgrp_pmucmd_construct_impl(struct gk20a *g, struct boardobjgrp | ||
142 | *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, | ||
143 | u8 hdrsize, u8 entrysize, u16 fbsize) | ||
144 | { | ||
145 | gk20a_dbg_info(""); | ||
146 | |||
147 | /* Copy the parameters into the CMD*/ | ||
148 | cmd->id = id; | ||
149 | cmd->msgid = msgid; | ||
150 | cmd->hdrsize = hdrsize; | ||
151 | cmd->entrysize = entrysize; | ||
152 | cmd->fbsize = fbsize; | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | |||
158 | u32 boardobjgrp_pmucmd_destroy_impl(struct boardobjgrp_pmu_cmd *cmd) | ||
159 | { | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | u32 boardobjgrp_pmucmd_pmuinithandle_impl(struct gk20a *g, | ||
164 | struct boardobjgrp *pboardobjgrp, | ||
165 | struct boardobjgrp_pmu_cmd *pcmd) | ||
166 | { | ||
167 | u32 status = 0; | ||
168 | struct mem_desc *sysmem_desc = &pcmd->surf.sysmem_desc; | ||
169 | |||
170 | gk20a_dbg_info(""); | ||
171 | |||
172 | if (pcmd->id == BOARDOBJGRP_GRP_CMD_ID_INVALID) | ||
173 | goto boardobjgrp_pmucmd_pmuinithandle_exit; | ||
174 | |||
175 | gk20a_pmu_sysmem_surface_alloc(g, sysmem_desc, pcmd->fbsize); | ||
176 | |||
177 | pcmd->buf = (struct nv_pmu_boardobjgrp_super *)sysmem_desc->cpu_va; | ||
178 | |||
179 | boardobjgrp_pmucmd_pmuinithandle_exit: | ||
180 | return status; | ||
181 | } | ||
182 | |||
183 | u32 boardobjgrp_pmuinithandle_impl(struct gk20a *g, | ||
184 | struct boardobjgrp *pboardobjgrp) | ||
185 | { | ||
186 | u32 status = 0; | ||
187 | |||
188 | gk20a_dbg_info(""); | ||
189 | |||
190 | status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, | ||
191 | &pboardobjgrp->pmu.set); | ||
192 | if (status) { | ||
193 | gk20a_err(dev_from_gk20a(g), "failed to init pmu set cmd"); | ||
194 | goto boardobjgrp_pmuinithandle_exit; | ||
195 | } | ||
196 | |||
197 | status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, | ||
198 | &pboardobjgrp->pmu.getstatus); | ||
199 | if (status) { | ||
200 | gk20a_err(dev_from_gk20a(g), "failed to init get status command"); | ||
201 | goto boardobjgrp_pmuinithandle_exit; | ||
202 | } | ||
203 | |||
204 | /* If the GRP_SET CMD has not been allocated, nothing left to do. */ | ||
205 | if (((pboardobjgrp->pmu.set.id) == BOARDOBJGRP_GRP_CMD_ID_INVALID) || | ||
206 | (BOARDOBJGRP_IS_EMPTY(pboardobjgrp))) | ||
207 | goto boardobjgrp_pmuinithandle_exit; | ||
208 | |||
209 | /* Send the BOARDOBJGRP to the pmu via RM_PMU_BOARDOBJ_CMD_GRP. */ | ||
210 | status = pboardobjgrp->pmuset(g, pboardobjgrp); | ||
211 | if (status) | ||
212 | gk20a_err(dev_from_gk20a(g), "failed to send boardobg grp to PMU"); | ||
213 | |||
214 | boardobjgrp_pmuinithandle_exit: | ||
215 | return status; | ||
216 | } | ||
217 | |||
218 | |||
219 | u32 boardobjgrp_pmuhdrdatainit_super(struct gk20a *g, struct boardobjgrp | ||
220 | *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, | ||
221 | struct boardobjgrpmask *mask) | ||
222 | { | ||
223 | gk20a_dbg_info(""); | ||
224 | |||
225 | if (pboardobjgrp == NULL) | ||
226 | return -EINVAL; | ||
227 | if (pboardobjgrppmu == NULL) | ||
228 | return -EINVAL; | ||
229 | pboardobjgrppmu->type = pboardobjgrp->type; | ||
230 | pboardobjgrppmu->class_id = pboardobjgrp->classid; | ||
231 | pboardobjgrppmu->obj_slots = BOARDOBJGRP_PMU_SLOTS_GET(pboardobjgrp); | ||
232 | |||
233 | gk20a_dbg_info(" Done"); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | u32 boardobjgrp_pmudatainstget_stub(struct gk20a *g, | ||
238 | struct nv_pmu_boardobjgrp *boardobjgrppmu, | ||
239 | struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx) | ||
240 | { | ||
241 | gk20a_dbg_info(""); | ||
242 | return -EINVAL; | ||
243 | } | ||
244 | |||
245 | |||
246 | u32 boardobjgrp_pmustatusinstget_stub(struct gk20a *g, void *pboardobjgrppmu, | ||
247 | struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx) | ||
248 | { | ||
249 | gk20a_dbg_info(""); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | |||
254 | u32 boardobjgrp_pmudatainit_super(struct gk20a *g, struct boardobjgrp | ||
255 | *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) | ||
256 | { | ||
257 | u32 status = 0; | ||
258 | struct boardobj *pboardobj = NULL; | ||
259 | struct nv_pmu_boardobj *ppmudata = NULL; | ||
260 | u8 index; | ||
261 | |||
262 | gk20a_dbg_info(""); | ||
263 | |||
264 | if (pboardobjgrp == NULL) | ||
265 | return -EINVAL; | ||
266 | if (pboardobjgrppmu == NULL) | ||
267 | return -EINVAL; | ||
268 | |||
269 | /* Initialize the PMU HDR data.*/ | ||
270 | status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, pboardobjgrppmu, | ||
271 | pboardobjgrp->mask); | ||
272 | if (status) { | ||
273 | gk20a_err(dev_from_gk20a(g), | ||
274 | "unable to init boardobjgrp pmuhdr data"); | ||
275 | goto boardobjgrppmudatainit_super_done; | ||
276 | } | ||
277 | |||
278 | BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { | ||
279 | status = pboardobjgrp->pmudatainstget(g, | ||
280 | (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, | ||
281 | &ppmudata, index); | ||
282 | if (status) { | ||
283 | gk20a_err(dev_from_gk20a(g), | ||
284 | "could not get object instance"); | ||
285 | goto boardobjgrppmudatainit_super_done; | ||
286 | } | ||
287 | |||
288 | /* Initialize the PMU Data and send to PMU */ | ||
289 | status = pboardobj->pmudatainit(g, pboardobj, ppmudata); | ||
290 | if (status) { | ||
291 | gk20a_err(dev_from_gk20a(g), | ||
292 | "could not parse pmu for device %d", index); | ||
293 | goto boardobjgrppmudatainit_super_done; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | boardobjgrppmudatainit_super_done: | ||
298 | gk20a_dbg_info(" Done"); | ||
299 | return status; | ||
300 | } | ||
301 | |||
302 | u32 boardobjgrp_pmuset_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp) | ||
303 | { | ||
304 | u32 status = 0; | ||
305 | |||
306 | gk20a_dbg_info(""); | ||
307 | |||
308 | if (pboardobjgrp == NULL) | ||
309 | return -EINVAL; | ||
310 | |||
311 | if (!pboardobjgrp->bconstructed) | ||
312 | return -EINVAL; | ||
313 | |||
314 | if (pboardobjgrp->pmu.unitid == BOARDOBJGRP_UNIT_ID_INVALID) | ||
315 | return -EINVAL; | ||
316 | |||
317 | if (pboardobjgrp->pmu.classid == BOARDOBJGRP_GRP_CLASS_ID_INVALID) | ||
318 | return -EINVAL; | ||
319 | |||
320 | if (pboardobjgrp->pmu.set.id == BOARDOBJGRP_GRP_CMD_ID_INVALID) | ||
321 | return -EINVAL; | ||
322 | |||
323 | if ((pboardobjgrp->pmu.set.hdrsize == 0) || | ||
324 | (pboardobjgrp->pmu.set.entrysize == 0) || | ||
325 | (pboardobjgrp->pmu.set.buf == NULL)) | ||
326 | return -EINVAL; | ||
327 | |||
328 | /* If no objects in the group, return early */ | ||
329 | if (BOARDOBJGRP_IS_EMPTY(pboardobjgrp)) | ||
330 | return -EINVAL; | ||
331 | |||
332 | /* Initialize PMU buffer with BOARDOBJGRP data. */ | ||
333 | memset(pboardobjgrp->pmu.set.buf, 0x0, pboardobjgrp->pmu.set.fbsize); | ||
334 | status = pboardobjgrp->pmudatainit(g, pboardobjgrp, | ||
335 | pboardobjgrp->pmu.set.buf); | ||
336 | if (status) { | ||
337 | gk20a_err(dev_from_gk20a(g), | ||
338 | "could not parse pmu data"); | ||
339 | goto boardobjgrp_pmuset_exit; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Reset the boolean that indicates set status for most recent | ||
344 | * instance of BOARDOBJGRP. | ||
345 | */ | ||
346 | pboardobjgrp->pmu.bset = false; | ||
347 | |||
348 | /* Send the SET PMU CMD to the PMU */ | ||
349 | status = boardobjgrp_pmucmdsend(g, pboardobjgrp, | ||
350 | &pboardobjgrp->pmu.set); | ||
351 | if (status) { | ||
352 | gk20a_err(dev_from_gk20a(g), "could not send SET CMD to PMU"); | ||
353 | goto boardobjgrp_pmuset_exit; | ||
354 | } | ||
355 | |||
356 | pboardobjgrp->pmu.bset = true; | ||
357 | |||
358 | boardobjgrp_pmuset_exit: | ||
359 | return status; | ||
360 | } | ||
361 | |||
362 | u32 | ||
363 | boardobjgrp_pmugetstatus_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp, | ||
364 | struct boardobjgrpmask *mask) | ||
365 | { | ||
366 | u32 status = 0; | ||
367 | |||
368 | gk20a_dbg_info(""); | ||
369 | |||
370 | if (pboardobjgrp == NULL) | ||
371 | return -EINVAL; | ||
372 | |||
373 | if (!pboardobjgrp->bconstructed) | ||
374 | return -EINVAL; | ||
375 | |||
376 | if (pboardobjgrp->pmu.unitid == BOARDOBJGRP_UNIT_ID_INVALID) | ||
377 | return -EINVAL; | ||
378 | |||
379 | if (pboardobjgrp->pmu.classid == BOARDOBJGRP_GRP_CLASS_ID_INVALID) | ||
380 | return -EINVAL; | ||
381 | |||
382 | if (pboardobjgrp->pmu.set.id == BOARDOBJGRP_GRP_CMD_ID_INVALID) | ||
383 | return -EINVAL; | ||
384 | |||
385 | if ((pboardobjgrp->pmu.set.hdrsize == 0) || | ||
386 | (pboardobjgrp->pmu.set.entrysize == 0) || | ||
387 | (pboardobjgrp->pmu.set.buf == NULL)) | ||
388 | return -EINVAL; | ||
389 | |||
390 | /* If no objects in the group, return early */ | ||
391 | if (BOARDOBJGRP_IS_EMPTY(pboardobjgrp)) | ||
392 | return -EINVAL; | ||
393 | |||
394 | /* | ||
395 | * Can only GET_STATUS if the BOARDOBJGRP has been previously SET to the | ||
396 | * PMU | ||
397 | */ | ||
398 | if (!pboardobjgrp->pmu.bset) | ||
399 | return -EINVAL; | ||
400 | |||
401 | /* | ||
402 | * Initialize PMU buffer with the mask of BOARDOBJGRPs for which to | ||
403 | * retrieve status | ||
404 | */ | ||
405 | |||
406 | memset(pboardobjgrp->pmu.getstatus.buf, 0x0, | ||
407 | pboardobjgrp->pmu.getstatus.fbsize); | ||
408 | status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, | ||
409 | pboardobjgrp->pmu.getstatus.buf, mask); | ||
410 | if (status) { | ||
411 | gk20a_err(dev_from_gk20a(g), "could not init PMU HDR data"); | ||
412 | goto boardobjgrp_pmugetstatus_exit; | ||
413 | } | ||
414 | |||
415 | /* Send the GET_STATUS PMU CMD to the PMU */ | ||
416 | status = boardobjgrp_pmucmdsend(g, pboardobjgrp, | ||
417 | &pboardobjgrp->pmu.getstatus); | ||
418 | if (status) { | ||
419 | gk20a_err(dev_from_gk20a(g), | ||
420 | "could not send GET_STATUS cmd to PMU"); | ||
421 | goto boardobjgrp_pmugetstatus_exit; | ||
422 | } | ||
423 | |||
424 | boardobjgrp_pmugetstatus_exit: | ||
425 | return status; | ||
426 | } | ||
427 | |||
428 | static u32 | ||
429 | boardobjgrp_objinsert_final(struct boardobjgrp *pboardobjgrp, | ||
430 | struct boardobj *pboardobj, u8 index) | ||
431 | { | ||
432 | |||
433 | gk20a_dbg_info(""); | ||
434 | |||
435 | if (pboardobjgrp == NULL) | ||
436 | return -EINVAL; | ||
437 | |||
438 | if (pboardobj == NULL) | ||
439 | return -EINVAL; | ||
440 | |||
441 | if (index > pboardobjgrp->objslots) | ||
442 | return -EINVAL; | ||
443 | |||
444 | if (pboardobjgrp->ppobjects[index] != NULL) | ||
445 | return -EINVAL; | ||
446 | |||
447 | /* | ||
448 | * Check that this BOARDOBJ has not already been added to a | ||
449 | * BOARDOBJGRP | ||
450 | */ | ||
451 | if (pboardobj->idx != CTRL_BOARDOBJ_IDX_INVALID) | ||
452 | return -EINVAL; | ||
453 | |||
454 | pboardobjgrp->ppobjects[index] = pboardobj; | ||
455 | pboardobjgrp->objmaxidx = BOARDOBJGRP_IS_EMPTY(pboardobjgrp) ? | ||
456 | index : max(pboardobjgrp->objmaxidx, index); | ||
457 | pboardobj->idx = index; | ||
458 | |||
459 | pboardobjgrp->objmask |= BIT(index); | ||
460 | |||
461 | gk20a_dbg_info(" Done"); | ||
462 | |||
463 | return boardobjgrpmask_bitset(pboardobjgrp->mask, index); | ||
464 | } | ||
465 | |||
466 | static struct boardobj *boardobjgrp_objgetbyidx_final( | ||
467 | struct boardobjgrp *pboardobjgrp, u8 index) | ||
468 | { | ||
469 | if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) | ||
470 | return NULL; | ||
471 | return pboardobjgrp->ppobjects[index]; | ||
472 | } | ||
473 | |||
474 | static struct boardobj *boardobjgrp_objgetnext_final( | ||
475 | struct boardobjgrp *pboardobjgrp, u8 *currentindex, | ||
476 | struct boardobjgrpmask *mask) | ||
477 | { | ||
478 | struct boardobj *pboardobjnext = NULL; | ||
479 | u8 objmaxidx; | ||
480 | u8 index; | ||
481 | |||
482 | if (currentindex == NULL) | ||
483 | return NULL; | ||
484 | |||
485 | if (pboardobjgrp == NULL) | ||
486 | return NULL; | ||
487 | |||
488 | /* Search from next element unless first object was requested */ | ||
489 | index = (*currentindex != CTRL_BOARDOBJ_IDX_INVALID) ? | ||
490 | (*currentindex + 1) : 0; | ||
491 | |||
492 | /* For the cases below in which we have to return NULL */ | ||
493 | *currentindex = CTRL_BOARDOBJ_IDX_INVALID; | ||
494 | |||
495 | |||
496 | /* Validate provided mask */ | ||
497 | if (mask != NULL) { | ||
498 | if (!(boardobjgrpmask_sizeeq(pboardobjgrp->mask, mask))) | ||
499 | return NULL; | ||
500 | } | ||
501 | |||
502 | objmaxidx = pboardobjgrp->objmaxidx; | ||
503 | |||
504 | if (objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { | ||
505 | for (; index <= objmaxidx; index++) { | ||
506 | pboardobjnext = pboardobjgrp->ppobjects[index]; | ||
507 | if (pboardobjnext != NULL) { | ||
508 | /* Filter results using client provided mask.*/ | ||
509 | if (mask != NULL) { | ||
510 | if (!boardobjgrpmask_bitget(mask, | ||
511 | index)) { | ||
512 | pboardobjnext = NULL; | ||
513 | continue; | ||
514 | } | ||
515 | } | ||
516 | *currentindex = index; | ||
517 | break; | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | |||
522 | return pboardobjnext; | ||
523 | } | ||
524 | |||
525 | static u32 boardobjgrp_objremoveanddestroy_final( | ||
526 | struct boardobjgrp *pboardobjgrp, | ||
527 | u8 index) | ||
528 | { | ||
529 | u32 status = 0; | ||
530 | u32 stat; | ||
531 | |||
532 | gk20a_dbg_info(""); | ||
533 | |||
534 | if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) | ||
535 | return -EINVAL; | ||
536 | |||
537 | if (pboardobjgrp->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID) | ||
538 | return -EINVAL; | ||
539 | |||
540 | status = pboardobjgrp->ppobjects[index]->destruct( | ||
541 | pboardobjgrp->ppobjects[index]); | ||
542 | |||
543 | pboardobjgrp->ppobjects[index] = NULL; | ||
544 | |||
545 | pboardobjgrp->objmask &= ~BIT(index); | ||
546 | |||
547 | stat = boardobjgrpmask_bitclr(pboardobjgrp->mask, index); | ||
548 | if (stat) { | ||
549 | if (status == 0) | ||
550 | status = stat; | ||
551 | } | ||
552 | |||
553 | /* objmaxidx requires update only if that very object was removed */ | ||
554 | if (pboardobjgrp->objmaxidx == index) { | ||
555 | pboardobjgrp->objmaxidx = | ||
556 | boardobjgrpmask_bitidxhighest(pboardobjgrp->mask); | ||
557 | } | ||
558 | |||
559 | return status; | ||
560 | } | ||
561 | |||
562 | void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask) | ||
563 | { | ||
564 | u32 slots = objmask; | ||
565 | |||
566 | gk20a_dbg_info(""); | ||
567 | |||
568 | HIGHESTBITIDX_32(slots); | ||
569 | slots++; | ||
570 | |||
571 | hdr->super.type = CTRL_BOARDOBJGRP_TYPE_E32; | ||
572 | hdr->super.class_id = 0; | ||
573 | hdr->super.obj_slots = (u8)slots; | ||
574 | hdr->obj_mask = objmask; | ||
575 | } | ||
576 | |||
577 | static void boardobjgrp_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, | ||
578 | void *param, u32 handle, u32 status) | ||
579 | { | ||
580 | struct nv_pmu_boardobj_msg_grp *pgrpmsg; | ||
581 | struct boardobjgrp_pmucmdhandler_params *phandlerparams = | ||
582 | (struct boardobjgrp_pmucmdhandler_params *)param; | ||
583 | struct boardobjgrp *pboardobjgrp = phandlerparams->pboardobjgrp; | ||
584 | struct boardobjgrp_pmu_cmd *pgrpcmd = phandlerparams->pcmd; | ||
585 | |||
586 | gk20a_dbg_info(""); | ||
587 | |||
588 | pgrpmsg = &msg->msg.boardobj.grp; | ||
589 | |||
590 | if (pgrpmsg->class_id != pboardobjgrp->pmu.classid) { | ||
591 | gk20a_err(dev_from_gk20a(g), | ||
592 | "Unrecognized GRP type: unit %x class id=0x%02x cmd id %x", | ||
593 | msg->hdr.unit_id, pboardobjgrp->pmu.classid, | ||
594 | pgrpcmd->id); | ||
595 | return; | ||
596 | } | ||
597 | |||
598 | if (msg->msg.boardobj.msg_type != pgrpcmd->msgid) { | ||
599 | gk20a_err(dev_from_gk20a(g), | ||
600 | "unsupported msg for unit %x class %x cmd id %x msg %x", | ||
601 | msg->hdr.unit_id, pboardobjgrp->pmu.classid, | ||
602 | pgrpcmd->id, msg->msg.boardobj.msg_type); | ||
603 | return; | ||
604 | } | ||
605 | |||
606 | if (msg->msg.boardobj.grp_set.flcn_status != 0) { | ||
607 | gk20a_err(dev_from_gk20a(g), | ||
608 | "cmd abort for unit %x class %x cmd id %x status %x", | ||
609 | msg->hdr.unit_id, pboardobjgrp->pmu.classid, | ||
610 | pgrpcmd->id, | ||
611 | msg->msg.boardobj.grp_set.flcn_status); | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | phandlerparams->success = pgrpmsg->b_success ? 1 : 0; | ||
616 | |||
617 | if (!pgrpmsg->b_success) { | ||
618 | gk20a_err(dev_from_gk20a(g), | ||
619 | "failed GRPCMD: msgtype=0x%x, classid=0x%x, cmd id %x", | ||
620 | pgrpmsg->msg_type, pgrpmsg->class_id, | ||
621 | pgrpcmd->id); | ||
622 | return; | ||
623 | } | ||
624 | } | ||
625 | |||
626 | static u32 boardobjgrp_pmucmdsend(struct gk20a *g, | ||
627 | struct boardobjgrp *pboardobjgrp, | ||
628 | struct boardobjgrp_pmu_cmd *pcmd) | ||
629 | { | ||
630 | struct boardobjgrp_pmucmdhandler_params handlerparams = { 0 }; | ||
631 | struct pmu_payload payload = { {0} }; | ||
632 | struct nv_pmu_boardobj_cmd_grp *pgrpcmd; | ||
633 | struct pmu_cmd cmd; | ||
634 | u32 seqdesc; | ||
635 | u32 status = 0; | ||
636 | |||
637 | gk20a_dbg_info(""); | ||
638 | |||
639 | memset(&cmd, 0, sizeof(struct pmu_cmd)); | ||
640 | cmd.hdr.unit_id = pboardobjgrp->pmu.unitid; | ||
641 | cmd.hdr.size = sizeof(struct nv_pmu_boardobj_cmd_grp) + | ||
642 | sizeof(struct pmu_hdr); | ||
643 | |||
644 | pgrpcmd = &cmd.cmd.boardobj.grp; | ||
645 | pgrpcmd->cmd_type = pcmd->id; | ||
646 | pgrpcmd->class_id = pboardobjgrp->pmu.classid; | ||
647 | pgrpcmd->grp.hdr_size = pcmd->hdrsize; | ||
648 | pgrpcmd->grp.entry_size = pcmd->entrysize; | ||
649 | |||
650 | /* | ||
651 | * alloc mem in vidmem & copy constructed pmu boardobjgrp data from | ||
652 | * sysmem to vidmem | ||
653 | */ | ||
654 | gk20a_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc, | ||
655 | pcmd->fbsize); | ||
656 | gk20a_pmu_surface_describe(g, &pcmd->surf.vidmem_desc, | ||
657 | &pgrpcmd->grp.fb); | ||
658 | gk20a_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize); | ||
659 | |||
660 | /* | ||
661 | * PMU reads command from sysmem so assigned | ||
662 | * "payload.in.buf = pcmd->buf" | ||
663 | * but PMU access pmu boardobjgrp data from vidmem copied above | ||
664 | */ | ||
665 | payload.in.buf = pcmd->buf; | ||
666 | payload.in.size = max(pcmd->hdrsize, pcmd->entrysize); | ||
667 | payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
668 | payload.in.offset = offsetof(struct nv_pmu_boardobj_cmd_grp, grp); | ||
669 | |||
670 | /* Setup the handler params to communicate back results.*/ | ||
671 | handlerparams.pboardobjgrp = pboardobjgrp; | ||
672 | handlerparams.pcmd = pcmd; | ||
673 | handlerparams.success = 0; | ||
674 | |||
675 | status = gk20a_pmu_cmd_post(g, &cmd, NULL, &payload, | ||
676 | PMU_COMMAND_QUEUE_LPQ, | ||
677 | boardobjgrp_pmucmdhandler, | ||
678 | (void *)&handlerparams, | ||
679 | &seqdesc, ~0); | ||
680 | if (status) { | ||
681 | gk20a_err(dev_from_gk20a(g), | ||
682 | "unable to post boardobj grp cmd for unit %x cmd id %x", | ||
683 | cmd.hdr.unit_id, pcmd->id); | ||
684 | goto boardobjgrp_pmucmdsend_exit; | ||
685 | } | ||
686 | pmu_wait_message_cond(&g->pmu, | ||
687 | gk20a_get_gr_idle_timeout(g), | ||
688 | &handlerparams.success, 1); | ||
689 | if (handlerparams.success == 0) { | ||
690 | gk20a_err(dev_from_gk20a(g), "could not process cmd\n"); | ||
691 | status = -ETIMEDOUT; | ||
692 | goto boardobjgrp_pmucmdsend_exit; | ||
693 | } | ||
694 | |||
695 | boardobjgrp_pmucmdsend_exit: | ||
696 | return status; | ||
697 | } | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp.h b/drivers/gpu/nvgpu/boardobj/boardobjgrp.h new file mode 100644 index 00000000..e98a6cdb --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp.h | |||
@@ -0,0 +1,390 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _BOARDOBJGRP_H_ | ||
15 | #define _BOARDOBJGRP_H_ | ||
16 | |||
17 | struct boardobjgrp; | ||
18 | |||
19 | /* ------------------------ Includes ----------------------------------------*/ | ||
20 | #include <linux/nvgpu.h> | ||
21 | #include "gk20a/gk20a.h" | ||
22 | #include "gk20a/pmu_gk20a.h" | ||
23 | #include "ctrl/ctrlboardobj.h" | ||
24 | #include "boardobj.h" | ||
25 | #include "boardobjgrpmask.h" | ||
26 | #include "pmuif/gpmuifboardobj.h" | ||
27 | |||
28 | /* | ||
29 | * Board Object Group destructor. | ||
30 | * | ||
31 | */ | ||
32 | typedef u32 boardobjgrp_destruct(struct boardobjgrp *pboardobjgrp); | ||
33 | |||
34 | /* | ||
35 | * Inserts a previously constructed Board Object into a Board Object Group for | ||
36 | * tracking. Objects are inserted in the array based on the given index. | ||
37 | */ | ||
38 | typedef u32 boardobjgrp_objinsert(struct boardobjgrp *pboardobjgrp, | ||
39 | struct boardobj *pboardobj, u8 index); | ||
40 | |||
41 | /* | ||
42 | * Retrieves a Board Object from a Board Object Group using the group's index. | ||
43 | * | ||
44 | */ | ||
45 | typedef struct boardobj *boardobjgrp_objgetbyidx( | ||
46 | struct boardobjgrp *pBobrdobjgrp, u8 index); | ||
47 | |||
48 | /* | ||
49 | * Retrieve Board Object immediately following one pointed by @ref pcurrentindex | ||
50 | * filtered out by the provided mask. If (pMask == NULL) => no filtering. | ||
51 | */ | ||
52 | typedef struct boardobj *boardobjgrp_objgetnext( | ||
53 | struct boardobjgrp *pboardobjgrp, | ||
54 | u8 *currentindex, struct boardobjgrpmask *mask); | ||
55 | |||
56 | /* | ||
57 | * Board Object Group Remover and destructor. This is used to remove and | ||
58 | * destruct specific entry from the Board Object Group. | ||
59 | */ | ||
60 | typedef u32 boardobjgrp_objremoveanddestroy(struct boardobjgrp *pboardobjgrp, | ||
61 | u8 index); | ||
62 | |||
63 | /* | ||
64 | * BOARDOBJGRP handler for PMU_UNIT_INIT. Calls the PMU_UNIT_INIT handlers | ||
65 | * for the constructed PMU CMDs, and then sets the object via the | ||
66 | * PMU_BOARDOBJ_CMD_GRP interface (if constructed). | ||
67 | */ | ||
68 | typedef u32 boardobjgrp_pmuinithandle(struct gk20a *g, | ||
69 | struct boardobjgrp *pboardobjGrp); | ||
70 | |||
71 | /* | ||
72 | * Fills out the appropriate the PMU_BOARDOBJGRP_<xyz> driver<->PMU description | ||
73 | * header structure, more specifically a mask of BOARDOBJs. | ||
74 | */ | ||
75 | typedef u32 boardobjgrp_pmuhdrdatainit(struct gk20a *g, | ||
76 | struct boardobjgrp *pboardobjgrp, | ||
77 | struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, | ||
78 | struct boardobjgrpmask *mask); | ||
79 | |||
80 | /* | ||
81 | * Fills out the appropriate the PMU_BOARDOBJGRP_<xyz> driver->PMU description | ||
82 | * structure, describing the BOARDOBJGRP and all of its BOARDOBJs to the PMU. | ||
83 | */ | ||
84 | typedef u32 boardobjgrp_pmudatainit(struct gk20a *g, | ||
85 | struct boardobjgrp *pboardobjgrp, | ||
86 | struct nv_pmu_boardobjgrp_super *pboardobjgrppmu); | ||
87 | |||
88 | /* | ||
89 | * Sends a BOARDOBJGRP to the PMU via the PMU_BOARDOBJ_CMD_GRP interface. | ||
90 | * This interface leverages @ref boardobjgrp_pmudatainit to populate the | ||
91 | * structure. | ||
92 | */ | ||
93 | typedef u32 boardobjgrp_pmuset(struct gk20a *g, | ||
94 | struct boardobjgrp *pboardobjgrp); | ||
95 | |||
96 | /* | ||
97 | * Gets the dynamic status of the PMU BOARDOBJGRP via the | ||
98 | * PMU_BOARDOBJ_CMD_GRP GET_STATUS interface. | ||
99 | */ | ||
100 | typedef u32 boardobjgrp_pmugetstatus(struct gk20a *g, | ||
101 | struct boardobjgrp *pboardobjgrp, | ||
102 | struct boardobjgrpmask *mask); | ||
103 | |||
104 | typedef u32 boardobjgrp_pmudatainstget(struct gk20a *g, | ||
105 | struct nv_pmu_boardobjgrp *boardobjgrppmu, | ||
106 | struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx); | ||
107 | |||
108 | typedef u32 boardobjgrp_pmustatusinstget(struct gk20a *g, void *pboardobjgrppmu, | ||
109 | struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx); | ||
110 | |||
111 | /* | ||
112 | * Structure describing an PMU CMD for interacting with the representaition | ||
113 | * of this BOARDOBJGRP within the PMU. | ||
114 | */ | ||
115 | struct boardobjgrp_pmu_cmd { | ||
116 | u8 id; | ||
117 | u8 msgid; | ||
118 | u8 hdrsize; | ||
119 | u8 entrysize; | ||
120 | u16 fbsize; | ||
121 | struct nv_pmu_boardobjgrp_super *buf; | ||
122 | struct pmu_surface surf; | ||
123 | }; | ||
124 | |||
125 | /* | ||
126 | * Structure of state describing how to communicate with representation of this | ||
127 | * BOARDOBJGRP in the PMU. | ||
128 | */ | ||
129 | struct boardobjgrp_pmu { | ||
130 | u8 unitid; | ||
131 | u8 classid; | ||
132 | bool bset; | ||
133 | struct boardobjgrp_pmu_cmd set; | ||
134 | struct boardobjgrp_pmu_cmd getstatus; | ||
135 | }; | ||
136 | |||
137 | /* | ||
138 | * Function by which a class which implements BOARDOBJGRP can construct a PMU | ||
139 | * CMD. This provides the various information describing the PMU CMD including | ||
140 | * the CMD and MSG ID and the size of the various sturctures in the payload. | ||
141 | */ | ||
142 | typedef u32 boardobjgrp_pmucmd_construct(struct gk20a *g, | ||
143 | struct boardobjgrp *pboardobjgrp, | ||
144 | struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, | ||
145 | u8 hdrsize, u8 entrysize, u16 fbsize); | ||
146 | |||
147 | /* | ||
148 | * Destroys BOARDOBJGRP PMU SW state. CMD. | ||
149 | */ | ||
150 | typedef u32 boardobjgrp_pmucmd_destroy(struct boardobjgrp_pmu_cmd *cmd); | ||
151 | |||
152 | /* | ||
153 | * init handler for the BOARDOBJGRP PMU CMD. Allocates and maps the | ||
154 | * PMU CMD payload within both the PMU and driver so that it can be referenced | ||
155 | * at run-time. | ||
156 | */ | ||
157 | typedef u32 boardobjgrp_pmucmd_pmuinithandle(struct gk20a *g, | ||
158 | struct boardobjgrp *pboardobjgrp, | ||
159 | struct boardobjgrp_pmu_cmd *cmd); | ||
160 | |||
161 | /* | ||
162 | * Base Class Group for all physical or logical device on the PCB. | ||
163 | * Contains fields common to all devices on the board. Specific types of | ||
164 | * devices groups may extend this object adding any details specific to that | ||
165 | * device group or device-type. | ||
166 | */ | ||
167 | struct boardobjgrp { | ||
168 | u32 objmask; | ||
169 | bool bconstructed; | ||
170 | u8 type; | ||
171 | u8 classid; | ||
172 | struct boardobj **ppobjects; | ||
173 | struct boardobjgrpmask *mask; | ||
174 | u8 objslots; | ||
175 | u8 objmaxidx; | ||
176 | struct boardobjgrp_pmu pmu; | ||
177 | |||
178 | /* Basic interfaces */ | ||
179 | boardobjgrp_destruct *destruct; | ||
180 | boardobjgrp_objinsert *objinsert; | ||
181 | boardobjgrp_objgetbyidx *objgetbyidx; | ||
182 | boardobjgrp_objgetnext *objgetnext; | ||
183 | boardobjgrp_objremoveanddestroy *objremoveanddestroy; | ||
184 | |||
185 | /* PMU interfaces */ | ||
186 | boardobjgrp_pmuinithandle *pmuinithandle; | ||
187 | boardobjgrp_pmuhdrdatainit *pmuhdrdatainit; | ||
188 | boardobjgrp_pmudatainit *pmudatainit; | ||
189 | boardobjgrp_pmuset *pmuset; | ||
190 | boardobjgrp_pmugetstatus *pmugetstatus; | ||
191 | |||
192 | boardobjgrp_pmudatainstget *pmudatainstget; | ||
193 | boardobjgrp_pmustatusinstget *pmustatusinstget; | ||
194 | }; | ||
195 | |||
196 | /* | ||
197 | * Macro test whether a specified index into the BOARDOBJGRP is valid. | ||
198 | * | ||
199 | */ | ||
200 | #define boardobjgrp_idxisvalid(_pboardobjgrp, _idx) \ | ||
201 | (((_idx) < (_pboardobjgrp)->objslots) && \ | ||
202 | ((_pboardobjgrp)->ppobjects[(_idx)] != NULL)) | ||
203 | |||
204 | /* | ||
205 | * Macro test whether a specified BOARDOBJGRP is empty. | ||
206 | */ | ||
207 | #define BOARDOBJGRP_IS_EMPTY(_pboardobjgrp) \ | ||
208 | ((!((_pboardobjgrp)->bconstructed)) || \ | ||
209 | ((_pboardobjgrp)->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID)) | ||
210 | |||
211 | #define boardobjgrp_objinsert(_pboardobjgrp, _pboardobj, _idx) \ | ||
212 | ((_pboardobjgrp)->objinsert((_pboardobjgrp), (_pboardobj), (_idx))) | ||
213 | |||
214 | /* | ||
215 | * Helper macro to determine the "next" open/empty index after all allocated | ||
216 | * objects. This is intended to be used to find the index at which objects can | ||
217 | * be inserted contiguously (i.e. w/o fear of colliding with existing objects). | ||
218 | */ | ||
219 | #define BOARDOBJGRP_NEXT_EMPTY_IDX(_pboardobjgrp) \ | ||
220 | ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0 : \ | ||
221 | ((((_pboardobjgrp)->objmaxidx + 1) >= (_pboardobjgrp)->objslots) ? \ | ||
222 | (u8)CTRL_BOARDOBJ_IDX_INVALID : (u8)((_pboardobjgrp)->objmaxidx + 1))) | ||
223 | |||
224 | /* | ||
225 | * Helper macro to determine the number of @ref BOARDOBJ pointers | ||
226 | * that are required to be allocated in PMU @ref ppObjects. | ||
227 | */ | ||
228 | #define BOARDOBJGRP_PMU_SLOTS_GET(_pboardobjgrp) \ | ||
229 | ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0 : \ | ||
230 | (u8)((_pboardobjgrp)->objmaxidx + 1)) | ||
231 | |||
232 | #define BOARDOBJGRP_OBJ_GET_BY_IDX(_pboardobjgrp, _idx) \ | ||
233 | ((_pboardobjgrp)->objgetbyidx((_pboardobjgrp), (_idx))) | ||
234 | |||
235 | /* | ||
236 | * macro to look-up next object while tolerating error if | ||
237 | * Board Object Group is not constructed. | ||
238 | */ | ||
239 | |||
240 | #define boardobjgrpobjgetnextsafe(_pgrp, _pindex, _pmask) \ | ||
241 | ((_pgrp)->bconstructed ? \ | ||
242 | (_pgrp)->objgetnext((_pgrp), (_pindex), (_pmask)) : NULL) | ||
243 | |||
244 | /* | ||
245 | * Used to traverse all Board Objects stored within @ref _pgrp in the increasing | ||
246 | * index order. | ||
247 | * If @ref _pmask is provided only objects specified by the mask are traversed. | ||
248 | */ | ||
249 | #define BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, _pmask) \ | ||
250 | for (_index = CTRL_BOARDOBJ_IDX_INVALID, \ | ||
251 | _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask));\ | ||
252 | _pobj != NULL; \ | ||
253 | _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask))) | ||
254 | #define BOARDOBJGRP_FOR_EACH(_pgrp, _ptype, _pobj, _index) \ | ||
255 | BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, NULL) | ||
256 | |||
257 | /*! | ||
258 | * Invalid UNIT_ID. Used to indicate that the implementing class has not set | ||
259 | * @ref BOARDOBJGRP::unitId and, thus, certain BOARDOBJGRP PMU interfaces are | ||
260 | * not supported. | ||
261 | */ | ||
262 | #define BOARDOBJGRP_UNIT_ID_INVALID 255 | ||
263 | |||
264 | /*! | ||
265 | * Invalid UNIT_ID. Used to indicate that the implementing class has not set | ||
266 | * @ref BOARDOBJGRP::grpType and, thus, certain BOARDOBJGRP PMU interfaces are | ||
267 | * not supported. | ||
268 | */ | ||
269 | #define BOARDOBJGRP_GRP_CLASS_ID_INVALID 255 | ||
270 | |||
271 | /*! | ||
272 | * Invalid UNIT_ID. Used to indicate that the implementing class has not set | ||
273 | * @ref BOARDOBJGRP::grpSetCmdId and, thus, certain BOARDOBJGRP PMU interfaces | ||
274 | * are not supported. | ||
275 | */ | ||
276 | #define BOARDOBJGRP_GRP_CMD_ID_INVALID 255 | ||
277 | |||
278 | /*! | ||
279 | * Helper macro to construct a BOARDOBJGRP's PMU SW state. | ||
280 | * | ||
281 | * @param[out] pboardobjgrp BOARDOBJGRP pointer | ||
282 | * @param[in] _eng | ||
283 | * Implementing engine/unit which manages the BOARDOBJGRP. | ||
284 | * @param[in] _class | ||
285 | * Class ID of BOARDOBJGRP. | ||
286 | */ | ||
287 | #define BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, _ENG, _CLASS) \ | ||
288 | do { \ | ||
289 | (pboardobjgrp)->pmu.unitid = PMU_UNIT_##_ENG; \ | ||
290 | (pboardobjgrp)->pmu.classid = \ | ||
291 | NV_PMU_##_ENG##_BOARDOBJGRP_CLASS_ID_##_CLASS; \ | ||
292 | } while (0) | ||
293 | |||
294 | #define BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(pgpu, pboardobjgrp, eng, ENG, \ | ||
295 | class, CLASS) \ | ||
296 | boardobjgrp_pmucmd_construct_impl( \ | ||
297 | pgpu, /* pgpu */ \ | ||
298 | pboardobjgrp, /* pboardobjgrp */ \ | ||
299 | &((pboardobjgrp)->pmu.set), /* pcmd */ \ | ||
300 | NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_SET, /* id */ \ | ||
301 | NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_SET, /* msgid */ \ | ||
302 | (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_set_header_aligned), \ | ||
303 | (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_set_union_aligned), \ | ||
304 | (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_set)) | ||
305 | |||
306 | #define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(pgpu, pboardobjgrp, \ | ||
307 | eng, ENG, class, CLASS) \ | ||
308 | boardobjgrp_pmucmd_construct_impl( \ | ||
309 | pgpu, /* pGpu */ \ | ||
310 | pboardobjgrp, /* pBoardObjGrp */ \ | ||
311 | &((pboardobjgrp)->pmu.getstatus), /* pCmd */ \ | ||
312 | NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_GET_STATUS, /* id */ \ | ||
313 | NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_SET, /* msgid */ \ | ||
314 | (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_get_status_header_aligned), \ | ||
315 | (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_get_status_union_aligned), \ | ||
316 | (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_get_status)) | ||
317 | |||
318 | /* ------------------------ Function Prototypes ----------------------------- */ | ||
319 | /* Constructor and destructor */ | ||
320 | u32 boardobjgrp_construct_super(struct boardobjgrp *pboardobjgrp); | ||
321 | boardobjgrp_destruct boardobjgrp_destruct_impl; | ||
322 | boardobjgrp_destruct boardobjgrp_destruct_super; | ||
323 | |||
324 | /* PMU_CMD interfaces */ | ||
325 | boardobjgrp_pmucmd_construct boardobjgrp_pmucmd_construct_impl; | ||
326 | boardobjgrp_pmucmd_destroy boardobjgrp_pmucmd_destroy_impl; | ||
327 | boardobjgrp_pmucmd_pmuinithandle boardobjgrp_pmucmd_pmuinithandle_impl; | ||
328 | |||
329 | /* BOARDOBJGRP interfaces */ | ||
330 | boardobjgrp_pmuinithandle boardobjgrp_pmuinithandle_impl; | ||
331 | boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_super; | ||
332 | boardobjgrp_pmudatainit boardobjgrp_pmudatainit_super; | ||
333 | |||
334 | boardobjgrp_pmudatainit boardobjgrp_pmudatainit_legacy; | ||
335 | boardobjgrp_pmuset boardobjgrp_pmuset_impl; | ||
336 | boardobjgrp_pmugetstatus boardobjgrp_pmugetstatus_impl; | ||
337 | |||
338 | void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask); | ||
339 | |||
340 | /* ------------------------ Include Derived Types --------------------------- */ | ||
341 | #include "boardobj/boardobjgrp_e32.h" | ||
342 | #include "boardobj/boardobjgrp_e255.h" | ||
343 | |||
344 | #define HIGHESTBITIDX_32(n32) \ | ||
345 | { \ | ||
346 | u32 count = 0; \ | ||
347 | while (n32 >>= 1) \ | ||
348 | count++; \ | ||
349 | n32 = count; \ | ||
350 | } | ||
351 | |||
352 | #define LOWESTBIT(x) ((x) & (((x)-1) ^ (x))) | ||
353 | |||
354 | #define HIGHESTBIT(n32) \ | ||
355 | { \ | ||
356 | HIGHESTBITIDX_32(n32); \ | ||
357 | n32 = NVBIT(n32); \ | ||
358 | } | ||
359 | |||
360 | #define ONEBITSET(x) ((x) && (((x) & ((x)-1)) == 0)) | ||
361 | |||
362 | #define LOWESTBITIDX_32(n32) \ | ||
363 | { \ | ||
364 | n32 = LOWESTBIT(n32); \ | ||
365 | IDX_32(n32); \ | ||
366 | } | ||
367 | |||
368 | #define NUMSETBITS_32(n32) \ | ||
369 | { \ | ||
370 | n32 = n32 - ((n32 >> 1) & 0x55555555); \ | ||
371 | n32 = (n32 & 0x33333333) + ((n32 >> 2) & 0x33333333); \ | ||
372 | n32 = (((n32 + (n32 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; \ | ||
373 | } | ||
374 | |||
375 | #define IDX_32(n32) \ | ||
376 | { \ | ||
377 | u32 idx = 0; \ | ||
378 | if ((n32) & 0xFFFF0000) \ | ||
379 | idx += 16; \ | ||
380 | if ((n32) & 0xFF00FF00) \ | ||
381 | idx += 8; \ | ||
382 | if ((n32) & 0xF0F0F0F0) \ | ||
383 | idx += 4; \ | ||
384 | if ((n32) & 0xCCCCCCCC) \ | ||
385 | idx += 2; \ | ||
386 | if ((n32) & 0xAAAAAAAA) \ | ||
387 | idx += 1; \ | ||
388 | (n32) = idx; \ | ||
389 | } | ||
390 | #endif | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c new file mode 100644 index 00000000..a56dca9b --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include "gk20a/gk20a.h" | ||
15 | #include "boardobj.h" | ||
16 | #include "boardobjgrp_e255.h" | ||
17 | #include "ctrl/ctrlboardobj.h" | ||
18 | #include "pmuif/gpmuifboardobj.h" | ||
19 | #include "boardobjgrp.h" | ||
20 | #include "boardobjgrpmask.h" | ||
21 | |||
22 | u32 boardobjgrpconstruct_e255(struct boardobjgrp_e255 *pboardobjgrp_e255) | ||
23 | { | ||
24 | u32 status = 0; | ||
25 | u8 objslots; | ||
26 | |||
27 | gk20a_dbg_info(""); | ||
28 | |||
29 | objslots = 255; | ||
30 | status = boardobjgrpmask_e255_init(&pboardobjgrp_e255->mask, NULL); | ||
31 | if (status) | ||
32 | goto boardobjgrpconstruct_e255_exit; | ||
33 | |||
34 | pboardobjgrp_e255->super.type = CTRL_BOARDOBJGRP_TYPE_E255; | ||
35 | pboardobjgrp_e255->super.ppobjects = pboardobjgrp_e255->objects; | ||
36 | pboardobjgrp_e255->super.objslots = objslots; | ||
37 | pboardobjgrp_e255->super.mask = &(pboardobjgrp_e255->mask.super); | ||
38 | |||
39 | status = boardobjgrp_construct_super(&pboardobjgrp_e255->super); | ||
40 | if (status) | ||
41 | goto boardobjgrpconstruct_e255_exit; | ||
42 | |||
43 | pboardobjgrp_e255->super.destruct = boardobjgrpdestruct_e255; | ||
44 | |||
45 | pboardobjgrp_e255->super.pmuhdrdatainit = | ||
46 | boardobjgrp_pmuhdrdatainit_e255; | ||
47 | |||
48 | boardobjgrpconstruct_e255_exit: | ||
49 | return status; | ||
50 | } | ||
51 | |||
52 | u32 boardobjgrpdestruct_e255(struct boardobjgrp *pboardobjgrp) | ||
53 | { | ||
54 | u32 status = 0; | ||
55 | |||
56 | gk20a_dbg_info(""); | ||
57 | |||
58 | pboardobjgrp->mask = NULL; | ||
59 | pboardobjgrp->objslots = 0; | ||
60 | pboardobjgrp->ppobjects = NULL; | ||
61 | |||
62 | return status; | ||
63 | } | ||
64 | |||
65 | u32 boardobjgrp_pmuhdrdatainit_e255(struct gk20a *g, | ||
66 | struct boardobjgrp *pboardobjgrp, | ||
67 | struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, | ||
68 | struct boardobjgrpmask *mask) | ||
69 | { | ||
70 | struct nv_pmu_boardobjgrp_e255 *pgrpe255 = | ||
71 | (struct nv_pmu_boardobjgrp_e255 *)pboardobjgrppmu; | ||
72 | u32 status; | ||
73 | |||
74 | gk20a_dbg_info(""); | ||
75 | |||
76 | if (pboardobjgrp == NULL) | ||
77 | return -EINVAL; | ||
78 | |||
79 | if (pboardobjgrppmu == NULL) | ||
80 | return -EINVAL; | ||
81 | |||
82 | status = boardobjgrpmask_export(mask, | ||
83 | mask->bitcount, | ||
84 | &pgrpe255->obj_mask.super); | ||
85 | if (status) { | ||
86 | gk20a_err(dev_from_gk20a(g), "e255 init:failed export grpmask"); | ||
87 | return status; | ||
88 | } | ||
89 | |||
90 | return boardobjgrp_pmuhdrdatainit_super(g, | ||
91 | pboardobjgrp, pboardobjgrppmu, mask); | ||
92 | } | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h new file mode 100644 index 00000000..929517ad --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _BOARDOBJGRP_E255_H_ | ||
15 | #define _BOARDOBJGRP_E255_H_ | ||
16 | |||
17 | #include <linux/nvgpu.h> | ||
18 | #include "gk20a/gk20a.h" | ||
19 | #include "gk20a/pmu_gk20a.h" | ||
20 | #include "ctrl/ctrlboardobj.h" | ||
21 | #include "boardobj.h" | ||
22 | #include "boardobjgrpmask.h" | ||
23 | #include "boardobj/boardobjgrp.h" | ||
24 | #include "boardobjgrp_e255.h" | ||
25 | |||
26 | /* | ||
27 | * boardobjgrp_e255 is @ref BOARDOBJGRP child class allowing storage of up | ||
28 | * to 255 @ref BOARDOBJ object pointers with single static 255-bit mask denoting | ||
29 | * valid object pointers. | ||
30 | */ | ||
31 | struct boardobjgrp_e255 { | ||
32 | struct boardobjgrp super; | ||
33 | struct boardobj *objects[CTRL_BOARDOBJGRP_E255_MAX_OBJECTS]; | ||
34 | struct boardobjgrpmask_e255 mask; | ||
35 | }; | ||
36 | |||
37 | #define boardobjgrp_pmudatainit_e255(g, pboardpbjgrp, pboardobjgrppmu) \ | ||
38 | boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu) | ||
39 | |||
40 | /* Constructor and destructor */ | ||
41 | u32 boardobjgrpconstruct_e255(struct boardobjgrp_e255 *pboardobjgrp); | ||
42 | boardobjgrp_destruct boardobjgrpdestruct_e255; | ||
43 | boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e255; | ||
44 | |||
45 | #endif | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c new file mode 100644 index 00000000..95610aba --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include "gk20a/gk20a.h" | ||
15 | #include "boardobj.h" | ||
16 | #include "boardobjgrp.h" | ||
17 | #include "boardobjgrp_e32.h" | ||
18 | #include "ctrl/ctrlboardobj.h" | ||
19 | #include "pmuif/gpmuifboardobj.h" | ||
20 | #include "boardobjgrpmask.h" | ||
21 | |||
22 | |||
23 | u32 boardobjgrpconstruct_e32(struct boardobjgrp_e32 *pboardobjgrp_e32) | ||
24 | { | ||
25 | u32 status; | ||
26 | u8 objslots; | ||
27 | |||
28 | gk20a_dbg_info(""); | ||
29 | objslots = 32; | ||
30 | |||
31 | status = boardobjgrpmask_e32_init(&pboardobjgrp_e32->mask, NULL); | ||
32 | if (status) | ||
33 | goto boardobjgrpconstruct_e32_exit; | ||
34 | |||
35 | pboardobjgrp_e32->super.type = CTRL_BOARDOBJGRP_TYPE_E32; | ||
36 | pboardobjgrp_e32->super.ppobjects = pboardobjgrp_e32->objects; | ||
37 | pboardobjgrp_e32->super.objslots = objslots; | ||
38 | pboardobjgrp_e32->super.mask = &(pboardobjgrp_e32->mask.super); | ||
39 | |||
40 | status = boardobjgrp_construct_super(&pboardobjgrp_e32->super); | ||
41 | if (status) | ||
42 | goto boardobjgrpconstruct_e32_exit; | ||
43 | |||
44 | pboardobjgrp_e32->super.destruct = boardobjgrpdestruct_e32; | ||
45 | |||
46 | pboardobjgrp_e32->super.pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_e32; | ||
47 | |||
48 | boardobjgrpconstruct_e32_exit: | ||
49 | return status; | ||
50 | } | ||
51 | |||
52 | u32 boardobjgrpdestruct_e32(struct boardobjgrp *pboardobjgrp) | ||
53 | { | ||
54 | u32 status = 0; | ||
55 | |||
56 | gk20a_dbg_info(""); | ||
57 | |||
58 | pboardobjgrp->mask = NULL; | ||
59 | pboardobjgrp->objslots = 0; | ||
60 | pboardobjgrp->ppobjects = NULL; | ||
61 | |||
62 | return status; | ||
63 | } | ||
64 | |||
65 | u32 boardobjgrp_pmuhdrdatainit_e32(struct gk20a *g, | ||
66 | struct boardobjgrp *pboardobjgrp, | ||
67 | struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, | ||
68 | struct boardobjgrpmask *mask) | ||
69 | { | ||
70 | struct nv_pmu_boardobjgrp_e32 *pgrpe32 = | ||
71 | (struct nv_pmu_boardobjgrp_e32 *)pboardobjgrppmu; | ||
72 | u32 status; | ||
73 | |||
74 | gk20a_dbg_info(""); | ||
75 | |||
76 | if (pboardobjgrp == NULL) | ||
77 | return -EINVAL; | ||
78 | |||
79 | if (pboardobjgrppmu == NULL) | ||
80 | return -EINVAL; | ||
81 | status = boardobjgrpmask_export(mask, | ||
82 | mask->bitcount, | ||
83 | &pgrpe32->obj_mask.super); | ||
84 | if (status) { | ||
85 | gk20a_err(dev_from_gk20a(g), "e32 init:failed export grpmask"); | ||
86 | return status; | ||
87 | } | ||
88 | |||
89 | return boardobjgrp_pmuhdrdatainit_super(g, | ||
90 | pboardobjgrp, pboardobjgrppmu, mask); | ||
91 | } | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h new file mode 100644 index 00000000..249d1dd6 --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _BOARDOBJGRP_E32_H_ | ||
15 | #define _BOARDOBJGRP_E32_H_ | ||
16 | |||
17 | #include <linux/nvgpu.h> | ||
18 | #include "gk20a/gk20a.h" | ||
19 | #include "gk20a/pmu_gk20a.h" | ||
20 | #include "ctrl/ctrlboardobj.h" | ||
21 | #include "boardobj.h" | ||
22 | #include "boardobjgrp.h" | ||
23 | #include "boardobjgrpmask.h" | ||
24 | #include "boardobj/boardobjgrp.h" | ||
25 | |||
26 | /* | ||
27 | * boardobjgrp_e32 is @ref BOARDOBJGRP child class allowing storage of up to 32 | ||
28 | * @ref BOARDOBJ object pointers with single static 32-bit mask denoting valid | ||
29 | * object pointers. | ||
30 | */ | ||
31 | struct boardobjgrp_e32 { | ||
32 | /* | ||
33 | * BOARDOBJGRP super-class. Must be first element of the structure. | ||
34 | */ | ||
35 | struct boardobjgrp super; | ||
36 | /* | ||
37 | * Statically allocated array of PBOARDOBJ-s | ||
38 | */ | ||
39 | struct boardobj *objects[CTRL_BOARDOBJGRP_E32_MAX_OBJECTS]; | ||
40 | |||
41 | /* | ||
42 | * Statically allocated mask strcuture referenced by super::pMask. | ||
43 | */ | ||
44 | struct boardobjgrpmask_e32 mask; | ||
45 | }; | ||
46 | |||
47 | /* | ||
48 | * Wrapper to the _SUPER implementation. Provided for the child classes which | ||
49 | * implement this interface. | ||
50 | */ | ||
51 | #define boardobjgrp_pmudatainit_e32(g, pboardpbjgrp, pboardobjgrppmu) \ | ||
52 | boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu) | ||
53 | |||
54 | /* Constructor and destructor */ | ||
55 | u32 boardobjgrpconstruct_e32(struct boardobjgrp_e32 *pboardobjgrp); | ||
56 | boardobjgrp_destruct boardobjgrpdestruct_e32; | ||
57 | boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e32; | ||
58 | |||
59 | #endif | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c new file mode 100644 index 00000000..47914038 --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c | |||
@@ -0,0 +1,357 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | #include "gk20a/gk20a.h" | ||
14 | #include "boardobjgrp.h" | ||
15 | #include "ctrl/ctrlboardobj.h" | ||
16 | |||
17 | /* | ||
18 | * Assures that unused bits (size .. (maskDataCount * 32 - 1)) are always zero. | ||
19 | */ | ||
20 | #define BOARDOBJGRPMASK_NORMALIZE(_pmask) \ | ||
21 | ((_pmask)->data[(_pmask)->maskdatacount-1] &= (_pmask)->lastmaskfilter) | ||
22 | |||
23 | u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize, | ||
24 | struct ctrl_boardobjgrp_mask *extmask) | ||
25 | { | ||
26 | if (mask == NULL) | ||
27 | return -EINVAL; | ||
28 | if ((bitsize != CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) && | ||
29 | (bitsize != CTRL_BOARDOBJGRP_E255_MAX_OBJECTS)) | ||
30 | return -EINVAL; | ||
31 | |||
32 | mask->bitcount = bitsize; | ||
33 | mask->maskdatacount = CTRL_BOARDOBJGRP_MASK_DATA_SIZE(bitsize); | ||
34 | mask->lastmaskfilter = bitsize % | ||
35 | CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; | ||
36 | |||
37 | mask->lastmaskfilter = (mask->lastmaskfilter == 0) ? | ||
38 | 0xFFFFFFFF : (u32)(BIT(mask->lastmaskfilter) - 1); | ||
39 | |||
40 | return (extmask == NULL) ? | ||
41 | boardobjgrpmask_clr(mask) : | ||
42 | boardobjgrpmask_import(mask, bitsize, extmask); | ||
43 | } | ||
44 | |||
45 | u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize, | ||
46 | struct ctrl_boardobjgrp_mask *extmask) | ||
47 | { | ||
48 | u8 index; | ||
49 | |||
50 | if (mask == NULL) | ||
51 | return -EINVAL; | ||
52 | if (extmask == NULL) | ||
53 | return -EINVAL; | ||
54 | if (mask->bitcount != bitsize) | ||
55 | return -EINVAL; | ||
56 | |||
57 | for (index = 0; index < mask->maskdatacount; index++) | ||
58 | mask->data[index] = extmask->data[index]; | ||
59 | |||
60 | BOARDOBJGRPMASK_NORMALIZE(mask); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize, | ||
66 | struct ctrl_boardobjgrp_mask *extmask) | ||
67 | { | ||
68 | u8 index; | ||
69 | |||
70 | if (mask == NULL) | ||
71 | return -EINVAL; | ||
72 | if (extmask == NULL) | ||
73 | return -EINVAL; | ||
74 | if (mask->bitcount != bitsize) | ||
75 | return -EINVAL; | ||
76 | |||
77 | for (index = 0; index < mask->maskdatacount; index++) | ||
78 | extmask->data[index] = mask->data[index]; | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask) | ||
84 | { | ||
85 | u8 index; | ||
86 | |||
87 | if (mask == NULL) | ||
88 | return -EINVAL; | ||
89 | for (index = 0; index < mask->maskdatacount; index++) | ||
90 | mask->data[index] = 0; | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | u32 boardobjgrpmask_set(struct boardobjgrpmask *mask) | ||
96 | { | ||
97 | u8 index; | ||
98 | |||
99 | if (mask == NULL) | ||
100 | return -EINVAL; | ||
101 | for (index = 0; index < mask->maskdatacount; index++) | ||
102 | mask->data[index] = 0xFFFFFFFF; | ||
103 | BOARDOBJGRPMASK_NORMALIZE(mask); | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask) | ||
108 | { | ||
109 | u8 index; | ||
110 | |||
111 | if (mask == NULL) | ||
112 | return -EINVAL; | ||
113 | for (index = 0; index < mask->maskdatacount; index++) | ||
114 | mask->data[index] = ~mask->data[index]; | ||
115 | BOARDOBJGRPMASK_NORMALIZE(mask); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask) | ||
120 | { | ||
121 | u8 index; | ||
122 | |||
123 | if (mask == NULL) | ||
124 | return true; | ||
125 | for (index = 0; index < mask->maskdatacount; index++) { | ||
126 | if (mask->data[index] != 0) | ||
127 | return false; | ||
128 | } | ||
129 | return true; | ||
130 | } | ||
131 | |||
132 | u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask) | ||
133 | { | ||
134 | u8 index; | ||
135 | u8 result = 0; | ||
136 | |||
137 | if (mask == NULL) | ||
138 | return result; | ||
139 | |||
140 | for (index = 0; index < mask->maskdatacount; index++) { | ||
141 | u32 m = mask->data[index]; | ||
142 | |||
143 | NUMSETBITS_32(m); | ||
144 | result += (u8)m; | ||
145 | } | ||
146 | |||
147 | return result; | ||
148 | } | ||
149 | |||
150 | u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask) | ||
151 | { | ||
152 | u8 index; | ||
153 | u8 result = CTRL_BOARDOBJ_IDX_INVALID; | ||
154 | |||
155 | if (mask == NULL) | ||
156 | return result; | ||
157 | |||
158 | for (index = 0; index < mask->maskdatacount; index++) { | ||
159 | u32 m = mask->data[index]; | ||
160 | |||
161 | if (m != 0) { | ||
162 | LOWESTBITIDX_32(m); | ||
163 | result = (u8)m + index * | ||
164 | CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; | ||
165 | break; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | return result; | ||
170 | } | ||
171 | |||
172 | u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask) | ||
173 | { | ||
174 | u8 index; | ||
175 | u8 result = CTRL_BOARDOBJ_IDX_INVALID; | ||
176 | |||
177 | if (mask == NULL) | ||
178 | return result; | ||
179 | |||
180 | for (index = 0; index < mask->maskdatacount; index++) { | ||
181 | u32 m = mask->data[index]; | ||
182 | |||
183 | if (m != 0) { | ||
184 | HIGHESTBITIDX_32(m); | ||
185 | result = (u8)m + index * | ||
186 | CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | return result; | ||
192 | } | ||
193 | |||
194 | u32 boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx) | ||
195 | { | ||
196 | u8 index; | ||
197 | u8 offset; | ||
198 | |||
199 | if (mask == NULL) | ||
200 | return -EINVAL; | ||
201 | if (bitidx >= mask->bitcount) | ||
202 | return -EINVAL; | ||
203 | |||
204 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
205 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
206 | |||
207 | mask->data[index] &= ~BIT(offset); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | u32 boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx) | ||
213 | { | ||
214 | u8 index; | ||
215 | u8 offset; | ||
216 | |||
217 | if (mask == NULL) | ||
218 | return -EINVAL; | ||
219 | if (bitidx >= mask->bitcount) | ||
220 | return -EINVAL; | ||
221 | |||
222 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
223 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
224 | |||
225 | mask->data[index] |= BIT(offset); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx) | ||
231 | { | ||
232 | u8 index; | ||
233 | u8 offset; | ||
234 | |||
235 | if (mask == NULL) | ||
236 | return -EINVAL; | ||
237 | if (bitidx >= mask->bitcount) | ||
238 | return -EINVAL; | ||
239 | |||
240 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
241 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
242 | |||
243 | mask->data[index] ^= ~BIT(offset); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx) | ||
249 | { | ||
250 | u8 index; | ||
251 | u8 offset; | ||
252 | |||
253 | if (mask == NULL) | ||
254 | return false; | ||
255 | if (bitidx >= mask->bitcount) | ||
256 | return false; | ||
257 | |||
258 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
259 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
260 | |||
261 | return (mask->data[index] & BIT(offset)) != 0; | ||
262 | } | ||
263 | |||
264 | u32 boardobjgrpmask_and(struct boardobjgrpmask *dst, | ||
265 | struct boardobjgrpmask *op1, | ||
266 | struct boardobjgrpmask *op2) | ||
267 | { | ||
268 | u8 index; | ||
269 | |||
270 | if (!boardobjgrpmask_sizeeq(dst, op1)) | ||
271 | return -EINVAL; | ||
272 | if (!boardobjgrpmask_sizeeq(dst, op2)) | ||
273 | return -EINVAL; | ||
274 | |||
275 | for (index = 0; index < dst->maskdatacount; index++) | ||
276 | dst->data[index] = op1->data[index] & op2->data[index]; | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, | ||
282 | struct boardobjgrpmask *op1, | ||
283 | struct boardobjgrpmask *op2) | ||
284 | { | ||
285 | u8 index; | ||
286 | |||
287 | if (!boardobjgrpmask_sizeeq(dst, op1)) | ||
288 | return -EINVAL; | ||
289 | if (!boardobjgrpmask_sizeeq(dst, op2)) | ||
290 | return -EINVAL; | ||
291 | |||
292 | for (index = 0; index < dst->maskdatacount; index++) | ||
293 | dst->data[index] = op1->data[index] | op2->data[index]; | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst, | ||
299 | struct boardobjgrpmask *op1, | ||
300 | struct boardobjgrpmask *op2) | ||
301 | { | ||
302 | u8 index; | ||
303 | |||
304 | if (!boardobjgrpmask_sizeeq(dst, op1)) | ||
305 | return -EINVAL; | ||
306 | if (!boardobjgrpmask_sizeeq(dst, op2)) | ||
307 | return -EINVAL; | ||
308 | |||
309 | for (index = 0; index < dst->maskdatacount; index++) | ||
310 | dst->data[index] = op1->data[index] ^ op2->data[index]; | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst, | ||
316 | struct boardobjgrpmask *src) | ||
317 | { | ||
318 | u8 index; | ||
319 | |||
320 | if (!boardobjgrpmask_sizeeq(dst, src)) | ||
321 | return -EINVAL; | ||
322 | |||
323 | for (index = 0; index < dst->maskdatacount; index++) | ||
324 | dst->data[index] = src->data[index]; | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1, | ||
330 | struct boardobjgrpmask *op2) | ||
331 | { | ||
332 | if (op1 == NULL) | ||
333 | return false; | ||
334 | if (op2 == NULL) | ||
335 | return false; | ||
336 | |||
337 | return op1->bitcount == op2->bitcount; | ||
338 | } | ||
339 | |||
340 | bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1, | ||
341 | struct boardobjgrpmask *op2) | ||
342 | { | ||
343 | u8 index; | ||
344 | |||
345 | if (!boardobjgrpmask_sizeeq(op2, op1)) | ||
346 | return false; | ||
347 | |||
348 | for (index = 0; index < op1->maskdatacount; index++) { | ||
349 | u32 op_1 = op1->data[index]; | ||
350 | u32 op_2 = op2->data[index]; | ||
351 | |||
352 | if ((op_1 & op_2) != op_1) | ||
353 | return false; | ||
354 | } | ||
355 | |||
356 | return true; | ||
357 | } | ||
diff --git a/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h new file mode 100644 index 00000000..c601d9d2 --- /dev/null +++ b/drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _BOARDOBJGRPMASK_H_ | ||
15 | #define _BOARDOBJGRPMASK_H_ | ||
16 | |||
17 | #include "ctrl/ctrlboardobj.h" | ||
18 | |||
19 | |||
20 | /* | ||
21 | * Board Object Group Mask super-structure. | ||
22 | * Used to unify access to all BOARDOBJGRPMASK_E** child classes | ||
23 | */ | ||
24 | struct boardobjgrpmask { | ||
25 | /* Number of bits supported by the mask */ | ||
26 | u8 bitcount; | ||
27 | /* Number of 32-bit words required to store all @ref bitCount bits */ | ||
28 | u8 maskdatacount; | ||
29 | /* | ||
30 | * Bit-mask of used-bits within last 32-bit word. Used to | ||
31 | * normalize data | ||
32 | */ | ||
33 | u32 lastmaskfilter; | ||
34 | /* | ||
35 | * Start of the array of 32-bit words representing the bit-mask | ||
36 | * Must be the last element of the structure. | ||
37 | */ | ||
38 | u32 data[CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE]; | ||
39 | }; | ||
40 | |||
41 | struct boardobjgrpmask_e32 { | ||
42 | /* | ||
43 | * BOARDOBJGRPMASK super-class. Must be the first element of the | ||
44 | * structure. | ||
45 | */ | ||
46 | struct boardobjgrpmask super; | ||
47 | /*u32 data_e32[1]; */ | ||
48 | }; | ||
49 | |||
50 | struct boardobjgrpmask_e255 { | ||
51 | /* | ||
52 | * BOARDOBJGRPMASK super-class. Must be the first element of the | ||
53 | * structure. | ||
54 | */ | ||
55 | struct boardobjgrpmask super; | ||
56 | u32 data_e255[254]; | ||
57 | }; | ||
58 | |||
59 | /* Init and I/O operations.*/ | ||
60 | u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize, | ||
61 | struct ctrl_boardobjgrp_mask *extmask); | ||
62 | u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize, | ||
63 | struct ctrl_boardobjgrp_mask *extmask); | ||
64 | u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize, | ||
65 | struct ctrl_boardobjgrp_mask *extmask); | ||
66 | |||
67 | /* Operations on all bits of a single mask.*/ | ||
68 | u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask); | ||
69 | u32 boardobjgrpmask_set(struct boardobjgrpmask *mask); | ||
70 | u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask); | ||
71 | bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask); | ||
72 | u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask); | ||
73 | u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask); | ||
74 | u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask); | ||
75 | |||
76 | /* Operations on a single bit of a single mask */ | ||
77 | u32 boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx); | ||
78 | u32 boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx); | ||
79 | u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx); | ||
80 | bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx); | ||
81 | |||
82 | /* Operations on a multiple masks */ | ||
83 | u32 boardobjgrpmask_and(struct boardobjgrpmask *dst, | ||
84 | struct boardobjgrpmask *op1, | ||
85 | struct boardobjgrpmask *op2); | ||
86 | u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, struct boardobjgrpmask *op1, | ||
87 | struct boardobjgrpmask *op2); | ||
88 | u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst, | ||
89 | struct boardobjgrpmask *op1, | ||
90 | struct boardobjgrpmask *op2); | ||
91 | |||
92 | /* Special interfaces */ | ||
93 | u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst, | ||
94 | struct boardobjgrpmask *src); | ||
95 | bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1, | ||
96 | struct boardobjgrpmask *op2); | ||
97 | bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1, | ||
98 | struct boardobjgrpmask *op2); | ||
99 | |||
100 | /* init boardobjgrpmask_e32 structure */ | ||
101 | #define boardobjgrpmask_e32_init(pmaske32, pextmask) \ | ||
102 | boardobjgrpmask_init(&(pmaske32)->super, \ | ||
103 | CTRL_BOARDOBJGRP_E32_MAX_OBJECTS, (pextmask)) | ||
104 | |||
105 | /* init boardobjgrpmask_e255 structure */ | ||
106 | #define boardobjgrpmask_e255_init(pmaske255, pextmask) \ | ||
107 | boardobjgrpmask_init(&(pmaske255)->super, \ | ||
108 | CTRL_BOARDOBJGRP_E255_MAX_OBJECTS, (pextmask)) | ||
109 | |||
110 | #endif | ||
diff --git a/drivers/gpu/nvgpu/ctrl/ctrlboardobj.h b/drivers/gpu/nvgpu/ctrl/ctrlboardobj.h new file mode 100644 index 00000000..3d9599a6 --- /dev/null +++ b/drivers/gpu/nvgpu/ctrl/ctrlboardobj.h | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _ctrlboardobj_h_ | ||
15 | #define _ctrlboardobj_h_ | ||
16 | |||
17 | struct ctrl_boardobj { | ||
18 | u8 type; | ||
19 | }; | ||
20 | |||
21 | #define CTRL_BOARDOBJGRP_TYPE_INVALID 0x00 | ||
22 | #define CTRL_BOARDOBJGRP_TYPE_E32 0x01 | ||
23 | #define CTRL_BOARDOBJGRP_TYPE_E255 0x02 | ||
24 | |||
25 | #define CTRL_BOARDOBJGRP_E32_MAX_OBJECTS 32 | ||
26 | |||
27 | #define CTRL_BOARDOBJGRP_E255_MAX_OBJECTS 255 | ||
28 | |||
29 | #define CTRL_BOARDOBJ_MAX_BOARD_OBJECTS \ | ||
30 | CTRL_BOARDOBJGRP_E32_MAX_OBJECTS | ||
31 | |||
32 | #define CTRL_BOARDOBJ_IDX_INVALID 255 | ||
33 | |||
34 | #define CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE 32 | ||
35 | |||
36 | #define CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(_bit) \ | ||
37 | ((_bit) / CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE) | ||
38 | |||
39 | #define CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(_bit) \ | ||
40 | ((_bit) % CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE) | ||
41 | |||
42 | #define CTRL_BOARDOBJGRP_MASK_DATA_SIZE(_bits) \ | ||
43 | (CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX((_bits) - 1) + 1) | ||
44 | |||
45 | |||
46 | #define CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE 1 | ||
47 | #define CTRL_BOARDOBJGRP_MASK_ARRAY_EXTENSION_SIZE(_bits) \ | ||
48 | (CTRL_BOARDOBJGRP_MASK_DATA_SIZE(_bits) - \ | ||
49 | CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE) | ||
50 | |||
51 | struct ctrl_boardobjgrp_mask { | ||
52 | u32 data[1]; | ||
53 | }; | ||
54 | |||
55 | struct ctrl_boardobjgrp_mask_e32 { | ||
56 | struct ctrl_boardobjgrp_mask super; | ||
57 | }; | ||
58 | |||
59 | struct ctrl_boardobjgrp_mask_e255 { | ||
60 | struct ctrl_boardobjgrp_mask super; | ||
61 | u32 data_e255[7]; | ||
62 | }; | ||
63 | |||
64 | struct ctrl_boardobjgrp_super { | ||
65 | struct ctrl_boardobjgrp_mask obj_mask; | ||
66 | }; | ||
67 | |||
68 | struct ctrl_boardobjgrp_e32 { | ||
69 | struct ctrl_boardobjgrp_mask_e32 obj_mask; | ||
70 | }; | ||
71 | |||
72 | struct CTRL_boardobjgrp_e255 { | ||
73 | struct ctrl_boardobjgrp_mask_e255 obj_mask; | ||
74 | }; | ||
75 | |||
76 | struct ctrl_boardobjgrp { | ||
77 | u32 obj_mask; | ||
78 | }; | ||
79 | |||
80 | #endif | ||
81 | |||
diff --git a/drivers/gpu/nvgpu/ctrl/ctrlclk.h b/drivers/gpu/nvgpu/ctrl/ctrlclk.h new file mode 100644 index 00000000..76054d27 --- /dev/null +++ b/drivers/gpu/nvgpu/ctrl/ctrlclk.h | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * general p state infrastructure | ||
3 | * | ||
4 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | #ifndef _ctrlclk_h_ | ||
16 | #define _ctrlclk_h_ | ||
17 | |||
18 | #include "ctrlboardobj.h" | ||
19 | #include "ctrlclkavfs.h" | ||
20 | #include "ctrlvolt.h" | ||
21 | |||
22 | #define CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS 4 | ||
23 | |||
24 | /* valid clock domain values */ | ||
25 | #define CTRL_CLK_DOMAIN_MCLK (0x00000010) | ||
26 | #define CTRL_CLK_DOMAIN_DISPCLK (0x00000040) | ||
27 | #define CTRL_CLK_DOMAIN_GPC2CLK (0x00010000) | ||
28 | #define CTRL_CLK_DOMAIN_XBAR2CLK (0x00040000) | ||
29 | #define CTRL_CLK_DOMAIN_SYS2CLK (0x00080000) | ||
30 | #define CTRL_CLK_DOMAIN_HUB2CLK (0x00100000) | ||
31 | #define CTRL_CLK_DOMAIN_PWRCLK (0x00800000) | ||
32 | #define CTRL_CLK_DOMAIN_NVDCLK (0x01000000) | ||
33 | #define CTRL_CLK_DOMAIN_PCIEGENCLK (0x02000000) | ||
34 | |||
35 | #define CTRL_CLK_DOMAIN_GPCCLK (0x10000000) | ||
36 | #define CTRL_CLK_DOMAIN_XBARCLK (0x20000000) | ||
37 | #define CTRL_CLK_DOMAIN_SYSCLK (0x40000000) | ||
38 | #define CTRL_CLK_DOMAIN_HUBCLK (0x80000000) | ||
39 | |||
40 | #define CTRL_CLK_CLK_DOMAIN_TYPE_3X 0x01 | ||
41 | #define CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED 0x02 | ||
42 | #define CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG 0x03 | ||
43 | #define CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER 0x04 | ||
44 | #define CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE 0x05 | ||
45 | |||
46 | #define CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID 0xFF | ||
47 | #define CTRL_CLK_CLK_DOMAIN_INDEX_INVALID 0xFF | ||
48 | |||
49 | #define CTRL_CLK_CLK_PROG_TYPE_1X 0x00 | ||
50 | #define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER 0x01 | ||
51 | #define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO 0x02 | ||
52 | #define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE 0x03 | ||
53 | #define CTRL_CLK_CLK_PROG_TYPE_UNKNOWN 255 | ||
54 | |||
55 | /*! | ||
56 | * Enumeration of CLK_PROG source types. | ||
57 | */ | ||
58 | #define CTRL_CLK_PROG_1X_SOURCE_PLL 0x00 | ||
59 | #define CTRL_CLK_PROG_1X_SOURCE_ONE_SOURCE 0x01 | ||
60 | #define CTRL_CLK_PROG_1X_SOURCE_FLL 0x02 | ||
61 | #define CTRL_CLK_PROG_1X_SOURCE_INVALID 255 | ||
62 | |||
63 | #define CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES 4 | ||
64 | #define CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES 6 | ||
65 | |||
66 | #define CTRL_CLK_CLK_VF_POINT_IDX_INVALID 255 | ||
67 | |||
68 | #define CTRL_CLK_CLK_VF_POINT_TYPE_FREQ 0x00 | ||
69 | #define CTRL_CLK_CLK_VF_POINT_TYPE_VOLT 0x01 | ||
70 | #define CTRL_CLK_CLK_VF_POINT_TYPE_UNKNOWN 255 | ||
71 | |||
72 | struct ctrl_clk_clk_prog_1x_master_source_fll { | ||
73 | u32 base_vfsmooth_volt_uv; | ||
74 | u32 max_vf_ramprate; | ||
75 | u32 max_freq_stepsize_mhz; | ||
76 | }; | ||
77 | |||
78 | union ctrl_clk_clk_prog_1x_master_source_data { | ||
79 | struct ctrl_clk_clk_prog_1x_master_source_fll fll; | ||
80 | }; | ||
81 | |||
82 | struct ctrl_clk_clk_vf_point_info_freq { | ||
83 | u16 freq_mhz; | ||
84 | }; | ||
85 | |||
86 | struct ctrl_clk_clk_vf_point_info_volt { | ||
87 | u32 sourceVoltageuV; | ||
88 | u8 vfGainVfeEquIdx; | ||
89 | u8 clkDomainIdx; | ||
90 | }; | ||
91 | |||
92 | struct ctrl_clk_clk_prog_1x_master_vf_entry { | ||
93 | u8 vfe_idx; | ||
94 | u8 gain_vfe_idx; | ||
95 | u8 vf_point_idx_first; | ||
96 | u8 vf_point_idx_last; | ||
97 | }; | ||
98 | |||
99 | struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry { | ||
100 | u8 clk_dom_idx; | ||
101 | u8 ratio; | ||
102 | }; | ||
103 | |||
104 | struct ctrl_clk_clk_prog_1x_master_table_slave_entry { | ||
105 | u8 clk_dom_idx; | ||
106 | u16 freq_mhz; | ||
107 | }; | ||
108 | |||
109 | struct ctrl_clk_clk_prog_1x_source_pll { | ||
110 | u8 pll_idx; | ||
111 | u8 freq_step_size_mhz; | ||
112 | }; | ||
113 | |||
114 | struct ctrl_clk_clk_delta { | ||
115 | int freq_delta_khz; | ||
116 | int volt_deltauv[CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS]; | ||
117 | |||
118 | }; | ||
119 | |||
120 | union ctrl_clk_clk_prog_1x_source_data { | ||
121 | struct ctrl_clk_clk_prog_1x_source_pll pll; | ||
122 | }; | ||
123 | |||
124 | struct ctrl_clk_vf_pair { | ||
125 | u16 freq_mhz; | ||
126 | u32 voltage_uv; | ||
127 | }; | ||
128 | |||
129 | struct ctrl_clk_clk_domain_list_item { | ||
130 | u32 clk_domain; | ||
131 | u32 clk_freq_khz; | ||
132 | u32 clk_flags; | ||
133 | u8 current_regime_id; | ||
134 | u8 target_regime_id; | ||
135 | }; | ||
136 | |||
137 | #define CTRL_CLK_VF_PAIR_FREQ_MHZ_GET(pvfpair) \ | ||
138 | ((pvfpair)->freq_mhz) | ||
139 | |||
140 | #define CTRL_CLK_VF_PAIR_VOLTAGE_UV_GET(pvfpair) \ | ||
141 | ((pvfpair)->voltage_uv) | ||
142 | |||
143 | #define CTRL_CLK_VF_PAIR_FREQ_MHZ_SET(pvfpair, _freqmhz) \ | ||
144 | (((pvfpair)->freq_mhz) = (_freqmhz)) | ||
145 | |||
146 | #define CTRL_CLK_VF_PAIR_FREQ_MHZ_SET(pvfpair, _freqmhz) \ | ||
147 | (((pvfpair)->freq_mhz) = (_freqmhz)) | ||
148 | |||
149 | |||
150 | #define CTRL_CLK_VF_PAIR_VOLTAGE_UV_SET(pvfpair, _voltageuv) \ | ||
151 | (((pvfpair)->voltage_uv) = (_voltageuv)) | ||
152 | |||
153 | #endif | ||
diff --git a/drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h b/drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h new file mode 100644 index 00000000..7e28a5d9 --- /dev/null +++ b/drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * _NVRM_COPYRIGHT_BEGIN_ | ||
3 | * | ||
4 | * Copyright 2015-2016 by NVIDIA Corporation. All rights reserved. All | ||
5 | * information contained herein is proprietary and confidential to NVIDIA | ||
6 | * Corporation. Any use, reproduction, or disclosure without the written | ||
7 | * permission of NVIDIA Corporation is prohibited. | ||
8 | * | ||
9 | * _NVRM_COPYRIGHT_END_ | ||
10 | */ | ||
11 | |||
12 | #ifndef _ctrlclkavfs_h_ | ||
13 | #define _ctrlclkavfs_h_ | ||
14 | |||
15 | #include "ctrlboardobj.h" | ||
16 | /*! | ||
17 | * Valid global VIN ID values | ||
18 | */ | ||
19 | #define CTRL_CLK_VIN_ID_SYS 0x00000000 | ||
20 | #define CTRL_CLK_VIN_ID_LTC 0x00000001 | ||
21 | #define CTRL_CLK_VIN_ID_XBAR 0x00000002 | ||
22 | #define CTRL_CLK_VIN_ID_GPC0 0x00000003 | ||
23 | #define CTRL_CLK_VIN_ID_GPC1 0x00000004 | ||
24 | #define CTRL_CLK_VIN_ID_GPC2 0x00000005 | ||
25 | #define CTRL_CLK_VIN_ID_GPC3 0x00000006 | ||
26 | #define CTRL_CLK_VIN_ID_GPC4 0x00000007 | ||
27 | #define CTRL_CLK_VIN_ID_GPC5 0x00000008 | ||
28 | #define CTRL_CLK_VIN_ID_GPCS 0x00000009 | ||
29 | #define CTRL_CLK_VIN_ID_SRAM 0x0000000A | ||
30 | #define CTRL_CLK_VIN_ID_UNDEFINED 0x000000FF | ||
31 | |||
32 | #define CTRL_CLK_VIN_TYPE_DISABLED 0x00000000 | ||
33 | |||
34 | /*! | ||
35 | * Mask of all GPC VIN IDs supported by RM | ||
36 | */ | ||
37 | #define CTRL_CLK_VIN_MASK_UNICAST_GPC (BIT(CTRL_CLK_VIN_ID_GPC0) | \ | ||
38 | BIT(CTRL_CLK_VIN_ID_GPC1) | \ | ||
39 | BIT(CTRL_CLK_VIN_ID_GPC2) | \ | ||
40 | BIT(CTRL_CLK_VIN_ID_GPC3) | \ | ||
41 | BIT(CTRL_CLK_VIN_ID_GPC4) | \ | ||
42 | BIT(CTRL_CLK_VIN_ID_GPC5)) | ||
43 | #define CTRL_CLK_LUT_NUM_ENTRIES 0x50 | ||
44 | #define CTRL_CLK_VIN_STEP_SIZE_UV (10000) | ||
45 | #define CTRL_CLK_LUT_MIN_VOLTAGE_UV (450000) | ||
46 | #define CTRL_CLK_FLL_TYPE_DISABLED 0 | ||
47 | |||
48 | #define CTRL_CLK_FLL_ID_SYS (0x00000000) | ||
49 | #define CTRL_CLK_FLL_ID_LTC (0x00000001) | ||
50 | #define CTRL_CLK_FLL_ID_XBAR (0x00000002) | ||
51 | #define CTRL_CLK_FLL_ID_GPC0 (0x00000003) | ||
52 | #define CTRL_CLK_FLL_ID_GPC1 (0x00000004) | ||
53 | #define CTRL_CLK_FLL_ID_GPC2 (0x00000005) | ||
54 | #define CTRL_CLK_FLL_ID_GPC3 (0x00000006) | ||
55 | #define CTRL_CLK_FLL_ID_GPC4 (0x00000007) | ||
56 | #define CTRL_CLK_FLL_ID_GPC5 (0x00000008) | ||
57 | #define CTRL_CLK_FLL_ID_GPCS (0x00000009) | ||
58 | #define CTRL_CLK_FLL_ID_UNDEFINED (0x000000FF) | ||
59 | #define CTRL_CLK_FLL_MASK_UNDEFINED (0x00000000) | ||
60 | |||
61 | /*! | ||
62 | * Mask of all GPC FLL IDs supported by RM | ||
63 | */ | ||
64 | #define CTRL_CLK_FLL_MASK_UNICAST_GPC (BIT(CTRL_CLK_FLL_ID_GPC0) | \ | ||
65 | BIT(CTRL_CLK_FLL_ID_GPC1) | \ | ||
66 | BIT(CTRL_CLK_FLL_ID_GPC2) | \ | ||
67 | BIT(CTRL_CLK_FLL_ID_GPC3) | \ | ||
68 | BIT(CTRL_CLK_FLL_ID_GPC4) | \ | ||
69 | BIT(CTRL_CLK_FLL_ID_GPC5)) | ||
70 | /*! | ||
71 | * Mask of all FLL IDs supported by RM | ||
72 | */ | ||
73 | #define CTRL_CLK_FLL_ID_ALL_MASK (BIT(CTRL_CLK_FLL_ID_SYS) | \ | ||
74 | BIT(CTRL_CLK_FLL_ID_LTC) | \ | ||
75 | BIT(CTRL_CLK_FLL_ID_XBAR) | \ | ||
76 | BIT(CTRL_CLK_FLL_ID_GPC0) | \ | ||
77 | BIT(CTRL_CLK_FLL_ID_GPC1) | \ | ||
78 | BIT(CTRL_CLK_FLL_ID_GPC2) | \ | ||
79 | BIT(CTRL_CLK_FLL_ID_GPC3) | \ | ||
80 | BIT(CTRL_CLK_FLL_ID_GPC4) | \ | ||
81 | BIT(CTRL_CLK_FLL_ID_GPC5) | \ | ||
82 | BIT(CTRL_CLK_FLL_ID_GPCS)) | ||
83 | |||
84 | #define CTRL_CLK_FLL_REGIME_ID_INVALID (0x00000000) | ||
85 | #define CTRL_CLK_FLL_REGIME_ID_FFR (0x00000001) | ||
86 | #define CTRL_CLK_FLL_REGIME_ID_FR (0x00000002) | ||
87 | |||
88 | #endif | ||
diff --git a/drivers/gpu/nvgpu/ctrl/ctrlperf.h b/drivers/gpu/nvgpu/ctrl/ctrlperf.h new file mode 100644 index 00000000..89697dfd --- /dev/null +++ b/drivers/gpu/nvgpu/ctrl/ctrlperf.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * general p state infrastructure | ||
3 | * | ||
4 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | #ifndef _ctrlperf_h_ | ||
16 | #define _ctrlperf_h_ | ||
17 | |||
18 | #include "ctrlvolt.h" | ||
19 | |||
20 | struct ctrl_perf_volt_rail_list_item { | ||
21 | u8 volt_domain; | ||
22 | u32 voltage_uv; | ||
23 | u32 voltage_min_noise_unaware_uv; | ||
24 | }; | ||
25 | |||
26 | struct ctrl_perf_volt_rail_list { | ||
27 | u8 num_rails; | ||
28 | struct ctrl_perf_volt_rail_list_item | ||
29 | rails[CTRL_VOLT_VOLT_RAIL_MAX_RAILS]; | ||
30 | }; | ||
31 | |||
32 | #endif | ||
diff --git a/drivers/gpu/nvgpu/ctrl/ctrlvolt.h b/drivers/gpu/nvgpu/ctrl/ctrlvolt.h new file mode 100644 index 00000000..b4769a18 --- /dev/null +++ b/drivers/gpu/nvgpu/ctrl/ctrlvolt.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * general p state infrastructure | ||
3 | * | ||
4 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | #ifndef _ctrlvolt_h_ | ||
16 | #define _ctrlvolt_h_ | ||
17 | |||
18 | #define CTRL_VOLT_VOLT_RAIL_MAX_RAILS \ | ||
19 | CTRL_BOARDOBJGRP_E32_MAX_OBJECTS | ||
20 | |||
21 | #include "ctrlperf.h" | ||
22 | #include "ctrlboardobj.h" | ||
23 | |||
24 | #define CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES 0x04 | ||
25 | #define CTRL_VOLT_VOLT_DEV_VID_VSEL_MAX_ENTRIES (8) | ||
26 | #define CTRL_VOLT_DOMAIN_INVALID 0x00 | ||
27 | #define CTRL_VOLT_DOMAIN_LOGIC 0x01 | ||
28 | |||
29 | struct ctrl_volt_volt_rail_list_item { | ||
30 | u8 rail_idx; | ||
31 | u32 voltage_uv; | ||
32 | }; | ||
33 | |||
34 | struct ctrl_volt_volt_rail_list { | ||
35 | u8 num_rails; | ||
36 | struct ctrl_volt_volt_rail_list_item | ||
37 | rails[CTRL_VOLT_VOLT_RAIL_MAX_RAILS]; | ||
38 | }; | ||
39 | |||
40 | #endif | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index ebe2dca4..c9f84041 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -63,6 +63,9 @@ | |||
63 | #include "hal.h" | 63 | #include "hal.h" |
64 | #include "vgpu/vgpu.h" | 64 | #include "vgpu/vgpu.h" |
65 | #include "pci.h" | 65 | #include "pci.h" |
66 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | ||
67 | #include "pstate/pstate.h" | ||
68 | #endif | ||
66 | 69 | ||
67 | #define CREATE_TRACE_POINTS | 70 | #define CREATE_TRACE_POINTS |
68 | #include <trace/events/gk20a.h> | 71 | #include <trace/events/gk20a.h> |
@@ -956,6 +959,16 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
956 | goto done; | 959 | goto done; |
957 | } | 960 | } |
958 | 961 | ||
962 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | ||
963 | if (g->ops.pmupstate) { | ||
964 | err = gk20a_init_pstate_support(g); | ||
965 | if (err) { | ||
966 | gk20a_err(dev, "failed to init pstates"); | ||
967 | goto done; | ||
968 | } | ||
969 | } | ||
970 | #endif | ||
971 | |||
959 | err = gk20a_init_pmu_support(g); | 972 | err = gk20a_init_pmu_support(g); |
960 | if (err) { | 973 | if (err) { |
961 | gk20a_err(dev, "failed to init gk20a pmu"); | 974 | gk20a_err(dev, "failed to init gk20a pmu"); |
@@ -968,6 +981,16 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
968 | goto done; | 981 | goto done; |
969 | } | 982 | } |
970 | 983 | ||
984 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | ||
985 | if (g->ops.pmupstate) { | ||
986 | err = gk20a_init_pstate_pmu_support(g); | ||
987 | if (err) { | ||
988 | gk20a_err(dev, "failed to init pstates"); | ||
989 | goto done; | ||
990 | } | ||
991 | } | ||
992 | #endif | ||
993 | |||
971 | if (g->ops.pmu.mclk_init) { | 994 | if (g->ops.pmu.mclk_init) { |
972 | err = g->ops.pmu.mclk_init(g); | 995 | err = g->ops.pmu.mclk_init(g); |
973 | if (err) { | 996 | if (err) { |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index c4744f3c..edc4a0e1 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -54,6 +54,11 @@ struct acr_desc; | |||
54 | #include "debug_gk20a.h" | 54 | #include "debug_gk20a.h" |
55 | #include "sched_gk20a.h" | 55 | #include "sched_gk20a.h" |
56 | #include "gm206/bios_gm206.h" | 56 | #include "gm206/bios_gm206.h" |
57 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | ||
58 | #include "clk/clk.h" | ||
59 | #include "perf/perf.h" | ||
60 | #endif | ||
61 | #include "gm206/bios_gm206.h" | ||
57 | 62 | ||
58 | /* PTIMER_REF_FREQ_HZ corresponds to a period of 32 nanoseconds. | 63 | /* PTIMER_REF_FREQ_HZ corresponds to a period of 32 nanoseconds. |
59 | 32 ns is the resolution of ptimer. */ | 64 | 32 ns is the resolution of ptimer. */ |
@@ -607,6 +612,7 @@ struct gpu_ops { | |||
607 | } clk; | 612 | } clk; |
608 | bool privsecurity; | 613 | bool privsecurity; |
609 | bool securegpccs; | 614 | bool securegpccs; |
615 | bool pmupstate; | ||
610 | struct { | 616 | struct { |
611 | const struct regop_offset_range* ( | 617 | const struct regop_offset_range* ( |
612 | *get_global_whitelist_ranges)(void); | 618 | *get_global_whitelist_ranges)(void); |
@@ -717,6 +723,7 @@ struct nvgpu_bios { | |||
717 | 723 | ||
718 | struct bit_token *perf_token; | 724 | struct bit_token *perf_token; |
719 | struct bit_token *clock_token; | 725 | struct bit_token *clock_token; |
726 | struct bit_token *virt_token; | ||
720 | u32 expansion_rom_offset; | 727 | u32 expansion_rom_offset; |
721 | }; | 728 | }; |
722 | 729 | ||
@@ -746,6 +753,10 @@ struct gk20a { | |||
746 | struct pmu_gk20a pmu; | 753 | struct pmu_gk20a pmu; |
747 | struct acr_desc acr; | 754 | struct acr_desc acr; |
748 | struct cooling_device_gk20a gk20a_cdev; | 755 | struct cooling_device_gk20a gk20a_cdev; |
756 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | ||
757 | struct clk_pmupstate clk_pmu; | ||
758 | struct perf_pmupstate perf_pmu; | ||
759 | #endif | ||
749 | 760 | ||
750 | #ifdef CONFIG_DEBUG_FS | 761 | #ifdef CONFIG_DEBUG_FS |
751 | struct railgate_stats pstats; | 762 | struct railgate_stats pstats; |
@@ -992,6 +1003,7 @@ enum gk20a_dbg_categories { | |||
992 | gpu_dbg_map_v = BIT(14), /* verbose mem mappings */ | 1003 | gpu_dbg_map_v = BIT(14), /* verbose mem mappings */ |
993 | gpu_dbg_sema = BIT(15), /* semaphore debugging */ | 1004 | gpu_dbg_sema = BIT(15), /* semaphore debugging */ |
994 | gpu_dbg_sema_v = BIT(16), /* verbose semaphore debugging */ | 1005 | gpu_dbg_sema_v = BIT(16), /* verbose semaphore debugging */ |
1006 | gpu_dbg_pmu_pstate = BIT(17), /* p state controlled by pmu */ | ||
995 | gpu_dbg_mem = BIT(31), /* memory accesses, very verbose */ | 1007 | gpu_dbg_mem = BIT(31), /* memory accesses, very verbose */ |
996 | }; | 1008 | }; |
997 | 1009 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c index 550dffa6..b1e94d7d 100644 --- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c | |||
@@ -142,6 +142,7 @@ int gk20a_init_hal(struct gk20a *g) | |||
142 | *gops = gk20a_ops; | 142 | *gops = gk20a_ops; |
143 | gops->privsecurity = 0; | 143 | gops->privsecurity = 0; |
144 | gops->securegpccs = 0; | 144 | gops->securegpccs = 0; |
145 | gops->pmupstate = false; | ||
145 | gk20a_init_mc(gops); | 146 | gk20a_init_mc(gops); |
146 | gk20a_init_ltc(gops); | 147 | gk20a_init_ltc(gops); |
147 | gk20a_init_gr_ops(gops); | 148 | gk20a_init_gr_ops(gops); |
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_api.h b/drivers/gpu/nvgpu/gk20a/pmu_api.h index aa10661c..d256f6d2 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_api.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_api.h | |||
@@ -458,6 +458,29 @@ enum { | |||
458 | PMU_PG_ELPG_CMD_UNFREEZE, | 458 | PMU_PG_ELPG_CMD_UNFREEZE, |
459 | }; | 459 | }; |
460 | 460 | ||
461 | enum { | ||
462 | PMU_PG_CMD_ID_ELPG_CMD = 0, | ||
463 | PMU_PG_CMD_ID_ENG_BUF_LOAD, | ||
464 | PMU_PG_CMD_ID_ENG_BUF_UNLOAD, | ||
465 | PMU_PG_CMD_ID_PG_STAT, | ||
466 | PMU_PG_CMD_ID_PG_LOG_INIT, | ||
467 | PMU_PG_CMD_ID_PG_LOG_FLUSH, | ||
468 | PMU_PG_CMD_ID_PG_PARAM, | ||
469 | PMU_PG_CMD_ID_ELPG_INIT, | ||
470 | PMU_PG_CMD_ID_ELPG_POLL_CTXSAVE, | ||
471 | PMU_PG_CMD_ID_ELPG_ABORT_POLL, | ||
472 | PMU_PG_CMD_ID_ELPG_PWR_UP, | ||
473 | PMU_PG_CMD_ID_ELPG_DISALLOW, | ||
474 | PMU_PG_CMD_ID_ELPG_ALLOW, | ||
475 | PMU_PG_CMD_ID_AP, | ||
476 | RM_PMU_PG_CMD_ID_PSI, | ||
477 | RM_PMU_PG_CMD_ID_CG, | ||
478 | PMU_PG_CMD_ID_ZBC_TABLE_UPDATE, | ||
479 | PMU_PG_CMD_ID_PWR_RAIL_GATE_DISABLE = 0x20, | ||
480 | PMU_PG_CMD_ID_PWR_RAIL_GATE_ENABLE, | ||
481 | PMU_PG_CMD_ID_PWR_RAIL_SMU_MSG_DISABLE | ||
482 | }; | ||
483 | |||
461 | struct pmu_pg_cmd_elpg_cmd { | 484 | struct pmu_pg_cmd_elpg_cmd { |
462 | u8 cmd_type; | 485 | u8 cmd_type; |
463 | u8 engine_id; | 486 | u8 engine_id; |
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_common.h b/drivers/gpu/nvgpu/gk20a/pmu_common.h index 76b37cf7..de37caeb 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_common.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_common.h | |||
@@ -95,6 +95,8 @@ struct flcn_u64 { | |||
95 | u32 hi; | 95 | u32 hi; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | #define nv_flcn_u64 flcn_u64 | ||
99 | |||
98 | struct flcn_mem_desc_v0 { | 100 | struct flcn_mem_desc_v0 { |
99 | struct flcn_u64 address; | 101 | struct flcn_u64 address; |
100 | u32 params; | 102 | u32 params; |
@@ -132,6 +134,8 @@ struct pmu_allocation_v3 { | |||
132 | } alloc; | 134 | } alloc; |
133 | }; | 135 | }; |
134 | 136 | ||
137 | #define nv_pmu_allocation pmu_allocation_v3 | ||
138 | |||
135 | struct pmu_hdr { | 139 | struct pmu_hdr { |
136 | u8 unit_id; | 140 | u8 unit_id; |
137 | u8 size; | 141 | u8 size; |
@@ -142,4 +146,36 @@ struct pmu_hdr { | |||
142 | #define nv_pmu_hdr pmu_hdr | 146 | #define nv_pmu_hdr pmu_hdr |
143 | typedef u8 flcn_status; | 147 | typedef u8 flcn_status; |
144 | 148 | ||
145 | #endif /*__PMU_COMMON_H__*/ | 149 | #define ALIGN_UP(v, gran) (((v) + ((gran) - 1)) & ~((gran)-1)) |
150 | |||
151 | /*! | ||
152 | * Falcon PMU DMA's minimum size in bytes. | ||
153 | */ | ||
154 | #define PMU_DMA_MIN_READ_SIZE_BYTES 16 | ||
155 | #define PMU_DMA_MIN_WRITE_SIZE_BYTES 4 | ||
156 | |||
157 | #define PMU_FB_COPY_RW_ALIGNMENT \ | ||
158 | (PMU_DMA_MIN_READ_SIZE_BYTES > PMU_DMA_MIN_WRITE_SIZE_BYTES ? \ | ||
159 | PMU_DMA_MIN_READ_SIZE_BYTES : PMU_DMA_MIN_WRITE_SIZE_BYTES) | ||
160 | |||
161 | /*! | ||
162 | * Macros to make aligned versions of RM_PMU_XXX structures. PMU needs aligned | ||
163 | * data structures to issue DMA read/write operations. | ||
164 | */ | ||
165 | #define NV_PMU_MAKE_ALIGNED_STRUCT(name, size) \ | ||
166 | union name##_aligned { \ | ||
167 | struct name data; \ | ||
168 | u8 pad[ALIGN_UP(sizeof(struct name), \ | ||
169 | (PMU_FB_COPY_RW_ALIGNMENT))]; \ | ||
170 | } | ||
171 | |||
172 | #define NV_PMU_MAKE_ALIGNED_UNION(name, size) \ | ||
173 | union name##_aligned { \ | ||
174 | union name data; \ | ||
175 | u8 pad[ALIGN_UP(sizeof(union name), \ | ||
176 | (PMU_FB_COPY_RW_ALIGNMENT))]; \ | ||
177 | } | ||
178 | |||
179 | #define NV_UNSIGNED_ROUNDED_DIV(a, b) (((a) + ((b) / 2)) / (b)) | ||
180 | |||
181 | #endif | ||
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index f041c9c1..13d3ec78 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | |||
@@ -3756,9 +3756,6 @@ static int pmu_response_handle(struct pmu_gk20a *pmu, | |||
3756 | } | 3756 | } |
3757 | if (pv->pmu_allocation_get_dmem_size(pmu, | 3757 | if (pv->pmu_allocation_get_dmem_size(pmu, |
3758 | pv->get_pmu_seq_out_a_ptr(seq)) != 0) { | 3758 | pv->get_pmu_seq_out_a_ptr(seq)) != 0) { |
3759 | gk20a_err(dev_from_gk20a(g), "dmem offs %x size %x\n", pv->pmu_allocation_get_dmem_offset(pmu,pv->get_pmu_seq_out_a_ptr(seq)), pv->pmu_allocation_get_dmem_size(pmu, | ||
3760 | pv->get_pmu_seq_out_a_ptr(seq))); | ||
3761 | gk20a_err(dev_from_gk20a(g), "copying to %p \n", seq->out_payload); | ||
3762 | pmu_copy_from_dmem(pmu, | 3759 | pmu_copy_from_dmem(pmu, |
3763 | pv->pmu_allocation_get_dmem_offset(pmu, | 3760 | pv->pmu_allocation_get_dmem_offset(pmu, |
3764 | pv->get_pmu_seq_out_a_ptr(seq)), | 3761 | pv->get_pmu_seq_out_a_ptr(seq)), |
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h index f0e5d3cf..fd27ab5c 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | |||
@@ -23,6 +23,9 @@ | |||
23 | 23 | ||
24 | #include "pmu_api.h" | 24 | #include "pmu_api.h" |
25 | #include "pmu_common.h" | 25 | #include "pmu_common.h" |
26 | #include "pmuif/gpmuifboardobj.h" | ||
27 | #include "pmuif/gpmuifclk.h" | ||
28 | #include "pmuif/gpmuifperf.h" | ||
26 | 29 | ||
27 | /* defined by pmu hw spec */ | 30 | /* defined by pmu hw spec */ |
28 | #define GK20A_PMU_VA_SIZE (512 * 1024 * 1024) | 31 | #define GK20A_PMU_VA_SIZE (512 * 1024 * 1024) |
@@ -172,8 +175,10 @@ struct pmu_ucode_desc_v1 { | |||
172 | #define PMU_UNIT_ACR (0x0A) | 175 | #define PMU_UNIT_ACR (0x0A) |
173 | #define PMU_UNIT_PERFMON_T18X (0x11) | 176 | #define PMU_UNIT_PERFMON_T18X (0x11) |
174 | #define PMU_UNIT_PERFMON (0x12) | 177 | #define PMU_UNIT_PERFMON (0x12) |
175 | #define PMU_UNIT_RC (0x1F) | 178 | #define PMU_UNIT_PERF (0x13) |
179 | #define PMU_UNIT_RC (0x1F) | ||
176 | #define PMU_UNIT_FECS_MEM_OVERRIDE (0x1E) | 180 | #define PMU_UNIT_FECS_MEM_OVERRIDE (0x1E) |
181 | #define PMU_UNIT_CLK (0x1C) | ||
177 | 182 | ||
178 | #define PMU_UNIT_END (0x23) | 183 | #define PMU_UNIT_END (0x23) |
179 | 184 | ||
@@ -295,29 +300,6 @@ struct pmu_rc_msg { | |||
295 | struct pmu_rc_msg_unhandled_cmd unhandled_cmd; | 300 | struct pmu_rc_msg_unhandled_cmd unhandled_cmd; |
296 | }; | 301 | }; |
297 | 302 | ||
298 | enum { | ||
299 | PMU_PG_CMD_ID_ELPG_CMD = 0, | ||
300 | PMU_PG_CMD_ID_ENG_BUF_LOAD, | ||
301 | PMU_PG_CMD_ID_ENG_BUF_UNLOAD, | ||
302 | PMU_PG_CMD_ID_PG_STAT, | ||
303 | PMU_PG_CMD_ID_PG_LOG_INIT, | ||
304 | PMU_PG_CMD_ID_PG_LOG_FLUSH, | ||
305 | PMU_PG_CMD_ID_PG_PARAM, | ||
306 | PMU_PG_CMD_ID_ELPG_INIT, | ||
307 | PMU_PG_CMD_ID_ELPG_POLL_CTXSAVE, | ||
308 | PMU_PG_CMD_ID_ELPG_ABORT_POLL, | ||
309 | PMU_PG_CMD_ID_ELPG_PWR_UP, | ||
310 | PMU_PG_CMD_ID_ELPG_DISALLOW, | ||
311 | PMU_PG_CMD_ID_ELPG_ALLOW, | ||
312 | PMU_PG_CMD_ID_AP, | ||
313 | RM_PMU_PG_CMD_ID_PSI, | ||
314 | RM_PMU_PG_CMD_ID_CG, | ||
315 | PMU_PG_CMD_ID_ZBC_TABLE_UPDATE, | ||
316 | PMU_PG_CMD_ID_PWR_RAIL_GATE_DISABLE = 0x20, | ||
317 | PMU_PG_CMD_ID_PWR_RAIL_GATE_ENABLE, | ||
318 | PMU_PG_CMD_ID_PWR_RAIL_SMU_MSG_DISABLE | ||
319 | }; | ||
320 | |||
321 | /***************************** ACR ERROR CODES ******************************/ | 303 | /***************************** ACR ERROR CODES ******************************/ |
322 | /*! | 304 | /*! |
323 | * Error codes used in PMU-ACR Task | 305 | * Error codes used in PMU-ACR Task |
@@ -369,6 +351,9 @@ struct pmu_cmd { | |||
369 | struct pmu_zbc_cmd zbc; | 351 | struct pmu_zbc_cmd zbc; |
370 | struct pmu_acr_cmd acr; | 352 | struct pmu_acr_cmd acr; |
371 | struct pmu_lrf_tex_ltc_dram_cmd lrf_tex_ltc_dram; | 353 | struct pmu_lrf_tex_ltc_dram_cmd lrf_tex_ltc_dram; |
354 | struct nv_pmu_boardobj_cmd boardobj; | ||
355 | struct nv_pmu_perf_cmd perf; | ||
356 | struct nv_pmu_clk_cmd clk; | ||
372 | } cmd; | 357 | } cmd; |
373 | }; | 358 | }; |
374 | 359 | ||
@@ -381,6 +366,9 @@ struct pmu_msg { | |||
381 | struct pmu_rc_msg rc; | 366 | struct pmu_rc_msg rc; |
382 | struct pmu_acr_msg acr; | 367 | struct pmu_acr_msg acr; |
383 | struct pmu_lrf_tex_ltc_dram_msg lrf_tex_ltc_dram; | 368 | struct pmu_lrf_tex_ltc_dram_msg lrf_tex_ltc_dram; |
369 | struct nv_pmu_boardobj_msg boardobj; | ||
370 | struct nv_pmu_perf_msg perf; | ||
371 | struct nv_pmu_clk_msg clk; | ||
384 | } msg; | 372 | } msg; |
385 | }; | 373 | }; |
386 | 374 | ||
@@ -813,4 +801,6 @@ int gk20a_pmu_vidmem_surface_alloc(struct gk20a *g, struct mem_desc *mem, | |||
813 | u32 size); | 801 | u32 size); |
814 | int gk20a_pmu_sysmem_surface_alloc(struct gk20a *g, struct mem_desc *mem, | 802 | int gk20a_pmu_sysmem_surface_alloc(struct gk20a *g, struct mem_desc *mem, |
815 | u32 size); | 803 | u32 size); |
804 | |||
805 | void print_vbios_table(u8 *msg, u8 *buff, int size); | ||
816 | #endif /*__PMU_GK20A_H__*/ | 806 | #endif /*__PMU_GK20A_H__*/ |
diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c index 6caecb32..21c852a5 100644 --- a/drivers/gpu/nvgpu/gm206/bios_gm206.c +++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c | |||
@@ -61,6 +61,7 @@ struct bit { | |||
61 | #define TOKEN_ID_FALCON_DATA 0x70 | 61 | #define TOKEN_ID_FALCON_DATA 0x70 |
62 | #define TOKEN_ID_PERF_PTRS 0x50 | 62 | #define TOKEN_ID_PERF_PTRS 0x50 |
63 | #define TOKEN_ID_CLOCK_PTRS 0x43 | 63 | #define TOKEN_ID_CLOCK_PTRS 0x43 |
64 | #define TOKEN_ID_VIRT_PTRS 0x56 | ||
64 | 65 | ||
65 | struct nvinit_ptrs { | 66 | struct nvinit_ptrs { |
66 | u16 initscript_table_ptr; | 67 | u16 initscript_table_ptr; |
@@ -434,17 +435,29 @@ static void *gm206_bios_get_perf_table_ptrs(struct gk20a *g, | |||
434 | { | 435 | { |
435 | u32 perf_table_id_offset = 0; | 436 | u32 perf_table_id_offset = 0; |
436 | u8 *perf_table_ptr = NULL; | 437 | u8 *perf_table_ptr = NULL; |
438 | u8 data_size = 4; | ||
437 | 439 | ||
438 | if (ptoken != NULL && | 440 | if (ptoken != NULL) { |
439 | table_id < (ptoken->data_size/sizeof(u32))) { | ||
440 | 441 | ||
441 | perf_table_id_offset = *((u32 *)&g->bios.data[ | 442 | if (ptoken->token_id == TOKEN_ID_VIRT_PTRS) { |
443 | perf_table_id_offset = *((u16 *)&g->bios.data[ | ||
444 | ptoken->data_ptr + | ||
445 | (table_id * PERF_PTRS_WIDTH_16)]); | ||
446 | data_size = PERF_PTRS_WIDTH_16; | ||
447 | } else { | ||
448 | perf_table_id_offset = *((u32 *)&g->bios.data[ | ||
442 | ptoken->data_ptr + | 449 | ptoken->data_ptr + |
443 | (table_id * PERF_PTRS_WIDTH)]); | 450 | (table_id * PERF_PTRS_WIDTH)]); |
451 | data_size = PERF_PTRS_WIDTH; | ||
452 | } | ||
453 | } else | ||
454 | return (void *)perf_table_ptr; | ||
455 | |||
456 | if (table_id < (ptoken->data_size/data_size)) { | ||
444 | 457 | ||
445 | gk20a_dbg_info("Perf_Tbl_ID-offset 0x%x Tbl_ID_Ptr-offset- 0x%x", | 458 | gk20a_dbg_info("Perf_Tbl_ID-offset 0x%x Tbl_ID_Ptr-offset- 0x%x", |
446 | (ptoken->data_ptr + | 459 | (ptoken->data_ptr + |
447 | (table_id * PERF_PTRS_WIDTH)), | 460 | (table_id * data_size)), |
448 | perf_table_id_offset); | 461 | perf_table_id_offset); |
449 | 462 | ||
450 | if (perf_table_id_offset != 0) { | 463 | if (perf_table_id_offset != 0) { |
@@ -503,6 +516,10 @@ static void gm206_bios_parse_bit(struct gk20a *g, int offset) | |||
503 | g->bios.clock_token = | 516 | g->bios.clock_token = |
504 | (struct bit_token *)&g->bios.data[offset]; | 517 | (struct bit_token *)&g->bios.data[offset]; |
505 | break; | 518 | break; |
519 | case TOKEN_ID_VIRT_PTRS: | ||
520 | g->bios.virt_token = | ||
521 | (struct bit_token *)&g->bios.data[offset]; | ||
522 | break; | ||
506 | default: | 523 | default: |
507 | break; | 524 | break; |
508 | } | 525 | } |
diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.h b/drivers/gpu/nvgpu/gm206/bios_gm206.h index f93e5f58..5aa20364 100644 --- a/drivers/gpu/nvgpu/gm206/bios_gm206.h +++ b/drivers/gpu/nvgpu/gm206/bios_gm206.h | |||
@@ -15,18 +15,34 @@ | |||
15 | #define NVGPU_BIOS_GM206_H | 15 | #define NVGPU_BIOS_GM206_H |
16 | 16 | ||
17 | #define PERF_PTRS_WIDTH 0x4 | 17 | #define PERF_PTRS_WIDTH 0x4 |
18 | #define PERF_PTRS_WIDTH_16 0x2 | ||
18 | 19 | ||
19 | enum { | 20 | enum { |
20 | CLOCKS_TABLE = 2, | 21 | CLOCKS_TABLE = 2, |
21 | CLOCK_PROGRAMMING_TABLE, | 22 | CLOCK_PROGRAMMING_TABLE, |
22 | NAFLL_TABLE, | 23 | FLL_TABLE, |
23 | ADC_TABLE, | 24 | VIN_TABLE, |
25 | FREQUENCY_CONTROLLER_TABLE | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | enum { | 28 | enum { |
29 | PERFORMANCE_TABLE = 0, | ||
30 | MEMORY_CLOCK_TABLE, | ||
31 | MEMORY_TWEAK_TABLE, | ||
32 | POWER_CONTROL_TABLE, | ||
33 | THERMAL_CONTROL_TABLE, | ||
34 | THERMAL_DEVICE_TABLE, | ||
35 | THERMAL_COOLERS_TABLE, | ||
36 | PERFORMANCE_SETTINGS_SCRIPT, | ||
27 | CONTINUOUS_VIRTUAL_BINNING_TABLE, | 37 | CONTINUOUS_VIRTUAL_BINNING_TABLE, |
28 | }; | 38 | }; |
29 | 39 | ||
40 | enum { | ||
41 | VP_FIELD_TABLE = 0, | ||
42 | VP_FIELD_REGISTER, | ||
43 | VP_TRANSLATION_TABLE, | ||
44 | }; | ||
45 | |||
30 | struct bit_token { | 46 | struct bit_token { |
31 | u8 token_id; | 47 | u8 token_id; |
32 | u8 data_version; | 48 | u8 data_version; |
diff --git a/drivers/gpu/nvgpu/gm206/hal_gm206.c b/drivers/gpu/nvgpu/gm206/hal_gm206.c index 6b43c8e9..f771c07d 100644 --- a/drivers/gpu/nvgpu/gm206/hal_gm206.c +++ b/drivers/gpu/nvgpu/gm206/hal_gm206.c | |||
@@ -181,7 +181,7 @@ int gm206_init_hal(struct gk20a *g) | |||
181 | 181 | ||
182 | gops->privsecurity = 1; | 182 | gops->privsecurity = 1; |
183 | gops->securegpccs = 1; | 183 | gops->securegpccs = 1; |
184 | 184 | gops->pmupstate = false; | |
185 | gm20b_init_mc(gops); | 185 | gm20b_init_mc(gops); |
186 | gm20b_init_ltc(gops); | 186 | gm20b_init_ltc(gops); |
187 | gm206_init_gr(gops); | 187 | gm206_init_gr(gops); |
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index 5133fb35..1c601894 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c | |||
@@ -184,6 +184,7 @@ int gm20b_init_hal(struct gk20a *g) | |||
184 | 184 | ||
185 | *gops = gm20b_ops; | 185 | *gops = gm20b_ops; |
186 | gops->securegpccs = false; | 186 | gops->securegpccs = false; |
187 | gops->pmupstate = false; | ||
187 | #ifdef CONFIG_TEGRA_ACR | 188 | #ifdef CONFIG_TEGRA_ACR |
188 | if (platform->is_fmodel) { | 189 | if (platform->is_fmodel) { |
189 | gops->privsecurity = 1; | 190 | gops->privsecurity = 1; |
diff --git a/drivers/gpu/nvgpu/pmuif/gpmuifbios.h b/drivers/gpu/nvgpu/pmuif/gpmuifbios.h new file mode 100644 index 00000000..2581d3fa --- /dev/null +++ b/drivers/gpu/nvgpu/pmuif/gpmuifbios.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | #ifndef _GPMUIFBIOS_H_ | ||
14 | #define _GPMUIFBIOS_H_ | ||
15 | |||
16 | struct nv_pmu_bios_vfield_register_segment_super { | ||
17 | u8 type; | ||
18 | u8 low_bit; | ||
19 | u8 high_bit; | ||
20 | }; | ||
21 | |||
22 | struct nv_pmu_bios_vfield_register_segment_reg { | ||
23 | struct nv_pmu_bios_vfield_register_segment_super super; | ||
24 | u32 addr; | ||
25 | }; | ||
26 | |||
27 | struct nv_pmu_bios_vfield_register_segment_index_reg { | ||
28 | struct nv_pmu_bios_vfield_register_segment_super super; | ||
29 | u32 addr; | ||
30 | u32 reg_index; | ||
31 | u32 index; | ||
32 | }; | ||
33 | |||
34 | union nv_pmu_bios_vfield_register_segment { | ||
35 | struct nv_pmu_bios_vfield_register_segment_super super; | ||
36 | struct nv_pmu_bios_vfield_register_segment_reg reg; | ||
37 | struct nv_pmu_bios_vfield_register_segment_index_reg index_reg; | ||
38 | }; | ||
39 | |||
40 | |||
41 | #endif /* _GPMUIFBIOS_H_*/ | ||
diff --git a/drivers/gpu/nvgpu/pmuif/gpmuifboardobj.h b/drivers/gpu/nvgpu/pmuif/gpmuifboardobj.h new file mode 100644 index 00000000..7a061472 --- /dev/null +++ b/drivers/gpu/nvgpu/pmuif/gpmuifboardobj.h | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | #ifndef _GPMUIFBOARDOBJ_H_ | ||
14 | #define _GPMUIFBOARDOBJ_H_ | ||
15 | |||
16 | #include "gk20a/gk20a.h" | ||
17 | #include "gk20a/pmu_gk20a.h" | ||
18 | #include "ctrl/ctrlboardobj.h" | ||
19 | |||
20 | /* | ||
21 | * Base structure describing a BOARDOBJ for communication between Kernel and | ||
22 | * PMU. | ||
23 | */ | ||
24 | struct nv_pmu_boardobj { | ||
25 | u8 type; | ||
26 | }; | ||
27 | |||
28 | /* | ||
29 | * Base structure describing a BOARDOBJ for Query interface between Kernel and | ||
30 | * PMU. | ||
31 | */ | ||
32 | struct nv_pmu_boardobj_query { | ||
33 | u8 type; | ||
34 | }; | ||
35 | |||
36 | /* | ||
37 | * Virtual base structure describing a BOARDOBJGRP interface between Kernel and | ||
38 | * PMU. | ||
39 | */ | ||
40 | struct nv_pmu_boardobjgrp_super { | ||
41 | u8 type; | ||
42 | u8 class_id; | ||
43 | u8 obj_slots; | ||
44 | u8 rsvd; | ||
45 | }; | ||
46 | |||
47 | struct nv_pmu_boardobjgrp { | ||
48 | struct nv_pmu_boardobjgrp_super super; | ||
49 | u32 obj_mask; | ||
50 | }; | ||
51 | |||
52 | struct nv_pmu_boardobjgrp_e32 { | ||
53 | struct nv_pmu_boardobjgrp_super super; | ||
54 | struct ctrl_boardobjgrp_mask_e32 obj_mask; | ||
55 | }; | ||
56 | |||
57 | struct nv_pmu_boardobjgrp_e255 { | ||
58 | struct nv_pmu_boardobjgrp_super super; | ||
59 | struct ctrl_boardobjgrp_mask_e255 obj_mask; | ||
60 | }; | ||
61 | |||
62 | struct nv_pmu_boardobj_cmd_grp_payload { | ||
63 | struct pmu_allocation_v3 dmem_buf; | ||
64 | struct flcn_mem_desc_v0 fb; | ||
65 | u8 hdr_size; | ||
66 | u8 entry_size; | ||
67 | }; | ||
68 | |||
69 | struct nv_pmu_boardobj_cmd_grp { | ||
70 | u8 cmd_type; | ||
71 | u8 pad[2]; | ||
72 | u8 class_id; | ||
73 | struct nv_pmu_boardobj_cmd_grp_payload grp; | ||
74 | }; | ||
75 | |||
76 | #define NV_PMU_BOARDOBJ_GRP_ALLOC_OFFSET \ | ||
77 | (NV_OFFSETOF(NV_PMU_BOARDOBJ_CMD_GRP, grp)) | ||
78 | |||
79 | struct nv_pmu_boardobj_cmd { | ||
80 | union { | ||
81 | u8 cmd_type; | ||
82 | struct nv_pmu_boardobj_cmd_grp grp; | ||
83 | struct nv_pmu_boardobj_cmd_grp grp_set; | ||
84 | struct nv_pmu_boardobj_cmd_grp grp_get_status; | ||
85 | }; | ||
86 | }; | ||
87 | |||
88 | struct nv_pmu_boardobj_msg_grp { | ||
89 | u8 msg_type; | ||
90 | bool b_success; | ||
91 | flcn_status flcn_status; | ||
92 | u8 class_id; | ||
93 | }; | ||
94 | |||
95 | struct nv_pmu_boardobj_msg { | ||
96 | union { | ||
97 | u8 msg_type; | ||
98 | struct nv_pmu_boardobj_msg_grp grp; | ||
99 | struct nv_pmu_boardobj_msg_grp grp_set; | ||
100 | struct nv_pmu_boardobj_msg_grp grp_get_status; | ||
101 | }; | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * Macro generating structures describing classes which implement | ||
106 | * NV_PMU_BOARDOBJGRP via the NV_PMU_BOARDBOBJ_CMD_GRP SET interface. | ||
107 | * | ||
108 | * @para _eng Name of implementing engine in which this structure is | ||
109 | * found. | ||
110 | * @param _class Class ID of Objects within Board Object Group. | ||
111 | * @param _slots Max number of elements this group can contain. | ||
112 | */ | ||
113 | #define NV_PMU_BOARDOBJ_GRP_SET_MAKE(_eng, _class, _slots) \ | ||
114 | NV_PMU_MAKE_ALIGNED_STRUCT( \ | ||
115 | nv_pmu_##_eng##_##_class##_boardobjgrp_set_header, one_structure); \ | ||
116 | NV_PMU_MAKE_ALIGNED_UNION( \ | ||
117 | nv_pmu_##_eng##_##_class##_boardobj_set_union, one_union); \ | ||
118 | struct nv_pmu_##_eng##_##_class##_boardobj_grp_set { \ | ||
119 | union nv_pmu_##_eng##_##_class##_boardobjgrp_set_header_aligned hdr; \ | ||
120 | union nv_pmu_##_eng##_##_class##_boardobj_set_union_aligned objects[(_slots)];\ | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Macro generating structures describing classes which implement | ||
125 | * NV_PMU_BOARDOBJGRP_E32 via the NV_PMU_BOARDBOBJ_CMD_GRP SET interface. | ||
126 | * | ||
127 | * @para _eng Name of implementing engine in which this structure is | ||
128 | * found. | ||
129 | * @param _class Class ID of Objects within Board Object Group. | ||
130 | */ | ||
131 | #define NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(_eng, _class) \ | ||
132 | NV_PMU_BOARDOBJ_GRP_SET_MAKE(_eng, _class, \ | ||
133 | CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) | ||
134 | |||
135 | /* | ||
136 | * Macro generating structures describing classes which implement | ||
137 | * NV_PMU_BOARDOBJGRP_E255 via the NV_PMU_BOARDBOBJ_CMD_GRP SET interface. | ||
138 | * | ||
139 | * @para _eng Name of implementing engine in which this structure is | ||
140 | * found. | ||
141 | * @param _class Class ID of Objects within Board Object Group. | ||
142 | */ | ||
143 | #define NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(_eng, _class) \ | ||
144 | NV_PMU_BOARDOBJ_GRP_SET_MAKE(_eng, _class, \ | ||
145 | CTRL_BOARDOBJGRP_E255_MAX_OBJECTS) | ||
146 | |||
147 | /* | ||
148 | * Macro generating structures for querying dynamic state for classes which | ||
149 | * implement NV_PMU_BOARDOBJGRP via the NV_PMU_BOARDOBJ_CMD_GRP GET_STATUS | ||
150 | * interface. | ||
151 | * | ||
152 | * @para _eng Name of implementing engine in which this structure is | ||
153 | * found. | ||
154 | * @param _class Class ID of Objects within Board Object Group. | ||
155 | * @param _slots Max number of elements this group can contain. | ||
156 | */ | ||
157 | #define NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE(_eng, _class, _slots) \ | ||
158 | NV_PMU_MAKE_ALIGNED_STRUCT( \ | ||
159 | nv_pmu_##_eng##_##_class##_boardobjgrp_get_status_header, struct); \ | ||
160 | NV_PMU_MAKE_ALIGNED_UNION( \ | ||
161 | nv_pmu_##_eng##_##_class##_boardobj_get_status_union, union); \ | ||
162 | struct nv_pmu_##_eng##_##_class##_boardobj_grp_get_status { \ | ||
163 | union nv_pmu_##_eng##_##_class##_boardobjgrp_get_status_header_aligned \ | ||
164 | hdr; \ | ||
165 | union nv_pmu_##_eng##_##_class##_boardobj_get_status_union_aligned \ | ||
166 | objects[(_slots)]; \ | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | * Macro generating structures for querying dynamic state for classes which | ||
171 | * implement NV_PMU_BOARDOBJGRP_E32 via the NV_PMU_BOARDOBJ_CMD_GRP GET_STATUS | ||
172 | * interface. | ||
173 | * | ||
174 | * @para _eng Name of implementing engine in which this structure is | ||
175 | * found. | ||
176 | * @param _class Class ID of Objects within Board Object Group. | ||
177 | */ | ||
178 | #define NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(_eng, _class) \ | ||
179 | NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE(_eng, _class, \ | ||
180 | CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) | ||
181 | |||
182 | /* | ||
183 | * Macro generating structures for querying dynamic state for classes which | ||
184 | * implement NV_PMU_BOARDOBJGRP_E255 via the NV_PMU_BOARDOBJ_CMD_GRP GET_STATUS | ||
185 | * interface. | ||
186 | * | ||
187 | * @para _eng Name of implementing engine in which this structure is | ||
188 | * found. | ||
189 | * @param _class Class ID of Objects within Board Object Group. | ||
190 | */ | ||
191 | #define NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E255(_eng, _class) \ | ||
192 | NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE(_eng, _class, \ | ||
193 | CTRL_BOARDOBJGRP_E255_MAX_OBJECTS) | ||
194 | |||
195 | |||
196 | #endif /* _GPMUIFBOARDOBJ_H_ */ | ||
diff --git a/drivers/gpu/nvgpu/pmuif/gpmuifclk.h b/drivers/gpu/nvgpu/pmuif/gpmuifclk.h new file mode 100644 index 00000000..36b9aace --- /dev/null +++ b/drivers/gpu/nvgpu/pmuif/gpmuifclk.h | |||
@@ -0,0 +1,414 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _GPMUIFCLK_H_ | ||
15 | #define _GPMUIFCLK_H_ | ||
16 | |||
17 | #include "gk20a/gk20a.h" | ||
18 | #include "gk20a/pmu_gk20a.h" | ||
19 | #include "ctrl/ctrlboardobj.h" | ||
20 | #include "ctrl/ctrlvolt.h" | ||
21 | #include "ctrl/ctrlperf.h" | ||
22 | #include "ctrl/ctrlclk.h" | ||
23 | #include "pmuif/gpmuifboardobj.h" | ||
24 | #include "pmuif/gpmuifvolt.h" | ||
25 | #include "gk20a/pmu_common.h" | ||
26 | |||
27 | enum nv_pmu_clk_clkwhich { | ||
28 | clkwhich_mclk = 5, | ||
29 | clkwhich_dispclk = 7, | ||
30 | clkwhich_gpc2clk = 17, | ||
31 | clkwhich_xbar2clk = 19, | ||
32 | clkwhich_sys2clk = 20, | ||
33 | clkwhich_hub2clk = 21, | ||
34 | clkwhich_pwrclk = 24, | ||
35 | clkwhich_nvdclk = 25, | ||
36 | clkwhich_pciegenclk = 31, | ||
37 | }; | ||
38 | |||
39 | /* | ||
40 | * Enumeration of BOARDOBJGRP class IDs within OBJCLK. Used as "classId" | ||
41 | * argument for communications between Kernel and PMU via the various generic | ||
42 | * BOARDOBJGRP interfaces. | ||
43 | */ | ||
44 | #define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_CLK_DOMAIN 0x00 | ||
45 | #define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_CLK_PROG 0x01 | ||
46 | #define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_VIN_DEVICE 0x02 | ||
47 | #define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_FLL_DEVICE 0x03 | ||
48 | #define NV_PMU_CLK_BOARDOBJGRP_CLASS_ID_CLK_VF_POINT 0x04 | ||
49 | |||
50 | /*! | ||
51 | * CLK_DOMAIN BOARDOBJGRP Header structure. Describes global state about the | ||
52 | * CLK_DOMAIN feature. | ||
53 | */ | ||
54 | struct nv_pmu_clk_clk_domain_boardobjgrp_set_header { | ||
55 | struct nv_pmu_boardobjgrp_e32 super; | ||
56 | u32 vbios_domains; | ||
57 | struct ctrl_boardobjgrp_mask_e32 master_domains_mask; | ||
58 | u16 cntr_sampling_periodms; | ||
59 | bool b_override_o_v_o_c; | ||
60 | bool b_debug_mode; | ||
61 | bool b_enforce_vf_monotonicity; | ||
62 | u8 volt_rails_max; | ||
63 | struct ctrl_clk_clk_delta deltas; | ||
64 | }; | ||
65 | |||
66 | struct nv_pmu_clk_clk_domain_boardobj_set { | ||
67 | struct nv_pmu_boardobj super; | ||
68 | enum nv_pmu_clk_clkwhich domain; | ||
69 | u32 api_domain; | ||
70 | u8 perf_domain_grp_idx; | ||
71 | }; | ||
72 | |||
73 | struct nv_pmu_clk_clk_domain_3x_boardobj_set { | ||
74 | struct nv_pmu_clk_clk_domain_boardobj_set super; | ||
75 | bool b_noise_aware_capable; | ||
76 | }; | ||
77 | |||
78 | struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set { | ||
79 | struct nv_pmu_clk_clk_domain_3x_boardobj_set super; | ||
80 | u16 freq_mhz; | ||
81 | }; | ||
82 | |||
83 | struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set { | ||
84 | struct nv_pmu_clk_clk_domain_3x_boardobj_set super; | ||
85 | u8 clk_prog_idx_first; | ||
86 | u8 clk_prog_idx_last; | ||
87 | u8 noise_unaware_ordering_index; | ||
88 | u8 noise_aware_ordering_index; | ||
89 | bool b_force_noise_unaware_ordering; | ||
90 | int factory_offset_khz; | ||
91 | short freq_delta_min_mhz; | ||
92 | short freq_delta_max_mhz; | ||
93 | struct ctrl_clk_clk_delta deltas; | ||
94 | }; | ||
95 | |||
96 | struct nv_pmu_clk_clk_domain_3x_master_boardobj_set { | ||
97 | struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set super; | ||
98 | u32 slave_idxs_mask; | ||
99 | }; | ||
100 | |||
101 | struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set { | ||
102 | struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set super; | ||
103 | u8 master_idx; | ||
104 | }; | ||
105 | |||
106 | union nv_pmu_clk_clk_domain_boardobj_set_union { | ||
107 | struct nv_pmu_boardobj board_obj; | ||
108 | struct nv_pmu_clk_clk_domain_boardobj_set super; | ||
109 | struct nv_pmu_clk_clk_domain_3x_boardobj_set v3x; | ||
110 | struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set v3x_fixed; | ||
111 | struct nv_pmu_clk_clk_domain_3x_prog_boardobj_set v3x_prog; | ||
112 | struct nv_pmu_clk_clk_domain_3x_master_boardobj_set v3x_master; | ||
113 | struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set v3x_slave; | ||
114 | }; | ||
115 | |||
116 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_domain); | ||
117 | |||
118 | struct nv_pmu_clk_clk_prog_boardobjgrp_set_header { | ||
119 | struct nv_pmu_boardobjgrp_e255 super; | ||
120 | u8 slave_entry_count; | ||
121 | u8 vf_entry_count; | ||
122 | }; | ||
123 | |||
124 | struct nv_pmu_clk_clk_prog_boardobj_set { | ||
125 | struct nv_pmu_boardobj super; | ||
126 | }; | ||
127 | |||
128 | struct nv_pmu_clk_clk_prog_1x_boardobj_set { | ||
129 | struct nv_pmu_clk_clk_prog_boardobj_set super; | ||
130 | u8 source; | ||
131 | u16 freq_max_mhz; | ||
132 | union ctrl_clk_clk_prog_1x_source_data source_data; | ||
133 | }; | ||
134 | |||
135 | struct nv_pmu_clk_clk_prog_1x_master_boardobj_set { | ||
136 | struct nv_pmu_clk_clk_prog_1x_boardobj_set super; | ||
137 | bool b_o_c_o_v_enabled; | ||
138 | struct ctrl_clk_clk_prog_1x_master_vf_entry vf_entries[ | ||
139 | CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES]; | ||
140 | struct ctrl_clk_clk_delta deltas; | ||
141 | }; | ||
142 | |||
143 | struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set { | ||
144 | struct nv_pmu_clk_clk_prog_1x_master_boardobj_set super; | ||
145 | struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry slave_entries[ | ||
146 | CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; | ||
147 | }; | ||
148 | |||
149 | struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set { | ||
150 | struct nv_pmu_clk_clk_prog_1x_master_boardobj_set super; | ||
151 | struct ctrl_clk_clk_prog_1x_master_table_slave_entry | ||
152 | slave_entries[CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; | ||
153 | }; | ||
154 | |||
155 | union nv_pmu_clk_clk_prog_boardobj_set_union { | ||
156 | struct nv_pmu_boardobj board_obj; | ||
157 | struct nv_pmu_clk_clk_prog_boardobj_set super; | ||
158 | struct nv_pmu_clk_clk_prog_1x_boardobj_set v1x; | ||
159 | struct nv_pmu_clk_clk_prog_1x_master_boardobj_set v1x_master; | ||
160 | struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set v1x_master_ratio; | ||
161 | struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set v1x_master_table; | ||
162 | }; | ||
163 | |||
164 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(clk, clk_prog); | ||
165 | |||
166 | struct nv_pmu_clk_lut_device_desc { | ||
167 | u8 vselect_mode; | ||
168 | u16 hysteresis_threshold; | ||
169 | }; | ||
170 | |||
171 | struct nv_pmu_clk_regime_desc { | ||
172 | u8 regime_id; | ||
173 | u16 fixed_freq_regime_limit_mhz; | ||
174 | }; | ||
175 | |||
176 | struct nv_pmu_clk_clk_fll_device_boardobjgrp_set_header { | ||
177 | struct nv_pmu_boardobjgrp_e32 super; | ||
178 | struct ctrl_boardobjgrp_mask_e32 lut_prog_master_mask; | ||
179 | u32 lut_step_size_uv; | ||
180 | u32 lut_min_voltage_uv; | ||
181 | u8 lut_num_entries; | ||
182 | u16 max_min_freq_mhz; | ||
183 | }; | ||
184 | |||
185 | struct nv_pmu_clk_clk_fll_device_boardobj_set { | ||
186 | struct nv_pmu_boardobj super; | ||
187 | u8 id; | ||
188 | u8 mdiv; | ||
189 | u8 vin_idx_logic; | ||
190 | u8 vin_idx_sram; | ||
191 | u8 rail_idx_for_lut; | ||
192 | u16 input_freq_mhz; | ||
193 | u32 clk_domain; | ||
194 | struct nv_pmu_clk_lut_device_desc lut_device; | ||
195 | struct nv_pmu_clk_regime_desc regime_desc; | ||
196 | u8 min_freq_vfe_idx; | ||
197 | u8 freq_ctrl_idx; | ||
198 | struct ctrl_boardobjgrp_mask_e32 lut_prog_broadcast_slave_mask; | ||
199 | }; | ||
200 | |||
201 | union nv_pmu_clk_clk_fll_device_boardobj_set_union { | ||
202 | struct nv_pmu_boardobj board_obj; | ||
203 | struct nv_pmu_clk_clk_fll_device_boardobj_set super; | ||
204 | }; | ||
205 | |||
206 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_fll_device); | ||
207 | |||
208 | struct nv_pmu_clk_clk_vin_device_boardobjgrp_set_header { | ||
209 | struct nv_pmu_boardobjgrp_e32 super; | ||
210 | bool b_vin_is_disable_allowed; | ||
211 | }; | ||
212 | |||
213 | struct nv_pmu_clk_clk_vin_device_boardobj_set { | ||
214 | struct nv_pmu_boardobj super; | ||
215 | u8 id; | ||
216 | u8 volt_domain; | ||
217 | u32 slope; | ||
218 | u32 intercept; | ||
219 | u32 flls_shared_mask; | ||
220 | }; | ||
221 | |||
222 | union nv_pmu_clk_clk_vin_device_boardobj_set_union { | ||
223 | struct nv_pmu_boardobj board_obj; | ||
224 | struct nv_pmu_clk_clk_vin_device_boardobj_set super; | ||
225 | }; | ||
226 | |||
227 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_vin_device); | ||
228 | |||
229 | struct nv_pmu_clk_clk_vf_point_boardobjgrp_set_header { | ||
230 | struct nv_pmu_boardobjgrp_e255 super; | ||
231 | }; | ||
232 | |||
233 | struct nv_pmu_clk_clk_vf_point_boardobj_set { | ||
234 | struct nv_pmu_boardobj super; | ||
235 | u8 vfe_equ_idx; | ||
236 | u8 volt_rail_idx; | ||
237 | }; | ||
238 | |||
239 | struct nv_pmu_clk_clk_vf_point_freq_boardobj_set { | ||
240 | struct nv_pmu_clk_clk_vf_point_boardobj_set super; | ||
241 | u16 freq_mhz; | ||
242 | int volt_delta_uv; | ||
243 | }; | ||
244 | |||
245 | struct nv_pmu_clk_clk_vf_point_volt_boardobj_set { | ||
246 | struct nv_pmu_clk_clk_vf_point_boardobj_set super; | ||
247 | u32 source_voltage_uv; | ||
248 | u8 vf_gain_vfe_equ_idx; | ||
249 | u8 clk_domain_idx; | ||
250 | int freq_delta_khz; | ||
251 | }; | ||
252 | |||
253 | union nv_pmu_clk_clk_vf_point_boardobj_set_union { | ||
254 | struct nv_pmu_boardobj board_obj; | ||
255 | struct nv_pmu_clk_clk_vf_point_boardobj_set super; | ||
256 | struct nv_pmu_clk_clk_vf_point_freq_boardobj_set freq; | ||
257 | struct nv_pmu_clk_clk_vf_point_volt_boardobj_set volt; | ||
258 | }; | ||
259 | |||
260 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(clk, clk_vf_point); | ||
261 | |||
262 | struct nv_pmu_clk_clk_vf_point_boardobjgrp_get_status_header { | ||
263 | struct nv_pmu_boardobjgrp_e255 super; | ||
264 | }; | ||
265 | |||
266 | struct nv_pmu_clk_clk_vf_point_boardobj_get_status { | ||
267 | struct nv_pmu_boardobj super; | ||
268 | struct ctrl_clk_vf_pair pair; | ||
269 | }; | ||
270 | |||
271 | struct nv_pmu_clk_clk_vf_point_volt_boardobj_get_status { | ||
272 | struct nv_pmu_clk_clk_vf_point_boardobj_get_status super; | ||
273 | u16 vf_gain_value; | ||
274 | }; | ||
275 | |||
276 | union nv_pmu_clk_clk_vf_point_boardobj_get_status_union { | ||
277 | struct nv_pmu_boardobj board_obj; | ||
278 | struct nv_pmu_clk_clk_vf_point_boardobj_get_status super; | ||
279 | struct nv_pmu_clk_clk_vf_point_volt_boardobj_get_status volt; | ||
280 | }; | ||
281 | |||
282 | NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E255(clk, clk_vf_point); | ||
283 | |||
284 | #define NV_PMU_VF_INJECT_MAX_CLOCK_DOMAINS (12) | ||
285 | |||
286 | struct nv_pmu_clk_clk_domain_list { | ||
287 | u8 num_domains; | ||
288 | struct ctrl_clk_clk_domain_list_item clk_domains[ | ||
289 | NV_PMU_VF_INJECT_MAX_CLOCK_DOMAINS]; | ||
290 | }; | ||
291 | |||
292 | struct nv_pmu_clk_vf_change_inject { | ||
293 | u8 flags; | ||
294 | struct nv_pmu_clk_clk_domain_list clk_list; | ||
295 | struct nv_pmu_volt_volt_rail_list volt_list; | ||
296 | }; | ||
297 | |||
298 | #define NV_NV_PMU_CLK_LOAD_FEATURE_VIN (0x00000002) | ||
299 | #define NV_NV_PMU_CLK_LOAD_ACTION_MASK_VIN_HW_CAL_PROGRAM_YES (0x00000001) | ||
300 | |||
301 | struct nv_pmu_clk_load_payload_freq_controllers { | ||
302 | struct ctrl_boardobjgrp_mask_e32 load_mask; | ||
303 | }; | ||
304 | |||
305 | struct nv_pmu_clk_load { | ||
306 | u8 feature; | ||
307 | u32 action_mask; | ||
308 | union { | ||
309 | struct nv_pmu_clk_load_payload_freq_controllers freq_controllers; | ||
310 | } payload; | ||
311 | }; | ||
312 | |||
313 | /* CLK CMD ID definitions. */ | ||
314 | #define NV_PMU_CLK_CMD_ID_BOARDOBJ_GRP_SET (0x00000000) | ||
315 | #define NV_PMU_CLK_CMD_ID_RPC (0x00000001) | ||
316 | #define NV_PMU_CLK_CMD_ID_BOARDOBJ_GRP_GET_STATUS (0x00000002) | ||
317 | |||
318 | #define NV_PMU_CLK_RPC_ID_LOAD (0x00000002) | ||
319 | #define NV_PMU_CLK_RPC_ID_CLK_VF_CHANGE_INJECT (0x00000001) | ||
320 | |||
321 | struct nv_pmu_clk_cmd_rpc { | ||
322 | u8 cmd_type; | ||
323 | u8 pad[3]; | ||
324 | struct nv_pmu_allocation request; | ||
325 | }; | ||
326 | |||
327 | #define NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET \ | ||
328 | (offsetof(struct nv_pmu_clk_cmd_rpc, request)) | ||
329 | |||
330 | struct nv_pmu_clk_cmd { | ||
331 | union { | ||
332 | u8 cmd_type; | ||
333 | struct nv_pmu_boardobj_cmd_grp grp_set; | ||
334 | struct nv_pmu_clk_cmd_rpc rpc; | ||
335 | struct nv_pmu_boardobj_cmd_grp grp_get_status; | ||
336 | }; | ||
337 | }; | ||
338 | |||
339 | struct nv_pmu_clk_rpc { | ||
340 | u8 function; | ||
341 | bool b_supported; | ||
342 | bool b_success; | ||
343 | flcn_status flcn_status; | ||
344 | union { | ||
345 | struct nv_pmu_clk_vf_change_inject clk_vf_change_inject; | ||
346 | struct nv_pmu_clk_load clk_load; | ||
347 | } params; | ||
348 | }; | ||
349 | |||
350 | /* CLK MSG ID definitions */ | ||
351 | #define NV_PMU_CLK_MSG_ID_BOARDOBJ_GRP_SET (0x00000000) | ||
352 | #define NV_PMU_CLK_MSG_ID_RPC (0x00000001) | ||
353 | #define NV_PMU_CLK_MSG_ID_BOARDOBJ_GRP_GET_STATUS (0x00000002) | ||
354 | |||
355 | struct nv_pmu_clk_msg_rpc { | ||
356 | u8 msg_type; | ||
357 | u8 rsvd[3]; | ||
358 | struct nv_pmu_allocation response; | ||
359 | }; | ||
360 | |||
361 | #define NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET \ | ||
362 | offsetof(struct nv_pmu_clk_msg_rpc, response) | ||
363 | |||
364 | struct nv_pmu_clk_msg { | ||
365 | union { | ||
366 | u8 msg_type; | ||
367 | struct nv_pmu_boardobj_msg_grp grp_set; | ||
368 | struct nv_pmu_clk_msg_rpc rpc; | ||
369 | struct nv_pmu_boardobj_msg_grp grp_get_status; | ||
370 | }; | ||
371 | }; | ||
372 | |||
373 | struct nv_pmu_clk_clk_vin_device_boardobjgrp_get_status_header { | ||
374 | struct nv_pmu_boardobjgrp_e32 super; | ||
375 | }; | ||
376 | |||
377 | struct nv_pmu_clk_clk_vin_device_boardobj_get_status { | ||
378 | struct nv_pmu_boardobj_query super; | ||
379 | u32 actual_voltage_uv; | ||
380 | u32 corrected_voltage_uv; | ||
381 | u8 sampled_code; | ||
382 | u8 override_code; | ||
383 | }; | ||
384 | |||
385 | union nv_pmu_clk_clk_vin_device_boardobj_get_status_union { | ||
386 | struct nv_pmu_boardobj_query board_obj; | ||
387 | struct nv_pmu_clk_clk_vin_device_boardobj_get_status super; | ||
388 | }; | ||
389 | |||
390 | NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(clk, clk_vin_device); | ||
391 | |||
392 | struct nv_pmu_clk_lut_vf_entry { | ||
393 | u32 entry; | ||
394 | }; | ||
395 | |||
396 | struct nv_pmu_clk_clk_fll_device_boardobjgrp_get_status_header { | ||
397 | struct nv_pmu_boardobjgrp_e32 super; | ||
398 | }; | ||
399 | |||
400 | struct nv_pmu_clk_clk_fll_device_boardobj_get_status { | ||
401 | struct nv_pmu_boardobj_query super; | ||
402 | u8 current_regime_id; | ||
403 | u16 min_freq_mhz; | ||
404 | struct nv_pmu_clk_lut_vf_entry lut_vf_curve[NV_UNSIGNED_ROUNDED_DIV(CTRL_CLK_LUT_NUM_ENTRIES, 2)]; | ||
405 | }; | ||
406 | |||
407 | union nv_pmu_clk_clk_fll_device_boardobj_get_status_union { | ||
408 | struct nv_pmu_boardobj_query board_obj; | ||
409 | struct nv_pmu_clk_clk_fll_device_boardobj_get_status super; | ||
410 | }; | ||
411 | |||
412 | NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(clk, clk_fll_device); | ||
413 | |||
414 | #endif /*_GPMUIFCLK_H_*/ | ||
diff --git a/drivers/gpu/nvgpu/pmuif/gpmuifperf.h b/drivers/gpu/nvgpu/pmuif/gpmuifperf.h new file mode 100644 index 00000000..b1d2f3fd --- /dev/null +++ b/drivers/gpu/nvgpu/pmuif/gpmuifperf.h | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | #ifndef _GPMUIFPERF_H_ | ||
14 | #define _GPMUIFPERF_H_ | ||
15 | |||
16 | #include "gpmuifvolt.h" | ||
17 | #include "gpmuifperfvfe.h" | ||
18 | |||
19 | /* | ||
20 | * Enumeration of BOARDOBJGRP class IDs within OBJPERF. Used as "classId" | ||
21 | * argument for communications between Kernel and PMU via the various generic | ||
22 | * BOARDOBJGRP interfaces. | ||
23 | */ | ||
24 | #define NV_PMU_PERF_BOARDOBJGRP_CLASS_ID_VFE_VAR 0x00 | ||
25 | #define NV_PMU_PERF_BOARDOBJGRP_CLASS_ID_VFE_EQU 0x01 | ||
26 | |||
27 | #define NV_PMU_PERF_CMD_ID_RPC (0x00000002) | ||
28 | #define NV_PMU_PERF_CMD_ID_BOARDOBJ_GRP_SET (0x00000003) | ||
29 | #define NV_PMU_PERF_CMD_ID_BOARDOBJ_GRP_GET_STATUS (0x00000004) | ||
30 | |||
31 | struct nv_pmu_perf_cmd_set_object { | ||
32 | u8 cmd_type; | ||
33 | u8 pad[2]; | ||
34 | u8 object_type; | ||
35 | struct nv_pmu_allocation object; | ||
36 | }; | ||
37 | |||
38 | #define NV_PMU_PERF_SET_OBJECT_ALLOC_OFFSET \ | ||
39 | (offsetof(struct nv_pmu_perf_cmd_set_object, object)) | ||
40 | |||
41 | /* RPC IDs */ | ||
42 | #define NV_PMU_PERF_RPC_ID_VFE_LOAD (0x00000001) | ||
43 | |||
44 | /*! | ||
45 | * Command requesting execution of the perf RPC. | ||
46 | */ | ||
47 | struct nv_pmu_perf_cmd_rpc { | ||
48 | u8 cmd_type; | ||
49 | u8 pad[3]; | ||
50 | struct nv_pmu_allocation request; | ||
51 | }; | ||
52 | |||
53 | #define NV_PMU_PERF_CMD_RPC_ALLOC_OFFSET \ | ||
54 | offsetof(struct nv_pmu_perf_cmd_rpc, request) | ||
55 | |||
56 | /*! | ||
57 | * Simply a union of all specific PERF commands. Forms the general packet | ||
58 | * exchanged between the Kernel and PMU when sending and receiving PERF commands | ||
59 | * (respectively). | ||
60 | */ | ||
61 | struct nv_pmu_perf_cmd { | ||
62 | union { | ||
63 | u8 cmd_type; | ||
64 | struct nv_pmu_perf_cmd_set_object set_object; | ||
65 | struct nv_pmu_boardobj_cmd_grp grp_set; | ||
66 | struct nv_pmu_boardobj_cmd_grp grp_get_status; | ||
67 | }; | ||
68 | }; | ||
69 | |||
70 | /*! | ||
71 | * Defines the data structure used to invoke PMU perf RPCs. Same structure is | ||
72 | * used to return the result of the RPC execution. | ||
73 | */ | ||
74 | struct nv_pmu_perf_rpc { | ||
75 | u8 function; | ||
76 | bool b_supported; | ||
77 | bool b_success; | ||
78 | flcn_status flcn_status; | ||
79 | union { | ||
80 | struct nv_pmu_perf_rpc_vfe_equ_eval vfe_equ_eval; | ||
81 | struct nv_pmu_perf_rpc_vfe_load vfe_load; | ||
82 | } params; | ||
83 | }; | ||
84 | |||
85 | |||
86 | /* PERF Message-type Definitions */ | ||
87 | #define NV_PMU_PERF_MSG_ID_RPC (0x00000003) | ||
88 | #define NV_PMU_PERF_MSG_ID_BOARDOBJ_GRP_SET (0x00000004) | ||
89 | #define NV_PMU_PERF_MSG_ID_BOARDOBJ_GRP_GET_STATUS (0x00000006) | ||
90 | |||
91 | /*! | ||
92 | * Message carrying the result of the perf RPC execution. | ||
93 | */ | ||
94 | struct nv_pmu_perf_msg_rpc { | ||
95 | u8 msg_type; | ||
96 | u8 rsvd[3]; | ||
97 | struct nv_pmu_allocation response; | ||
98 | }; | ||
99 | |||
100 | #define NV_PMU_PERF_MSG_RPC_ALLOC_OFFSET \ | ||
101 | (offsetof(struct nv_pmu_perf_msg_rpc, response)) | ||
102 | |||
103 | /*! | ||
104 | * Simply a union of all specific PERF messages. Forms the general packet | ||
105 | * exchanged between the Kernel and PMU when sending and receiving PERF messages | ||
106 | * (respectively). | ||
107 | */ | ||
108 | struct nv_pmu_perf_msg { | ||
109 | union { | ||
110 | u8 msg_type; | ||
111 | struct nv_pmu_perf_msg_rpc rpc; | ||
112 | struct nv_pmu_boardobj_msg_grp grp_set; | ||
113 | }; | ||
114 | }; | ||
115 | |||
116 | #endif /* _GPMUIFPERF_H_*/ | ||
diff --git a/drivers/gpu/nvgpu/pmuif/gpmuifperfvfe.h b/drivers/gpu/nvgpu/pmuif/gpmuifperfvfe.h new file mode 100644 index 00000000..6bad6445 --- /dev/null +++ b/drivers/gpu/nvgpu/pmuif/gpmuifperfvfe.h | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | #ifndef _GPMUIFPERFVFE_H_ | ||
14 | #define _GPMUIFPERFVFE_H_ | ||
15 | |||
16 | #include "gpmuifbios.h" | ||
17 | #include "gpmuifboardobj.h" | ||
18 | |||
19 | #define CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT 0x03 | ||
20 | #define NV_PMU_PERF_RPC_VFE_EQU_EVAL_VAR_COUNT_MAX 2 | ||
21 | #define NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX 16 | ||
22 | #define NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX 1 | ||
23 | |||
24 | struct nv_pmu_perf_vfe_var_value { | ||
25 | u8 var_type; | ||
26 | u8 reserved[3]; | ||
27 | u32 var_value; | ||
28 | }; | ||
29 | |||
30 | union nv_pmu_perf_vfe_equ_result { | ||
31 | u32 freq_m_hz; | ||
32 | u32 voltu_v; | ||
33 | u32 vf_gain; | ||
34 | int volt_deltau_v; | ||
35 | }; | ||
36 | |||
37 | struct nv_pmu_perf_rpc_vfe_equ_eval { | ||
38 | u8 equ_idx; | ||
39 | u8 var_count; | ||
40 | u8 output_type; | ||
41 | struct nv_pmu_perf_vfe_var_value var_values[ | ||
42 | NV_PMU_PERF_RPC_VFE_EQU_EVAL_VAR_COUNT_MAX]; | ||
43 | union nv_pmu_perf_vfe_equ_result result; | ||
44 | }; | ||
45 | |||
46 | struct nv_pmu_perf_rpc_vfe_load { | ||
47 | bool b_load; | ||
48 | }; | ||
49 | |||
50 | struct nv_pmu_perf_vfe_var_boardobjgrp_get_status_header { | ||
51 | struct nv_pmu_boardobjgrp_e32 super; | ||
52 | }; | ||
53 | |||
54 | struct nv_pmu_perf_vfe_var_get_status_super { | ||
55 | struct nv_pmu_boardobj_query board_obj; | ||
56 | }; | ||
57 | |||
58 | struct nv_pmu_perf_vfe_var_single_sensed_fuse_get_status { | ||
59 | struct nv_pmu_perf_vfe_var_get_status_super super; | ||
60 | u32 fuse_value_integer; | ||
61 | u32 fuse_value_hw_integer; | ||
62 | u8 fuse_version; | ||
63 | bool b_version_check_failed; | ||
64 | }; | ||
65 | |||
66 | union nv_pmu_perf_vfe_var_boardobj_get_status_union { | ||
67 | struct nv_pmu_boardobj_query board_obj; | ||
68 | struct nv_pmu_perf_vfe_var_get_status_super super; | ||
69 | struct nv_pmu_perf_vfe_var_single_sensed_fuse_get_status fuse_status; | ||
70 | }; | ||
71 | |||
72 | NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(perf, vfe_var); | ||
73 | |||
74 | struct nv_pmu_vfe_var { | ||
75 | struct nv_pmu_boardobj super; | ||
76 | u32 out_range_min; | ||
77 | u32 out_range_max; | ||
78 | }; | ||
79 | |||
80 | struct nv_pmu_vfe_var_derived { | ||
81 | struct nv_pmu_vfe_var super; | ||
82 | }; | ||
83 | |||
84 | struct nv_pmu_vfe_var_derived_product { | ||
85 | struct nv_pmu_vfe_var_derived super; | ||
86 | u8 var_idx0; | ||
87 | u8 var_idx1; | ||
88 | }; | ||
89 | |||
90 | struct nv_pmu_vfe_var_derived_sum { | ||
91 | struct nv_pmu_vfe_var_derived super; | ||
92 | u8 var_idx0; | ||
93 | u8 var_idx1; | ||
94 | }; | ||
95 | |||
96 | struct nv_pmu_vfe_var_single { | ||
97 | struct nv_pmu_vfe_var super; | ||
98 | u8 override_type; | ||
99 | u32 override_value; | ||
100 | }; | ||
101 | |||
102 | struct nv_pmu_vfe_var_single_frequency { | ||
103 | struct nv_pmu_vfe_var_single super; | ||
104 | }; | ||
105 | |||
106 | struct nv_pmu_vfe_var_single_sensed { | ||
107 | struct nv_pmu_vfe_var_single super; | ||
108 | }; | ||
109 | |||
110 | struct nv_pmu_vfe_var_single_sensed_fuse_info { | ||
111 | u8 segment_count; | ||
112 | union nv_pmu_bios_vfield_register_segment segments[ | ||
113 | NV_PMU_VFE_VAR_SINGLE_SENSED_FUSE_SEGMENTS_MAX]; | ||
114 | }; | ||
115 | |||
116 | struct nv_pmu_vfe_var_single_sensed_fuse_vfield_info { | ||
117 | struct nv_pmu_vfe_var_single_sensed_fuse_info fuse; | ||
118 | u32 fuse_val_default; | ||
119 | int hw_correction_scale; | ||
120 | int hw_correction_offset; | ||
121 | u8 v_field_id; | ||
122 | }; | ||
123 | |||
124 | struct nv_pmu_vfe_var_single_sensed_fuse_ver_vfield_info { | ||
125 | struct nv_pmu_vfe_var_single_sensed_fuse_info fuse; | ||
126 | u8 ver_expected; | ||
127 | bool b_ver_check; | ||
128 | bool b_use_default_on_ver_check_fail; | ||
129 | u8 v_field_id_ver; | ||
130 | }; | ||
131 | |||
132 | struct nv_pmu_vfe_var_single_sensed_fuse_override_info { | ||
133 | u32 fuse_val_override; | ||
134 | bool b_fuse_regkey_override; | ||
135 | }; | ||
136 | |||
137 | struct nv_pmu_vfe_var_single_sensed_fuse { | ||
138 | struct nv_pmu_vfe_var_single_sensed super; | ||
139 | struct nv_pmu_vfe_var_single_sensed_fuse_override_info override_info; | ||
140 | struct nv_pmu_vfe_var_single_sensed_fuse_vfield_info vfield_info; | ||
141 | struct nv_pmu_vfe_var_single_sensed_fuse_ver_vfield_info vfield_ver_info; | ||
142 | }; | ||
143 | |||
144 | struct nv_pmu_vfe_var_single_sensed_temp { | ||
145 | struct nv_pmu_vfe_var_single_sensed super; | ||
146 | u8 therm_channel_index; | ||
147 | int temp_hysteresis_positive; | ||
148 | int temp_hysteresis_negative; | ||
149 | int temp_default; | ||
150 | }; | ||
151 | |||
152 | struct nv_pmu_vfe_var_single_voltage { | ||
153 | struct nv_pmu_vfe_var_single super; | ||
154 | }; | ||
155 | |||
156 | struct nv_pmu_perf_vfe_var_boardobjgrp_set_header { | ||
157 | struct nv_pmu_boardobjgrp_e32 super; | ||
158 | u8 polling_periodms; | ||
159 | }; | ||
160 | |||
161 | union nv_pmu_perf_vfe_var_boardobj_set_union { | ||
162 | struct nv_pmu_boardobj board_obj; | ||
163 | struct nv_pmu_vfe_var var; | ||
164 | struct nv_pmu_vfe_var_derived var_derived; | ||
165 | struct nv_pmu_vfe_var_derived_product var_derived_product; | ||
166 | struct nv_pmu_vfe_var_derived_sum var_derived_sum; | ||
167 | struct nv_pmu_vfe_var_single var_single; | ||
168 | struct nv_pmu_vfe_var_single_frequency var_single_frequiency; | ||
169 | struct nv_pmu_vfe_var_single_sensed var_single_sensed; | ||
170 | struct nv_pmu_vfe_var_single_sensed_fuse var_single_sensed_fuse; | ||
171 | struct nv_pmu_vfe_var_single_sensed_temp var_single_sensed_temp; | ||
172 | struct nv_pmu_vfe_var_single_voltage var_single_voltage; | ||
173 | }; | ||
174 | |||
175 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(perf, vfe_var); | ||
176 | |||
177 | struct nv_pmu_vfe_equ { | ||
178 | struct nv_pmu_boardobj super; | ||
179 | u8 var_idx; | ||
180 | u8 equ_idx_next; | ||
181 | u8 output_type; | ||
182 | u32 out_range_min; | ||
183 | u32 out_range_max; | ||
184 | }; | ||
185 | |||
186 | struct nv_pmu_vfe_equ_compare { | ||
187 | struct nv_pmu_vfe_equ super; | ||
188 | u8 func_id; | ||
189 | u8 equ_idx_true; | ||
190 | u8 equ_idx_false; | ||
191 | u32 criteria; | ||
192 | }; | ||
193 | |||
194 | struct nv_pmu_vfe_equ_minmax { | ||
195 | struct nv_pmu_vfe_equ super; | ||
196 | bool b_max; | ||
197 | u8 equ_idx0; | ||
198 | u8 equ_idx1; | ||
199 | }; | ||
200 | |||
201 | struct nv_pmu_vfe_equ_quadratic { | ||
202 | struct nv_pmu_vfe_equ super; | ||
203 | u32 coeffs[CTRL_PERF_VFE_EQU_QUADRATIC_COEFF_COUNT]; | ||
204 | }; | ||
205 | |||
206 | struct nv_pmu_perf_vfe_equ_boardobjgrp_set_header { | ||
207 | struct nv_pmu_boardobjgrp_e255 super; | ||
208 | }; | ||
209 | |||
210 | union nv_pmu_perf_vfe_equ_boardobj_set_union { | ||
211 | struct nv_pmu_boardobj board_obj; | ||
212 | struct nv_pmu_vfe_equ equ; | ||
213 | struct nv_pmu_vfe_equ_compare equ_comapre; | ||
214 | struct nv_pmu_vfe_equ_minmax equ_minmax; | ||
215 | struct nv_pmu_vfe_equ_quadratic equ_quadratic; | ||
216 | }; | ||
217 | |||
218 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(perf, vfe_equ); | ||
219 | |||
220 | #endif /* _GPMUIFPERFVFE_H_*/ | ||
diff --git a/drivers/gpu/nvgpu/pmuif/gpmuifvolt.h b/drivers/gpu/nvgpu/pmuif/gpmuifvolt.h new file mode 100644 index 00000000..c480b1cf --- /dev/null +++ b/drivers/gpu/nvgpu/pmuif/gpmuifvolt.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | #ifndef _GPMUIFVOLT_H_ | ||
14 | #define _GPMUIFVOLT_H_ | ||
15 | |||
16 | #include "ctrl/ctrlvolt.h" | ||
17 | |||
18 | /*! | ||
19 | * Structure containing the number of voltage rails and the list of rail items | ||
20 | * @ref CTRL_PERF_VOLT_RAIL_LIST_ITEM. | ||
21 | */ | ||
22 | struct nv_pmu_volt_volt_rail_list { | ||
23 | /*! | ||
24 | * Number of VOLT_RAILs that require the voltage change. | ||
25 | */ | ||
26 | u8 num_rails; | ||
27 | /*! | ||
28 | * List of @ref CTRL_PERF_VOLT_RAIL_LIST_ITEM entries. | ||
29 | */ | ||
30 | struct ctrl_perf_volt_rail_list_item rails[2]; | ||
31 | }; | ||
32 | |||
33 | #endif /* _GPMUIFVOLT_H_*/ | ||