Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/evbarm/rpi add hardware cursor support



details:   https://anonhg.NetBSD.org/src/rev/82026aee7a52
branches:  trunk
changeset: 802712:82026aee7a52
user:      macallan <macallan%NetBSD.org@localhost>
date:      Sun Sep 28 14:38:29 2014 +0000

description:
add hardware cursor support

diffstat:

 sys/arch/evbarm/rpi/rpi_machdep.c |  183 +++++++++++++++----
 sys/arch/evbarm/rpi/vcprop.h      |   14 +-
 sys/arch/evbarm/rpi/vcprop_subr.c |  343 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 494 insertions(+), 46 deletions(-)

diffs (truncated from 632 to 300 lines):

diff -r 7bc587a3f08e -r 82026aee7a52 sys/arch/evbarm/rpi/rpi_machdep.c
--- a/sys/arch/evbarm/rpi/rpi_machdep.c Sun Sep 28 12:57:22 2014 +0000
+++ b/sys/arch/evbarm/rpi/rpi_machdep.c Sun Sep 28 14:38:29 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rpi_machdep.c,v 1.47 2014/09/12 15:29:30 jmcneill Exp $        */
+/*     $NetBSD: rpi_machdep.c,v 1.48 2014/09/28 14:38:29 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.47 2014/09/12 15:29:30 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.48 2014/09/28 14:38:29 macallan Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_ddb.h"
@@ -71,6 +71,7 @@
 #include <arm/broadcom/bcm2835var.h>
 #include <arm/broadcom/bcm2835_pmvar.h>
 #include <arm/broadcom/bcm2835_mbox.h>
+#include <arm/broadcom/bcm_amba.h>
 
 #include <evbarm/rpi/vcio.h>
 #include <evbarm/rpi/vcpm.h>
@@ -376,16 +377,21 @@
        },
 };
 
-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 *);
 
+int rpi_video_on = WSDISPLAYIO_VIDEO_ON;
+uint32_t hcursor = 0;
+bus_addr_t pcursor = 0;
+uint32_t *cmem = NULL;
+int cursor_x = 0, cursor_y = 0, hot_x = 0, hot_y = 0, cursor_on = 0;
+uint32_t cursor_cmap[4];
+uint8_t cursor_mask[8 * 64], cursor_bitmap[8 * 64];
 #endif
 
+
 static void
 rpi_bootparams(void)
 {
@@ -731,8 +737,10 @@
  *  - If "console=fb" is present, attach framebuffer to console.
  */
 static bool
-rpi_fb_init(prop_dictionary_t dict)
+rpi_fb_init(prop_dictionary_t dict, void *aux)
 {
+       struct amba_attach_args *aaa = aux;
+       bus_space_handle_t hc;
        uint32_t width = 0, height = 0;
        uint32_t res;
        char *ptr;
@@ -818,49 +826,105 @@
                prop_dictionary_set_uint32(dict, "wsdisplay_type", integer);
        }
 
+       hcursor = rpi_alloc_mem(64 * 64 * 4, PAGE_SIZE,
+           MEM_FLAG_L1_NONALLOCATING | MEM_FLAG_HINT_PERMALOCK);
+       pcursor = rpi_lock_mem(hcursor);
+#ifdef RPI_IOCTL_DEBUG
+       printf("hcursor: %08x\n", hcursor);
+       printf("pcursor: %08x\n", (uint32_t)pcursor);
+       printf("fb: %08x\n", (uint32_t)vb_setfb.vbt_allocbuf.address);
+#endif
+       if (bus_space_map(aaa->aaa_iot, pcursor, 64 * 64 * 4,
+           BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE, &hc) != 0) {
+               printf("couldn't map cursor memory\n");
+       } else {
+               int i, j, k;
+
+               cmem = bus_space_vaddr(aaa->aaa_iot, hc);
+               k = 0;
+               for (j = 0; j < 64; j++) {
+                       for (i = 0; i < 64; i++) {
+                               cmem[i + k] = 
+                                ((i & 8) ^ (j & 8)) ? 0xa0ff0000 : 0xa00000ff;
+                       }
+                       k += 64;
+               }
+               cpu_dcache_wb_range(cmem, 64 * 64 * 4);
+               rpi_fb_initcursor(pcursor, 0, 0);
+       }       
+#ifdef RPI_IOCTL_DEBUG
+       rpi_fb_movecursor(600, 400, 1);
+#else
+       rpi_fb_movecursor(cursor_x, cursor_y, cursor_on);
+#endif
        return true;
 }
 
