Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Apr 2012 16:46:28 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 210366 for review
Message-ID:  <201204291646.q3TGkSJU089917@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@210366?ac=10

Change 210366 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/04/29 16:45:25

	Commit a number of bug fixes and enhancements to the new Terasic
	MTL driver:
	
	- Add underlying I/O routines to allow syscons to control cursor
	  location and generate text frame buffer output.
	
	- Fix nexus attachment resource allocation, which was incorrectly
	  allocating one-byte bus space-managed memory regions for the
	  register and frame buffers.
	
	- Print out memory regions used by each of the sub-drivers during
	  attach.
	
	- Fix bugs in the sub-driver device node write routines for each
	  of the register, pixel, and frame buffer devices that caused
	  write() to be off by four bytes.
	
	- Add additional debugging information in cases where device
	  driver attach fails.
	
	- Use printf() instead of panic() when syscons calls, somewhat
	  to our surprise, methods for functions declared unsupported
	  during video adapter attach.
	
	- Add a work-around for a possible hardware bug in which the
	  base address for the text frame buffer is not as expected,
	  overwriting the apparent value with the desired value.
	
	Even with these changes, the text frame buffer still does not
	work, but it does an increasingly good job of thinking that it is
	working, despite touch screen contents to the contrary!

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl.h#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_nexus.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_pixel.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_reg.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_syscons.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_text.c#2 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl.c#2 (text+ko) ====


==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl.h#2 (text+ko) ====

@@ -76,6 +76,31 @@
 #define	TERASIC_MTL_ROWS	40
 
 /*
+ * MTL control register offsets.
+ */
+#define	TERASIC_MTL_OFF_FRAMEBLENDING		0
+#define	TERASIC_MTL_OFF_TEXTCURSOR		4
+#define	TERASIC_MTL_OFF_TEXTFRAMEBUFADDR	8
+#define	TERASIC_MTL_OFF_TOUCHPOINT_X1		12
+#define	TERASIC_MTL_OFF_TOUCHPOINT_Y1		16
+#define	TERASIC_MTL_OFF_TOUCHPOINT_X2		20
+#define	TERASIC_MTL_OFF_TOUCHPOINT_Y2		24
+#define	TERASIC_MTL_OFF_TOUCHGESTURE		28
+
+/*
+ * Constants to help interpret various control registers.
+ */
+#define	TERASIC_MTL_TEXTCURSOR_COL_MASK		0xff00
+#define	TERASIC_MTL_TEXTCURSOR_COL_SHIFT	8
+#define	TERASIC_MTL_TEXTCURSOR_ROW_MASK		0xff
+
+/*
+ * Constants to help interpret the text frame buffer.
+ */
+#define	TERASIC_MTL_TEXTFRAMEBUF_CHAR_SHIFT	8
+#define	TERASIC_MTL_TEXTFRAMEBUF_ATTR_SHIFT	0
+
+/*
  * Driver setup routines from the bus attachment/teardown.
  */
 int	terasic_mtl_attach(struct terasic_mtl_softc *sc);
@@ -93,4 +118,21 @@
 int	terasic_mtl_text_attach(struct terasic_mtl_softc *sc);
 void	terasic_mtl_text_detach(struct terasic_mtl_softc *sc);
 
+/*
+ * Control register I/O routines.
+ */
+void	terasic_mtl_reg_blank(struct terasic_mtl_softc *sc);
+void	terasic_mtl_reg_textcursor_get(struct terasic_mtl_softc *sc,
+	    uint8_t *colp, uint8_t *rowp);
+void	terasic_mtl_reg_textcursor_set(struct terasic_mtl_softc *sc,
+	    uint8_t col, uint8_t row);
+void	terasic_mtl_reg_textframebufaddr_set(struct terasic_mtl_softc *sc,
+	    uint32_t addr);
+
+/*
+ * Text frame buffer I/O routines.
+ */
+void	terasic_mtl_text_putc(struct terasic_mtl_softc *sc, u_int x, u_int y,
+	    uint8_t c, uint8_t a);
+
 #endif /* _DEV_TERASIC_MTL_H_ */

==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_nexus.c#2 (text+ko) ====

@@ -114,34 +114,40 @@
 	 */
 	sc->mtl_reg_rid = 0;
 	sc->mtl_reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
-	    &sc->mtl_reg_rid, reg_maddr, reg_maddr + reg_msize, 1, RF_ACTIVE);
+	    &sc->mtl_reg_rid, reg_maddr, reg_maddr + reg_msize - 1,
+	    reg_msize, RF_ACTIVE);
 	if (sc->mtl_reg_res == NULL) {
 		device_printf(dev, "couldn't map register memory\n");
 		error = ENXIO;
 		goto error;
 	}
