Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/omap support a hardware cursor
details: https://anonhg.NetBSD.org/src/rev/880c817c2fc9
branches: trunk
changeset: 784878:880c817c2fc9
user: macallan <macallan%NetBSD.org@localhost>
date: Tue Feb 12 21:17:37 2013 +0000
description:
support a hardware cursor
diffstat:
sys/arch/arm/omap/omapfb.c | 226 ++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 211 insertions(+), 15 deletions(-)
diffs (truncated from 301 to 300 lines):
diff -r 636323c9ee35 -r 880c817c2fc9 sys/arch/arm/omap/omapfb.c
--- a/sys/arch/arm/omap/omapfb.c Tue Feb 12 21:17:17 2013 +0000
+++ b/sys/arch/arm/omap/omapfb.c Tue Feb 12 21:17:37 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: omapfb.c,v 1.21 2013/02/09 13:28:59 jmcneill Exp $ */
+/* $NetBSD: omapfb.c,v 1.22 2013/02/12 21:17:37 macallan Exp $ */
/*
* Copyright (c) 2010 Michael Lorenz
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: omapfb.c,v 1.21 2013/02/09 13:28:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: omapfb.c,v 1.22 2013/02/12 21:17:37 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -75,6 +75,15 @@
int sc_width, sc_height, sc_depth, sc_stride;
int sc_locked;
void *sc_fbaddr, *sc_vramaddr;
+
+ int sc_cursor_offset;
+ uint32_t *sc_cursor_img;
+ int sc_cursor_x, sc_cursor_y;
+ int sc_hot_x, sc_hot_y;
+ uint8_t sc_cursor_bitmap[8 * 64];
+ uint8_t sc_cursor_mask[8 * 64];
+ uint32_t sc_cursor_cmap[4];
+
bus_addr_t sc_fbhwaddr;
uint32_t *sc_clut;
uint32_t sc_dispc_config;
@@ -112,6 +121,10 @@
static int omapfb_set_depth(struct omapfb_softc *, int);
static void omapfb_set_video(struct omapfb_softc *, int);
+static void omapfb_move_cursor(struct omapfb_softc *, int, int);
+static int omapfb_do_cursor(struct omapfb_softc *,
+ struct wsdisplay_cursor *);
+
#if NOMAPDMA > 0
static void omapfb_init(struct omapfb_softc *);
static void omapfb_wait_idle(struct omapfb_softc *);
@@ -300,24 +313,53 @@
bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_SYSCONFIG,
OMAP_SYSCONF_AUTOIDLE);
- reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG);
- reg = OMAP_DISPC_CTRL_ACTIVE_MTRX;
+
+ reg = OMAP_DISPC_CFG_TV_ALPHA_EN | OMAP_DISPC_CFG_LCD_ALPHA_EN;
bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG, reg);
sc->sc_dispc_config = reg;
+ /* we use overlay 1 for the console and X */
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GLOBAL_ALPHA, 0x00ff00ff);
sc->sc_fbhwaddr = sc->sc_dmamem->ds_addr + 0x1000;
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_BASE_0,
+ sc->sc_fbhwaddr);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_POSITION,
+ 0);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_SIZE,
+ ((sc->sc_height - 1) << 16) | (sc->sc_width - 1));
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_PICTURE_SIZE,
+ ((sc->sc_height - 1) << 16) | (sc->sc_width - 1));
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_ROW_INC, 1);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_PIXEL_INC, 1);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_PRELOAD, 0x60);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_ATTRIBUTES,
+ OMAP_VID_ATTR_ENABLE |
+ OMAP_VID_ATTR_BURST_16x32 |
+ OMAP_VID_ATTR_RGB16 |
+ OMAP_VID_ATTR_REPLICATION);
+
+ /* turn off overlay 2 */
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID2_ATTRIBUTES, 0);
+
+ /* initialize the gfx layer for use as hardware cursor */
+ sc->sc_cursor_cmap[0] = 0;
+ sc->sc_cursor_offset = (12 << 20) - (64 * 64 * 4);
+ sc->sc_cursor_img = (uint32_t *)((uint8_t *)sc->sc_fbaddr + sc->sc_cursor_offset);
bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_BASE_0,
- sc->sc_fbhwaddr);
+ sc->sc_fbhwaddr + sc->sc_cursor_offset);
bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_TABLE_BASE,
sc->sc_dmamem->ds_addr);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE,
+ 0x003f003f);
bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_POSITION,
- 0);
+ 0x00100010);
bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PRELOAD, 0x60);
bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES,
- OMAP_DISPC_ATTR_ENABLE |
+ /*OMAP_DISPC_ATTR_ENABLE |*/
OMAP_DISPC_ATTR_BURST_16x32 |
- /*OMAP_DISPC_ATTR_8BIT*/OMAP_DISPC_ATTR_RGB16
- | OMAP_DISPC_ATTR_REPLICATION);
+ OMAP_DISPC_ATTR_ARGB32 |
+ OMAP_DISPC_ATTR_REPLICATION);
+
#if 0
printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh,
OMAPFB_DSS_CONTROL));
@@ -532,6 +574,36 @@
omapfb_set_video(sc, *on);
}
return 0;
+
+ case WSDISPLAYIO_GCURPOS:
+ {
+ struct wsdisplay_curpos *cp = (void *)data;
+
+ cp->x = sc->sc_cursor_x;
+ cp->y = sc->sc_cursor_y;
+ }
+ return 0;
+ case WSDISPLAYIO_SCURPOS:
+ {
+ struct wsdisplay_curpos *cp = (void *)data;
+
+ omapfb_move_cursor(sc, cp->x, cp->y);
+ }
+ return 0;
+ case WSDISPLAYIO_GCURMAX:
+ {
+ struct wsdisplay_curpos *cp = (void *)data;
+
+ cp->x = 64;
+ cp->y = 64;
+ }
+ return 0;
+ case WSDISPLAYIO_SCURSOR:
+ {
+ struct wsdisplay_cursor *cursor = (void *)data;
+
+ return omapfb_do_cursor(sc, cursor);
+ }
}
return EPASSTHROUGH;
}
@@ -685,15 +757,15 @@
{
uint32_t reg;
- reg = OMAP_DISPC_ATTR_ENABLE |
- OMAP_DISPC_ATTR_BURST_16x32 |
- OMAP_DISPC_ATTR_REPLICATION;
+ reg = OMAP_VID_ATTR_ENABLE |
+ OMAP_VID_ATTR_BURST_16x32 |
+ OMAP_VID_ATTR_REPLICATION;
switch (d) {
case 16:
- reg |= OMAP_DISPC_ATTR_RGB16;
+ reg |= OMAP_VID_ATTR_RGB16;
break;
case 32:
- reg |= OMAP_DISPC_ATTR_RGB24;
+ reg |= OMAP_VID_ATTR_RGB24;
break;
default:
aprint_error_dev(sc->sc_dev, "unsupported depth (%d)\n", d);
@@ -701,7 +773,7 @@
}
bus_space_write_4(sc->sc_iot, sc->sc_regh,
- OMAPFB_DISPC_GFX_ATTRIBUTES, reg);
+ OMAPFB_DISPC_VID1_ATTRIBUTES, reg);
/*
* now tell the video controller that we're done mucking around and
@@ -1025,3 +1097,127 @@
}
}
#endif /* NOMAPDMA > 0 */
+
+static void
+omapfb_move_cursor(struct omapfb_softc *sc, int x, int y)
+{
+ uint32_t pos, reg, addr;
+ int xx, yy, wi = 64, he = 64;
+
+ /*
+ * we need to special case anything and everything where the cursor
+ * may be partially off screen
+ */
+
+ addr = sc->sc_fbhwaddr + sc->sc_cursor_offset;
+ xx = x - sc->sc_hot_x;
+ yy = y - sc->sc_hot_y;
+
+ /*
+ * if we're off to the top or left we need to shif the start address
+ * and shrink the gfx layer size
+ */
+ if (xx < 0) {
+ wi += xx;
+ addr -= xx * 4;
+ xx = 0;
+ }
+ if (yy < 0) {
+ he += yy;
+ addr -= yy * 64 * 4;
+ yy = 0;
+ }
+ if (xx > (sc->sc_width - 64)) {
+ wi -= (xx + 64 - sc->sc_width);
+ }
+ if (yy > (sc->sc_height - 64)) {
+ he -= (yy + 64 - sc->sc_height);
+ }
+ pos = (yy << 16) | xx;
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_BASE_0,
+ addr);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_POSITION,
+ pos);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE,
+ ((he - 1) << 16) | (wi - 1));
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ROW_INC,
+ (64 - wi) * 4 + 1);
+ /*
+ * now tell the video controller that we're done mucking around and
+ * actually update its settings
+ */
+ reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL,
+ reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL);
+}
+
+static int
+omapfb_do_cursor(struct omapfb_softc * sc,
+ struct wsdisplay_cursor *cur)
+{
+ int whack = 0;
+ int shape = 0;
+
+ if (cur->which & WSDISPLAY_CURSOR_DOCUR) {
+ uint32_t attr = OMAP_DISPC_ATTR_BURST_16x32 |
+ OMAP_DISPC_ATTR_ARGB32 |
+ OMAP_DISPC_ATTR_REPLICATION;
+
+ if (cur->enable) attr |= OMAP_DISPC_ATTR_ENABLE;
+ bus_space_write_4(sc->sc_iot, sc->sc_regh,
+ OMAPFB_DISPC_GFX_ATTRIBUTES, attr);
+ whack = 1;
+ }
+ if (cur->which & WSDISPLAY_CURSOR_DOHOT) {
+
+ sc->sc_hot_x = cur->hot.x;
+ sc->sc_hot_y = cur->hot.y;
+ cur->which |= WSDISPLAY_CURSOR_DOPOS;
+ }
+ if (cur->which & WSDISPLAY_CURSOR_DOPOS) {
+
+ omapfb_move_cursor(sc, cur->pos.x, cur->pos.y);
+ }
+ if (cur->which & WSDISPLAY_CURSOR_DOCMAP) {
+ int i;
+ uint32_t val;
+
+ for (i = 0; i < min(cur->cmap.count, 3); i++) {
+ val = (cur->cmap.red[i] << 16 ) |
+ (cur->cmap.green[i] << 8) |
+ (cur->cmap.blue[i] ) |
+ 0xff000000;
+ sc->sc_cursor_cmap[i + cur->cmap.index + 2] = val;
+ }
+ shape = 1;
+ }
+ if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) {
+
+ copyin(cur->mask, sc->sc_cursor_mask, 64 * 8);
+ copyin(cur->image, sc->sc_cursor_bitmap, 64 * 8);
+ shape = 1;
+ }
+ if (shape) {
+ int i, j, idx;
+ uint8_t mask;
+
+ for (i = 0; i < 64 * 8; i++) {
+ mask = 0x01;
+ for (j = 0; j < 8; j++) {
+ idx = ((sc->sc_cursor_mask[i] & mask) ? 2 : 0) |
+ ((sc->sc_cursor_bitmap[i] & mask) ? 1 : 0);
+ sc->sc_cursor_img[i * 8 + j] = sc->sc_cursor_cmap[idx];
+ mask = mask << 1;
+ }
+ }
+ }
+ if (whack) {
+ uint32_t reg;
+
+ reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL);
+ bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL,
+ reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL);
+ }
+ return 0;
+
Home |
Main Index |
Thread Index |
Old Index