-int
-rpi_fb_set_video(int b)
+static int
+rpi_fb_do_cursor(struct wsdisplay_cursor *cur)
 {
-       int error;
-       uint32_t res;
+       int pos = 0;
+       int shape = 0;
+
+       if (cur->which & WSDISPLAY_CURSOR_DOCUR) {
+               if (cursor_on != cur->enable) {
+                       cursor_on = cur->enable;
+                       pos = 1;
+               }
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOHOT) {
+
+               hot_x = cur->hot.x;
+               hot_y = cur->hot.y;
+               pos = 1;
+               shape = 1;
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOPOS) {
+
+               cursor_x = cur->pos.x;
+               cursor_y = cur->pos.y;
+               pos = 1;
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOCMAP) {
+               int i;
+               uint32_t val;
 
-       /*
-        * 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,
-               },
-       };
+               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;
+                       cursor_cmap[i + cur->cmap.index + 2] = val;
+               }
+               shape = 1;
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) {
 
-       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);
+               copyin(cur->mask, cursor_mask, 64 * 8);
+               copyin(cur->image, 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 = ((cursor_mask[i] & mask) ? 2 : 0) |
+                                   ((cursor_bitmap[i] & mask) ? 1 : 0);
+                               cmem[i * 8 + j] = cursor_cmap[idx];
+                               mask = mask << 1;
+                       }
+               }
+               /* just in case */
+               cpu_dcache_wb_range(cmem, 64 * 64 * 4);
+               rpi_fb_initcursor(pcursor, hot_x, hot_y);
+       }
+       if (pos) {
+               rpi_fb_movecursor(cursor_x, cursor_y, cursor_on);
+       }
+       return 0;
 }
 
 static int
@@ -880,6 +944,37 @@
        case WSDISPLAYIO_GVIDEO:
                *(int *)data = rpi_video_on;
                return 0;
+       case WSDISPLAYIO_GCURPOS:
+               {
+                       struct wsdisplay_curpos *cp = (void *)data;
+
+                       cp->x = cursor_x;
+                       cp->y = cursor_y;
+               }
+               return 0;
+       case WSDISPLAYIO_SCURPOS:
+               {
+                       struct wsdisplay_curpos *cp = (void *)data;
+
+                       cursor_x = cp->x;
+                       cursor_y = cp->y;
+                       rpi_fb_movecursor(cursor_x, cursor_y, cursor_on);
+               }
+               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 rpi_fb_do_cursor(cursor);
+               }
        default:
                return EPASSTHROUGH;
        }
@@ -942,7 +1037,7 @@
                db_trap_callback = bcmgenfb_ddb_trap_callback;
 #endif
 
-               if (rpi_fb_init(dict) == false)
+               if (rpi_fb_init(dict, aux) == false)
                        return;
                if (get_bootconf_option(boot_args, "console",
                    BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) {
diff -r 7bc587a3f08e -r 82026aee7a52 sys/arch/evbarm/rpi/vcprop.h
--- a/sys/arch/evbarm/rpi/vcprop.h      Sun Sep 28 12:57:22 2014 +0000
+++ b/sys/arch/evbarm/rpi/vcprop.h      Sun Sep 28 14:38:29 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vcprop.h,v 1.12 2014/09/28 12:57:22 macallan Exp $     */
+/*     $NetBSD: vcprop.h,v 1.13 2014/09/28 14:38:29 macallan Exp $     */
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -287,7 +287,7 @@
        struct vcprop_tag tag;
        uint32_t width;
        uint32_t height;
-       uint32_t __pad;         /* unused */
+       uint32_t format;
        uint32_t pixels;        /* bus address in VC memory */
        uint32_t hotspot_x;
        uint32_t hotspot_y;
@@ -356,3 +356,13 @@
 }
 
 #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);
+int rpi_release_mem(uint32_t);
+
+int rpi_fb_set_video(int);
+
+int rpi_fb_movecursor(int, int, int);
+int rpi_fb_initcursor(bus_addr_t, int, int);
diff -r 7bc587a3f08e -r 82026aee7a52 sys/arch/evbarm/rpi/vcprop_subr.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/evbarm/rpi/vcprop_subr.c Sun Sep 28 14:38:29 2014 +0000
@@ -0,0 +1,343 @@
+/*     $NetBSD: vcprop_subr.c,v 1.1 2014/09/28 14:38:29 macallan Exp $ */
+
+/*
+ * Copyright (c) 2014 Michael Lorenz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.



Home | Main Index | Thread Index | Old Index