+	device_printf(sc->mtl_dev, "registers at mem %p-%p\n",
+	    (void *)reg_maddr, (void *)(reg_maddr + reg_msize));
 	sc->mtl_pixel_rid = 0;
 	sc->mtl_pixel_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
-	    &sc->mtl_pixel_rid, pixel_maddr, pixel_maddr + pixel_msize, 1,
-	    RF_ACTIVE);
+	    &sc->mtl_pixel_rid, pixel_maddr, pixel_maddr + pixel_msize - 1,
+	    pixel_msize, RF_ACTIVE);
 	if (sc->mtl_pixel_res == NULL) {
 		device_printf(dev, "couldn't map pixel memory\n");
 		error = ENXIO;
 		goto error;
 	}
+	device_printf(sc->mtl_dev, "pixel frame buffer at mem %p-%p\n",
+	    (void *)pixel_maddr, (void *)(pixel_maddr + pixel_msize));
 	sc->mtl_text_rid = 0;
 	sc->mtl_text_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
-	    &sc->mtl_text_rid, text_maddr, text_maddr + text_msize, 1,
-	    RF_ACTIVE);
+	    &sc->mtl_text_rid, text_maddr, text_maddr + text_msize - 1,
+	    text_msize, RF_ACTIVE);
 	if (sc->mtl_text_res == NULL) {
 		device_printf(dev, "couldn't map text memory\n");
 		error = ENXIO;
 		goto error;
 	}
+	device_printf(sc->mtl_dev, "text frame buffer at mem %p-%p\n",
+	    (void *)text_maddr, (void *)(text_maddr + text_msize));
 	error = terasic_mtl_attach(sc);
 	if (error == 0)
 		return (0);
-
 error:
 	if (sc->mtl_text_res != NULL)
 		bus_release_resource(dev, SYS_RES_MEMORY, sc->mtl_text_rid,

==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_pixel.c#2 (text+ko) ====

@@ -106,12 +106,12 @@
 	size = rman_get_size(sc->mtl_pixel_res);
 	error = 0;
 	while (uio->uio_resid > 0) {
+		offset = uio->uio_offset;
+		if (offset + sizeof(v) > size)
+			return (ENODEV);
 		error = uiomove(&v, sizeof(v), uio);
 		if (error)
 			return (error);
-		offset = uio->uio_offset;
-		if (offset + sizeof(v) > size)
-			return (ENODEV);
 		bus_write_4(sc->mtl_pixel_res, offset, v);
 	}
 	return (error);
@@ -141,8 +141,10 @@
 
 	sc->mtl_pixel_cdev = make_dev(&mtl_pixel_cdevsw, sc->mtl_unit,
 	    UID_ROOT, GID_WHEEL, 0400, "mtl_pixel%d", sc->mtl_unit);
-	if (sc->mtl_pixel_cdev == NULL)
+	if (sc->mtl_pixel_cdev == NULL) {
+		device_printf(sc->mtl_dev, "%s: make_dev failed\n", __func__);
 		return (ENXIO);
+	}
 	/* XXXRW: Slight race between make_dev(9) and here. */
 	sc->mtl_pixel_cdev->si_drv1 = sc;
 	return (0);

==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_reg.c#2 (text+ko) ====

@@ -35,10 +35,12 @@
 #include <sys/bus.h>
 #include <sys/conf.h>
 #include <sys/consio.h>				/* struct vt_mode */
+#include <sys/endian.h>
 #include <sys/fbio.h>				/* video_adapter_t */
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/rman.h>
+#include <sys/systm.h>
 #include <sys/uio.h>
 
 #include <machine/bus.h>
@@ -107,12 +109,12 @@
 	size = rman_get_size(sc->mtl_reg_res);
 	error = 0;
 	while (uio->uio_resid > 0) {
+		offset = uio->uio_offset;
+		if (offset + sizeof(v) > size)
+			return (ENODEV);
 		error = uiomove(&v, sizeof(v), uio);
 		if (error)
 			return (error);
-		offset = uio->uio_offset;
-		if (offset + sizeof(v) > size)
-			return (ENODEV);
 		bus_write_4(sc->mtl_reg_res, offset, v);
 	}
 	return (error);
@@ -136,14 +138,56 @@
 	return (error);
 }
 
