diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-10 23:04:31 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-10 23:04:31 -0700 |
| commit | 0f3f33d3056bea4fc8cc48a18ced89762af3917e (patch) | |
| tree | 095aee575e708d5a695d3062a26d4210bcecad2a | |
| parent | 1ea8d85f0dbe764a2b43a210c9b564950b54d9ca (diff) | |
| download | patches-0f3f33d3056bea4fc8cc48a18ced89762af3917e.tar.gz | |
add 0.2.3 version of udlfb
| -rw-r--r-- | series | 1 | ||||
| -rw-r--r-- | staging/staging-udlfb-update-to-version-0.2.3.patch | 586 |
2 files changed, 587 insertions, 0 deletions
@@ -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, |
