vcprop_subr.c revision 1.3.2.2 1 /* $NetBSD: vcprop_subr.c,v 1.3.2.2 2017/12/03 11:36:06 jdolecek Exp $ */
2
3 /*
4 * Copyright (c) 2014 Michael Lorenz
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /*
29 * Mailbox property interface wrapper functions
30 */
31
32 #include <sys/param.h>
33 #include <sys/device.h>
34 #include <sys/bus.h>
35
36 #include <uvm/uvm_extern.h>
37
38 #include <arm/arm32/machdep.h>
39
40 #include <arm/broadcom/bcm2835reg.h>
41 #include <arm/broadcom/bcm2835var.h>
42 #include <arm/broadcom/bcm2835_pmvar.h>
43 #include <arm/broadcom/bcm2835_mbox.h>
44
45 #include <evbarm/rpi/vcio.h>
46 #include <evbarm/rpi/vcpm.h>
47 #include <evbarm/rpi/vcprop.h>
48
49 #include <evbarm/rpi/rpi.h>
50
51 #include <dev/wscons/wsconsio.h>
52
53 int
54 rpi_fb_set_video(int b)
55 {
56 int error;
57 uint32_t res;
58
59 /*
60 * might as well put it here since we need to re-init it every time
61 * and it's not like this is going to be called very often anyway
62 */
63 struct __aligned(16) {
64 struct vcprop_buffer_hdr vb_hdr;
65 struct vcprop_tag_blankscreen vbt_blank;
66 struct vcprop_tag end;
67 } vb_setblank =
68 {
69 .vb_hdr = {
70 .vpb_len = sizeof(vb_setblank),
71 .vpb_rcode = VCPROP_PROCESS_REQUEST,
72 },
73 .vbt_blank = {
74 .tag = {
75 .vpt_tag = VCPROPTAG_BLANK_SCREEN,
76 .vpt_len = VCPROPTAG_LEN(vb_setblank.vbt_blank),
77 .vpt_rcode = VCPROPTAG_REQUEST,
78 },
79 .state = (b != 0) ? VCPROP_BLANK_OFF : VCPROP_BLANK_ON,
80 },
81 .end = {
82 .vpt_tag = VCPROPTAG_NULL,
83 },
84 };
85
86 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setblank,
87 sizeof(vb_setblank), &res);
88 #ifdef RPI_IOCTL_DEBUG
89 printf("%s: %d %d %d %08x %08x\n", __func__, b,
90 vb_setblank.vbt_blank.state, error, res,
91 vb_setblank.vbt_blank.tag.vpt_rcode);
92 #endif
93 if (error)
94 return error;
95
96 if (!vcprop_buffer_success_p(&vb_setblank.vb_hdr) ||
97 !vcprop_tag_success_p(&vb_setblank.vbt_blank.tag)) {
98 return EIO;
99 }
100
101 return 0;
102 }
103
104 uint32_t
105 rpi_alloc_mem(uint32_t size, uint32_t align, uint32_t flags)
106 {
107 int error;
108 uint32_t res;
109
110 struct __aligned(16) {
111 struct vcprop_buffer_hdr vb_hdr;
112 struct vcprop_tag_allocmem vbt_am;
113 struct vcprop_tag end;
114 } vb_allocmem =
115 {
116 .vb_hdr = {
117 .vpb_len = sizeof(vb_allocmem),
118 .vpb_rcode = VCPROP_PROCESS_REQUEST,
119 },
120 .vbt_am = {
121 .tag = {
122 .vpt_tag = VCPROPTAG_ALLOCMEM,
123 .vpt_len = VCPROPTAG_LEN(vb_allocmem.vbt_am),
124 .vpt_rcode = VCPROPTAG_REQUEST,
125 },
126 .size = size,
127 .align = align,
128 .flags = flags,
129 },
130 .end = {
131 .vpt_tag = VCPROPTAG_NULL,
132 },
133 };
134
135 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_allocmem,
136 sizeof(vb_allocmem), &res);
137 #ifdef RPI_IOCTL_DEBUG
138 printf("%s: %d %d %08x %08x\n", __func__,
139 vb_allocmem.vbt_am.size, error, res,
140 vb_allocmem.vbt_am.tag.vpt_rcode);
141 #endif
142 if (error)
143 return error;
144
145 if (!vcprop_buffer_success_p(&vb_allocmem.vb_hdr) ||
146 !vcprop_tag_success_p(&vb_allocmem.vbt_am.tag)) {
147 return EIO;
148 }
149
150 /* Return the handle from the VC */
151 return vb_allocmem.vbt_am.size;
152 }
153
154 bus_addr_t
155 rpi_lock_mem(uint32_t handle)
156 {
157 int error;
158 uint32_t res;
159
160 struct __aligned(16) {
161 struct vcprop_buffer_hdr vb_hdr;
162 struct vcprop_tag_lockmem vbt_lm;
163 struct vcprop_tag end;
164 } vb_lockmem =
165 {
166 .vb_hdr = {
167 .vpb_len = sizeof(vb_lockmem),
168 .vpb_rcode = VCPROP_PROCESS_REQUEST,
169 },
170 .vbt_lm = {
171 .tag = {
172 .vpt_tag = VCPROPTAG_LOCKMEM,
173 .vpt_len = VCPROPTAG_LEN(vb_lockmem.vbt_lm),
174 .vpt_rcode = VCPROPTAG_REQUEST,
175 },
176 .handle = handle,
177 },
178 .end = {
179 .vpt_tag = VCPROPTAG_NULL,
180 },
181 };
182
183 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_lockmem,
184 sizeof(vb_lockmem), &res);
185 #ifdef RPI_IOCTL_DEBUG
186 printf("%s: %d %d %08x %08x\n", __func__,
187 vb_lockmem.vbt_lm.handle, error, res,
188 vb_lockmem.vbt_lm.tag.vpt_rcode);
189 #endif
190 if (error)
191 return 0;
192
193 if (!vcprop_buffer_success_p(&vb_lockmem.vb_hdr) ||
194 !vcprop_tag_success_p(&vb_lockmem.vbt_lm.tag)) {
195 return 0;
196 }
197
198 return vb_lockmem.vbt_lm.handle;
199 }
200
201 int
202 rpi_unlock_mem(uint32_t handle)
203 {
204 int error;
205 uint32_t res;
206
207 struct __aligned(16) {
208 struct vcprop_buffer_hdr vb_hdr;
209 struct vcprop_tag_lockmem vbt_lm;
210 struct vcprop_tag end;
211 } vb_unlockmem =
212 {
213 .vb_hdr = {
214 .vpb_len = sizeof(vb_unlockmem),
215 .vpb_rcode = VCPROP_PROCESS_REQUEST,
216 },
217 .vbt_lm = {
218 .tag = {
219 .vpt_tag = VCPROPTAG_UNLOCKMEM,
220 .vpt_len = VCPROPTAG_LEN(vb_unlockmem.vbt_lm),
221 .vpt_rcode = VCPROPTAG_REQUEST,
222 },
223 .handle = handle,
224 },
225 .end = {
226 .vpt_tag = VCPROPTAG_NULL,
227 },
228 };
229
230 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_unlockmem,
231 sizeof(vb_unlockmem), &res);
232 #ifdef RPI_IOCTL_DEBUG
233 printf("%s: %d %d %08x %08x\n", __func__,
234 vb_unlockmem.vbt_lm.handle, error, res,
235 vb_unlockmem.vbt_lm.tag.vpt_rcode);
236 #endif
237 if (error)
238 return error;
239
240 if (!vcprop_buffer_success_p(&vb_unlockmem.vb_hdr) ||
241 !vcprop_tag_success_p(&vb_unlockmem.vbt_lm.tag)) {
242 return EIO;
243 }
244
245 return 0;
246 }
247
248 int
249 rpi_release_mem(uint32_t handle)
250 {
251 int error;
252 uint32_t res;
253
254 struct __aligned(16) {
255 struct vcprop_buffer_hdr vb_hdr;
256 struct vcprop_tag_lockmem vbt_lm;
257 struct vcprop_tag end;
258 } vb_releasemem =
259 {
260 .vb_hdr = {
261 .vpb_len = sizeof(vb_releasemem),
262 .vpb_rcode = VCPROP_PROCESS_REQUEST,
263 },
264 .vbt_lm = {
265 .tag = {
266 .vpt_tag = VCPROPTAG_RELEASEMEM,
267 .vpt_len = VCPROPTAG_LEN(vb_releasemem.vbt_lm),
268 .vpt_rcode = VCPROPTAG_REQUEST,
269 },
270 .handle = handle,
271 },
272 .end = {
273 .vpt_tag = VCPROPTAG_NULL,
274 },
275 };
276
277 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_releasemem,
278 sizeof(vb_releasemem), &res);
279 #ifdef RPI_IOCTL_DEBUG
280 printf("%s: %d %d %08x %08x\n", __func__,
281 vb_releasemem.vbt_lm.handle, error, res,
282 vb_releasemem.vbt_lm.tag.vpt_rcode);
283 #endif
284 if (error)
285 return error;
286
287 if (!vcprop_buffer_success_p(&vb_releasemem.vb_hdr) ||
288 !vcprop_tag_success_p(&vb_releasemem.vbt_lm.tag)) {
289 return EIO;
290 }
291
292 return 0;
293 }
294
295 int
296 rpi_fb_movecursor(int x, int y, int on)
297 {
298 int error;
299 uint32_t res;
300
301 struct __aligned(16) {
302 struct vcprop_buffer_hdr vb_hdr;
303 struct vcprop_tag_cursorstate vbt_cs;
304 struct vcprop_tag end;
305 } vb_cursorstate =
306 {
307 .vb_hdr = {
308 .vpb_len = sizeof(vb_cursorstate),
309 .vpb_rcode = VCPROP_PROCESS_REQUEST,
310 },
311 .vbt_cs = {
312 .tag = {
313 .vpt_tag = VCPROPTAG_SET_CURSOR_STATE,
314 .vpt_len = VCPROPTAG_LEN(vb_cursorstate.vbt_cs),
315 .vpt_rcode = VCPROPTAG_REQUEST,
316 },
317 .enable = (on != 0) ? 1 : 0,
318 .x = x,
319 .y = y,
320 .flags = 1,
321 },
322 .end = {
323 .vpt_tag = VCPROPTAG_NULL,
324 },
325 };
326
327 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_cursorstate,
328 sizeof(vb_cursorstate), &res);
329 #ifdef RPI_IOCTL_DEBUG
330 printf("%s: %08x %d %08x %08x\n", __func__,
331 vb_cursorstate.vbt_cs.enable, error, res,
332 vb_cursorstate.vbt_cs.tag.vpt_rcode);
333 #endif
334 if (error)
335 return error;
336
337 if (!vcprop_buffer_success_p(&vb_cursorstate.vb_hdr) ||
338 !vcprop_tag_success_p(&vb_cursorstate.vbt_cs.tag)) {
339 return EIO;
340 }
341
342 return 0;
343 }
344
345 int
346 rpi_fb_initcursor(bus_addr_t pixels, int hx, int hy)
347 {
348 int error;
349 uint32_t res;
350
351
352 struct __aligned(16) {
353 struct vcprop_buffer_hdr vb_hdr;
354 struct vcprop_tag_cursorinfo vbt_ci;
355 struct vcprop_tag end;
356 } vb_cursorinfo =
357 {
358 .vb_hdr = {
359 .vpb_len = sizeof(vb_cursorinfo),
360 .vpb_rcode = VCPROP_PROCESS_REQUEST,
361 },
362 .vbt_ci = {
363 .tag = {
364 .vpt_tag = VCPROPTAG_SET_CURSOR_INFO,
365 .vpt_len = VCPROPTAG_LEN(vb_cursorinfo.vbt_ci),
366 .vpt_rcode = VCPROPTAG_REQUEST,
367 },
368 .width = 64,
369 .height = 64,
370 .format = 0,
371 .pixels = pixels,
372 .hotspot_x = hx,
373 .hotspot_y = hy,
374 },
375 .end = {
376 .vpt_tag = VCPROPTAG_NULL,
377 },
378 };
379
380 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_cursorinfo,
381 sizeof(vb_cursorinfo), &res);
382 #ifdef RPI_IOCTL_DEBUG
383 printf("%s: %d %d %08x %08x\n", __func__,
384 vb_cursorinfo.vbt_ci.width, error, res,
385 vb_cursorinfo.vbt_ci.tag.vpt_rcode);
386 #endif
387 if (error)
388 return error;
389
390 if (!vcprop_buffer_success_p(&vb_cursorinfo.vb_hdr) ||
391 !vcprop_tag_success_p(&vb_cursorinfo.vbt_ci.tag)) {
392 return EIO;
393 }
394
395 return 0;
396 }
397