+void
+terasic_mtl_reg_textcursor_get(struct terasic_mtl_softc *sc, uint8_t *colp,
+    uint8_t *rowp)
+{
+	uint32_t v;
+
+	v = bus_read_4(sc->mtl_reg_res, TERASIC_MTL_OFF_TEXTCURSOR);
+	v = le32toh(v);
+	*rowp = (v & TERASIC_MTL_TEXTCURSOR_COL_MASK) >>
+	    TERASIC_MTL_TEXTCURSOR_COL_SHIFT;
+	*colp = (v & TERASIC_MTL_TEXTCURSOR_ROW_MASK);
+}
+
+void
+terasic_mtl_reg_textcursor_set(struct terasic_mtl_softc *sc, uint8_t col,
+    uint8_t row)
+{
+	uint32_t v;
+
+	v = col << TERASIC_MTL_TEXTCURSOR_COL_SHIFT | row;
+	v = htole32(v);
+	bus_write_4(sc->mtl_reg_res, TERASIC_MTL_OFF_TEXTCURSOR, v);
+}
+
+void
+terasic_mtl_reg_blank(struct terasic_mtl_softc *sc)
+{
+
+	device_printf(sc->mtl_dev, "%s: not yet", __func__);
+}
+
+void
+terasic_mtl_reg_textframebufaddr_set(struct terasic_mtl_softc *sc,
+    uint32_t addr)
+{
+
+	addr = htole32(addr);
+	bus_write_4(sc->mtl_reg_res, TERASIC_MTL_OFF_TEXTFRAMEBUFADDR, addr);
+}
+
 int
 terasic_mtl_reg_attach(struct terasic_mtl_softc *sc)
 {
 
 	sc->mtl_reg_cdev = make_dev(&terasic_mtl_reg_cdevsw, sc->mtl_unit,
 	    UID_ROOT, GID_WHEEL, 0400, "mtl_reg%d", sc->mtl_unit);
-	if (sc->mtl_reg_cdev == NULL)
+	if (sc->mtl_reg_cdev == NULL) {
+		device_printf(sc->mtl_dev, "%s: make_dev failed\n", __func__);
 		return (ENXIO);
+	}
 	/* XXXRW: Slight race between make_dev(9) and here. */
 	sc->mtl_reg_cdev->si_drv1 = sc;
 	return (0);

==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_syscons.c#2 (text+ko) ====

@@ -103,7 +103,7 @@
 	sc = (struct terasic_mtl_softc *)adp;
 
 	vi = &adp->va_info;
-	vid_init_struct(adp, "mtlsc", -1, unit);
+	vid_init_struct(adp, "terasic_mtl_syscons", -1, unit);
 
 	vi->vi_width = TERASIC_MTL_COLS;
 	if (vi->vi_width > COL)
@@ -136,8 +136,11 @@
 	 * V_ADP_REGISTERED.
 	 */
 	adp->va_flags |= V_ADP_COLOR | V_ADP_INITIALIZED;
-	if (vid_register(adp) < 0)
+	if (vid_register(adp) < 0) {
+		device_printf(sc->mtl_dev, "%s: vid_register failed\n",
+		    __func__);
 		return (ENXIO);
+	}
 	adp->va_flags |= V_ADP_REGISTERED;
 	return (0);
 }
@@ -171,7 +174,8 @@
     int width, u_char *data, int c, int count)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
@@ -179,67 +183,76 @@
     int width, u_char *data, int c, int count)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
 terasic_mtl_vidsw_show_font(video_adapter_t *adp, int page)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
 terasic_mtl_vidsw_save_palette(video_adapter_t *adp, u_char *palette)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
 terasic_mtl_vidsw_load_palette(video_adapter_t *adp, u_char *palette)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
 terasic_mtl_vidsw_set_border(video_adapter_t *adp, int border)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
 terasic_mtl_vidsw_save_state(video_adapter_t *adp, void *p, size_t size)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
 terasic_mtl_vidsw_load_state(video_adapter_t *adp, void *p)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
 terasic_mtl_vidsw_set_win_org(video_adapter_t *adp, off_t offset)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 static int
-terasic_mtl_vidsw_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+terasic_mtl_vidsw_read_hw_cursor(video_adapter_t *adp, int *colp, int *rowp)
 {
 	struct terasic_mtl_softc *sc;
+	uint8_t col, row;
 
 	sc = (struct terasic_mtl_softc *)adp;
-	*col = *row = 0;
-	printf("%s: not yet terasic_mtl_io_cursor_getxy(sc, col, row);\n",
-	    __func__);
+	terasic_mtl_reg_textcursor_get(sc, &col, &row);
+	*colp = col;
+	*rowp = row;
 	return (0);
 }
 
@@ -249,7 +262,7 @@
 	struct terasic_mtl_softc *sc;
 
 	sc = (struct terasic_mtl_softc *)adp;
-	printf("%s: not yet terasic_mtl_io_setxy(sc, col, row);\n", __func__);
+	terasic_mtl_reg_textcursor_set(sc, col, row);
 	return (0);
 }
 
@@ -268,7 +281,7 @@
 	struct terasic_mtl_softc *sc;
 
 	sc = (struct terasic_mtl_softc *)adp;
-	printf("%s: not yet terasic_mtl_io_blank(sc);\n", __func__);
+	terasic_mtl_reg_blank(sc);
 	return (0);
 }
 
