diff options
author | Vijayakumar Subbu <vsubbu@nvidia.com> | 2016-07-28 01:29:15 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2016-09-29 16:17:46 -0400 |
commit | b17d9708c9e9930778de43de1edf1385acb13ebd (patch) | |
tree | fc485e96cc19575d463c61c8b80a09dd89745f3f /drivers/gpu/nvgpu/boardobj | |
parent | 27b47b1969d7d9cdd3de9fd6f0131ad357f4b0fa (diff) |
gpu: nvgpu: Add dGPU clocks support
JIRA DNVGPU-45
Change-Id: I237ce81e31b036c05c82d46eea8694ffe1c2e3df
Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com>
Signed-off-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-on: http://git-master/r/1205849
(cherry picked from commit 9a4006f76b75a8ad525e7aa5ad1f609aaae49126)
Reviewed-on: http://git-master/r/1227256
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/boardobj')
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobj.c | 80 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobj.h | 83 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrp.c | 697 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrp.h | 390 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.c | 92 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrp_e255.h | 45 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.c | 91 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrp_e32.h | 59 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrpmask.c | 357 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobjgrpmask.h | 110 |
10 files changed, 2004 insertions, 0 deletions
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 | ||