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