summaryrefslogtreecommitdiff
path: root/fb.c
diff options
context:
space:
mode:
authorJakob Kaivo <jakob@kaivo.net>2018-11-12 10:42:23 -0500
committerJakob Kaivo <jakob@kaivo.net>2018-11-12 10:42:23 -0500
commit888154172ac00710a5f792a56c7b8e82377160ad (patch)
tree01b16c061a1c5ae7fd391f9c4efe263818ecea05 /fb.c
parent72386a1678a0cac81b865e4ff1c7991578b9b0f3 (diff)
further progress
Diffstat (limited to 'fb.c')
-rw-r--r--fb.c147
1 files changed, 88 insertions, 59 deletions
diff --git a/fb.c b/fb.c
index d745698..df2674e 100644
--- a/fb.c
+++ b/fb.c
@@ -1,65 +1,73 @@
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
+#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
-#include <linux/fb.h>
+#include <linux/mxcfb.h>
#include <sys/ioctl.h>
#include "fb.h"
#include "gpio.h"
-struct imx_epdc_fb_mode {
- struct fb_videomode *vmode;
- int vscan_holdoff;
- int sdoed_width;
- int sdoed_delay;
- int sdoez_width;
- int sdoez_delay;
- int gdclk_hp_offs;
- int gdsp_offs;
- int gdoe_offs;
- int gdclk_offs;
- int num_ce;
-};
-
-static unsigned char *fbaddr;
-static struct fb_fix_screeninfo fsi;
-static struct fb_var_screeninfo vsi;
-
-static void dumpvsi(const char *ctl, int io)
+static struct {
+ int fd;
+ unsigned char *addr;
+ struct fb_fix_screeninfo fsi;
+ struct fb_var_screeninfo vsi;
+ size_t size;
+} fb;
+
+static void fb_update(int x, int y, int w, int h)
{
- printf("- %s\n", ctl);
- printf("\tioctl returned %d\n", io);
- printf("\txres: %d\n", vsi.xres);
- printf("\tyres: %d\n", vsi.yres);
- printf("\txres_virtual: %d\n", vsi.xres_virtual);
- printf("\tyres_virtual: %d\n", vsi.yres_virtual);
- printf("\txoffset: %d\n", vsi.xoffset);
- printf("\tyoffset: %d\n", vsi.yoffset);
- printf("\tbits_per_pixel: %d\n", vsi.bits_per_pixel);
- printf("\tgrayscale: %d\n", vsi.grayscale);
+ static int marker = 0;
+ marker++;
+
+ struct mxcfb_update_data data = {
+ .update_mode = UPDATE_MODE_PARTIAL,
+ .waveform_mode = WAVEFORM_MODE_AUTO, /* DU? */
+ .update_region.left = x,
+ .update_region.top = y,
+ .update_region.width = w,
+ .update_region.height = h,
+ .update_marker = marker,
+ .temp = TEMP_USE_AMBIENT,
+ .flags = 0,
+ };
+ ioctl(fb.fd, MXCFB_SEND_UPDATE, &data);
+
+ struct mxcfb_update_marker_data md = {
+ .update_marker = marker,
+ };
+
+ ioctl(fb.fd, MXCFB_WAIT_FOR_UPDATE_COMPLETE, &md);
}
-static void dumpfsi(const char *ctl, int io)
+static void fb_blank(void)
{
- printf("- %s\n", ctl);
- printf("\tioctl returned %d\n", io);
- printf("\tid: %16s\n", fsi.id);
- printf("\tsmem_len: %d\n", fsi.smem_len);
- printf("\ttype: %d\n", fsi.type);
- printf("\ttype_aux: %d\n", fsi.type_aux);
- printf("\tvisual: %d\n", fsi.visual);
- printf("\txpanstep: %d\n", fsi.xpanstep);
- printf("\typanstep: %d\n", fsi.ypanstep);
- printf("\tywrapstep: %d\n", fsi.ywrapstep);
- printf("\tline_length: %d\n", fsi.line_length);
- printf("\tmmio_start: %lu\n", fsi.mmio_start);
- printf("\tmmio_len: %d\n", fsi.mmio_len);
- printf("\taccel: %d\n", fsi.accel);
- printf("\tcapabilities: %d\n", fsi.capabilities);
+ memset(fb.addr, 0xff, fb.size);
+ fb_update(0, 0, fb.vsi.xres, fb.vsi.yres);
+}
+
+static void fb_loadimage(const char *path)
+{
+ int fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ return;
+ }
+
+ char *img = mmap(NULL, fb.size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (img == MAP_FAILED) {
+ return;
+ }
+
+ memcpy(fb.addr, img, fb.size);
+ munmap(img, fb.size);
+ close(fd);
+
+ fb_update(0, 0, fb.vsi.xres, fb.vsi.yres);
}
void fb_init(void)
@@ -73,23 +81,44 @@ void fb_init(void)
printf("mapping framebuffer...\n");
- int fbfd = open("/dev/fb0", O_RDWR);
+ fb.fd = open("/dev/fb0", O_RDWR);
+
+ ioctl(fb.fd, FBIOGET_FSCREENINFO, &fb.fsi);
+
+ ioctl(fb.fd, FBIOGET_VSCREENINFO, &fb.vsi);
+
+ fb.vsi.bits_per_pixel = 8;
+ fb.vsi.grayscale = GRAYSCALE_8BIT_INVERTED;
+ fb.vsi.activate = FB_ACTIVATE_FORCE;
- int io = ioctl(fbfd, FBIOGET_FSCREENINFO, &fsi);
- dumpfsi("FBIOGET_FSCREENINFO", io);
+ ioctl(fb.fd, FBIOPUT_VSCREENINFO, &fb.vsi);
- io = ioctl(fbfd, FBIOGET_VSCREENINFO, &vsi);
- dumpvsi("FBIOEGET_VSCREENINFO", io);
+ fb.size = fb.vsi.xres_virtual * fb.vsi.yres_virtual;
+ fb.addr = mmap(NULL, fb.size, PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0);
- vsi.bits_per_pixel = 8;
- vsi.grayscale = 1;
- vsi.activate = FB_ACTIVATE_FORCE;
+ printf("at %p\n", fb.addr);
- io = ioctl(fbfd, FBIOPUT_VSCREENINFO, &vsi);
- dumpvsi("FBIOPUT_VSCREENINFO", io);
+ int updatemode = AUTO_UPDATE_MODE_REGION_MODE;
+ ioctl(fb.fd, MXCFB_SET_AUTO_UPDATE_MODE, &updatemode);
- fbaddr = mmap(NULL, fsi.smem_len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fbfd, 0);
+ /*
+ struct mxcfb_waveform_modes wave = {
+ .mode_init = WAVEFORM_MODE_INIT,
+ .mode_du = WAVEFORM_MODE_DU,
+ .mode_gc4 = WAVEFORM_MODE_GC4,
+ .mode_gc8 = WAVEFORM_MODE_GC16,
+ .mode_gc16 = WAVEFORM_MODE_GC16,
+ .mode_gc32 = WAVEFORM_MODE_GC16,
+ };
+ ioctl(fb.fd, MXCFB_SET_WAVEFORM_MODES, &wave);
+
+ int scheme = UPDATE_SCHEME_QUEUE_AND_MERGE;
+ ioctl(fb.fd, MXCFB_SET_UPDATE_SCHEME, &scheme);
+
+ int powerdelay = 0;
+ ioctl(fb.fd, MXCFB_SET_PWRDOWN_DELAY, &powerdelay);
+ */
- close(fbfd);
- printf("at %p\n", fbaddr);
+ fb_blank();
+ //fb_loadimage("/run/media/mmcblk0p1/left-screen.dat");
}