aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2009-06-10 23:04:31 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-10 23:04:31 -0700
commit0f3f33d3056bea4fc8cc48a18ced89762af3917e (patch)
tree095aee575e708d5a695d3062a26d4210bcecad2a
parent1ea8d85f0dbe764a2b43a210c9b564950b54d9ca (diff)
downloadpatches-0f3f33d3056bea4fc8cc48a18ced89762af3917e.tar.gz
add 0.2.3 version of udlfb
-rw-r--r--series1
-rw-r--r--staging/staging-udlfb-update-to-version-0.2.3.patch586
2 files changed, 587 insertions, 0 deletions
diff --git a/series b/series
index 3e4396256e8941..0ce4f9183d40b7 100644
--- a/series
+++ b/series
@@ -632,6 +632,7 @@ staging/staging-udlfb-add-udlfb-driver-to-build.patch
staging/staging-udlfb-clean-up-checkpatch-warnings-in-udlfb.h.patch
staging/staging-udlfb-clean-up-checkpatch-warnings-in-udlfb.c.patch
staging/staging-udlfb-fix-some-sparse-warnings.patch
+staging/staging-udlfb-update-to-version-0.2.3.patch
staging/staging-add-octeon-ethernet-driver.patch
staging/staging-octeon-hookup-octeon-ethernet-driver.patch
diff --git a/staging/staging-udlfb-update-to-version-0.2.3.patch b/staging/staging-udlfb-update-to-version-0.2.3.patch
new file mode 100644
index 00000000000000..7f47c5ba6d6afd
--- /dev/null
+++ b/staging/staging-udlfb-update-to-version-0.2.3.patch
@@ -0,0 +1,586 @@
+From foo@baz Wed Jun 10 23:02:19 PDT 2009
+Date: Wed, 10 Jun 2009 23:02:19 -0700
+To: Greg KH <greg@kroah.com>
+From: Roberto De Ioris <roberto@unbit.it>
+Subject: Staging: udlfb: update to version 0.2.3
+
+This updates the udlfb to the 0.2.3 version.
+
+From: Roberto De Ioris <roberto@unbit.it>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/udlfb/udlfb.c | 352 +++++++++++++++++++++++++++++++-----------
+ drivers/staging/udlfb/udlfb.h | 29 +++
+ 2 files changed, 296 insertions(+), 85 deletions(-)
+
+--- a/drivers/staging/udlfb/udlfb.c
++++ b/drivers/staging/udlfb/udlfb.c
+@@ -7,6 +7,8 @@
+ * Based on the amazing work of Florian Echtler and libdlo 0.1 *
+ * *
+ * *
++ * 10.06.09 release 0.2.3 (edid ioctl, fallback for unsupported modes) *
++ * 05.06.09 release 0.2.2 (real screen blanking, rle compression, double buffer) *
+ * 31.05.09 release 0.2 *
+ * 22.05.09 First public (ugly) release *
+ *****************************************************************************/
+@@ -99,6 +101,7 @@ static int dlfb_mmap(struct fb_info *inf
+ struct dloarea {
+ int x, y;
+ int w, h;
++ int x2, y2;
+ };
+
+ /*
+@@ -116,6 +119,37 @@ MODULE_DEVICE_TABLE(usb, id_table);
+
+ static struct usb_driver dlfb_driver;
+
++// thanks to Henrik Bjerregaard Pedersen for this function
++static char *rle_compress16(uint16_t * src, char *dst, int rem)
++{
++
++ int rl;
++ uint16_t pix0;
++ char *end_if_raw = dst + 6 + 2 * rem;
++
++ dst += 6; // header will be filled in if RLE is worth it
++
++ while (rem && dst < end_if_raw) {
++ char *start = (char *)src;
++
++ pix0 = *src++;
++ rl = 1;
++ rem--;
++ while (rem && *src == pix0)
++ rem--, rl++, src++;
++ *dst++ = rl;
++ *dst++ = start[1];
++ *dst++ = start[0];
++ }
++
++ return dst;
++}
++
++/*
++Thanks to Henrik Bjerregaard Pedersen for rle implementation and code refactoring.
++Next step is huffman compression.
++*/
++
+ static int
+ image_blit(struct dlfb_data *dev_info, int x, int y, int width, int height,
+ char *data)
+@@ -125,7 +159,7 @@ image_blit(struct dlfb_data *dev_info, i
+ int rem = width;
+ int ret;
+
+- int diff;
++ int firstdiff, thistime;
+
+ char *bufptr;
+
+@@ -137,7 +171,8 @@ image_blit(struct dlfb_data *dev_info, i
+
+ mutex_lock(&dev_info->bulk_mutex);
+
+- base = dev_info->base16 + (dev_info->info->var.xres * 2 * y) + (x * 2);
++ base =
++ dev_info->base16 + ((dev_info->info->var.xres * 2 * y) + (x * 2));
+
+ data += (dev_info->info->var.xres * 2 * y) + (x * 2);
+
+@@ -164,86 +199,84 @@ image_blit(struct dlfb_data *dev_info, i
+ bufptr - dev_info->buf);
+ bufptr = dev_info->buf;
+ }
+-
+- if (rem > 255) {
+-
+- diff = 0;
+- for (j = 0; j < 510; j++) {
+- if (dev_info->
+- backing_buffer[base + j] !=
+- data[j]) {
+- diff = 1;
+- break;
+- }
++ // number of pixels to consider this time
++ thistime = rem;
++ if (thistime > 255)
++ thistime = 255;
++
++ // find position of first pixel that has changed
++ firstdiff = -1;
++ for (j = 0; j < thistime * 2; j++) {
++ if (dev_info->backing_buffer
++ [base - dev_info->base16 + j] != data[j]) {
++ firstdiff = j / 2;
++ break;
+ }
++ }
+
+- if (diff == 1) {
+- *bufptr++ = 0xAF;
+- *bufptr++ = 0x68;
+-
+- *bufptr++ = (char)(base >> 16);
+- *bufptr++ = (char)(base >> 8);
+- *bufptr++ = (char)(base);
+- *bufptr++ = 255;
+- /* PUT COMPRESSION HERE */
+- for (j = 0; j < 510; j += 2) {
+- bufptr[j] = data[j + 1];
+- bufptr[j + 1] = data[j];
+- }
+- bufptr += 510;
+- }
+-
+- rem -= 255;
+- base += 510;
+- data += 510;
+- } else {
+-
+- diff = 0;
++ if (firstdiff >= 0) {
++ char *end_of_rle;
+
+- for (j = 0; j < rem * 2; j++) {
+- if (dev_info->
+- backing_buffer[base + j] !=
+- data[j]) {
+- diff = 1;
+- break;
+- }
+- }
++ end_of_rle =
++ rle_compress16((uint16_t *) (data +
++ firstdiff * 2),
++ bufptr,
++ thistime - firstdiff);
++
++ if (end_of_rle <
++ bufptr + 6 + 2 * (thistime - firstdiff)) {
++ bufptr[0] = 0xAF;
++ bufptr[1] = 0x69;
++
++ bufptr[2] =
++ (char)((base +
++ firstdiff * 2) >> 16);
++ bufptr[3] =
++ (char)((base + firstdiff * 2) >> 8);
++ bufptr[4] =
++ (char)(base + firstdiff * 2);
++ bufptr[5] = thistime - firstdiff;
+
+- if (diff == 1) {
++ bufptr = end_of_rle;
+
++ } else {
++ // fallback to raw (or some other encoding?)
+ *bufptr++ = 0xAF;
+ *bufptr++ = 0x68;
+
+- *bufptr++ = (char)(base >> 16);
+- *bufptr++ = (char)(base >> 8);
+- *bufptr++ = (char)(base);
+- *bufptr++ = rem;
+- /* PUT COMPRESSION HERE */
+- for (j = 0; j < rem * 2; j += 2) {
+- bufptr[j] = data[j + 1];
+- bufptr[j + 1] = data[j];
++ *bufptr++ =
++ (char)((base +
++ firstdiff * 2) >> 16);
++ *bufptr++ =
++ (char)((base + firstdiff * 2) >> 8);
++ *bufptr++ =
++ (char)(base + firstdiff * 2);
++ *bufptr++ = thistime - firstdiff;
++ // PUT COMPRESSION HERE
++ for (j = firstdiff * 2;
++ j < thistime * 2; j += 2) {
++ *bufptr++ = data[j + 1];
++ *bufptr++ = data[j];
+ }
+- bufptr += rem * 2;
+-
+ }
+-
+- base += rem * 2;
+- data += rem * 2;
+- rem = 0;
+ }
+
++ base += thistime * 2;
++ data += thistime * 2;
++ rem -= thistime;
+ }
+
+- memcpy(dev_info->backing_buffer + base - (width * 2),
+- data - (width * 2), width * 2);
++ memcpy(dev_info->backing_buffer + (base - dev_info->base16) -
++ (width * 2), data - (width * 2), width * 2);
+
+ base += (dev_info->info->var.xres * 2) - (width * 2);
+ data += (dev_info->info->var.xres * 2) - (width * 2);
+
+ }
+
+- if (bufptr > dev_info->buf)
++ if (bufptr > dev_info->buf) {
+ ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
++ }
+
+ mutex_unlock(&dev_info->bulk_mutex);
+
+@@ -280,8 +313,10 @@ draw_rect(struct dlfb_data *dev_info, in
+ for (i = y; i < y + height; i++) {
+
+ for (j = 0; j < width * 2; j += 2) {
+- dev_info->backing_buffer[base + j] = (char)(col >> 8);
+- dev_info->backing_buffer[base + j + 1] = (char)(col);
++ dev_info->backing_buffer[base - dev_info->base16 + j] =
++ (char)(col >> 8);
++ dev_info->backing_buffer[base - dev_info->base16 + j +
++ 1] = (char)(col);
+ }
+ if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
+ ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+@@ -335,6 +370,111 @@ draw_rect(struct dlfb_data *dev_info, in
+ return 1;
+ }
+
++static void swapfb(struct dlfb_data *dev_info)
++{
++
++ int tmpbase;
++ char *bufptr;
++
++ mutex_lock(&dev_info->bulk_mutex);
++
++ tmpbase = dev_info->base16;
++
++ dev_info->base16 = dev_info->base16d;
++ dev_info->base16d = tmpbase;
++
++ bufptr = dev_info->buf;
++
++ bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
++
++ // set addresses
++ bufptr =
++ dlfb_set_register(bufptr, 0x20, (char)(dev_info->base16 >> 16));
++ bufptr = dlfb_set_register(bufptr, 0x21, (char)(dev_info->base16 >> 8));
++ bufptr = dlfb_set_register(bufptr, 0x22, (char)(dev_info->base16));
++
++ bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
++
++ dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
++
++ mutex_unlock(&dev_info->bulk_mutex);
++}
++
++static int copyfb(struct dlfb_data *dev_info)
++{
++ int base;
++ int source;
++ int rem;
++ int i, ret;
++
++ char *bufptr;
++
++ base = dev_info->base16d;
++
++ mutex_lock(&dev_info->bulk_mutex);
++
++ source = dev_info->base16;
++
++ bufptr = dev_info->buf;
++
++ for (i = 0; i < dev_info->info->var.yres; i++) {
++
++ if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
++ ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
++ bufptr = dev_info->buf;
++ }
++
++ rem = dev_info->info->var.xres;
++
++ while (rem) {
++
++ if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
++ ret =
++ dlfb_bulk_msg(dev_info,
++ bufptr - dev_info->buf);
++ bufptr = dev_info->buf;
++
++ }
++
++ *bufptr++ = 0xAF;
++ *bufptr++ = 0x6A;
++
++ *bufptr++ = (char)(base >> 16);
++ *bufptr++ = (char)(base >> 8);
++ *bufptr++ = (char)(base);
++
++ if (rem > 255) {
++ *bufptr++ = 255;
++ *bufptr++ = (char)(source >> 16);
++ *bufptr++ = (char)(source >> 8);
++ *bufptr++ = (char)(source);
++
++ rem -= 255;
++ base += 255 * 2;
++ source += 255 * 2;
++
++ } else {
++ *bufptr++ = rem;
++ *bufptr++ = (char)(source >> 16);
++ *bufptr++ = (char)(source >> 8);
++ *bufptr++ = (char)(source);
++
++ base += rem * 2;
++ source += rem * 2;
++ rem = 0;
++ }
++ }
++ }
++
++ if (bufptr > dev_info->buf)
++ ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
++
++ mutex_unlock(&dev_info->bulk_mutex);
++
++ return 1;
++
++}
++
+ static int
+ copyarea(struct dlfb_data *dev_info, int dx, int dy, int sx, int sy,
+ int width, int height)
+@@ -362,7 +502,7 @@ copyarea(struct dlfb_data *dev_info, int
+
+ for (i = sy; i < sy + height; i++) {
+
+- memcpy(dev_info->backing_buffer + base,
++ memcpy(dev_info->backing_buffer + base - dev_info->base16,
+ dev_info->backing_buffer + source, width * 2);
+
+ if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
+@@ -447,7 +587,8 @@ static void dlfb_imageblit(struct fb_inf
+ /* printk("IMAGE BLIT (2) %d %d %d %d DEPTH %d {%p} %d!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev, ret); */
+ }
+
+-static void dlfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
++static void dlfb_fillrect(struct fb_info *info,
++ const struct fb_fillrect *region)
+ {
+
+ unsigned char red, green, blue;
+@@ -466,9 +607,18 @@ static int dlfb_ioctl(struct fb_info *in
+ {
+
+ struct dlfb_data *dev_info = info->par;
+- struct dloarea *area;
++ struct dloarea *area = NULL;
+
+- if (cmd == 0xAA) {
++ if (cmd == 0xAD) {
++ char *edid = (char *)arg;
++ dlfb_edid(dev_info);
++ if (copy_to_user(edid, dev_info->edid, 128)) {
++ return -EFAULT;
++ }
++ return 0;
++ }
++
++ if (cmd == 0xAA || cmd == 0xAB || cmd == 0xAC) {
+
+ area = (struct dloarea *)arg;
+
+@@ -483,10 +633,29 @@ static int dlfb_ioctl(struct fb_info *in
+
+ if (area->y > info->var.yres)
+ area->y = info->var.yres;
++ }
+
++ if (cmd == 0xAA) {
+ image_blit(dev_info, area->x, area->y, area->w, area->h,
+ info->screen_base);
+ }
++ if (cmd == 0xAC) {
++ copyfb(dev_info);
++ image_blit(dev_info, area->x, area->y, area->w, area->h,
++ info->screen_base);
++ swapfb(dev_info);
++ } else if (cmd == 0xAB) {
++
++ if (area->x2 < 0)
++ area->x2 = 0;
++
++ if (area->y2 < 0)
++ area->y2 = 0;
++
++ copyarea(dev_info,
++ area->x2, area->y2, area->x, area->y, area->w,
++ area->h);
++ }
+ return 0;
+ }
+
+@@ -528,6 +697,19 @@ static int dlfb_release(struct fb_info *
+
+ static int dlfb_blank(int blank_mode, struct fb_info *info)
+ {
++ struct dlfb_data *dev_info = info->par;
++ char *bufptr = dev_info->buf;
++
++ bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
++ if (blank_mode != FB_BLANK_UNBLANK) {
++ bufptr = dlfb_set_register(bufptr, 0x1F, 0x01);
++ } else {
++ bufptr = dlfb_set_register(bufptr, 0x1F, 0x00);
++ }
++ bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF);
++
++ dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
++
+ return 0;
+ }
+
+@@ -547,7 +729,6 @@ dlfb_probe(struct usb_interface *interfa
+ {
+ struct dlfb_data *dev_info;
+ struct fb_info *info;
+- int i;
+
+ int ret;
+ char rbuf[4];
+@@ -588,15 +769,7 @@ dlfb_probe(struct usb_interface *interfa
+ printk("ret control msg 0: %d %x%x%x%x\n", ret, rbuf[0], rbuf[1],
+ rbuf[2], rbuf[3]);
+
+- for (i = 0; i < 128; i++) {
+- ret =
+- usb_control_msg(dev_info->udev,
+- usb_rcvctrlpipe(dev_info->udev, 0), (0x02),
+- (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
+- 0);
+- /* printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */
+- dev_info->edid[i] = rbuf[1];
+- }
++ dlfb_edid(dev_info);
+
+ info = framebuffer_alloc(sizeof(u32) * 256, &dev_info->udev->dev);
+
+@@ -609,8 +782,14 @@ dlfb_probe(struct usb_interface *interfa
+
+ printk("EDID XRES %d YRES %d\n", info->var.xres, info->var.yres);
+
+- if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0)
+- goto out;
++ if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0) {
++ info->var.xres = 1280;
++ info->var.yres = 1024;
++ if (dlfb_set_video_mode
++ (dev_info, info->var.xres, info->var.yres) != 0) {
++ goto out;
++ }
++ }
+
+ printk("found valid mode...%d\n", info->var.pixclock);
+
+@@ -661,7 +840,12 @@ dlfb_probe(struct usb_interface *interfa
+
+ info->fix.smem_start = (unsigned long)info->screen_base;
+ info->fix.smem_len = PAGE_ALIGN(dev_info->screen_size);
+- memcpy(info->fix.id, "DisplayLink FB", 14);
++ if (strlen(dev_info->udev->product) > 15) {
++ memcpy(info->fix.id, dev_info->udev->product, 15);
++ } else {
++ memcpy(info->fix.id, dev_info->udev->product,
++ strlen(dev_info->udev->product));
++ }
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.accel = info->flags;
+@@ -679,13 +863,13 @@ dlfb_probe(struct usb_interface *interfa
+
+ return 0;
+
+- out2:
++out2:
+ fb_dealloc_cmap(&info->cmap);
+- out1:
++out1:
+ rvfree(info->screen_base, dev_info->screen_size);
+- out0:
++out0:
+ framebuffer_release(info);
+- out:
++out:
+ usb_set_intfdata(interface, NULL);
+ usb_put_dev(dev_info->udev);
+ kfree(dev_info);
+--- a/drivers/staging/udlfb/udlfb.h
++++ b/drivers/staging/udlfb/udlfb.h
+@@ -26,7 +26,9 @@ struct dlfb_data {
+ int line_length;
+ struct completion done;
+ int base16;
++ int base16d;
+ int base8;
++ int base8d;
+ };
+
+ struct dlfb_video_mode {
+@@ -48,6 +50,24 @@ static void dlfb_bulk_callback(struct ur
+ complete(&dev_info->done);
+ }
+
++static void dlfb_edid(struct dlfb_data *dev_info)
++{
++ int i;
++ int ret;
++ char rbuf[2];
++
++ for (i = 0; i < 128; i++) {
++ ret =
++ usb_control_msg(dev_info->udev,
++ usb_rcvctrlpipe(dev_info->udev, 0), (0x02),
++ (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
++ 0);
++ /*printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */
++ dev_info->edid[i] = rbuf[1];
++ }
++
++}
++
+ static int dlfb_bulk_msg(struct dlfb_data *dev_info, int len)
+ {
+ int ret;
+@@ -129,8 +149,12 @@ static int dlfb_set_video_mode(struct dl
+ && dlfb_video_modes[i].yres == height) {
+
+ dev_info->base16 = 0;
++ dev_info->base16d = width * height * (FB_BPP / 8);
+
+- dev_info->base8 = width * height * (FB_BPP / 8);;
++ //dev_info->base8 = width * height * (FB_BPP / 8);
++
++ dev_info->base8 = dev_info->base16;
++ dev_info->base8d = dev_info->base16d;
+
+ /* set encryption key (null) */
+ memcpy(dev_info->buf, STD_CHANNEL, 16);
+@@ -144,6 +168,9 @@ static int dlfb_set_video_mode(struct dl
+ /* set registers */
+ bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
+
++ /* set color depth */
++ bufptr = dlfb_set_register(bufptr, 0x00, 0x00);
++
+ /* set addresses */
+ bufptr =
+ dlfb_set_register(bufptr, 0x20,