Home | History | Annotate | Line # | Download | only in rpi
      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