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