Lines Matching refs:dlfb
79 static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len);
83 static struct urb *dlfb_get_urb(struct dlfb_data *dlfb);
84 static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb * urb, size_t len);
85 static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size);
86 static void dlfb_free_urb_list(struct dlfb_data *dlfb);
281 static int dlfb_set_video_mode(struct dlfb_data *dlfb, in dlfb_set_video_mode() argument
290 if (!atomic_read(&dlfb->usb_active)) in dlfb_set_video_mode()
293 urb = dlfb_get_urb(dlfb); in dlfb_set_video_mode()
309 wrptr = dlfb_set_base8bpp(wrptr, dlfb->info->fix.smem_len); in dlfb_set_video_mode()
317 retval = dlfb_submit_urb(dlfb, urb, writesize); in dlfb_set_video_mode()
319 dlfb->blank_mode = FB_BLANK_UNBLANK; in dlfb_set_video_mode()
542 static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr, in dlfb_render_hline() argument
548 u32 dev_addr = dlfb->base16 + byte_offset; in dlfb_render_hline()
558 if (dlfb->backing_buffer) { in dlfb_render_hline()
560 const u8 *back_start = (u8 *) (dlfb->backing_buffer in dlfb_render_hline()
584 if (dlfb_submit_urb(dlfb, urb, len)) in dlfb_render_hline()
587 urb = dlfb_get_urb(dlfb); in dlfb_render_hline()
601 static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) in dlfb_handle_damage() argument
613 mutex_lock(&dlfb->render_mutex); in dlfb_handle_damage()
620 (x + width > dlfb->info->var.xres) || in dlfb_handle_damage()
621 (y + height > dlfb->info->var.yres)) { in dlfb_handle_damage()
626 if (!atomic_read(&dlfb->usb_active)) { in dlfb_handle_damage()
631 urb = dlfb_get_urb(dlfb); in dlfb_handle_damage()
639 const int line_offset = dlfb->info->fix.line_length * i; in dlfb_handle_damage()
642 if (dlfb_render_hline(dlfb, &urb, in dlfb_handle_damage()
643 (char *) dlfb->info->fix.smem_start, in dlfb_handle_damage()
655 dlfb_submit_urb(dlfb, urb, len); in dlfb_handle_damage()
661 atomic_add(bytes_sent, &dlfb->bytes_sent); in dlfb_handle_damage()
662 atomic_add(bytes_identical, &dlfb->bytes_identical); in dlfb_handle_damage()
663 atomic_add(width*height*2, &dlfb->bytes_rendered); in dlfb_handle_damage()
667 &dlfb->cpu_kcycles_used); in dlfb_handle_damage()
672 mutex_unlock(&dlfb->render_mutex); in dlfb_handle_damage()
676 static void dlfb_init_damage(struct dlfb_data *dlfb) in dlfb_init_damage() argument
678 dlfb->damage_x = INT_MAX; in dlfb_init_damage()
679 dlfb->damage_x2 = 0; in dlfb_init_damage()
680 dlfb->damage_y = INT_MAX; in dlfb_init_damage()
681 dlfb->damage_y2 = 0; in dlfb_init_damage()
686 struct dlfb_data *dlfb = container_of(w, struct dlfb_data, damage_work); in dlfb_damage_work() local
689 spin_lock_irq(&dlfb->damage_lock); in dlfb_damage_work()
690 x = dlfb->damage_x; in dlfb_damage_work()
691 x2 = dlfb->damage_x2; in dlfb_damage_work()
692 y = dlfb->damage_y; in dlfb_damage_work()
693 y2 = dlfb->damage_y2; in dlfb_damage_work()
694 dlfb_init_damage(dlfb); in dlfb_damage_work()
695 spin_unlock_irq(&dlfb->damage_lock); in dlfb_damage_work()
698 dlfb_handle_damage(dlfb, x, y, x2 - x, y2 - y); in dlfb_damage_work()
701 static void dlfb_offload_damage(struct dlfb_data *dlfb, int x, int y, int width, int height) in dlfb_offload_damage() argument
710 spin_lock_irqsave(&dlfb->damage_lock, flags); in dlfb_offload_damage()
711 dlfb->damage_x = min(x, dlfb->damage_x); in dlfb_offload_damage()
712 dlfb->damage_x2 = max(x2, dlfb->damage_x2); in dlfb_offload_damage()
713 dlfb->damage_y = min(y, dlfb->damage_y); in dlfb_offload_damage()
714 dlfb->damage_y2 = max(y2, dlfb->damage_y2); in dlfb_offload_damage()
715 spin_unlock_irqrestore(&dlfb->damage_lock, flags); in dlfb_offload_damage()
717 schedule_work(&dlfb->damage_work); in dlfb_offload_damage()
729 struct dlfb_data *dlfb = info->par; in dlfb_dpy_deferred_io() local
737 mutex_lock(&dlfb->render_mutex); in dlfb_dpy_deferred_io()
742 if (!atomic_read(&dlfb->usb_active)) in dlfb_dpy_deferred_io()
747 urb = dlfb_get_urb(dlfb); in dlfb_dpy_deferred_io()
755 if (dlfb_render_hline(dlfb, &urb, (char *) info->fix.smem_start, in dlfb_dpy_deferred_io()
768 dlfb_submit_urb(dlfb, urb, len); in dlfb_dpy_deferred_io()
774 atomic_add(bytes_sent, &dlfb->bytes_sent); in dlfb_dpy_deferred_io()
775 atomic_add(bytes_identical, &dlfb->bytes_identical); in dlfb_dpy_deferred_io()
776 atomic_add(bytes_rendered, &dlfb->bytes_rendered); in dlfb_dpy_deferred_io()
780 &dlfb->cpu_kcycles_used); in dlfb_dpy_deferred_io()
782 mutex_unlock(&dlfb->render_mutex); in dlfb_dpy_deferred_io()
785 static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len) in dlfb_get_edid() argument
795 ret = usb_control_msg(dlfb->udev, in dlfb_get_edid()
796 usb_rcvctrlpipe(dlfb->udev, 0), 0x02, in dlfb_get_edid()
800 dev_err(&dlfb->udev->dev, in dlfb_get_edid()
817 struct dlfb_data *dlfb = info->par; in dlfb_ops_ioctl() local
819 if (!atomic_read(&dlfb->usb_active)) in dlfb_ops_ioctl()
825 if (copy_to_user(edid, dlfb->edid, dlfb->edid_size)) in dlfb_ops_ioctl()
860 dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h); in dlfb_ops_ioctl()
900 struct dlfb_data *dlfb = info->par; in dlfb_ops_open() local
911 if (dlfb->virtualized) in dlfb_ops_open()
914 dlfb->fb_count++; in dlfb_ops_open()
934 user, info, dlfb->fb_count); in dlfb_ops_open()
941 struct dlfb_data *dlfb = info->par; in dlfb_ops_destroy() local
943 cancel_work_sync(&dlfb->damage_work); in dlfb_ops_destroy()
945 mutex_destroy(&dlfb->render_mutex); in dlfb_ops_destroy()
955 while (!list_empty(&dlfb->deferred_free)) { in dlfb_ops_destroy()
956 …struct dlfb_deferred_free *d = list_entry(dlfb->deferred_free.next, struct dlfb_deferred_free, lis… in dlfb_ops_destroy()
961 vfree(dlfb->backing_buffer); in dlfb_ops_destroy()
962 kfree(dlfb->edid); in dlfb_ops_destroy()
963 dlfb_free_urb_list(dlfb); in dlfb_ops_destroy()
964 usb_put_dev(dlfb->udev); in dlfb_ops_destroy()
965 kfree(dlfb); in dlfb_ops_destroy()
976 struct dlfb_data *dlfb = info->par; in dlfb_ops_release() local
978 dlfb->fb_count--; in dlfb_ops_release()
980 if ((dlfb->fb_count == 0) && (info->fbdefio)) { in dlfb_ops_release()
986 dev_dbg(info->dev, "release, user=%d count=%d\n", user, dlfb->fb_count); in dlfb_ops_release()
995 static int dlfb_is_valid_mode(struct fb_videomode *mode, struct dlfb_data *dlfb) in dlfb_is_valid_mode() argument
997 if (mode->xres * mode->yres > dlfb->sku_pixel_limit) in dlfb_is_valid_mode()
1019 struct dlfb_data *dlfb = info->par; in dlfb_ops_check_var() local
1026 if (!dlfb_is_valid_mode(&mode, dlfb)) in dlfb_ops_check_var()
1034 struct dlfb_data *dlfb = info->par; in dlfb_ops_set_par() local
1046 if (!memcmp(&dlfb->current_mode, &fvs, sizeof(struct fb_var_screeninfo))) in dlfb_ops_set_par()
1049 result = dlfb_realloc_framebuffer(dlfb, info, info->var.yres * line_length); in dlfb_ops_set_par()
1053 result = dlfb_set_video_mode(dlfb, &info->var); in dlfb_ops_set_par()
1058 dlfb->current_mode = fvs; in dlfb_ops_set_par()
1061 if (dlfb->fb_count == 0) { in dlfb_ops_set_par()
1070 dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres); in dlfb_ops_set_par()
1095 struct dlfb_data *dlfb = info->par; in dlfb_ops_blank() local
1100 dlfb->blank_mode, blank_mode); in dlfb_ops_blank()
1102 if ((dlfb->blank_mode == FB_BLANK_POWERDOWN) && in dlfb_ops_blank()
1106 dlfb_set_video_mode(dlfb, &info->var); in dlfb_ops_blank()
1109 urb = dlfb_get_urb(dlfb); in dlfb_ops_blank()
1121 dlfb_submit_urb(dlfb, urb, bufptr - in dlfb_ops_blank()
1124 dlfb->blank_mode = blank_mode; in dlfb_ops_blank()
1131 struct dlfb_data *dlfb = info->par; in dlfb_ops_damage_range() local
1135 dlfb_handle_damage(dlfb, 0, start, info->var.xres, lines); in dlfb_ops_damage_range()
1140 struct dlfb_data *dlfb = info->par; in dlfb_ops_damage_area() local
1142 dlfb_offload_damage(dlfb, x, y, width, height); in dlfb_ops_damage_area()
1165 static void dlfb_deferred_vfree(struct dlfb_data *dlfb, void *mem) in dlfb_deferred_vfree() argument
1171 list_add(&d->list, &dlfb->deferred_free); in dlfb_deferred_vfree()
1178 static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len) in dlfb_realloc_framebuffer() argument
1200 dlfb_deferred_vfree(dlfb, info->screen_buffer); in dlfb_realloc_framebuffer()
1220 dlfb_deferred_vfree(dlfb, dlfb->backing_buffer); in dlfb_realloc_framebuffer()
1221 dlfb->backing_buffer = new_back; in dlfb_realloc_framebuffer()
1241 static int dlfb_setup_modes(struct dlfb_data *dlfb, in dlfb_setup_modes() argument
1274 i = dlfb_get_edid(dlfb, edid, EDID_LENGTH); in dlfb_setup_modes()
1280 dlfb->edid = edid; in dlfb_setup_modes()
1281 dlfb->edid_size = i; in dlfb_setup_modes()
1290 if (dlfb->edid) { in dlfb_setup_modes()
1291 fb_edid_to_monspecs(dlfb->edid, &info->monspecs); in dlfb_setup_modes()
1303 dlfb->edid = edid; in dlfb_setup_modes()
1304 dlfb->edid_size = default_edid_size; in dlfb_setup_modes()
1315 if (dlfb_is_valid_mode(mode, dlfb)) { in dlfb_setup_modes()
1344 if (dlfb_is_valid_mode(mode, dlfb)) in dlfb_setup_modes()
1363 if ((default_vmode != NULL) && (dlfb->fb_count == 0)) { in dlfb_setup_modes()
1376 if (edid && (dlfb->edid != edid)) in dlfb_setup_modes()
1388 struct dlfb_data *dlfb = fb_info->par; in metrics_bytes_rendered_show() local
1390 atomic_read(&dlfb->bytes_rendered)); in metrics_bytes_rendered_show()
1396 struct dlfb_data *dlfb = fb_info->par; in metrics_bytes_identical_show() local
1398 atomic_read(&dlfb->bytes_identical)); in metrics_bytes_identical_show()
1404 struct dlfb_data *dlfb = fb_info->par; in metrics_bytes_sent_show() local
1406 atomic_read(&dlfb->bytes_sent)); in metrics_bytes_sent_show()
1412 struct dlfb_data *dlfb = fb_info->par; in metrics_cpu_kcycles_used_show() local
1414 atomic_read(&dlfb->cpu_kcycles_used)); in metrics_cpu_kcycles_used_show()
1423 struct dlfb_data *dlfb = fb_info->par; in edid_show() local
1425 if (dlfb->edid == NULL) in edid_show()
1428 if ((off >= dlfb->edid_size) || (count > dlfb->edid_size)) in edid_show()
1431 if (off + count > dlfb->edid_size) in edid_show()
1432 count = dlfb->edid_size - off; in edid_show()
1434 memcpy(buf, dlfb->edid, count); in edid_show()
1445 struct dlfb_data *dlfb = fb_info->par; in edid_store() local
1452 ret = dlfb_setup_modes(dlfb, fb_info, src, src_size); in edid_store()
1456 if (!dlfb->edid || memcmp(src, dlfb->edid, src_size)) in edid_store()
1471 struct dlfb_data *dlfb = fb_info->par; in metrics_reset_store() local
1473 atomic_set(&dlfb->bytes_rendered, 0); in metrics_reset_store()
1474 atomic_set(&dlfb->bytes_identical, 0); in metrics_reset_store()
1475 atomic_set(&dlfb->bytes_sent, 0); in metrics_reset_store()
1476 atomic_set(&dlfb->cpu_kcycles_used, 0); in metrics_reset_store()
1500 static int dlfb_select_std_channel(struct dlfb_data *dlfb) in dlfb_select_std_channel() argument
1509 ret = usb_control_msg_send(dlfb->udev, 0, NR_USB_REQUEST_CHANNEL, in dlfb_select_std_channel()
1517 static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb, in dlfb_parse_vendor_descriptor() argument
1573 dlfb->sku_pixel_limit = max_area; in dlfb_parse_vendor_descriptor()
1602 struct dlfb_data *dlfb; in dlfb_usb_probe() local
1609 dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL); in dlfb_usb_probe()
1610 if (!dlfb) { in dlfb_usb_probe()
1615 INIT_LIST_HEAD(&dlfb->deferred_free); in dlfb_usb_probe()
1617 dlfb->udev = usb_get_dev(usbdev); in dlfb_usb_probe()
1618 usb_set_intfdata(intf, dlfb); in dlfb_usb_probe()
1630 dlfb->sku_pixel_limit = 2048 * 1152; /* default to maximum */ in dlfb_usb_probe()
1632 if (!dlfb_parse_vendor_descriptor(dlfb, intf)) { in dlfb_usb_probe()
1642 dlfb->sku_pixel_limit, pixel_limit); in dlfb_usb_probe()
1643 dlfb->sku_pixel_limit = pixel_limit; in dlfb_usb_probe()
1648 info = framebuffer_alloc(0, &dlfb->udev->dev); in dlfb_usb_probe()
1654 dlfb->info = info; in dlfb_usb_probe()
1655 info->par = dlfb; in dlfb_usb_probe()
1656 info->pseudo_palette = dlfb->pseudo_palette; in dlfb_usb_probe()
1657 dlfb->ops = dlfb_ops; in dlfb_usb_probe()
1658 info->fbops = &dlfb->ops; in dlfb_usb_probe()
1660 mutex_init(&dlfb->render_mutex); in dlfb_usb_probe()
1661 dlfb_init_damage(dlfb); in dlfb_usb_probe()
1662 spin_lock_init(&dlfb->damage_lock); in dlfb_usb_probe()
1663 INIT_WORK(&dlfb->damage_work, dlfb_damage_work); in dlfb_usb_probe()
1667 if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) { in dlfb_usb_probe()
1681 retval = dlfb_setup_modes(dlfb, info, NULL, 0); in dlfb_usb_probe()
1690 atomic_set(&dlfb->usb_active, 1); in dlfb_usb_probe()
1691 dlfb_select_std_channel(dlfb); in dlfb_usb_probe()
1722 ((dlfb->backing_buffer) ? in dlfb_usb_probe()
1727 if (dlfb->info) { in dlfb_usb_probe()
1728 dlfb_ops_destroy(dlfb->info); in dlfb_usb_probe()
1730 usb_put_dev(dlfb->udev); in dlfb_usb_probe()
1731 kfree(dlfb); in dlfb_usb_probe()
1738 struct dlfb_data *dlfb; in dlfb_usb_disconnect() local
1742 dlfb = usb_get_intfdata(intf); in dlfb_usb_disconnect()
1743 info = dlfb->info; in dlfb_usb_disconnect()
1748 dlfb->virtualized = true; in dlfb_usb_disconnect()
1751 atomic_set(&dlfb->usb_active, 0); in dlfb_usb_disconnect()
1754 dlfb_free_urb_list(dlfb); in dlfb_usb_disconnect()
1776 struct dlfb_data *dlfb = unode->dlfb; in dlfb_urb_completion() local
1789 dev_err(&dlfb->udev->dev, in dlfb_urb_completion()
1792 atomic_set(&dlfb->lost_pixels, 1); in dlfb_urb_completion()
1796 urb->transfer_buffer_length = dlfb->urbs.size; /* reset to actual */ in dlfb_urb_completion()
1798 spin_lock_irqsave(&dlfb->urbs.lock, flags); in dlfb_urb_completion()
1799 list_add_tail(&unode->entry, &dlfb->urbs.list); in dlfb_urb_completion()
1800 dlfb->urbs.available++; in dlfb_urb_completion()
1801 spin_unlock_irqrestore(&dlfb->urbs.lock, flags); in dlfb_urb_completion()
1803 up(&dlfb->urbs.limit_sem); in dlfb_urb_completion()
1806 static void dlfb_free_urb_list(struct dlfb_data *dlfb) in dlfb_free_urb_list() argument
1808 int count = dlfb->urbs.count; in dlfb_free_urb_list()
1815 down(&dlfb->urbs.limit_sem); in dlfb_free_urb_list()
1817 spin_lock_irq(&dlfb->urbs.lock); in dlfb_free_urb_list()
1819 node = dlfb->urbs.list.next; /* have reserved one with sem */ in dlfb_free_urb_list()
1822 spin_unlock_irq(&dlfb->urbs.lock); in dlfb_free_urb_list()
1828 usb_free_coherent(urb->dev, dlfb->urbs.size, in dlfb_free_urb_list()
1834 dlfb->urbs.count = 0; in dlfb_free_urb_list()
1837 static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size) in dlfb_alloc_urb_list() argument
1844 spin_lock_init(&dlfb->urbs.lock); in dlfb_alloc_urb_list()
1847 dlfb->urbs.size = size; in dlfb_alloc_urb_list()
1848 INIT_LIST_HEAD(&dlfb->urbs.list); in dlfb_alloc_urb_list()
1850 sema_init(&dlfb->urbs.limit_sem, 0); in dlfb_alloc_urb_list()
1851 dlfb->urbs.count = 0; in dlfb_alloc_urb_list()
1852 dlfb->urbs.available = 0; in dlfb_alloc_urb_list()
1854 while (dlfb->urbs.count * size < wanted_size) { in dlfb_alloc_urb_list()
1858 unode->dlfb = dlfb; in dlfb_alloc_urb_list()
1867 buf = usb_alloc_coherent(dlfb->udev, size, GFP_KERNEL, in dlfb_alloc_urb_list()
1874 dlfb_free_urb_list(dlfb); in dlfb_alloc_urb_list()
1881 usb_fill_bulk_urb(urb, dlfb->udev, in dlfb_alloc_urb_list()
1882 usb_sndbulkpipe(dlfb->udev, OUT_EP_NUM), in dlfb_alloc_urb_list()
1886 list_add_tail(&unode->entry, &dlfb->urbs.list); in dlfb_alloc_urb_list()
1888 up(&dlfb->urbs.limit_sem); in dlfb_alloc_urb_list()
1889 dlfb->urbs.count++; in dlfb_alloc_urb_list()
1890 dlfb->urbs.available++; in dlfb_alloc_urb_list()
1893 return dlfb->urbs.count; in dlfb_alloc_urb_list()
1896 static struct urb *dlfb_get_urb(struct dlfb_data *dlfb) in dlfb_get_urb() argument
1903 ret = down_timeout(&dlfb->urbs.limit_sem, GET_URB_TIMEOUT); in dlfb_get_urb()
1905 atomic_set(&dlfb->lost_pixels, 1); in dlfb_get_urb()
1906 dev_warn(&dlfb->udev->dev, in dlfb_get_urb()
1908 ret, dlfb->urbs.available); in dlfb_get_urb()
1912 spin_lock_irq(&dlfb->urbs.lock); in dlfb_get_urb()
1914 BUG_ON(list_empty(&dlfb->urbs.list)); /* reserved one with limit_sem */ in dlfb_get_urb()
1915 entry = dlfb->urbs.list.next; in dlfb_get_urb()
1917 dlfb->urbs.available--; in dlfb_get_urb()
1919 spin_unlock_irq(&dlfb->urbs.lock); in dlfb_get_urb()
1925 static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb *urb, size_t len) in dlfb_submit_urb() argument
1929 BUG_ON(len > dlfb->urbs.size); in dlfb_submit_urb()
1935 atomic_set(&dlfb->lost_pixels, 1); in dlfb_submit_urb()
1936 dev_err(&dlfb->udev->dev, "submit urb error: %d\n", ret); in dlfb_submit_urb()