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 <[email protected]>
@@ -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;
+}
+