Module Name: src Committed By: mlelstv Date: Mon Mar 8 13:53:08 UTC 2021
Modified Files: src/sys/arch/evbarm/rpi: rpi_vcmbox.c vcprop.h vcprop_subr.c Log Message: Add some firmware support functions and define more properties - framebuffer - power management - vchiq init - RPI4 USB firmware support To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/rpi/rpi_vcmbox.c cvs rdiff -u -r1.19 -r1.20 src/sys/arch/evbarm/rpi/vcprop.h cvs rdiff -u -r1.9 -r1.10 src/sys/arch/evbarm/rpi/vcprop_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/evbarm/rpi/rpi_vcmbox.c diff -u src/sys/arch/evbarm/rpi/rpi_vcmbox.c:1.7 src/sys/arch/evbarm/rpi/rpi_vcmbox.c:1.8 --- src/sys/arch/evbarm/rpi/rpi_vcmbox.c:1.7 Tue Dec 1 04:14:31 2020 +++ src/sys/arch/evbarm/rpi/rpi_vcmbox.c Mon Mar 8 13:53:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: rpi_vcmbox.c,v 1.7 2020/12/01 04:14:31 rin Exp $ */ +/* $NetBSD: rpi_vcmbox.c,v 1.8 2021/03/08 13:53:08 mlelstv Exp $ */ /*- * Copyright (c) 2013 Jared D. McNeill <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rpi_vcmbox.c,v 1.7 2020/12/01 04:14:31 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rpi_vcmbox.c,v 1.8 2021/03/08 13:53:08 mlelstv Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -65,19 +65,8 @@ struct vcmbox_clockrate_request { #define RATE2MHZ(rate) ((rate) / 1000000) #define MHZ2RATE(mhz) ((mhz) * 1000000) -#define VCMBOX_INIT_REQUEST(req) \ - do { \ - memset(&(req), 0, sizeof((req))); \ - (req).vb_hdr.vpb_len = htole32(sizeof((req))); \ - (req).vb_hdr.vpb_rcode = htole32(VCPROP_PROCESS_REQUEST);\ - (req).end.vpt_tag = htole32(VCPROPTAG_NULL); \ - } while (0) -#define VCMBOX_INIT_TAG(s, t) \ - do { \ - (s).tag.vpt_tag = htole32(t); \ - (s).tag.vpt_rcode = htole32(VCPROPTAG_REQUEST); \ - (s).tag.vpt_len = htole32(VCPROPTAG_LEN(s)); \ - } while (0) +#define VCMBOX_INIT_REQUEST(r) VCPROP_INIT_REQUEST(r) +#define VCMBOX_INIT_TAG(s, t) VCPROP_INIT_TAG(s, t) struct vcmbox_softc { device_t sc_dev; Index: src/sys/arch/evbarm/rpi/vcprop.h diff -u src/sys/arch/evbarm/rpi/vcprop.h:1.19 src/sys/arch/evbarm/rpi/vcprop.h:1.20 --- src/sys/arch/evbarm/rpi/vcprop.h:1.19 Tue Dec 1 04:14:31 2020 +++ src/sys/arch/evbarm/rpi/vcprop.h Mon Mar 8 13:53:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: vcprop.h,v 1.19 2020/12/01 04:14:31 rin Exp $ */ +/* $NetBSD: vcprop.h,v 1.20 2021/03/08 13:53:08 mlelstv Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -44,6 +44,8 @@ struct vcprop_tag { uint32_t vpt_tag; #define VCPROPTAG_NULL 0x00000000 #define VCPROPTAG_GET_FIRMWAREREV 0x00000001 +#define VCPROPTAG_GET_FIRMWAREVARIANT 0x00000002 +#define VCPROPTAG_GET_FIRMWAREHASH 0x00000003 #define VCPROPTAG_GET_BOARDMODEL 0x00010001 #define VCPROPTAG_GET_BOARDREVISION 0x00010002 #define VCPROPTAG_GET_MACADDRESS 0x00010003 @@ -65,6 +67,11 @@ struct vcprop_tag { #define VCPROPTAG_GET_TURBO 0x00030009 #define VCPROPTAG_SET_TURBO 0x00038009 +#define VCPROPTAG_GET_STC 0x0003000b +#define VCPROPTAG_GET_THROTTLED 0x00030046 +#define VCPROPTAG_GET_CLOCK_MEASURED 0x00030047 +#define VCPROPTAG_NOTIFY_REBOOT 0x00030048 + #define VCPROPTAG_GET_VOLTAGE 0x00030003 #define VCPROPTAG_SET_VOLTAGE 0x00038003 #define VCPROPTAG_GET_MIN_VOLTAGE 0x00030008 @@ -73,24 +80,84 @@ struct vcprop_tag { #define VCPROPTAG_GET_TEMPERATURE 0x00030006 #define VCPROPTAG_GET_MAX_TEMPERATURE 0x0003000a +#define VCPROPTAG_GET_DOMAIN_STATE 0x00030030 +#define VCPROPTAG_SET_DOMAIN_STATE 0x00038030 + +#define VCPROPTAG_GET_GPIO_STATE 0x00030041 +#define VCPROPTAG_SET_GPIO_STATE 0x00038041 +#define VCPROPTAG_GET_GPIO_CONFIG 0x00030041 +#define VCPROPTAG_SET_GPIO_CONFIG 0x00038041 +#define VCPROPTAG_GET_PERIPH_REG 0x00030045 +#define VCPROPTAG_SET_PERIPH_REG 0x00038045 + +#define VCPROPTAG_GET_OTP 0x00030021 +#define VCPROPTAG_SET_OTP 0x00038021 + +#define VCPROPTAG_SET_SDHOST_CLOCK 0x00038042 + +#define VCPROPTAG_GET_POE_HAT_VAL 0x00030049 +#define VCPROPTAG_SET_POE_HAT_VAL 0x00030050 + +#define VCPROPTAG_NOTIFY_XHCI_RESET 0x00030058 + #define VCPROPTAG_GET_CMDLINE 0x00050001 #define VCPROPTAG_GET_DMACHAN 0x00060001 #define VCPROPTAG_ALLOCATE_BUFFER 0x00040001 +#define VCPROPTAG_RELEASE_BUFFER 0x00048001 #define VCPROPTAG_BLANK_SCREEN 0x00040002 #define VCPROPTAG_GET_FB_RES 0x00040003 +#define VCPROPTAG_TST_FB_RES 0x00044003 #define VCPROPTAG_SET_FB_RES 0x00048003 #define VCPROPTAG_GET_FB_VRES 0x00040004 +#define VCPROPTAG_TST_FB_VRES 0x00044004 #define VCPROPTAG_SET_FB_VRES 0x00048004 #define VCPROPTAG_GET_FB_DEPTH 0x00040005 +#define VCPROPTAG_TST_FB_DEPTH 0x00044005 #define VCPROPTAG_SET_FB_DEPTH 0x00048005 #define VCPROPTAG_GET_FB_PIXEL_ORDER 0x00040006 +#define VCPROPTAG_TST_FB_PIXEL_ORDER 0x00044006 #define VCPROPTAG_SET_FB_PIXEL_ORDER 0x00048006 #define VCPROPTAG_GET_FB_ALPHA_MODE 0x00040007 +#define VCPROPTAG_TST_FB_ALPHA_MODE 0x00044007 #define VCPROPTAG_SET_FB_ALPHA_MODE 0x00048007 #define VCPROPTAG_GET_FB_PITCH 0x00040008 +#define VCPROPTAG_GET_VIRTUAL_OFFSET 0x00040009 +#define VCPROPTAG_TST_VIRTUAL_OFFSET 0x00044009 +#define VCPROPTAG_SET_VIRTUAL_OFFSET 0x00048009 +#define VCPROPTAG_GET_OVERSCAN 0x0004000a +#define VCPROPTAG_TST_OVERSCAN 0x0004400a +#define VCPROPTAG_SET_OVERSCAN 0x0004800a +#define VCPROPTAG_GET_PALETTE 0x0004000b +#define VCPROPTAG_TST_PALETTE 0x0004400b +#define VCPROPTAG_SET_PALETTE 0x0004800b +#define VCPROPTAG_GET_FB_LAYER 0x0004000c +#define VCPROPTAG_TST_FB_LAYER 0x0004400c +#define VCPROPTAG_SET_FB_LAYER 0x0004800c +#define VCPROPTAG_GET_TRANSFORM 0x0004000d +#define VCPROPTAG_TST_TRANSFORM 0x0004400d +#define VCPROPTAG_SET_TRANSFORM 0x0004800d +#define VCPROPTAG_GET_VSYNC 0x0004000e +#define VCPROPTAG_TST_VSYNC 0x0004400e +#define VCPROPTAG_SET_VSYNC 0x0004800e +#define VCPROPTAG_GET_TOUCHBUF 0x0004000f +#define VCPROPTAG_GET_SET_BACKLIGHT 0x0004800f +#define VCPROPTAG_GET_GPIOVIRTBUF 0x00040010 +#define VCPROPTAG_SET_GPIOVIRTBUF 0x00048020 +#define VCPROPTAG_GET_NUM_DISPLAYS 0x00040013 +#define VCPROPTAG_SET_DISPLAYNUM 0x00048013 +#define VCPROPTAG_GET_DISPLAY_SETTINGS 0x00040014 +#define VCPROPTAG_GET_DISPLAYID 0x00040016 + +#define VCPROPTAG_VCHIQ_INIT 0x00048010 + +#define VCPROPTAG_SET_PLANE 0x00048015 +#define VCPROPTAG_GET_TIMING 0x00040017 +#define VCPROPTAG_SET_TIMING 0x00048017 +#define VCPROPTAG_GET_DISPLAY_CFG 0x00048018 #define VCPROPTAG_GET_EDID_BLOCK 0x00030020 +#define VCPROPTAG_GET_EDID_BLOCK_DISP 0x00030021 #define VCPROPTAG_ALLOCMEM 0x0003000c #define VCPROPTAG_LOCKMEM 0x0003000d @@ -113,6 +180,20 @@ struct vcprop_tag { #define VCPROPTAG_LEN(x) (sizeof((x)) - sizeof(struct vcprop_tag)) +#define VCPROP_INIT_REQUEST(req) \ + do { \ + memset(&(req), 0, sizeof((req))); \ + (req).vb_hdr.vpb_len = htole32(sizeof((req))); \ + (req).vb_hdr.vpb_rcode = htole32(VCPROP_PROCESS_REQUEST);\ + (req).end.vpt_tag = htole32(VCPROPTAG_NULL); \ + } while (0) +#define VCPROP_INIT_TAG(s, t) \ + do { \ + (s).tag.vpt_tag = htole32(t); \ + (s).tag.vpt_rcode = htole32(VCPROPTAG_REQUEST); \ + (s).tag.vpt_len = htole32(VCPROPTAG_LEN(s)); \ + } while (0) + struct vcprop_memory { uint32_t base; uint32_t size; @@ -148,16 +229,31 @@ struct vcprop_tag_boardrev { #define RPI_MODEL_B_PI2 4 #define RPI_MODEL_ALPHA 5 #define RPI_MODEL_COMPUTE 6 -#define RPI_MODEL_ZERO 7 #define RPI_MODEL_B_PI3 8 -#define RPI_MODEL_COMPUTE_PI3 9 -#define RPI_MODEL_ZERO_W 10 +#define RPI_MODEL_ZERO 9 +#define RPI_MODEL_COMPUTE_PI3 10 +#define RPI_MODEL_ZERO_W 12 +#define RPI_MODEL_B_PLUS_PI3 13 +#define RPI_MODEL_A_PLUS_PI3 14 +#define RPI_MODEL_CM_PLUS_PI3 16 +#define RPI_MODEL_B_PI4 17 #define VCPROP_REV_PROCESSOR __BITS(15,12) #define RPI_PROCESSOR_BCM2835 0 #define RPI_PROCESSOR_BCM2836 1 #define RPI_PROCESSOR_BCM2837 2 +#define RPI_PROCESSOR_BCM2711 3 #define VCPROP_REV_MANUF __BITS(19,16) +#define RPI_MANUF_SONY 0 +#define RPI_MANUF_EGOMAN 1 +#define RPI_MANUF_QISDA 16 +#define RPI_MANUF_EMBEST 2 +#define RPI_MANUF_SONYJAPAN 3 #define VCPROP_REV_MEMSIZE __BITS(22,20) +#define RPI_MEMSIZE_256 0 +#define RPI_MEMSIZE_512 1 +#define RPI_MEMSIZE_1024 2 +#define RPI_MEMSIZE_2048 3 +#define RPI_MEMSIZE_4096 4 #define VCPROP_REV_ENCFLAG __BIT(23) #define VCPROP_REV_WARRANTY __BITS(25,24) @@ -220,6 +316,13 @@ struct vcprop_tag_clockrate { uint32_t noturbo; }; +struct vcprop_tag_sdhostclock { + struct vcprop_tag tag; + uint32_t clock; + uint32_t clock1; + uint32_t clock2; +}; + #define VCPROP_VOLTAGE_CORE 1 #define VCPROP_VOLTAGE_SDRAM_C 2 #define VCPROP_VOLTAGE_SDRAM_P 3 @@ -249,6 +352,30 @@ struct vcprop_tag_temperature { #define VCPROP_POWER_SPI 7 #define VCPROP_POWER_CCP2TX 8 +#define VCPROP_DOMAIN_I2C0 1 +#define VCPROP_DOMAIN_I2C1 2 +#define VCPROP_DOMAIN_I2C2 3 +#define VCPROP_DOMAIN_VIDEO_SCALER 4 +#define VCPROP_DOMAIN_VPU1 5 +#define VCPROP_DOMAIN_HDMI 6 +#define VCPROP_DOMAIN_USB 7 +#define VCPROP_DOMAIN_VEC 8 +#define VCPROP_DOMAIN_JPEG 9 +#define VCPROP_DOMAIN_H264 10 +#define VCPROP_DOMAIN_V3D 11 +#define VCPROP_DOMAIN_ISP 12 +#define VCPROP_DOMAIN_UNICAM0 13 +#define VCPROP_DOMAIN_UNICAM1 14 +#define VCPROP_DOMAIN_CCP2RX 15 +#define VCPROP_DOMAIN_CSI2 16 +#define VCPROP_DOMAIN_CPI 17 +#define VCPROP_DOMAIN_DSI0 18 +#define VCPROP_DOMAIN_DSI1 19 +#define VCPROP_DOMAIN_TRANSPOSER 20 +#define VCPROP_DOMAIN_CCP2TX 21 +#define VCPROP_DOMAIN_CDP 22 +#define VCPROP_DOMAIN_ARM 23 + struct vcprop_tag_powertiming { struct vcprop_tag tag; uint32_t id; @@ -291,7 +418,7 @@ struct vcprop_tag_fbdepth { struct vcprop_tag_fbpixelorder { struct vcprop_tag tag; - uint32_t state; + uint32_t order; }; struct vcprop_tag_fbpitch { @@ -315,6 +442,16 @@ struct vcprop_tag_edidblock { uint8_t data[128]; }; +struct vcprop_tag_numdpy { + struct vcprop_tag tag; + uint32_t count; +}; + +struct vcprop_tag_setdpy { + struct vcprop_tag tag; + uint32_t display_num; +}; + struct vcprop_tag_cursorinfo { struct vcprop_tag tag; uint32_t width; @@ -358,6 +495,16 @@ struct vcprop_tag_lockmem { uint32_t handle; /* bus address returned here */ }; +struct vcprop_tag_vchiqinit { + struct vcprop_tag tag; + uint32_t base; +}; + +struct vcprop_tag_notifyxhcireset { + struct vcprop_tag tag; + uint32_t deviceaddress; +}; + struct vcprop_buffer_hdr { uint32_t vpb_len; uint32_t vpb_rcode; @@ -387,8 +534,6 @@ vcprop_tag_resplen(struct vcprop_tag *vp return le32toh(vpbt->vpt_rcode) & ~VCPROPTAG_RESPONSE; } -#endif /* _EVBARM_RPI_VCPROP_H_ */ - uint32_t rpi_alloc_mem(uint32_t, uint32_t, uint32_t); bus_addr_t rpi_lock_mem(uint32_t); int rpi_unlock_mem(uint32_t); @@ -398,3 +543,16 @@ int rpi_fb_set_video(int); int rpi_fb_movecursor(int, int, int); int rpi_fb_initcursor(bus_addr_t, int, int); + +int rpi_fb_set_pixelorder(uint32_t); +int rpi_fb_get_pixelorder(uint32_t *); + +int rpi_set_domain(uint32_t, uint32_t); +int rpi_get_domain(uint32_t, uint32_t *); + +int rpi_vchiq_init(uint32_t *); + +int rpi_notify_xhci_reset(uint32_t); + +#endif /* _EVBARM_RPI_VCPROP_H_ */ + Index: src/sys/arch/evbarm/rpi/vcprop_subr.c diff -u src/sys/arch/evbarm/rpi/vcprop_subr.c:1.9 src/sys/arch/evbarm/rpi/vcprop_subr.c:1.10 --- src/sys/arch/evbarm/rpi/vcprop_subr.c:1.9 Tue Dec 1 04:14:31 2020 +++ src/sys/arch/evbarm/rpi/vcprop_subr.c Mon Mar 8 13:53:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: vcprop_subr.c,v 1.9 2020/12/01 04:14:31 rin Exp $ */ +/* $NetBSD: vcprop_subr.c,v 1.10 2021/03/08 13:53:08 mlelstv Exp $ */ /* * Copyright (c) 2014 Michael Lorenz @@ -29,7 +29,7 @@ * Mailbox property interface wrapper functions */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vcprop_subr.c,v 1.9 2020/12/01 04:14:31 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vcprop_subr.c,v 1.10 2021/03/08 13:53:08 mlelstv Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -400,3 +400,290 @@ rpi_fb_initcursor(bus_addr_t pixels, int return 0; } + +int +rpi_fb_get_pixelorder(uint32_t *orderp) +{ + int error; + uint32_t res; + + + struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_fbpixelorder vbt_po; + struct vcprop_tag end; + } vb_pixelorder = + { + .vb_hdr = { + .vpb_len = htole32(sizeof(vb_pixelorder)), + .vpb_rcode = htole32(VCPROP_PROCESS_REQUEST), + }, + .vbt_po = { + .tag = { + .vpt_tag = htole32(VCPROPTAG_GET_FB_PIXEL_ORDER), + .vpt_len = htole32(VCPROPTAG_LEN( + vb_pixelorder.vbt_po)), + .vpt_rcode = htole32(VCPROPTAG_REQUEST), + }, + }, + .end = { + .vpt_tag = htole32(VCPROPTAG_NULL), + }, + }; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_pixelorder, + sizeof(vb_pixelorder), &res); +#ifdef RPI_IOCTL_DEBUG + printf("%s: %d %d %08x %08x\n", __func__, + le32toh(vb_pixelorder.vbt_po.order), error, res, + le32toh(vb_pixelorder.vbt_po.tag.vpt_rcode)); +#endif + if (error) + return error; + + if (!vcprop_buffer_success_p(&vb_pixelorder.vb_hdr) || + !vcprop_tag_success_p(&vb_pixelorder.vbt_po.tag)) { + return EIO; + } + + *orderp = vb_pixelorder.vbt_po.order; + + return 0; +} + +int +rpi_fb_set_pixelorder(uint32_t order) +{ + int error; + uint32_t res; + + + struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_fbpixelorder vbt_po; + struct vcprop_tag end; + } vb_pixelorder = + { + .vb_hdr = { + .vpb_len = htole32(sizeof(vb_pixelorder)), + .vpb_rcode = htole32(VCPROP_PROCESS_REQUEST), + }, + .vbt_po = { + .tag = { + .vpt_tag = htole32(VCPROPTAG_SET_FB_PIXEL_ORDER), + .vpt_len = htole32(VCPROPTAG_LEN( + vb_pixelorder.vbt_po)), + .vpt_rcode = htole32(VCPROPTAG_REQUEST), + }, + .order = order + }, + .end = { + .vpt_tag = htole32(VCPROPTAG_NULL), + }, + }; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_pixelorder, + sizeof(vb_pixelorder), &res); +#ifdef RPI_IOCTL_DEBUG + printf("%s: %d %d %08x %08x\n", __func__, + le32toh(vb_pixelorder.vbt_po.order), error, res, + le32toh(vb_pixelorder.vbt_po.tag.vpt_rcode)); +#endif + if (error) + return error; + + if (!vcprop_buffer_success_p(&vb_pixelorder.vb_hdr) || + !vcprop_tag_success_p(&vb_pixelorder.vbt_po.tag)) { + return EIO; + } + + return 0; +} + +int +rpi_set_domain(uint32_t domain, uint32_t state) +{ + int error; + uint32_t tag, res; + + tag = VCPROPTAG_SET_DOMAIN_STATE; + if (domain == VCPROP_DOMAIN_USB) { + /* use old interface */ + tag = VCPROPTAG_SET_POWERSTATE; + domain = VCPROP_POWER_USB; + } + + /* + * might as well put it here since we need to re-init it every time + * and it's not like this is going to be called very often anyway + */ + struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_powerstate vbt_power; + struct vcprop_tag end; + } vb_setpower = + { + .vb_hdr = { + .vpb_len = sizeof(vb_setpower), + .vpb_rcode = VCPROP_PROCESS_REQUEST, + }, + .vbt_power = { + .tag = { + .vpt_tag = tag, + .vpt_len = VCPROPTAG_LEN(vb_setpower.vbt_power), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .id = domain, + .state = state + }, + .end = { + .vpt_tag = VCPROPTAG_NULL, + }, + }; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setpower, + sizeof(vb_setpower), &res); +#ifdef RPI_IOCTL_DEBUG + printf("%s: %08x %08x %d %08x %08x %d %d %08x %08x\n", __func__, + tag, domain, state, + vb_setpower.vbt_power.tag.vpt_tag, + vb_setpower.vbt_power.id, + vb_setpower.vbt_power.state, + error, res, + vb_setpower.vbt_power.tag.vpt_rcode); +#endif + if (error) + return error; + + if (!vcprop_buffer_success_p(&vb_setpower.vb_hdr) || + !vcprop_tag_success_p(&vb_setpower.vbt_power.tag)) { + return EIO; + } + + return 0; +} + +int +rpi_get_domain(uint32_t domain, uint32_t *statep) +{ + int error; + uint32_t tag, res; + + tag = VCPROPTAG_GET_DOMAIN_STATE; + if (domain == VCPROP_DOMAIN_USB) { + /* use old interface */ + tag = VCPROPTAG_GET_POWERSTATE; + domain = VCPROP_POWER_USB; + } + + /* + * might as well put it here since we need to re-init it every time + * and it's not like this is going to be called very often anyway + */ + struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_powerstate vbt_power; + struct vcprop_tag end; + } vb_setpower = + { + .vb_hdr = { + .vpb_len = sizeof(vb_setpower), + .vpb_rcode = VCPROP_PROCESS_REQUEST, + }, + .vbt_power = { + .tag = { + .vpt_tag = tag, + .vpt_len = VCPROPTAG_LEN(vb_setpower.vbt_power), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .id = domain, + .state = ~0 + }, + .end = { + .vpt_tag = VCPROPTAG_NULL, + }, + }; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setpower, + sizeof(vb_setpower), &res); +#ifdef RPI_IOCTL_DEBUG + printf("%s: %08x %08x %d %08x %08x %d %d %08x %08x\n", __func__, + tag, domain, *statep, + vb_setpower.vbt_power.tag.vpt_tag, + vb_setpower.vbt_power.id, + vb_setpower.vbt_power.state, + error, res, + vb_setpower.vbt_power.tag.vpt_rcode); +#endif + if (error) + return error; + + if (!vcprop_buffer_success_p(&vb_setpower.vb_hdr) || + !vcprop_tag_success_p(&vb_setpower.vbt_power.tag)) { + return EIO; + } + + *statep = vb_setpower.vbt_power.state; + + return 0; +} + +int +rpi_vchiq_init(uint32_t *channelbasep) +{ + int error; + uint32_t tag, res; + struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_vchiqinit vbt_vchiq; + struct vcprop_tag end; + } vb; + + tag = VCPROPTAG_VCHIQ_INIT; + + VCPROP_INIT_REQUEST(vb); + VCPROP_INIT_TAG(vb.vbt_vchiq, tag); + vb.vbt_vchiq.base = *channelbasep; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb, sizeof(vb), &res); + if (error) + return error; + + if (!vcprop_buffer_success_p(&vb.vb_hdr) || + !vcprop_tag_success_p(&vb.vbt_vchiq.tag)) { + return EIO; + } + *channelbasep = vb.vbt_vchiq.base; + + return 0; +} + +int +rpi_notify_xhci_reset(uint32_t address) +{ + int error; + uint32_t tag, res; + struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_notifyxhcireset vbt_nhr; + struct vcprop_tag end; + } vb; + + tag = VCPROPTAG_NOTIFY_XHCI_RESET; + + VCPROP_INIT_REQUEST(vb); + VCPROP_INIT_TAG(vb.vbt_nhr, tag); + vb.vbt_nhr.deviceaddress = address; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb, sizeof(vb), &res); + if (error) + return error; + + if (!vcprop_buffer_success_p(&vb.vb_hdr) || + !vcprop_tag_success_p(&vb.vbt_nhr.tag)) { + return EIO; + } + + return 0; +} +