vcprop_subr.c revision 1.10 1 1.10 mlelstv /* $NetBSD: vcprop_subr.c,v 1.10 2021/03/08 13:53:08 mlelstv 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.10 mlelstv __KERNEL_RCSID(0, "$NetBSD: vcprop_subr.c,v 1.10 2021/03/08 13:53:08 mlelstv 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 1.10 mlelstv
404 1.10 mlelstv int
405 1.10 mlelstv rpi_fb_get_pixelorder(uint32_t *orderp)
406 1.10 mlelstv {
407 1.10 mlelstv int error;
408 1.10 mlelstv uint32_t res;
409 1.10 mlelstv
410 1.10 mlelstv
411 1.10 mlelstv struct __aligned(16) {
412 1.10 mlelstv struct vcprop_buffer_hdr vb_hdr;
413 1.10 mlelstv struct vcprop_tag_fbpixelorder vbt_po;
414 1.10 mlelstv struct vcprop_tag end;
415 1.10 mlelstv } vb_pixelorder =
416 1.10 mlelstv {
417 1.10 mlelstv .vb_hdr = {
418 1.10 mlelstv .vpb_len = htole32(sizeof(vb_pixelorder)),
419 1.10 mlelstv .vpb_rcode = htole32(VCPROP_PROCESS_REQUEST),
420 1.10 mlelstv },
421 1.10 mlelstv .vbt_po = {
422 1.10 mlelstv .tag = {
423 1.10 mlelstv .vpt_tag = htole32(VCPROPTAG_GET_FB_PIXEL_ORDER),
424 1.10 mlelstv .vpt_len = htole32(VCPROPTAG_LEN(
425 1.10 mlelstv vb_pixelorder.vbt_po)),
426 1.10 mlelstv .vpt_rcode = htole32(VCPROPTAG_REQUEST),
427 1.10 mlelstv },
428 1.10 mlelstv },
429 1.10 mlelstv .end = {
430 1.10 mlelstv .vpt_tag = htole32(VCPROPTAG_NULL),
431 1.10 mlelstv },
432 1.10 mlelstv };
433 1.10 mlelstv
434 1.10 mlelstv error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_pixelorder,
435 1.10 mlelstv sizeof(vb_pixelorder), &res);
436 1.10 mlelstv #ifdef RPI_IOCTL_DEBUG
437 1.10 mlelstv printf("%s: %d %d %08x %08x\n", __func__,
438 1.10 mlelstv le32toh(vb_pixelorder.vbt_po.order), error, res,
439 1.10 mlelstv le32toh(vb_pixelorder.vbt_po.tag.vpt_rcode));
440 1.10 mlelstv #endif
441 1.10 mlelstv if (error)
442 1.10 mlelstv return error;
443 1.10 mlelstv
444 1.10 mlelstv if (!vcprop_buffer_success_p(&vb_pixelorder.vb_hdr) ||
445 1.10 mlelstv !vcprop_tag_success_p(&vb_pixelorder.vbt_po.tag)) {
446 1.10 mlelstv return EIO;
447 1.10 mlelstv }
448 1.10 mlelstv
449 1.10 mlelstv *orderp = vb_pixelorder.vbt_po.order;
450 1.10 mlelstv
451 1.10 mlelstv return 0;
452 1.10 mlelstv }
453 1.10 mlelstv
454 1.10 mlelstv int
455 1.10 mlelstv rpi_fb_set_pixelorder(uint32_t order)
456 1.10 mlelstv {
457 1.10 mlelstv int error;
458 1.10 mlelstv uint32_t res;
459 1.10 mlelstv
460 1.10 mlelstv
461 1.10 mlelstv struct __aligned(16) {
462 1.10 mlelstv struct vcprop_buffer_hdr vb_hdr;
463 1.10 mlelstv struct vcprop_tag_fbpixelorder vbt_po;
464 1.10 mlelstv struct vcprop_tag end;
465 1.10 mlelstv } vb_pixelorder =
466 1.10 mlelstv {
467 1.10 mlelstv .vb_hdr = {
468 1.10 mlelstv .vpb_len = htole32(sizeof(vb_pixelorder)),
469 1.10 mlelstv .vpb_rcode = htole32(VCPROP_PROCESS_REQUEST),
470 1.10 mlelstv },
471 1.10 mlelstv .vbt_po = {
472 1.10 mlelstv .tag = {
473 1.10 mlelstv .vpt_tag = htole32(VCPROPTAG_SET_FB_PIXEL_ORDER),
474 1.10 mlelstv .vpt_len = htole32(VCPROPTAG_LEN(
475 1.10 mlelstv vb_pixelorder.vbt_po)),
476 1.10 mlelstv .vpt_rcode = htole32(VCPROPTAG_REQUEST),
477 1.10 mlelstv },
478 1.10 mlelstv .order = order
479 1.10 mlelstv },
480 1.10 mlelstv .end = {
481 1.10 mlelstv .vpt_tag = htole32(VCPROPTAG_NULL),
482 1.10 mlelstv },
483 1.10 mlelstv };
484 1.10 mlelstv
485 1.10 mlelstv error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_pixelorder,
486 1.10 mlelstv sizeof(vb_pixelorder), &res);
487 1.10 mlelstv #ifdef RPI_IOCTL_DEBUG
488 1.10 mlelstv printf("%s: %d %d %08x %08x\n", __func__,
489 1.10 mlelstv le32toh(vb_pixelorder.vbt_po.order), error, res,
490 1.10 mlelstv le32toh(vb_pixelorder.vbt_po.tag.vpt_rcode));
491 1.10 mlelstv #endif
492 1.10 mlelstv if (error)
493 1.10 mlelstv return error;
494 1.10 mlelstv
495 1.10 mlelstv if (!vcprop_buffer_success_p(&vb_pixelorder.vb_hdr) ||
496 1.10 mlelstv !vcprop_tag_success_p(&vb_pixelorder.vbt_po.tag)) {
497 1.10 mlelstv return EIO;
498 1.10 mlelstv }
499 1.10 mlelstv
500 1.10 mlelstv return 0;
501 1.10 mlelstv }
502 1.10 mlelstv
503 1.10 mlelstv int
504 1.10 mlelstv rpi_set_domain(uint32_t domain, uint32_t state)
505 1.10 mlelstv {
506 1.10 mlelstv int error;
507 1.10 mlelstv uint32_t tag, res;
508 1.10 mlelstv
509 1.10 mlelstv tag = VCPROPTAG_SET_DOMAIN_STATE;
510 1.10 mlelstv if (domain == VCPROP_DOMAIN_USB) {
511 1.10 mlelstv /* use old interface */
512 1.10 mlelstv tag = VCPROPTAG_SET_POWERSTATE;
513 1.10 mlelstv domain = VCPROP_POWER_USB;
514 1.10 mlelstv }
515 1.10 mlelstv
516 1.10 mlelstv /*
517 1.10 mlelstv * might as well put it here since we need to re-init it every time
518 1.10 mlelstv * and it's not like this is going to be called very often anyway
519 1.10 mlelstv */
520 1.10 mlelstv struct __aligned(16) {
521 1.10 mlelstv struct vcprop_buffer_hdr vb_hdr;
522 1.10 mlelstv struct vcprop_tag_powerstate vbt_power;
523 1.10 mlelstv struct vcprop_tag end;
524 1.10 mlelstv } vb_setpower =
525 1.10 mlelstv {
526 1.10 mlelstv .vb_hdr = {
527 1.10 mlelstv .vpb_len = sizeof(vb_setpower),
528 1.10 mlelstv .vpb_rcode = VCPROP_PROCESS_REQUEST,
529 1.10 mlelstv },
530 1.10 mlelstv .vbt_power = {
531 1.10 mlelstv .tag = {
532 1.10 mlelstv .vpt_tag = tag,
533 1.10 mlelstv .vpt_len = VCPROPTAG_LEN(vb_setpower.vbt_power),
534 1.10 mlelstv .vpt_rcode = VCPROPTAG_REQUEST,
535 1.10 mlelstv },
536 1.10 mlelstv .id = domain,
537 1.10 mlelstv .state = state
538 1.10 mlelstv },
539 1.10 mlelstv .end = {
540 1.10 mlelstv .vpt_tag = VCPROPTAG_NULL,
541 1.10 mlelstv },
542 1.10 mlelstv };
543 1.10 mlelstv
544 1.10 mlelstv error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setpower,
545 1.10 mlelstv sizeof(vb_setpower), &res);
546 1.10 mlelstv #ifdef RPI_IOCTL_DEBUG
547 1.10 mlelstv printf("%s: %08x %08x %d %08x %08x %d %d %08x %08x\n", __func__,
548 1.10 mlelstv tag, domain, state,
549 1.10 mlelstv vb_setpower.vbt_power.tag.vpt_tag,
550 1.10 mlelstv vb_setpower.vbt_power.id,
551 1.10 mlelstv vb_setpower.vbt_power.state,
552 1.10 mlelstv error, res,
553 1.10 mlelstv vb_setpower.vbt_power.tag.vpt_rcode);
554 1.10 mlelstv #endif
555 1.10 mlelstv if (error)
556 1.10 mlelstv return error;
557 1.10 mlelstv
558 1.10 mlelstv if (!vcprop_buffer_success_p(&vb_setpower.vb_hdr) ||
559 1.10 mlelstv !vcprop_tag_success_p(&vb_setpower.vbt_power.tag)) {
560 1.10 mlelstv return EIO;
561 1.10 mlelstv }
562 1.10 mlelstv
563 1.10 mlelstv return 0;
564 1.10 mlelstv }
565 1.10 mlelstv
566 1.10 mlelstv int
567 1.10 mlelstv rpi_get_domain(uint32_t domain, uint32_t *statep)
568 1.10 mlelstv {
569 1.10 mlelstv int error;
570 1.10 mlelstv uint32_t tag, res;
571 1.10 mlelstv
572 1.10 mlelstv tag = VCPROPTAG_GET_DOMAIN_STATE;
573 1.10 mlelstv if (domain == VCPROP_DOMAIN_USB) {
574 1.10 mlelstv /* use old interface */
575 1.10 mlelstv tag = VCPROPTAG_GET_POWERSTATE;
576 1.10 mlelstv domain = VCPROP_POWER_USB;
577 1.10 mlelstv }
578 1.10 mlelstv
579 1.10 mlelstv /*
580 1.10 mlelstv * might as well put it here since we need to re-init it every time
581 1.10 mlelstv * and it's not like this is going to be called very often anyway
582 1.10 mlelstv */
583 1.10 mlelstv struct __aligned(16) {
584 1.10 mlelstv struct vcprop_buffer_hdr vb_hdr;
585 1.10 mlelstv struct vcprop_tag_powerstate vbt_power;
586 1.10 mlelstv struct vcprop_tag end;
587 1.10 mlelstv } vb_setpower =
588 1.10 mlelstv {
589 1.10 mlelstv .vb_hdr = {
590 1.10 mlelstv .vpb_len = sizeof(vb_setpower),
591 1.10 mlelstv .vpb_rcode = VCPROP_PROCESS_REQUEST,
592 1.10 mlelstv },
593 1.10 mlelstv .vbt_power = {
594 1.10 mlelstv .tag = {
595 1.10 mlelstv .vpt_tag = tag,
596 1.10 mlelstv .vpt_len = VCPROPTAG_LEN(vb_setpower.vbt_power),
597 1.10 mlelstv .vpt_rcode = VCPROPTAG_REQUEST,
598 1.10 mlelstv },
599 1.10 mlelstv .id = domain,
600 1.10 mlelstv .state = ~0
601 1.10 mlelstv },
602 1.10 mlelstv .end = {
603 1.10 mlelstv .vpt_tag = VCPROPTAG_NULL,
604 1.10 mlelstv },
605 1.10 mlelstv };
606 1.10 mlelstv
607 1.10 mlelstv error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setpower,
608 1.10 mlelstv sizeof(vb_setpower), &res);
609 1.10 mlelstv #ifdef RPI_IOCTL_DEBUG
610 1.10 mlelstv printf("%s: %08x %08x %d %08x %08x %d %d %08x %08x\n", __func__,
611 1.10 mlelstv tag, domain, *statep,
612 1.10 mlelstv vb_setpower.vbt_power.tag.vpt_tag,
613 1.10 mlelstv vb_setpower.vbt_power.id,
614 1.10 mlelstv vb_setpower.vbt_power.state,
615 1.10 mlelstv error, res,
616 1.10 mlelstv vb_setpower.vbt_power.tag.vpt_rcode);
617 1.10 mlelstv #endif
618 1.10 mlelstv if (error)
619 1.10 mlelstv return error;
620 1.10 mlelstv
621 1.10 mlelstv if (!vcprop_buffer_success_p(&vb_setpower.vb_hdr) ||
622 1.10 mlelstv !vcprop_tag_success_p(&vb_setpower.vbt_power.tag)) {
623 1.10 mlelstv return EIO;
624 1.10 mlelstv }
625 1.10 mlelstv
626 1.10 mlelstv *statep = vb_setpower.vbt_power.state;
627 1.10 mlelstv
628 1.10 mlelstv return 0;
629 1.10 mlelstv }
630 1.10 mlelstv
631 1.10 mlelstv int
632 1.10 mlelstv rpi_vchiq_init(uint32_t *channelbasep)
633 1.10 mlelstv {
634 1.10 mlelstv int error;
635 1.10 mlelstv uint32_t tag, res;
636 1.10 mlelstv struct __aligned(16) {
637 1.10 mlelstv struct vcprop_buffer_hdr vb_hdr;
638 1.10 mlelstv struct vcprop_tag_vchiqinit vbt_vchiq;
639 1.10 mlelstv struct vcprop_tag end;
640 1.10 mlelstv } vb;
641 1.10 mlelstv
642 1.10 mlelstv tag = VCPROPTAG_VCHIQ_INIT;
643 1.10 mlelstv
644 1.10 mlelstv VCPROP_INIT_REQUEST(vb);
645 1.10 mlelstv VCPROP_INIT_TAG(vb.vbt_vchiq, tag);
646 1.10 mlelstv vb.vbt_vchiq.base = *channelbasep;
647 1.10 mlelstv
648 1.10 mlelstv error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb, sizeof(vb), &res);
649 1.10 mlelstv if (error)
650 1.10 mlelstv return error;
651 1.10 mlelstv
652 1.10 mlelstv if (!vcprop_buffer_success_p(&vb.vb_hdr) ||
653 1.10 mlelstv !vcprop_tag_success_p(&vb.vbt_vchiq.tag)) {
654 1.10 mlelstv return EIO;
655 1.10 mlelstv }
656 1.10 mlelstv *channelbasep = vb.vbt_vchiq.base;
657 1.10 mlelstv
658 1.10 mlelstv return 0;
659 1.10 mlelstv }
660 1.10 mlelstv
661 1.10 mlelstv int
662 1.10 mlelstv rpi_notify_xhci_reset(uint32_t address)
663 1.10 mlelstv {
664 1.10 mlelstv int error;
665 1.10 mlelstv uint32_t tag, res;
666 1.10 mlelstv struct __aligned(16) {
667 1.10 mlelstv struct vcprop_buffer_hdr vb_hdr;
668 1.10 mlelstv struct vcprop_tag_notifyxhcireset vbt_nhr;
669 1.10 mlelstv struct vcprop_tag end;
670 1.10 mlelstv } vb;
671 1.10 mlelstv
672 1.10 mlelstv tag = VCPROPTAG_NOTIFY_XHCI_RESET;
673 1.10 mlelstv
674 1.10 mlelstv VCPROP_INIT_REQUEST(vb);
675 1.10 mlelstv VCPROP_INIT_TAG(vb.vbt_nhr, tag);
676 1.10 mlelstv vb.vbt_nhr.deviceaddress = address;
677 1.10 mlelstv
678 1.10 mlelstv error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb, sizeof(vb), &res);
679 1.10 mlelstv if (error)
680 1.10 mlelstv return error;
681 1.10 mlelstv
682 1.10 mlelstv if (!vcprop_buffer_success_p(&vb.vb_hdr) ||
683 1.10 mlelstv !vcprop_tag_success_p(&vb.vbt_nhr.tag)) {
684 1.10 mlelstv return EIO;
685 1.10 mlelstv }
686 1.10 mlelstv
687 1.10 mlelstv return 0;
688 1.10 mlelstv }
689 1.10 mlelstv
690