Module Name:    src
Committed By:   macallan
Date:           Fri Sep  5 21:22:35 UTC 2014

Modified Files:
        src/sys/arch/evbarm/rpi: rpi_machdep.c

Log Message:
implement WSCONSIO_[G|S]VIDEO by hijacking bcm2835_genfb's ioctl
next step: hardware cursor


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/sys/arch/evbarm/rpi/rpi_machdep.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_machdep.c
diff -u src/sys/arch/evbarm/rpi/rpi_machdep.c:1.44 src/sys/arch/evbarm/rpi/rpi_machdep.c:1.45
--- src/sys/arch/evbarm/rpi/rpi_machdep.c:1.44	Fri Aug 22 09:49:13 2014
+++ src/sys/arch/evbarm/rpi/rpi_machdep.c	Fri Sep  5 21:22:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rpi_machdep.c,v 1.44 2014/08/22 09:49:13 skrll Exp $	*/
+/*	$NetBSD: rpi_machdep.c,v 1.45 2014/09/05 21:22:35 macallan Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.44 2014/08/22 09:49:13 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.45 2014/09/05 21:22:35 macallan Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_ddb.h"
@@ -92,6 +92,7 @@ __KERNEL_RCSID(0, "$NetBSD: rpi_machdep.
 #if NGENFB > 0
 #include <dev/videomode/videomode.h>
 #include <dev/videomode/edidvar.h>
+#include <dev/wscons/wsconsio.h>
 #endif
 
 #if NUKBD > 0
@@ -367,8 +368,14 @@ static struct __aligned(16) {
 	},
 };
 
+int rpi_fb_set_video(int);
+int rpi_video_on = WSDISPLAYIO_VIDEO_ON;
+
 extern void bcmgenfb_set_console_dev(device_t dev);
+void bcmgenfb_set_ioctl(int(*)(void *, void *, u_long, void *, int, struct lwp *));
 extern void bcmgenfb_ddb_trap_callback(int where);
+static int	rpi_ioctl(void *, void *, u_long, void *, int, lwp_t *);
+
 #endif
 
 static void
@@ -802,6 +809,71 @@ rpi_fb_init(prop_dictionary_t dict)
 
 	return true;
 }
+
+int
+rpi_fb_set_video(int b)
+{
+	int error;
+	uint32_t res;
+
+	/*
+	 * 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_blankscreen	vbt_blank;
+		struct vcprop_tag end;
+	} vb_setblank =
+	{
+		.vb_hdr = {
+			.vpb_len = sizeof(vb_setblank),
+			.vpb_rcode = VCPROP_PROCESS_REQUEST,
+		},
+		.vbt_blank = {
+			.tag = {
+				.vpt_tag = VCPROPTAG_BLANK_SCREEN,
+				.vpt_len = VCPROPTAG_LEN(vb_setblank.vbt_blank),
+				.vpt_rcode = VCPROPTAG_REQUEST,
+			},
+			.state = (b != 0) ? VCPROP_BLANK_OFF : VCPROP_BLANK_ON,
+		},
+		.end = {
+			.vpt_tag = VCPROPTAG_NULL,
+		},
+	};
+
+	error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setblank,
+	    sizeof(vb_setblank), &res);
+#ifdef RPI_IOCTL_DEBUG
+	printf("%s: %d %d %d %08x %08x\n", __func__, b,
+	    vb_setblank.vbt_blank.state, error, res, vb_setblank.vbt_blank.tag.vpt_rcode);
+#endif
+	return (error == 0);
+}
+
+static int
+rpi_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l)
+{
+
+	switch (cmd) {
+	case WSDISPLAYIO_SVIDEO:
+		{
+			int d = *(int *)data;
+			if (d == rpi_video_on)
+				return 0;
+			rpi_video_on = d;
+			rpi_fb_set_video(d);
+		}
+		return 0;
+	case WSDISPLAYIO_GVIDEO:
+		*(int *)data = rpi_video_on;
+		return 0;
+	default:
+		return EPASSTHROUGH;
+	}
+}
+
 #endif
 
 static void
@@ -849,6 +921,7 @@ rpi_device_register(device_t dev, void *
 		char *ptr;
 
 		bcmgenfb_set_console_dev(dev);
+		bcmgenfb_set_ioctl(&rpi_ioctl);
 #ifdef DDB
 		db_trap_callback = bcmgenfb_ddb_trap_callback;
 #endif

Reply via email to