From owner-p4-projects@FreeBSD.ORG Sun Apr 29 16:46:29 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id AB2571065675; Sun, 29 Apr 2012 16:46:29 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 62B891065672 for ; Sun, 29 Apr 2012 16:46:29 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 4848D8FC17 for ; Sun, 29 Apr 2012 16:46:29 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id q3TGkTbH089920 for ; Sun, 29 Apr 2012 16:46:29 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id q3TGkSJU089917 for perforce@freebsd.org; Sun, 29 Apr 2012 16:46:28 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sun, 29 Apr 2012 16:46:28 GMT Message-Id: <201204291646.q3TGkSJU089917@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 210366 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 29 Apr 2012 16:46:30 -0000 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 #include #include /* struct vt_mode */ +#include #include /* video_adapter_t */ #include #include #include +#include #include #include @@ -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 #include #include /* struct vt_mode */ +#include #include /* video_adapter_t */ #include #include #include +#include #include #include @@ -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);