@@ -362,15 +375,12 @@
     uint8_t a)
 {
 	struct terasic_mtl_softc *sc;
-	u_int x, y;
+	u_int col, row;
 
 	sc = (struct terasic_mtl_softc *)adp;
-	x = (off % adp->va_info.vi_width);
-	y = (off / adp->va_info.vi_width);
-
-	/* XXXRW: more required here. */
-	printf("%s: not yet terasic_mtl_io_putc(sc, x, y, c, a);\n",
-	    __func__);
+	col = (off % adp->va_info.vi_width);
+	row = (off / adp->va_info.vi_width);
+	terasic_mtl_text_putc(sc, col, row, c, a);
 	return (0);
 }
 
@@ -390,7 +400,8 @@
     uint8_t *pixel_image, uint32_t pixel_mask, int size, int width)
 {
 
-	panic("%s: not yet", __func__);
+	printf("%s: not yet\n", __func__);
+	return (ENODEV);
 }
 
 /*
@@ -417,9 +428,16 @@
 	sc->mtl_text_soft  =
 	    malloc(sizeof(uint16_t) * TERASIC_MTL_ROWS * TERASIC_MTL_COLS,
 	    M_TERASIC_MTL, M_WAITOK | M_ZERO);
+	error = terasic_mtl_vidsw_init(0, &sc->mtl_va, 0);
+	if (error)
+		goto out;
 	error = sc_attach_unit(sc->mtl_unit, device_get_flags(sc->mtl_dev) |
 	    SC_AUTODETECT_KBD);
 	if (error)
+		device_printf(sc->mtl_dev, "%s: sc_attach_unit failed (%d)\n",
+		    __func__, error);
+out:
+	if (error)
 		free(sc->mtl_text_soft, M_TERASIC_MTL);
 	return (error);
 }

==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtl/terasic_mtl_text.c#2 (text+ko) ====

@@ -35,10 +35,12 @@
 #include <sys/bus.h>
 #include <sys/conf.h>
 #include <sys/consio.h>				/* struct vt_mode */
+#include <sys/endian.h>
 #include <sys/fbio.h>				/* video_adapter_t */
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/rman.h>
+#include <sys/systm.h>
 #include <sys/uio.h>
 
 #include <machine/bus.h>
@@ -106,12 +108,12 @@
 	size = rman_get_size(sc->mtl_text_res);
 	error = 0;
 	while (uio->uio_resid > 0) {
+		offset = uio->uio_offset;
+		if (offset + sizeof(v) > size)
+			return (ENODEV);
 		error = uiomove(&v, sizeof(v), uio);
 		if (error)
 			return (error);
-		offset = uio->uio_offset;
-		if (offset + sizeof(v) > size)
-			return (ENODEV);
 		bus_write_2(sc->mtl_text_res, offset, v);
 	}
 	return (error);
@@ -135,15 +137,38 @@
 	return (error);
 }
 
+void
+terasic_mtl_text_putc(struct terasic_mtl_softc *sc, u_int x, u_int y,
+    uint8_t c, uint8_t a)
+{
+	u_int offset;
+	uint16_t v;
+
+	KASSERT(x < TERASIC_MTL_COLS, ("%s: TERASIC_MTL_COLS", __func__));
+	KASSERT(y < TERASIC_MTL_ROWS, ("%s: TERASIC_MTL_ROWS", __func__));
+
+	offset = sizeof(uint16_t) * (x + y * TERASIC_MTL_COLS);
+	v = (c << TERASIC_MTL_TEXTFRAMEBUF_CHAR_SHIFT) |
+	    (a << TERASIC_MTL_TEXTFRAMEBUF_ATTR_SHIFT);
+	v = htole16(v);
+	bus_write_2(sc->mtl_text_res, offset, v);
+}
+
 int
 terasic_mtl_text_attach(struct terasic_mtl_softc *sc)
 {
 
+	/*
+	 * XXXRW: Work around a feature in which the default address of the
+	 * text frame buffer is not initialised at reset as expected.
+	 */
+	terasic_mtl_reg_textframebufaddr_set(sc, 0x0177000);
 	sc->mtl_text_cdev = make_dev(&terasic_mtl_text_cdevsw, sc->mtl_unit,
 	    UID_ROOT, GID_WHEEL, 0400, "mtl_text%d", sc->mtl_unit);
-	if (sc->mtl_text_cdev == NULL)
+	if (sc->mtl_text_cdev == NULL) {
+		device_printf(sc->mtl_dev, "%s: make_dev failed\n", __func__);
 		return (ENXIO);
-
+	}
 	/* XXXRW: Slight race between make_dev(9) and here. */
 	sc->mtl_text_cdev->si_drv1 = sc;
 	return (0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204291646.q3TGkSJU089917>