Lines Matching refs:dlfb

80 static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len);
84 static struct urb *dlfb_get_urb(struct dlfb_data *dlfb);
85 static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb * urb, size_t len);
86 static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size);
87 static void dlfb_free_urb_list(struct dlfb_data *dlfb);
282 static int dlfb_set_video_mode(struct dlfb_data *dlfb, in dlfb_set_video_mode() argument
291 if (!atomic_read(&dlfb->usb_active)) in dlfb_set_video_mode()
294 urb = dlfb_get_urb(dlfb); in dlfb_set_video_mode()
310 wrptr = dlfb_set_base8bpp(wrptr, dlfb->info->fix.smem_len); in dlfb_set_video_mode()
318 retval = dlfb_submit_urb(dlfb, urb, writesize); in dlfb_set_video_mode()
320 dlfb->blank_mode = FB_BLANK_UNBLANK; in dlfb_set_video_mode()
538 static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr, in dlfb_render_hline() argument
544 u32 dev_addr = dlfb->base16 + byte_offset; in dlfb_render_hline()
554 if (dlfb->backing_buffer) { in dlfb_render_hline()
556 const u8 *back_start = (u8 *) (dlfb->backing_buffer in dlfb_render_hline()
580 if (dlfb_submit_urb(dlfb, urb, len)) in dlfb_render_hline()
583 urb = dlfb_get_urb(dlfb); in dlfb_render_hline()
597 static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, in dlfb_handle_damage() argument
615 (x + width > dlfb->info->var.xres) || in dlfb_handle_damage()
616 (y + height > dlfb->info->var.yres)) in dlfb_handle_damage()
619 if (!atomic_read(&dlfb->usb_active)) in dlfb_handle_damage()
622 urb = dlfb_get_urb(dlfb); in dlfb_handle_damage()
628 const int line_offset = dlfb->info->fix.line_length * i; in dlfb_handle_damage()
631 if (dlfb_render_hline(dlfb, &urb, in dlfb_handle_damage()
632 (char *) dlfb->info->fix.smem_start, in dlfb_handle_damage()
644 ret = dlfb_submit_urb(dlfb, urb, len); in dlfb_handle_damage()
650 atomic_add(bytes_sent, &dlfb->bytes_sent); in dlfb_handle_damage()
651 atomic_add(bytes_identical, &dlfb->bytes_identical); in dlfb_handle_damage()
652 atomic_add(width*height*2, &dlfb->bytes_rendered); in dlfb_handle_damage()
656 &dlfb->cpu_kcycles_used); in dlfb_handle_damage()
671 struct dlfb_data *dlfb = info->par; in dlfb_ops_write() local
681 dlfb_handle_damage(dlfb, 0, start, info->var.xres, in dlfb_ops_write()
693 struct dlfb_data *dlfb = info->par; in dlfb_ops_copyarea() local
697 dlfb_handle_damage(dlfb, area->dx, area->dy, in dlfb_ops_copyarea()
704 struct dlfb_data *dlfb = info->par; in dlfb_ops_imageblit() local
708 dlfb_handle_damage(dlfb, image->dx, image->dy, in dlfb_ops_imageblit()
715 struct dlfb_data *dlfb = info->par; in dlfb_ops_fillrect() local
719 dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width, in dlfb_ops_fillrect()
734 struct dlfb_data *dlfb = info->par; in dlfb_dpy_deferred_io() local
745 if (!atomic_read(&dlfb->usb_active)) in dlfb_dpy_deferred_io()
750 urb = dlfb_get_urb(dlfb); in dlfb_dpy_deferred_io()
759 if (dlfb_render_hline(dlfb, &urb, (char *) info->fix.smem_start, in dlfb_dpy_deferred_io()
772 dlfb_submit_urb(dlfb, urb, len); in dlfb_dpy_deferred_io()
778 atomic_add(bytes_sent, &dlfb->bytes_sent); in dlfb_dpy_deferred_io()
779 atomic_add(bytes_identical, &dlfb->bytes_identical); in dlfb_dpy_deferred_io()
780 atomic_add(bytes_rendered, &dlfb->bytes_rendered); in dlfb_dpy_deferred_io()
784 &dlfb->cpu_kcycles_used); in dlfb_dpy_deferred_io()
787 static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len) in dlfb_get_edid() argument
797 ret = usb_control_msg(dlfb->udev, in dlfb_get_edid()
798 usb_rcvctrlpipe(dlfb->udev, 0), 0x02, in dlfb_get_edid()
802 dev_err(&dlfb->udev->dev, in dlfb_get_edid()
819 struct dlfb_data *dlfb = info->par; in dlfb_ops_ioctl() local
821 if (!atomic_read(&dlfb->usb_active)) in dlfb_ops_ioctl()
827 if (copy_to_user(edid, dlfb->edid, dlfb->edid_size)) in dlfb_ops_ioctl()
862 dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h, in dlfb_ops_ioctl()
903 struct dlfb_data *dlfb = info->par; in dlfb_ops_open() local
914 if (dlfb->virtualized) in dlfb_ops_open()
917 dlfb->fb_count++; in dlfb_ops_open()
919 kref_get(&dlfb->kref); in dlfb_ops_open()
938 user, info, dlfb->fb_count); in dlfb_ops_open()
950 struct dlfb_data *dlfb = container_of(kref, struct dlfb_data, kref); in dlfb_free() local
952 while (!list_empty(&dlfb->deferred_free)) { in dlfb_free()
953 …struct dlfb_deferred_free *d = list_entry(dlfb->deferred_free.next, struct dlfb_deferred_free, lis… in dlfb_free()
958 vfree(dlfb->backing_buffer); in dlfb_free()
959 kfree(dlfb->edid); in dlfb_free()
960 kfree(dlfb); in dlfb_free()
963 static void dlfb_free_framebuffer(struct dlfb_data *dlfb) in dlfb_free_framebuffer() argument
965 struct fb_info *info = dlfb->info; in dlfb_free_framebuffer()
978 dlfb->info = NULL; in dlfb_free_framebuffer()
985 kref_put(&dlfb->kref, dlfb_free); in dlfb_free_framebuffer()
990 struct dlfb_data *dlfb = container_of(work, struct dlfb_data, in dlfb_free_framebuffer_work() local
992 dlfb_free_framebuffer(dlfb); in dlfb_free_framebuffer_work()
999 struct dlfb_data *dlfb = info->par; in dlfb_ops_release() local
1001 dlfb->fb_count--; in dlfb_ops_release()
1004 if (dlfb->virtualized && (dlfb->fb_count == 0)) in dlfb_ops_release()
1005 schedule_delayed_work(&dlfb->free_framebuffer_work, HZ); in dlfb_ops_release()
1007 if ((dlfb->fb_count == 0) && (info->fbdefio)) { in dlfb_ops_release()
1014 dev_dbg(info->dev, "release, user=%d count=%d\n", user, dlfb->fb_count); in dlfb_ops_release()
1016 kref_put(&dlfb->kref, dlfb_free); in dlfb_ops_release()
1025 static int dlfb_is_valid_mode(struct fb_videomode *mode, struct dlfb_data *dlfb) in dlfb_is_valid_mode() argument
1027 if (mode->xres * mode->yres > dlfb->sku_pixel_limit) in dlfb_is_valid_mode()
1049 struct dlfb_data *dlfb = info->par; in dlfb_ops_check_var() local
1056 if (!dlfb_is_valid_mode(&mode, dlfb)) in dlfb_ops_check_var()
1064 struct dlfb_data *dlfb = info->par; in dlfb_ops_set_par() local
1076 if (!memcmp(&dlfb->current_mode, &fvs, sizeof(struct fb_var_screeninfo))) in dlfb_ops_set_par()
1079 result = dlfb_realloc_framebuffer(dlfb, info, info->var.yres * line_length); in dlfb_ops_set_par()
1083 result = dlfb_set_video_mode(dlfb, &info->var); in dlfb_ops_set_par()
1088 dlfb->current_mode = fvs; in dlfb_ops_set_par()
1091 if (dlfb->fb_count == 0) { in dlfb_ops_set_par()
1100 dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres, in dlfb_ops_set_par()
1126 struct dlfb_data *dlfb = info->par; in dlfb_ops_blank() local
1131 dlfb->blank_mode, blank_mode); in dlfb_ops_blank()
1133 if ((dlfb->blank_mode == FB_BLANK_POWERDOWN) && in dlfb_ops_blank()
1137 dlfb_set_video_mode(dlfb, &info->var); in dlfb_ops_blank()
1140 urb = dlfb_get_urb(dlfb); in dlfb_ops_blank()
1152 dlfb_submit_urb(dlfb, urb, bufptr - in dlfb_ops_blank()
1155 dlfb->blank_mode = blank_mode; in dlfb_ops_blank()
1178 static void dlfb_deferred_vfree(struct dlfb_data *dlfb, void *mem) in dlfb_deferred_vfree() argument
1184 list_add(&d->list, &dlfb->deferred_free); in dlfb_deferred_vfree()
1191 static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len) in dlfb_realloc_framebuffer() argument
1213 dlfb_deferred_vfree(dlfb, (void __force *)info->screen_base); in dlfb_realloc_framebuffer()
1233 dlfb_deferred_vfree(dlfb, dlfb->backing_buffer); in dlfb_realloc_framebuffer()
1234 dlfb->backing_buffer = new_back; in dlfb_realloc_framebuffer()
1254 static int dlfb_setup_modes(struct dlfb_data *dlfb, in dlfb_setup_modes() argument
1287 i = dlfb_get_edid(dlfb, edid, EDID_LENGTH); in dlfb_setup_modes()
1293 dlfb->edid = edid; in dlfb_setup_modes()
1294 dlfb->edid_size = i; in dlfb_setup_modes()
1303 if (dlfb->edid) { in dlfb_setup_modes()
1304 fb_edid_to_monspecs(dlfb->edid, &info->monspecs); in dlfb_setup_modes()
1316 dlfb->edid = edid; in dlfb_setup_modes()
1317 dlfb->edid_size = default_edid_size; in dlfb_setup_modes()
1328 if (dlfb_is_valid_mode(mode, dlfb)) { in dlfb_setup_modes()
1357 if (dlfb_is_valid_mode(mode, dlfb)) in dlfb_setup_modes()
1376 if ((default_vmode != NULL) && (dlfb->fb_count == 0)) { in dlfb_setup_modes()
1389 if (edid && (dlfb->edid != edid)) in dlfb_setup_modes()
1401 struct dlfb_data *dlfb = fb_info->par; in metrics_bytes_rendered_show() local
1403 atomic_read(&dlfb->bytes_rendered)); in metrics_bytes_rendered_show()
1409 struct dlfb_data *dlfb = fb_info->par; in metrics_bytes_identical_show() local
1411 atomic_read(&dlfb->bytes_identical)); in metrics_bytes_identical_show()
1417 struct dlfb_data *dlfb = fb_info->par; in metrics_bytes_sent_show() local
1419 atomic_read(&dlfb->bytes_sent)); in metrics_bytes_sent_show()
1425 struct dlfb_data *dlfb = fb_info->par; in metrics_cpu_kcycles_used_show() local
1427 atomic_read(&dlfb->cpu_kcycles_used)); in metrics_cpu_kcycles_used_show()
1436 struct dlfb_data *dlfb = fb_info->par; in edid_show() local
1438 if (dlfb->edid == NULL) in edid_show()
1441 if ((off >= dlfb->edid_size) || (count > dlfb->edid_size)) in edid_show()
1444 if (off + count > dlfb->edid_size) in edid_show()
1445 count = dlfb->edid_size - off; in edid_show()
1447 memcpy(buf, dlfb->edid, count); in edid_show()
1458 struct dlfb_data *dlfb = fb_info->par; in edid_store() local
1465 ret = dlfb_setup_modes(dlfb, fb_info, src, src_size); in edid_store()
1469 if (!dlfb->edid || memcmp(src, dlfb->edid, src_size)) in edid_store()
1484 struct dlfb_data *dlfb = fb_info->par; in metrics_reset_store() local
1486 atomic_set(&dlfb->bytes_rendered, 0); in metrics_reset_store()
1487 atomic_set(&dlfb->bytes_identical, 0); in metrics_reset_store()
1488 atomic_set(&dlfb->bytes_sent, 0); in metrics_reset_store()
1489 atomic_set(&dlfb->cpu_kcycles_used, 0); in metrics_reset_store()
1513 static int dlfb_select_std_channel(struct dlfb_data *dlfb) in dlfb_select_std_channel() argument
1528 ret = usb_control_msg(dlfb->udev, usb_sndctrlpipe(dlfb->udev, 0), in dlfb_select_std_channel()
1538 static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb, in dlfb_parse_vendor_descriptor() argument
1594 dlfb->sku_pixel_limit = max_area; in dlfb_parse_vendor_descriptor()
1623 struct dlfb_data *dlfb; in dlfb_usb_probe() local
1628 dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL); in dlfb_usb_probe()
1629 if (!dlfb) { in dlfb_usb_probe()
1634 kref_init(&dlfb->kref); /* matching kref_put in usb .disconnect fn */ in dlfb_usb_probe()
1635 INIT_LIST_HEAD(&dlfb->deferred_free); in dlfb_usb_probe()
1637 dlfb->udev = usbdev; in dlfb_usb_probe()
1638 usb_set_intfdata(intf, dlfb); in dlfb_usb_probe()
1644 dlfb->sku_pixel_limit = 2048 * 1152; /* default to maximum */ in dlfb_usb_probe()
1646 if (!dlfb_parse_vendor_descriptor(dlfb, intf)) { in dlfb_usb_probe()
1655 dlfb->sku_pixel_limit, pixel_limit); in dlfb_usb_probe()
1656 dlfb->sku_pixel_limit = pixel_limit; in dlfb_usb_probe()
1660 if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) { in dlfb_usb_probe()
1666 kref_get(&dlfb->kref); /* matching kref_put in free_framebuffer_work */ in dlfb_usb_probe()
1671 INIT_DELAYED_WORK(&dlfb->init_framebuffer_work, in dlfb_usb_probe()
1673 schedule_delayed_work(&dlfb->init_framebuffer_work, 0); in dlfb_usb_probe()
1678 if (dlfb) { in dlfb_usb_probe()
1680 kref_put(&dlfb->kref, dlfb_free); /* last ref from kref_init */ in dlfb_usb_probe()
1693 struct dlfb_data *dlfb = container_of(work, struct dlfb_data, in dlfb_init_framebuffer_work() local
1697 info = framebuffer_alloc(0, &dlfb->udev->dev); in dlfb_init_framebuffer_work()
1699 dev_err(&dlfb->udev->dev, "framebuffer_alloc failed\n"); in dlfb_init_framebuffer_work()
1703 dlfb->info = info; in dlfb_init_framebuffer_work()
1704 info->par = dlfb; in dlfb_init_framebuffer_work()
1705 info->pseudo_palette = dlfb->pseudo_palette; in dlfb_init_framebuffer_work()
1706 dlfb->ops = dlfb_ops; in dlfb_init_framebuffer_work()
1707 info->fbops = &dlfb->ops; in dlfb_init_framebuffer_work()
1715 INIT_DELAYED_WORK(&dlfb->free_framebuffer_work, in dlfb_init_framebuffer_work()
1720 retval = dlfb_setup_modes(dlfb, info, NULL, 0); in dlfb_init_framebuffer_work()
1729 atomic_set(&dlfb->usb_active, 1); in dlfb_init_framebuffer_work()
1730 dlfb_select_std_channel(dlfb); in dlfb_init_framebuffer_work()
1761 ((dlfb->backing_buffer) ? in dlfb_init_framebuffer_work()
1766 dlfb_free_framebuffer(dlfb); in dlfb_init_framebuffer_work()
1771 struct dlfb_data *dlfb; in dlfb_usb_disconnect() local
1775 dlfb = usb_get_intfdata(intf); in dlfb_usb_disconnect()
1776 info = dlfb->info; in dlfb_usb_disconnect()
1781 dlfb->virtualized = true; in dlfb_usb_disconnect()
1784 atomic_set(&dlfb->usb_active, 0); in dlfb_usb_disconnect()
1787 dlfb_free_urb_list(dlfb); in dlfb_usb_disconnect()
1798 dlfb->udev = NULL; in dlfb_usb_disconnect()
1801 if (dlfb->fb_count == 0) in dlfb_usb_disconnect()
1802 schedule_delayed_work(&dlfb->free_framebuffer_work, 0); in dlfb_usb_disconnect()
1805 kref_put(&dlfb->kref, dlfb_free); in dlfb_usb_disconnect()
1822 struct dlfb_data *dlfb = unode->dlfb; in dlfb_urb_completion() local
1835 dev_err(&dlfb->udev->dev, in dlfb_urb_completion()
1838 atomic_set(&dlfb->lost_pixels, 1); in dlfb_urb_completion()
1842 urb->transfer_buffer_length = dlfb->urbs.size; /* reset to actual */ in dlfb_urb_completion()
1844 spin_lock_irqsave(&dlfb->urbs.lock, flags); in dlfb_urb_completion()
1845 list_add_tail(&unode->entry, &dlfb->urbs.list); in dlfb_urb_completion()
1846 dlfb->urbs.available++; in dlfb_urb_completion()
1847 spin_unlock_irqrestore(&dlfb->urbs.lock, flags); in dlfb_urb_completion()
1849 up(&dlfb->urbs.limit_sem); in dlfb_urb_completion()
1852 static void dlfb_free_urb_list(struct dlfb_data *dlfb) in dlfb_free_urb_list() argument
1854 int count = dlfb->urbs.count; in dlfb_free_urb_list()
1861 down(&dlfb->urbs.limit_sem); in dlfb_free_urb_list()
1863 spin_lock_irq(&dlfb->urbs.lock); in dlfb_free_urb_list()
1865 node = dlfb->urbs.list.next; /* have reserved one with sem */ in dlfb_free_urb_list()
1868 spin_unlock_irq(&dlfb->urbs.lock); in dlfb_free_urb_list()
1874 usb_free_coherent(urb->dev, dlfb->urbs.size, in dlfb_free_urb_list()
1880 dlfb->urbs.count = 0; in dlfb_free_urb_list()
1883 static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size) in dlfb_alloc_urb_list() argument
1890 spin_lock_init(&dlfb->urbs.lock); in dlfb_alloc_urb_list()
1893 dlfb->urbs.size = size; in dlfb_alloc_urb_list()
1894 INIT_LIST_HEAD(&dlfb->urbs.list); in dlfb_alloc_urb_list()
1896 sema_init(&dlfb->urbs.limit_sem, 0); in dlfb_alloc_urb_list()
1897 dlfb->urbs.count = 0; in dlfb_alloc_urb_list()
1898 dlfb->urbs.available = 0; in dlfb_alloc_urb_list()
1900 while (dlfb->urbs.count * size < wanted_size) { in dlfb_alloc_urb_list()
1904 unode->dlfb = dlfb; in dlfb_alloc_urb_list()
1913 buf = usb_alloc_coherent(dlfb->udev, size, GFP_KERNEL, in dlfb_alloc_urb_list()
1920 dlfb_free_urb_list(dlfb); in dlfb_alloc_urb_list()
1927 usb_fill_bulk_urb(urb, dlfb->udev, usb_sndbulkpipe(dlfb->udev, 1), in dlfb_alloc_urb_list()
1931 list_add_tail(&unode->entry, &dlfb->urbs.list); in dlfb_alloc_urb_list()
1933 up(&dlfb->urbs.limit_sem); in dlfb_alloc_urb_list()
1934 dlfb->urbs.count++; in dlfb_alloc_urb_list()
1935 dlfb->urbs.available++; in dlfb_alloc_urb_list()
1938 return dlfb->urbs.count; in dlfb_alloc_urb_list()
1941 static struct urb *dlfb_get_urb(struct dlfb_data *dlfb) in dlfb_get_urb() argument
1948 ret = down_timeout(&dlfb->urbs.limit_sem, GET_URB_TIMEOUT); in dlfb_get_urb()
1950 atomic_set(&dlfb->lost_pixels, 1); in dlfb_get_urb()
1951 dev_warn(&dlfb->udev->dev, in dlfb_get_urb()
1953 ret, dlfb->urbs.available); in dlfb_get_urb()
1957 spin_lock_irq(&dlfb->urbs.lock); in dlfb_get_urb()
1959 BUG_ON(list_empty(&dlfb->urbs.list)); /* reserved one with limit_sem */ in dlfb_get_urb()
1960 entry = dlfb->urbs.list.next; in dlfb_get_urb()
1962 dlfb->urbs.available--; in dlfb_get_urb()
1964 spin_unlock_irq(&dlfb->urbs.lock); in dlfb_get_urb()
1970 static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb *urb, size_t len) in dlfb_submit_urb() argument
1974 BUG_ON(len > dlfb->urbs.size); in dlfb_submit_urb()
1980 atomic_set(&dlfb->lost_pixels, 1); in dlfb_submit_urb()
1981 dev_err(&dlfb->udev->dev, "submit urb error: %d\n", ret); in dlfb_submit_urb()